summaryrefslogtreecommitdiff
path: root/sw/source/core/fields/reffld.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/fields/reffld.cxx')
-rw-r--r--sw/source/core/fields/reffld.cxx1099
1 files changed, 1099 insertions, 0 deletions
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
new file mode 100644
index 000000000000..8b03b7e54664
--- /dev/null
+++ b/sw/source/core/fields/reffld.cxx
@@ -0,0 +1,1099 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#define _SVSTDARR_USHORTSSORT
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include <com/sun/star/text/ReferenceFieldPart.hpp>
+#include <com/sun/star/text/ReferenceFieldSource.hpp>
+#include <unotools/localedatawrapper.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <editeng/unolingu.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <cntfrm.hxx>
+#include <pagefrm.hxx>
+#include <docary.hxx>
+#include <fmtfld.hxx>
+#include <txtfld.hxx>
+#include <txtftn.hxx>
+#include <fmtrfmrk.hxx>
+#include <txtrfmrk.hxx>
+#include <fmtftn.hxx>
+#include <ndtxt.hxx>
+#include <chpfld.hxx>
+#include <reffld.hxx>
+#include <expfld.hxx>
+#include <txtfrm.hxx>
+#include <flyfrm.hxx>
+#include <pagedesc.hxx>
+#include <IMark.hxx>
+// --> OD 2007-10-18 #i81002#
+#include <crossrefbookmark.hxx>
+// <--
+#include <ftnidx.hxx>
+#include <viewsh.hxx>
+#ifndef _UNOFLDMID_H
+#include <unofldmid.h>
+#endif
+#include <SwStyleNameMapper.hxx>
+#include <shellres.hxx>
+#include <poolfmt.hxx>
+#ifndef _POOLFMT_HRC
+#include <poolfmt.hrc>
+#endif
+#ifndef _COMCORE_HRC
+#include <comcore.hrc>
+#endif
+#include <numrule.hxx>
+#include <SwNodeNum.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::lang;
+using ::rtl::OUString;
+
+extern void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 );
+
+void lcl_GetLayTree( const SwFrm* pFrm, SvPtrarr& rArr )
+{
+ while( pFrm )
+ {
+ if( pFrm->IsBodyFrm() ) // soll uns nicht weiter interessieren
+ pFrm = pFrm->GetUpper();
+ else
+ {
+ void* p = (void*)pFrm;
+ rArr.Insert( p, rArr.Count() );
+
+ // bei der Seite ist schluss
+ if( pFrm->IsPageFrm() )
+ break;
+
+ if( pFrm->IsFlyFrm() )
+ pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
+ else
+ pFrm = pFrm->GetUpper();
+ }
+ }
+}
+
+
+BOOL IsFrameBehind( const SwTxtNode& rMyNd, USHORT nMySttPos,
+ const SwTxtNode& rBehindNd, USHORT nSttPos )
+{
+ const SwTxtFrm *pMyFrm = (SwTxtFrm*)rMyNd.GetFrm(0,0,FALSE),
+ *pFrm = (SwTxtFrm*)rBehindNd.GetFrm(0,0,FALSE);
+
+ while( pFrm && !pFrm->IsInside( nSttPos ) )
+ pFrm = (SwTxtFrm*)pFrm->GetFollow();
+ while( pMyFrm && !pMyFrm->IsInside( nMySttPos ) )
+ pMyFrm = (SwTxtFrm*)pMyFrm->GetFollow();
+
+ if( !pFrm || !pMyFrm || pFrm == pMyFrm )
+ return FALSE;
+
+ SvPtrarr aRefArr( 10, 10 ), aArr( 10, 10 );
+ ::lcl_GetLayTree( pFrm, aRefArr );
+ ::lcl_GetLayTree( pMyFrm, aArr );
+
+ USHORT nRefCnt = aRefArr.Count() - 1, nCnt = aArr.Count() - 1;
+ BOOL bVert = FALSE;
+ BOOL bR2L = FALSE;
+
+ // solange bis ein Frame ungleich ist ?
+ while( nRefCnt && nCnt && aRefArr[ nRefCnt ] == aArr[ nCnt ] )
+ {
+ const SwFrm* pTmpFrm = (const SwFrm*)aArr[ nCnt ];
+ bVert = pTmpFrm->IsVertical();
+ bR2L = pTmpFrm->IsRightToLeft();
+ --nCnt, --nRefCnt;
+ }
+
+ // sollte einer der Counter ueberlaeufen?
+ if( aRefArr[ nRefCnt ] == aArr[ nCnt ] )
+ {
+ if( nCnt )
+ --nCnt;
+ else
+ --nRefCnt;
+ }
+
+ const SwFrm* pRefFrm = (const SwFrm*)aRefArr[ nRefCnt ];
+ const SwFrm* pFldFrm = (const SwFrm*)aArr[ nCnt ];
+
+ // unterschiedliche Frames, dann ueberpruefe deren Y-/X-Position
+ BOOL bRefIsLower = FALSE;
+ if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() ||
+ ( FRM_COLUMN | FRM_CELL ) & pRefFrm->GetType() )
+ {
+ if( pFldFrm->GetType() == pRefFrm->GetType() )
+ {
+ // hier ist die X-Pos wichtiger!
+ if( bVert )
+ {
+ if( bR2L )
+ bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
+ ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
+ pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
+ else
+ bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
+ ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
+ pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
+ }
+ else if( bR2L )
+ bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
+ ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
+ pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
+ else
+ bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
+ ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
+ pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
+ pRefFrm = 0;
+ }
+ else if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() )
+ pFldFrm = (const SwFrm*)aArr[ nCnt - 1 ];
+ else
+ pRefFrm = (const SwFrm*)aRefArr[ nRefCnt - 1 ];
+ }
+
+ if( pRefFrm ) // als Flag missbrauchen
+ {
+ if( bVert )
+ {
+ if( bR2L )
+ bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
+ ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
+ pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
+ else
+ bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
+ ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
+ pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
+ }
+ else if( bR2L )
+ bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
+ ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
+ pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
+ else
+ bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
+ ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
+ pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
+ }
+ return bRefIsLower;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Referenzen holen
+ --------------------------------------------------------------------*/
+
+
+SwGetRefField::SwGetRefField( SwGetRefFieldType* pFldType,
+ const String& rSetRef, USHORT nSubTyp,
+ USHORT nSeqenceNo, ULONG nFmt )
+ : SwField( pFldType, nFmt ),
+ sSetRefName( rSetRef ),
+ nSubType( nSubTyp ),
+ nSeqNo( nSeqenceNo )
+{
+}
+
+SwGetRefField::~SwGetRefField()
+{
+}
+
+String SwGetRefField::GetDescription() const
+{
+ return SW_RES(STR_REFERENCE);
+}
+
+USHORT SwGetRefField::GetSubType() const
+{
+ return nSubType;
+}
+
+void SwGetRefField::SetSubType( USHORT n )
+{
+ nSubType = n;
+}
+
+// --> OD 2007-11-09 #i81002#
+bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const
+{
+ return GetSubType() == REF_BOOKMARK &&
+ ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName);
+}
+
+bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
+{
+ return GetSubType() == REF_BOOKMARK &&
+ ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName);
+}
+
+const SwTxtNode* SwGetRefField::GetReferencedTxtNode() const
+{
+ SwDoc* pDoc = dynamic_cast<SwGetRefFieldType*>(GetTyp())->GetDoc();
+ USHORT nDummy = USHRT_MAX;
+ return SwGetRefFieldType::FindAnchor( pDoc, sSetRefName, nSubType, nSeqNo, &nDummy );
+}
+// <--
+// --> OD 2008-01-09 #i85090#
+String SwGetRefField::GetExpandedTxtOfReferencedTxtNode() const
+{
+ const SwTxtNode* pReferencedTxtNode( GetReferencedTxtNode() );
+ return pReferencedTxtNode
+ ? pReferencedTxtNode->GetExpandTxt( 0, STRING_LEN, true, true )
+ : aEmptyStr;
+}
+
+String SwGetRefField::Expand() const
+{
+ return sTxt;
+}
+
+
+String SwGetRefField::GetCntnt(BOOL bName) const
+{
+ if( !bName )
+ return Expand();
+
+ String aStr(GetTyp()->GetName());
+ aStr += ' ';
+ aStr += sSetRefName;
+ return aStr;
+}
+
+// --> OD 2007-09-07 #i81002# - parameter <pFldTxtAttr> added
+void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
+{
+ sTxt.Erase();
+
+ SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
+ USHORT nStt = USHRT_MAX;
+ USHORT nEnd = USHRT_MAX;
+ SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( pDoc, sSetRefName,
+ nSubType, nSeqNo, &nStt, &nEnd );
+ if ( !pTxtNd )
+ {
+ sTxt = ViewShell::GetShellRes()->aGetRefFld_RefItemNotFound;
+ return ;
+ }
+
+ switch( GetFormat() )
+ {
+ case REF_CONTENT:
+ case REF_ONLYNUMBER:
+ case REF_ONLYCAPTION:
+ case REF_ONLYSEQNO:
+ {
+ switch( nSubType )
+ {
+ case REF_SEQUENCEFLD:
+ nEnd = pTxtNd->GetTxt().Len();
+ switch( GetFormat() )
+ {
+ case REF_ONLYNUMBER:
+ if( nStt + 1 < nEnd )
+ nEnd = nStt + 1;
+ nStt = 0;
+ break;
+
+ case REF_ONLYCAPTION:
+ {
+ const SwTxtAttr* const pTxtAttr =
+ pTxtNd->GetTxtAttrForCharAt(nStt, RES_TXTATR_FIELD);
+ if( pTxtAttr )
+ nStt = SwGetExpField::GetReferenceTextPos(
+ pTxtAttr->GetFld(), *pDoc );
+ else if( nStt + 1 < nEnd )
+ ++nStt;
+ }
+ break;
+
+ case REF_ONLYSEQNO:
+ if( nStt + 1 < nEnd )
+ nEnd = nStt + 1;
+ break;
+
+ default:
+ nStt = 0;
+ break;
+ }
+ break;
+
+ case REF_BOOKMARK:
+ if( USHRT_MAX == nEnd )
+ {
+ // Text steht ueber verschiedene Nodes verteilt.
+ // Gesamten Text oder nur bis zum Ende vom Node?
+ nEnd = pTxtNd->GetTxt().Len();
+ }
+ break;
+
+ case REF_OUTLINE:
+ break;
+
+ case REF_FOOTNOTE:
+ case REF_ENDNOTE:
+ {
+ // die Nummer oder den NumString besorgen
+ USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+ SwTxtFtn* pFtnIdx;
+ for( n = 0; n < nFtnCnt; ++n )
+ if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
+ {
+ sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
+ break;
+ }
+ nStt = nEnd; // kein Bereich, der String ist fertig
+ }
+ break;
+ }
+
+ if( nStt != nEnd ) // ein Bereich?
+ {
+ sTxt = pTxtNd->GetExpandTxt( nStt, nEnd - nStt );
+
+ // alle Sonderzeichen entfernen (durch Blanks ersetzen):
+ if( sTxt.Len() )
+ {
+ sTxt.EraseAllChars( 0xad );
+ for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p )
+ {
+ if( *p < 0x20 )
+ *p = 0x20;
+ else if(*p == 0x2011)
+ *p = '-';
+ }
+ }
+ }
+ }
+ break;
+
+ case REF_PAGE:
+ case REF_PAGE_PGDESC:
+ {
+ const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->GetFrm(0,0,FALSE),
+ *pSave = pFrm;
+ while( pFrm && !pFrm->IsInside( nStt ) )
+ pFrm = (SwTxtFrm*)pFrm->GetFollow();
+
+ if( pFrm || 0 != ( pFrm = pSave ))
+ {
+ USHORT nPageNo = pFrm->GetVirtPageNum();
+ const SwPageFrm *pPage;
+ if( REF_PAGE_PGDESC == GetFormat() &&
+ 0 != ( pPage = pFrm->FindPageFrm() ) &&
+ pPage->GetPageDesc() )
+ sTxt = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo );
+ else
+ sTxt = String::CreateFromInt32(nPageNo);
+ }
+ }
+ break;
+
+ case REF_CHAPTER:
+ {
+ // ein bischen trickreich: suche irgend einen Frame
+ const SwFrm* pFrm = pTxtNd->GetFrm();
+ if( pFrm )
+ {
+ SwChapterFieldType aFldTyp;
+ SwChapterField aFld( &aFldTyp, 0 );
+ aFld.SetLevel( MAXLEVEL - 1 );
+ aFld.ChangeExpansion( pFrm, pTxtNd, TRUE );
+ sTxt = aFld.GetNumber();
+ }
+ }
+ break;
+
+ case REF_UPDOWN:
+ {
+ // --> OD 2007-09-07 #i81002#
+ // simplified: use parameter <pFldTxtAttr>
+ if( !pFldTxtAttr || !pFldTxtAttr->GetpTxtNode() )
+ break;
+
+ LocaleDataWrapper aLocaleData(
+ ::comphelper::getProcessServiceFactory(),
+ SvxCreateLocale( GetLanguage() ) );
+
+ // erstmal ein "Kurz" - Test - falls beide im selben
+ // Node stehen!
+ if( pFldTxtAttr->GetpTxtNode() == pTxtNd )
+ {
+ sTxt = nStt < *pFldTxtAttr->GetStart()
+ ? aLocaleData.getAboveWord()
+ : aLocaleData.getBelowWord();
+ break;
+ }
+
+ sTxt = ::IsFrameBehind( *pFldTxtAttr->GetpTxtNode(), *pFldTxtAttr->GetStart(),
+ *pTxtNd, nStt )
+ ? aLocaleData.getAboveWord()
+ : aLocaleData.getBelowWord();
+ }
+ break;
+ // --> OD 2007-08-24 #i81002#
+ case REF_NUMBER:
+ case REF_NUMBER_NO_CONTEXT:
+ case REF_NUMBER_FULL_CONTEXT:
+ {
+ if ( pFldTxtAttr && pFldTxtAttr->GetpTxtNode() )
+ {
+ sTxt = MakeRefNumStr( pFldTxtAttr->GetTxtNode(), *pTxtNd, GetFormat() );
+ }
+ }
+ break;
+ // <--
+ default:
+ DBG_ERROR("<SwGetRefField::UpdateField(..)> - unknown format type");
+ }
+}
+
+// --> OD 2007-09-06 #i81002#
+String SwGetRefField::MakeRefNumStr( const SwTxtNode& rTxtNodeOfField,
+ const SwTxtNode& rTxtNodeOfReferencedItem,
+ const sal_uInt32 nRefNumFormat ) const
+{
+ if ( rTxtNodeOfReferencedItem.HasNumber() &&
+ rTxtNodeOfReferencedItem.IsCountedInList() )
+ {
+ ASSERT( rTxtNodeOfReferencedItem.GetNum(),
+ "<SwGetRefField::MakeRefNumStr(..)> - referenced paragraph has number, but no <SwNodeNum> instance --> please inform OD!" );
+
+ // Determine, up to which level the superior list labels have to be
+ // included - default is to include all superior list labels.
+ sal_uInt8 nRestrictInclToThisLevel( 0 );
+ // Determine for format REF_NUMBER the level, up to which the superior
+ // list labels have to be restricted, if the text node of the reference
+ // field and the text node of the referenced item are in the same
+ // document context.
+ if ( nRefNumFormat == REF_NUMBER &&
+ rTxtNodeOfField.FindFlyStartNode()
+ == rTxtNodeOfReferencedItem.FindFlyStartNode() &&
+ rTxtNodeOfField.FindFootnoteStartNode()
+ == rTxtNodeOfReferencedItem.FindFootnoteStartNode() &&
+ rTxtNodeOfField.FindHeaderStartNode()
+ == rTxtNodeOfReferencedItem.FindHeaderStartNode() &&
+ rTxtNodeOfField.FindFooterStartNode()
+ == rTxtNodeOfReferencedItem.FindFooterStartNode() )
+ {
+ const SwNodeNum* pNodeNumForTxtNodeOfField( 0 );
+ if ( rTxtNodeOfField.HasNumber() &&
+ rTxtNodeOfField.GetNumRule() == rTxtNodeOfReferencedItem.GetNumRule() )
+ {
+ pNodeNumForTxtNodeOfField = rTxtNodeOfField.GetNum();
+ }
+ else
+ {
+ pNodeNumForTxtNodeOfField =
+ rTxtNodeOfReferencedItem.GetNum()->GetPrecedingNodeNumOf( rTxtNodeOfField );
+ }
+ if ( pNodeNumForTxtNodeOfField )
+ {
+ const SwNumberTree::tNumberVector rFieldNumVec = pNodeNumForTxtNodeOfField->GetNumberVector();
+ const SwNumberTree::tNumberVector rRefItemNumVec = rTxtNodeOfReferencedItem.GetNum()->GetNumberVector();
+ sal_uInt8 nLevel( 0 );
+ while ( nLevel < rFieldNumVec.size() && nLevel < rRefItemNumVec.size() )
+ {
+ if ( rRefItemNumVec[nLevel] == rFieldNumVec[nLevel] )
+ {
+ nRestrictInclToThisLevel = nLevel + 1;
+ }
+ else
+ {
+ break;
+ }
+ ++nLevel;
+ }
+ }
+ }
+
+ // Determine, if superior list labels have to be included
+ const bool bInclSuperiorNumLabels(
+ ( nRestrictInclToThisLevel < rTxtNodeOfReferencedItem.GetActualListLevel() &&
+ ( nRefNumFormat == REF_NUMBER || nRefNumFormat == REF_NUMBER_FULL_CONTEXT ) ) );
+
+ ASSERT( rTxtNodeOfReferencedItem.GetNumRule(),
+ "<SwGetRefField::MakeRefNumStr(..)> - referenced numbered paragraph has no numbering rule set --> please inform OD!" );
+ return rTxtNodeOfReferencedItem.GetNumRule()->MakeRefNumString(
+ *(rTxtNodeOfReferencedItem.GetNum()),
+ bInclSuperiorNumLabels,
+ nRestrictInclToThisLevel );
+ }
+
+ return String();
+}
+// <--
+
+SwField* SwGetRefField::Copy() const
+{
+ SwGetRefField* pFld = new SwGetRefField( (SwGetRefFieldType*)GetTyp(),
+ sSetRefName, nSubType,
+ nSeqNo, GetFormat() );
+ pFld->sTxt = sTxt;
+ return pFld;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: ReferenzName holen
+ --------------------------------------------------------------------*/
+
+
+const String& SwGetRefField::GetPar1() const
+{
+ return sSetRefName;
+}
+
+
+void SwGetRefField::SetPar1( const String& rName )
+{
+ sSetRefName = rName;
+}
+
+
+String SwGetRefField::GetPar2() const
+{
+ return Expand();
+}
+
+/*-----------------06.03.98 13:34-------------------
+
+--------------------------------------------------*/
+BOOL SwGetRefField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_USHORT1:
+ {
+ sal_Int16 nPart = 0;
+ switch(GetFormat())
+ {
+ case REF_PAGE : nPart = ReferenceFieldPart::PAGE ; break;
+ case REF_CHAPTER : nPart = ReferenceFieldPart::CHAPTER ; break;
+ case REF_CONTENT : nPart = ReferenceFieldPart::TEXT ; break;
+ case REF_UPDOWN : nPart = ReferenceFieldPart::UP_DOWN ; break;
+ case REF_PAGE_PGDESC: nPart = ReferenceFieldPart::PAGE_DESC ; break;
+ case REF_ONLYNUMBER : nPart = ReferenceFieldPart::CATEGORY_AND_NUMBER ; break;
+ case REF_ONLYCAPTION: nPart = ReferenceFieldPart::ONLY_CAPTION ; break;
+ case REF_ONLYSEQNO : nPart = ReferenceFieldPart::ONLY_SEQUENCE_NUMBER; break;
+ // --> OD 2007-09-06 #i81002#
+ case REF_NUMBER: nPart = ReferenceFieldPart::NUMBER; break;
+ case REF_NUMBER_NO_CONTEXT: nPart = ReferenceFieldPart::NUMBER_NO_CONTEXT; break;
+ case REF_NUMBER_FULL_CONTEXT: nPart = ReferenceFieldPart::NUMBER_FULL_CONTEXT; break;
+ // <--
+ }
+ rAny <<= nPart;
+ }
+ break;
+ case FIELD_PROP_USHORT2:
+ {
+ sal_Int16 nSource = 0;
+ switch(nSubType)
+ {
+ case REF_SETREFATTR : nSource = ReferenceFieldSource::REFERENCE_MARK; break;
+ case REF_SEQUENCEFLD: nSource = ReferenceFieldSource::SEQUENCE_FIELD; break;
+ case REF_BOOKMARK : nSource = ReferenceFieldSource::BOOKMARK; break;
+ case REF_OUTLINE : DBG_ERROR("not implemented"); break;
+ case REF_FOOTNOTE : nSource = ReferenceFieldSource::FOOTNOTE; break;
+ case REF_ENDNOTE : nSource = ReferenceFieldSource::ENDNOTE; break;
+ }
+ rAny <<= nSource;
+ }
+ break;
+ case FIELD_PROP_PAR1:
+ {
+ String sTmp(GetPar1());
+ if(REF_SEQUENCEFLD == nSubType)
+ {
+ sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sTmp, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
+ switch( nPoolId )
+ {
+ case RES_POOLCOLL_LABEL_ABB:
+ case RES_POOLCOLL_LABEL_TABLE:
+ case RES_POOLCOLL_LABEL_FRAME:
+ case RES_POOLCOLL_LABEL_DRAWING:
+ SwStyleNameMapper::FillProgName(nPoolId, sTmp) ;
+ break;
+ }
+ }
+ rAny <<= rtl::OUString(sTmp);
+ }
+ break;
+ case FIELD_PROP_PAR3:
+ rAny <<= rtl::OUString(Expand());
+ break;
+ case FIELD_PROP_SHORT1:
+ rAny <<= (sal_Int16)nSeqNo;
+ break;
+ default:
+ DBG_ERROR("illegal property");
+ }
+ return TRUE;
+}
+/*-----------------06.03.98 13:34-------------------
+
+--------------------------------------------------*/
+BOOL SwGetRefField::PutValue( const uno::Any& rAny, USHORT nWhichId )
+{
+ String sTmp;
+ switch( nWhichId )
+ {
+ case FIELD_PROP_USHORT1:
+ {
+ sal_Int16 nPart = 0;
+ rAny >>= nPart;
+ switch(nPart)
+ {
+ case ReferenceFieldPart::PAGE: nPart = REF_PAGE; break;
+ case ReferenceFieldPart::CHAPTER: nPart = REF_CHAPTER; break;
+ case ReferenceFieldPart::TEXT: nPart = REF_CONTENT; break;
+ case ReferenceFieldPart::UP_DOWN: nPart = REF_UPDOWN; break;
+ case ReferenceFieldPart::PAGE_DESC: nPart = REF_PAGE_PGDESC; break;
+ case ReferenceFieldPart::CATEGORY_AND_NUMBER: nPart = REF_ONLYNUMBER; break;
+ case ReferenceFieldPart::ONLY_CAPTION: nPart = REF_ONLYCAPTION; break;
+ case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER : nPart = REF_ONLYSEQNO; break;
+ // --> OD 2007-09-06 #i81002#
+ case ReferenceFieldPart::NUMBER: nPart = REF_NUMBER; break;
+ case ReferenceFieldPart::NUMBER_NO_CONTEXT: nPart = REF_NUMBER_NO_CONTEXT; break;
+ case ReferenceFieldPart::NUMBER_FULL_CONTEXT: nPart = REF_NUMBER_FULL_CONTEXT; break;
+ // <--
+ default: return FALSE;
+ }
+ SetFormat(nPart);
+ }
+ break;
+ case FIELD_PROP_USHORT2:
+ {
+ sal_Int16 nSource = 0;
+ rAny >>= nSource;
+ switch(nSource)
+ {
+ case ReferenceFieldSource::REFERENCE_MARK : nSubType = REF_SETREFATTR ; break;
+ case ReferenceFieldSource::SEQUENCE_FIELD :
+ {
+ if(REF_SEQUENCEFLD == nSubType)
+ break;
+ nSubType = REF_SEQUENCEFLD;
+ ConvertProgrammaticToUIName();
+ }
+ break;
+ case ReferenceFieldSource::BOOKMARK : nSubType = REF_BOOKMARK ; break;
+ case ReferenceFieldSource::FOOTNOTE : nSubType = REF_FOOTNOTE ; break;
+ case ReferenceFieldSource::ENDNOTE : nSubType = REF_ENDNOTE ; break;
+ }
+ }
+ break;
+ case FIELD_PROP_PAR1:
+ {
+ OUString sTmpStr;
+ rAny >>= sTmpStr;
+ SetPar1(sTmpStr);
+ ConvertProgrammaticToUIName();
+ }
+ break;
+ case FIELD_PROP_PAR3:
+ SetExpand( ::GetString( rAny, sTmp ));
+ break;
+ case FIELD_PROP_SHORT1:
+ {
+ sal_Int16 nSetSeq = 0;
+ rAny >>= nSetSeq;
+ if(nSetSeq >= 0)
+ nSeqNo = nSetSeq;
+ }
+ break;
+ default:
+ DBG_ERROR("illegal property");
+ }
+ return TRUE;
+}
+/* -----------------------------11.01.2002 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwGetRefField::ConvertProgrammaticToUIName()
+{
+ if(GetTyp() && REF_SEQUENCEFLD == nSubType)
+ {
+ SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
+ const String& rPar1 = GetPar1();
+ //don't convert when the name points to an existing field type
+ if(!pDoc->GetFldType(RES_SETEXPFLD, rPar1, false))
+ {
+ sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromProgName( rPar1, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
+ USHORT nResId = USHRT_MAX;
+ switch( nPoolId )
+ {
+ case RES_POOLCOLL_LABEL_ABB:
+ nResId = STR_POOLCOLL_LABEL_ABB;
+ break;
+ case RES_POOLCOLL_LABEL_TABLE:
+ nResId = STR_POOLCOLL_LABEL_TABLE;
+ break;
+ case RES_POOLCOLL_LABEL_FRAME:
+ nResId = STR_POOLCOLL_LABEL_FRAME;
+ break;
+ case RES_POOLCOLL_LABEL_DRAWING:
+ nResId = STR_POOLCOLL_LABEL_DRAWING;
+ break;
+ }
+ if( nResId != USHRT_MAX )
+ SetPar1(SW_RESSTR( nResId ));
+ }
+ }
+}
+/*-----------------JP: 18.06.93 -------------------
+ Get-Referenz-Type
+ --------------------------------------------------*/
+
+
+SwGetRefFieldType::SwGetRefFieldType( SwDoc* pDc )
+ : SwFieldType( RES_GETREFFLD ), pDoc( pDc )
+{}
+
+
+SwFieldType* SwGetRefFieldType::Copy() const
+{
+ return new SwGetRefFieldType( pDoc );
+}
+
+
+void SwGetRefFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+ // Update auf alle GetReferenz-Felder
+ if( !pNew && !pOld )
+ {
+ SwClientIter aIter( *this );
+ for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+ pFld; pFld = (SwFmtFld*)aIter.Next() )
+ {
+ // nur die GetRef-Felder Updaten
+ //JP 3.4.2001: Task 71231 - we need the correct language
+ SwGetRefField* pGRef = (SwGetRefField*)pFld->GetFld();
+ const SwTxtFld* pTFld;
+ if( !pGRef->GetLanguage() &&
+ 0 != ( pTFld = pFld->GetTxtFld()) &&
+ pTFld->GetpTxtNode() )
+ {
+ pGRef->SetLanguage( pTFld->GetpTxtNode()->GetLang(
+ *pTFld->GetStart() ) );
+ }
+
+ // --> OD 2007-09-06 #i81002#
+ pGRef->UpdateField( pFld->GetTxtFld() );
+ // <--
+ }
+ }
+ // weiter an die Text-Felder, diese "Expandieren" den Text
+ SwModify::Modify( pOld, pNew );
+}
+
+SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark,
+ USHORT nSubType, USHORT nSeqNo,
+ USHORT* pStt, USHORT* pEnd )
+{
+ ASSERT( pStt, "warum wird keine StartPos abgefragt?" );
+
+ SwTxtNode* pTxtNd = 0;
+ switch( nSubType )
+ {
+ case REF_SETREFATTR:
+ {
+ const SwFmtRefMark *pRef = pDoc->GetRefMark( rRefMark );
+ if( pRef && pRef->GetTxtRefMark() )
+ {
+ pTxtNd = (SwTxtNode*)&pRef->GetTxtRefMark()->GetTxtNode();
+ *pStt = *pRef->GetTxtRefMark()->GetStart();
+ if( pEnd )
+ *pEnd = *pRef->GetTxtRefMark()->GetAnyEnd();
+ }
+ }
+ break;
+
+ case REF_SEQUENCEFLD:
+ {
+ SwFieldType* pFldType = pDoc->GetFldType( RES_SETEXPFLD, rRefMark, false );
+ if( pFldType && pFldType->GetDepends() &&
+ nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType*)pFldType)->GetType() )
+ {
+ SwClientIter aIter( *pFldType );
+ for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+ pFld; pFld = (SwFmtFld*)aIter.Next() )
+ {
+ if( pFld->GetTxtFld() && nSeqNo ==
+ ((SwSetExpField*)pFld->GetFld())->GetSeqNumber() )
+ {
+ SwTxtFld* pTxtFld = pFld->GetTxtFld();
+ pTxtNd = (SwTxtNode*)pTxtFld->GetpTxtNode();
+ *pStt = *pTxtFld->GetStart();
+ if( pEnd )
+ *pEnd = (*pStt) + 1;
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case REF_BOOKMARK:
+ {
+ IDocumentMarkAccess::const_iterator_t ppMark = pDoc->getIDocumentMarkAccess()->findMark(rRefMark);
+ if(ppMark != pDoc->getIDocumentMarkAccess()->getMarksEnd())
+ {
+ const ::sw::mark::IMark* pBkmk = ppMark->get();
+ const SwPosition* pPos = &pBkmk->GetMarkStart();
+
+ pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
+ *pStt = pPos->nContent.GetIndex();
+ if(pEnd)
+ {
+ if(!pBkmk->IsExpanded())
+ {
+ *pEnd = *pStt;
+ // --> OD 2007-10-18 #i81002#
+ if(dynamic_cast< ::sw::mark::CrossRefBookmark const *>(pBkmk))
+ {
+ ASSERT( pTxtNd,
+ "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" );
+ *pEnd = pTxtNd->Len();
+ }
+ // <--
+ }
+ else if(pBkmk->GetOtherMarkPos().nNode == pBkmk->GetMarkPos().nNode)
+ *pEnd = pBkmk->GetMarkEnd().nContent.GetIndex();
+ else
+ *pEnd = USHRT_MAX;
+ }
+ }
+ }
+ break;
+
+ case REF_OUTLINE:
+ break;
+
+ case REF_FOOTNOTE:
+ case REF_ENDNOTE:
+ {
+ USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+ SwTxtFtn* pFtnIdx;
+ for( n = 0; n < nFtnCnt; ++n )
+ if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
+ {
+ SwNodeIndex* pIdx = pFtnIdx->GetStartNode();
+ if( pIdx )
+ {
+ SwNodeIndex aIdx( *pIdx, 1 );
+ if( 0 == ( pTxtNd = aIdx.GetNode().GetTxtNode()))
+ pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
+ }
+ *pStt = 0;
+ if( pEnd )
+ *pEnd = 0;
+ break;
+ }
+ }
+ break;
+ }
+
+ return pTxtNd;
+}
+
+
+struct _RefIdsMap
+{
+ String aName;
+ SvUShortsSort aIds, aDstIds, aIdsMap;
+ SvUShorts aMap;
+ BOOL bInit;
+
+ _RefIdsMap( const String& rName )
+ : aName( rName ), aIds( 16, 16 ), aIdsMap( 16, 16 ), aMap( 16, 16 ),
+ bInit( FALSE )
+ {}
+
+ void Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
+ BOOL bField = TRUE );
+
+ BOOL IsInit() const { return bInit; }
+};
+
+SV_DECL_PTRARR_DEL( _RefIdsMaps, _RefIdsMap*, 5, 5 )
+SV_IMPL_PTRARR( _RefIdsMaps, _RefIdsMap* )
+
+void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
+ BOOL bField )
+{
+
+ if( !bInit )
+ {
+ if( bField )
+ {
+ const SwTxtNode* pNd;
+ SwModify* pMod;
+ if( 0 != ( pMod = rDestDoc.GetFldType( RES_SETEXPFLD, aName, false ) ))
+ {
+ SwClientIter aIter( *pMod );
+ for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+ pF = (SwFmtFld*)aIter.Next() )
+ if( pF->GetTxtFld() &&
+ 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+ pNd->GetNodes().IsDocNodes() )
+ aIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+ }
+ if( 0 != ( pMod = rDoc.GetFldType( RES_SETEXPFLD, aName, false ) ))
+ {
+ SwClientIter aIter( *pMod );
+ for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+ pF = (SwFmtFld*)aIter.Next() )
+ if( pF->GetTxtFld() &&
+ 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+ pNd->GetNodes().IsDocNodes() )
+ aDstIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+ }
+ }
+ else
+ {
+ USHORT n;
+
+ for( n = rDestDoc.GetFtnIdxs().Count(); n; )
+ aIds.Insert( rDestDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
+ for( n = rDoc.GetFtnIdxs().Count(); n; )
+ aDstIds.Insert( rDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
+ }
+ bInit = TRUE;
+ }
+
+ // dann teste mal, ob die Nummer schon vergeben ist
+ // oder ob eine neue bestimmt werden muss.
+ USHORT nPos, nSeqNo = rFld.GetSeqNo();
+ if( aIds.Seek_Entry( nSeqNo ) && aDstIds.Seek_Entry( nSeqNo ))
+ {
+ // ist schon vergeben, also muss eine neue
+ // erzeugt werden.
+ if( aIdsMap.Seek_Entry( nSeqNo, &nPos ))
+ rFld.SetSeqNo( aMap[ nPos ] );
+ else
+ {
+ USHORT n;
+
+ for( n = 0; n < aIds.Count(); ++n )
+ if( n != aIds[ n ] )
+ break;
+
+ // die neue SeqNo eintragen, damit die "belegt" ist
+ aIds.Insert( n );
+ aIdsMap.Insert( nSeqNo, nPos );
+ aMap.Insert( n, nPos );
+ rFld.SetSeqNo( n );
+
+ // und noch die Felder oder Fuss-/EndNote auf die neue
+ // Id umsetzen
+ if( bField )
+ {
+ SwModify* pMod = rDoc.GetFldType( RES_SETEXPFLD, aName, false );
+ if( pMod )
+ {
+ SwClientIter aIter( *pMod );
+ for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+ pF = (SwFmtFld*)aIter.Next() )
+ if( pF->GetTxtFld() && nSeqNo ==
+ ((SwSetExpField*)pF->GetFld())->GetSeqNumber() )
+ ((SwSetExpField*)pF->GetFld())->SetSeqNumber( n );
+ }
+ }
+ else
+ {
+ SwTxtFtn* pFtnIdx;
+ for( USHORT i = 0, nCnt = rDoc.GetFtnIdxs().Count(); i < nCnt; ++i )
+ if( nSeqNo == (pFtnIdx = rDoc.GetFtnIdxs()[ i ])->GetSeqRefNo() )
+ {
+ pFtnIdx->SetSeqNo( n );
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ aIds.Insert( nSeqNo );
+ aIdsMap.Insert( nSeqNo, nPos );
+ aMap.Insert( nSeqNo, nPos );
+ }
+}
+
+
+void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc )
+{
+ if( &rDestDoc != pDoc &&
+ rDestDoc.GetSysFldType( RES_GETREFFLD )->GetDepends() )
+ {
+ // dann gibt es im DestDoc RefFelder, also muessen im SourceDoc
+ // alle RefFelder auf einduetige Ids in beiden Docs umgestellt
+ // werden.
+ _RefIdsMap aFntMap( aEmptyStr );
+ _RefIdsMaps aFldMap;
+
+ SwClientIter aIter( *this );
+ for( SwClient* pFld = aIter.First( TYPE( SwFmtFld ));
+ pFld; pFld = aIter.Next() )
+ {
+ SwGetRefField& rRefFld = *(SwGetRefField*)((SwFmtFld*)pFld)->GetFld();
+ switch( rRefFld.GetSubType() )
+ {
+ case REF_SEQUENCEFLD:
+ {
+ _RefIdsMap* pMap = 0;
+ for( USHORT n = aFldMap.Count(); n; )
+ if( aFldMap[ --n ]->aName == rRefFld.GetSetRefName() )
+ {
+ pMap = aFldMap[ n ];
+ break;
+ }
+ if( !pMap )
+ {
+ pMap = new _RefIdsMap( rRefFld.GetSetRefName() );
+ aFldMap.C40_INSERT( _RefIdsMap, pMap, aFldMap.Count() );
+ }
+
+ pMap->Check( *pDoc, rDestDoc, rRefFld, TRUE );
+ }
+ break;
+
+ case REF_FOOTNOTE:
+ case REF_ENDNOTE:
+ aFntMap.Check( *pDoc, rDestDoc, rRefFld, FALSE );
+ break;
+ }
+ }
+ }
+}
+