LCOV - code coverage report
Current view: top level - sw/source/core/fields - reffld.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 165 525 31.4 %
Date: 2014-11-03 Functions: 18 39 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/text/ReferenceFieldPart.hpp>
      21             : #include <com/sun/star/text/ReferenceFieldSource.hpp>
      22             : #include <unotools/localedatawrapper.hxx>
      23             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      24             : #include <comphelper/processfactory.hxx>
      25             : #include <comphelper/string.hxx>
      26             : #include <editeng/unolingu.hxx>
      27             : #include <doc.hxx>
      28             : #include <IDocumentFieldsAccess.hxx>
      29             : #include <IDocumentLayoutAccess.hxx>
      30             : #include <pam.hxx>
      31             : #include <cntfrm.hxx>
      32             : #include <pagefrm.hxx>
      33             : #include <docary.hxx>
      34             : #include <fmtfld.hxx>
      35             : #include <txtfld.hxx>
      36             : #include <txtftn.hxx>
      37             : #include <fmtrfmrk.hxx>
      38             : #include <txtrfmrk.hxx>
      39             : #include <fmtftn.hxx>
      40             : #include <ndtxt.hxx>
      41             : #include <chpfld.hxx>
      42             : #include <reffld.hxx>
      43             : #include <expfld.hxx>
      44             : #include <txtfrm.hxx>
      45             : #include <flyfrm.hxx>
      46             : #include <pagedesc.hxx>
      47             : #include <IMark.hxx>
      48             : #include <crossrefbookmark.hxx>
      49             : #include <ftnidx.hxx>
      50             : #include <viewsh.hxx>
      51             : #include <unofldmid.h>
      52             : #include <SwStyleNameMapper.hxx>
      53             : #include <shellres.hxx>
      54             : #include <poolfmt.hxx>
      55             : #include <poolfmt.hrc>
      56             : #include <comcore.hrc>
      57             : #include <numrule.hxx>
      58             : #include <SwNodeNum.hxx>
      59             : #include <switerator.hxx>
      60             : 
      61             : #include <set>
      62             : #include <map>
      63             : #include <algorithm>
      64             : 
      65             : #include <sfx2/childwin.hxx>
      66             : 
      67             : using namespace ::com::sun::star;
      68             : using namespace ::com::sun::star::text;
      69             : using namespace ::com::sun::star::lang;
      70             : 
      71           0 : static void lcl_GetLayTree( const SwFrm* pFrm, std::vector<const SwFrm*>& rArr )
      72             : {
      73           0 :     while( pFrm )
      74             :     {
      75           0 :         if( pFrm->IsBodyFrm() ) // unspectacular
      76           0 :             pFrm = pFrm->GetUpper();
      77             :         else
      78             :         {
      79           0 :             rArr.push_back( pFrm );
      80             : 
      81             :             // this is the last page
      82           0 :             if( pFrm->IsPageFrm() )
      83           0 :                 break;
      84             : 
      85           0 :             if( pFrm->IsFlyFrm() )
      86           0 :                 pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
      87             :             else
      88           0 :                 pFrm = pFrm->GetUpper();
      89             :         }
      90             :     }
      91           0 : }
      92             : 
      93           0 : bool IsFrameBehind( const SwTxtNode& rMyNd, sal_Int32 nMySttPos,
      94             :                     const SwTxtNode& rBehindNd, sal_Int32 nSttPos )
      95             : {
      96           0 :     const SwTxtFrm *pMyFrm = (SwTxtFrm*)rMyNd.getLayoutFrm( rMyNd.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), 0, 0, false),
      97           0 :                    *pFrm = (SwTxtFrm*)rBehindNd.getLayoutFrm( rBehindNd.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), 0, 0, false);
      98             : 
      99           0 :     while( pFrm && !pFrm->IsInside( nSttPos ) )
     100           0 :         pFrm = (SwTxtFrm*)pFrm->GetFollow();
     101           0 :     while( pMyFrm && !pMyFrm->IsInside( nMySttPos ) )
     102           0 :         pMyFrm = (SwTxtFrm*)pMyFrm->GetFollow();
     103             : 
     104           0 :     if( !pFrm || !pMyFrm || pFrm == pMyFrm )
     105           0 :         return false;
     106             : 
     107           0 :     std::vector<const SwFrm*> aRefArr, aArr;
     108           0 :     ::lcl_GetLayTree( pFrm, aRefArr );
     109           0 :     ::lcl_GetLayTree( pMyFrm, aArr );
     110             : 
     111           0 :     size_t nRefCnt = aRefArr.size() - 1, nCnt = aArr.size() - 1;
     112           0 :     bool bVert = false;
     113           0 :     bool bR2L = false;
     114             : 
     115             :     // Loop as long as a frame does not equal?
     116           0 :     while( nRefCnt && nCnt && aRefArr[ nRefCnt ] == aArr[ nCnt ] )
     117             :     {
     118           0 :         const SwFrm* pTmpFrm = aArr[ nCnt ];
     119           0 :         bVert = pTmpFrm->IsVertical();
     120           0 :         bR2L = pTmpFrm->IsRightToLeft();
     121           0 :         --nCnt, --nRefCnt;
     122             :     }
     123             : 
     124             :     // If a counter overflows?
     125           0 :     if( aRefArr[ nRefCnt ] == aArr[ nCnt ] )
     126             :     {
     127           0 :         if( nCnt )
     128           0 :             --nCnt;
     129             :         else
     130           0 :             --nRefCnt;
     131             :     }
     132             : 
     133           0 :     const SwFrm* pRefFrm = aRefArr[ nRefCnt ];
     134           0 :     const SwFrm* pFldFrm = aArr[ nCnt ];
     135             : 
     136             :     // different frames, check their Y-/X-position
     137           0 :     bool bRefIsLower = false;
     138           0 :     if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() ||
     139           0 :         ( FRM_COLUMN | FRM_CELL ) & pRefFrm->GetType() )
     140             :     {
     141           0 :         if( pFldFrm->GetType() == pRefFrm->GetType() )
     142             :         {
     143             :             // here, the X-pos is more important
     144           0 :             if( bVert )
     145             :             {
     146           0 :                 if( bR2L )
     147           0 :                     bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
     148           0 :                             ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
     149           0 :                               pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
     150             :                 else
     151           0 :                     bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
     152           0 :                             ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
     153           0 :                               pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
     154             :             }
     155           0 :             else if( bR2L )
     156           0 :                 bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
     157           0 :                             ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
     158           0 :                               pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
     159             :             else
     160           0 :                 bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
     161           0 :                             ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
     162           0 :                               pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
     163           0 :             pRefFrm = 0;
     164             :         }
     165           0 :         else if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() )
     166           0 :             pFldFrm = aArr[ nCnt - 1 ];
     167             :         else
     168           0 :             pRefFrm = aRefArr[ nRefCnt - 1 ];
     169             :     }
     170             : 
     171           0 :     if( pRefFrm ) // misuse as flag
     172             :     {
     173           0 :         if( bVert )
     174             :         {
     175           0 :             if( bR2L )
     176           0 :                 bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
     177           0 :                             ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
     178           0 :                                 pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
     179             :             else
     180           0 :                 bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
     181           0 :                             ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
     182           0 :                                 pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
     183             :         }
     184           0 :         else if( bR2L )
     185           0 :             bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
     186           0 :                         ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
     187           0 :                             pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
     188             :         else
     189           0 :             bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
     190           0 :                         ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
     191           0 :                             pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
     192             :     }
     193           0 :     return bRefIsLower;
     194             : }
     195             : 
     196             : /// get references
     197         424 : SwGetRefField::SwGetRefField( SwGetRefFieldType* pFldType,
     198             :                               const OUString& rSetRef, sal_uInt16 nSubTyp,
     199             :                               sal_uInt16 nSeqenceNo, sal_uLong nFmt )
     200             :     : SwField( pFldType, nFmt ),
     201             :       sSetRefName( rSetRef ),
     202             :       nSubType( nSubTyp ),
     203         424 :       nSeqNo( nSeqenceNo )
     204             : {
     205         424 : }
     206             : 
     207         844 : SwGetRefField::~SwGetRefField()
     208             : {
     209         844 : }
     210             : 
     211           0 : OUString SwGetRefField::GetDescription() const
     212             : {
     213           0 :     return SW_RES(STR_REFERENCE);
     214             : }
     215             : 
     216        1464 : sal_uInt16 SwGetRefField::GetSubType() const
     217             : {
     218        1464 :     return nSubType;
     219             : }
     220             : 
     221           0 : void SwGetRefField::SetSubType( sal_uInt16 n )
     222             : {
     223           0 :     nSubType = n;
     224           0 : }
     225             : 
     226             : // #i81002#
     227           0 : bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const
     228             : {
     229           0 :     return GetSubType() == REF_BOOKMARK &&
     230           0 :         ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName);
     231             : }
     232             : 
     233           0 : bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
     234             : {
     235           0 :     return GetSubType() == REF_BOOKMARK &&
     236           0 :         ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName);
     237             : }
     238             : 
     239           0 : const SwTxtNode* SwGetRefField::GetReferencedTxtNode() const
     240             : {
     241           0 :     SwGetRefFieldType *pTyp = dynamic_cast<SwGetRefFieldType*>(GetTyp());
     242           0 :     if (!pTyp)
     243           0 :         return NULL;
     244           0 :     sal_Int32 nDummy = -1;
     245           0 :     return SwGetRefFieldType::FindAnchor( pTyp->GetDoc(), sSetRefName, nSubType, nSeqNo, &nDummy );
     246             : }
     247             : 
     248             : // #i85090#
     249           0 : OUString SwGetRefField::GetExpandedTxtOfReferencedTxtNode() const
     250             : {
     251           0 :     const SwTxtNode* pReferencedTxtNode( GetReferencedTxtNode() );
     252             :     return pReferencedTxtNode
     253             :            ? OUString(pReferencedTxtNode->GetExpandTxt( 0, -1, true, true, false, false ))
     254           0 :            : OUString();
     255             : }
     256             : 
     257        2542 : OUString SwGetRefField::Expand() const
     258             : {
     259        2542 :     return sTxt;
     260             : }
     261             : 
     262           0 : OUString SwGetRefField::GetFieldName() const
     263             : {
     264           0 :     const OUString aName = GetTyp()->GetName();
     265           0 :     if ( !aName.isEmpty() || !sSetRefName.isEmpty() )
     266             :     {
     267           0 :         return aName + " " + sSetRefName;
     268             :     }
     269           0 :     return Expand();
     270             : }
     271             : 
     272             : // #i81002# - parameter <pFldTxtAttr> added
     273         936 : void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
     274             : {
     275         936 :     sTxt = OUString();
     276             : 
     277         936 :     SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
     278             :     // finding the reference target (the number)
     279         936 :     sal_Int32 nNumStart = -1;
     280         936 :     sal_Int32 nNumEnd = -1;
     281             :     SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor(
     282             :         pDoc, sSetRefName, nSubType, nSeqNo, &nNumStart, &nNumEnd
     283         936 :     );
     284             :     // not found?
     285         936 :     if ( !pTxtNd )
     286             :     {
     287          14 :         sTxt = SwViewShell::GetShellRes()->aGetRefFld_RefItemNotFound;
     288          14 :         return ;
     289             :     }
     290             :     // where is the category name (e.g. "Illustration")?
     291         922 :     OUString const sText = pTxtNd->GetTxt();
     292         922 :     const sal_Int32 nCatStart = sText.indexOf(sSetRefName);
     293         922 :     const bool bHasCat = nCatStart>=0;
     294         922 :     const sal_Int32 nCatEnd = bHasCat ? nCatStart + sSetRefName.getLength() : -1;
     295             : 
     296             :     // length of the referenced text
     297         922 :     const sal_Int32 nLen = sText.getLength();
     298             : 
     299             :     // which format?
     300         922 :     switch( GetFormat() )
     301             :     {
     302             :     case REF_CONTENT:
     303             :     case REF_ONLYNUMBER:
     304             :     case REF_ONLYCAPTION:
     305             :     case REF_ONLYSEQNO:
     306             :         {
     307             :             // needed part of Text
     308             :             sal_Int32 nStart;
     309             :             sal_Int32 nEnd;
     310             : 
     311           8 :             switch( nSubType )
     312             :             {
     313             :             case REF_SEQUENCEFLD:
     314             : 
     315           0 :                 switch( GetFormat() )
     316             :                 {
     317             :                 // "Category and Number"
     318             :                 case REF_ONLYNUMBER:
     319           0 :                     if (bHasCat) {
     320           0 :                         nStart = std::min(nNumStart, nCatStart);
     321           0 :                         nEnd = std::max(nNumEnd, nCatEnd);
     322             :                     } else {
     323           0 :                         nStart = nNumStart;
     324           0 :                         nEnd = nNumEnd;
     325             :                     }
     326           0 :                     break;
     327             : 
     328             :                 // "Caption Text"
     329             :                 case REF_ONLYCAPTION: {
     330             :                     // next alphanumeric character after category+number
     331           0 :                     if (const SwTxtAttr* const pTxtAttr =
     332           0 :                         pTxtNd->GetTxtAttrForCharAt(nNumStart, RES_TXTATR_FIELD)
     333             :                     ) {
     334             :                         // start searching from nFrom
     335             :                         const sal_Int32 nFrom = bHasCat
     336           0 :                             ? std::max(nNumStart + 1, nCatEnd)
     337           0 :                             : nNumStart + 1;
     338           0 :                         nStart = SwGetExpField::GetReferenceTextPos( pTxtAttr->GetFmtFld(), *pDoc, nFrom );
     339             :                     } else {
     340           0 :                         nStart = bHasCat ? std::max(nNumEnd, nCatEnd) : nNumEnd;
     341             :                     }
     342           0 :                     nEnd = nLen;
     343           0 :                     break;
     344             :                 }
     345             : 
     346             :                 // "Numbering"
     347             :                 case REF_ONLYSEQNO:
     348           0 :                     nStart = nNumStart;
     349           0 :                     nEnd = std::min(nStart + 1, nLen);
     350           0 :                     break;
     351             : 
     352             :                 // "Reference" (whole Text)
     353             :                 default:
     354           0 :                     nStart = 0;
     355           0 :                     nEnd = nLen;
     356           0 :                     break;
     357             :                 }
     358           0 :                 break;
     359             : 
     360             :             case REF_BOOKMARK:
     361           8 :                 nStart = nNumStart;
     362             :                 // text is spread across multiple nodes - get whole text or only until end of node?
     363           8 :                 nEnd = nNumEnd<0 ? nLen : nNumEnd;
     364           8 :                 break;
     365             : 
     366             :             case REF_OUTLINE:
     367           0 :                 nStart = nNumStart;
     368           0 :                 nEnd = nNumEnd;
     369           0 :                 break;
     370             : 
     371             :             case REF_FOOTNOTE:
     372             :             case REF_ENDNOTE:
     373             :                 // get number or numString
     374           0 :                 for( unsigned i = 0; i < pDoc->GetFtnIdxs().size(); ++i )
     375             :                 {
     376           0 :                     SwTxtFtn* const pFtnIdx = pDoc->GetFtnIdxs()[i];
     377           0 :                     if( nSeqNo == pFtnIdx->GetSeqRefNo() )
     378             :                     {
     379           0 :                         sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
     380           0 :                         break;
     381             :                     }
     382             :                 }
     383           0 :                 return;
     384             : 
     385             :             default:
     386           0 :                 nStart = nNumStart;
     387           0 :                 nEnd = nNumEnd;
     388           0 :                 break;
     389             :             }
     390             : 
     391           8 :             if( nStart != nEnd ) // a section?
     392             :             {
     393           8 :                 sTxt = pTxtNd->GetExpandTxt( nStart, nEnd - nStart );
     394             : 
     395             :                 // remove all special characters (replace them with blanks)
     396           8 :                 if( !sTxt.isEmpty() )
     397             :                 {
     398           8 :                     sTxt = comphelper::string::remove(sTxt, 0xad);
     399           8 :                     OUStringBuffer aBuf(sTxt);
     400           8 :                     const sal_Int32 l = aBuf.getLength();
     401          96 :                     for (sal_Int32 i=0; i<l; ++i)
     402             :                     {
     403          88 :                         if (aBuf[i]<' ')
     404             :                         {
     405           0 :                             aBuf[i]=' ';
     406             :                         }
     407          88 :                         else if (aBuf[i]==0x2011)
     408             :                         {
     409           0 :                             aBuf[i]='-';
     410             :                         }
     411             :                     }
     412           8 :                     sTxt = aBuf.makeStringAndClear();
     413             :                 }
     414             :             }
     415             :         }
     416           8 :         break;
     417             : 
     418             :     case REF_PAGE:
     419             :     case REF_PAGE_PGDESC:
     420             :         {
     421           0 :             const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout(), 0, 0, false),
     422           0 :                         *pSave = pFrm;
     423           0 :             while( pFrm && !pFrm->IsInside( nNumStart ) )
     424           0 :                 pFrm = (SwTxtFrm*)pFrm->GetFollow();
     425             : 
     426           0 :             if( pFrm || 0 != ( pFrm = pSave ))
     427             :             {
     428           0 :                 sal_uInt16 nPageNo = pFrm->GetVirtPageNum();
     429             :                 const SwPageFrm *pPage;
     430           0 :                 if( REF_PAGE_PGDESC == GetFormat() &&
     431           0 :                     0 != ( pPage = pFrm->FindPageFrm() ) &&
     432           0 :                     pPage->GetPageDesc() )
     433           0 :                     sTxt = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo );
     434             :                 else
     435           0 :                     sTxt = OUString::number(nPageNo);
     436             :             }
     437             :         }
     438           0 :         break;
     439             : 
     440             :     case REF_CHAPTER:
     441             :         {
     442             :             // a bit tricky: search any frame
     443           0 :             const SwFrm* pFrm = pTxtNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
     444           0 :             if( pFrm )
     445             :             {
     446           0 :                 SwChapterFieldType aFldTyp;
     447           0 :                 SwChapterField aFld( &aFldTyp, 0 );
     448           0 :                 aFld.SetLevel( MAXLEVEL - 1 );
     449           0 :                 aFld.ChangeExpansion( pFrm, pTxtNd, true );
     450           0 :                 sTxt = aFld.GetNumber();
     451             :             }
     452             :         }
     453           0 :         break;
     454             : 
     455             :     case REF_UPDOWN:
     456             :         {
     457             :             // #i81002#
     458             :             // simplified: use parameter <pFldTxtAttr>
     459           0 :             if( !pFldTxtAttr || !pFldTxtAttr->GetpTxtNode() )
     460           0 :                 break;
     461             : 
     462           0 :             LanguageTag aLanguageTag( GetLanguage());
     463           0 :             LocaleDataWrapper aLocaleData( aLanguageTag );
     464             : 
     465             :             // first a "short" test - in case both are in the same node
     466           0 :             if( pFldTxtAttr->GetpTxtNode() == pTxtNd )
     467             :             {
     468           0 :                 sTxt = nNumStart < pFldTxtAttr->GetStart()
     469             :                             ? aLocaleData.getAboveWord()
     470           0 :                             : aLocaleData.getBelowWord();
     471           0 :                 break;
     472             :             }
     473             : 
     474           0 :             sTxt = ::IsFrameBehind( *pFldTxtAttr->GetpTxtNode(), pFldTxtAttr->GetStart(),
     475           0 :                                     *pTxtNd, nNumStart )
     476             :                         ? aLocaleData.getAboveWord()
     477           0 :                         : aLocaleData.getBelowWord();
     478             :         }
     479           0 :         break;
     480             :     // #i81002#
     481             :     case REF_NUMBER:
     482             :     case REF_NUMBER_NO_CONTEXT:
     483             :     case REF_NUMBER_FULL_CONTEXT:
     484             :         {
     485         914 :             if ( pFldTxtAttr && pFldTxtAttr->GetpTxtNode() )
     486             :             {
     487         914 :                 sTxt = MakeRefNumStr( pFldTxtAttr->GetTxtNode(), *pTxtNd, GetFormat() );
     488             :             }
     489             :         }
     490         914 :         break;
     491             : 
     492             :     default:
     493             :         OSL_FAIL("<SwGetRefField::UpdateField(..)> - unknown format type");
     494         922 :     }
     495             : }
     496             : 
     497             : // #i81002#
     498         914 : OUString SwGetRefField::MakeRefNumStr( const SwTxtNode& rTxtNodeOfField,
     499             :                                      const SwTxtNode& rTxtNodeOfReferencedItem,
     500             :                                      const sal_uInt32 nRefNumFormat ) const
     501             : {
     502        1828 :     if ( rTxtNodeOfReferencedItem.HasNumber() &&
     503         914 :          rTxtNodeOfReferencedItem.IsCountedInList() )
     504             :     {
     505             :         OSL_ENSURE( rTxtNodeOfReferencedItem.GetNum(),
     506             :                 "<SwGetRefField::MakeRefNumStr(..)> - referenced paragraph has number, but no <SwNodeNum> instance --> please inform OD!" );
     507             : 
     508             :         // Determine, up to which level the superior list labels have to be
     509             :         // included - default is to include all superior list labels.
     510         914 :         sal_uInt8 nRestrictInclToThisLevel( 0 );
     511             :         // Determine for format REF_NUMBER the level, up to which the superior
     512             :         // list labels have to be restricted, if the text node of the reference
     513             :         // field and the text node of the referenced item are in the same
     514             :         // document context.
     515        1336 :         if ( nRefNumFormat == REF_NUMBER &&
     516         422 :              rTxtNodeOfField.FindFlyStartNode()
     517         844 :                             == rTxtNodeOfReferencedItem.FindFlyStartNode() &&
     518         422 :              rTxtNodeOfField.FindFootnoteStartNode()
     519         844 :                             == rTxtNodeOfReferencedItem.FindFootnoteStartNode() &&
     520         422 :              rTxtNodeOfField.FindHeaderStartNode()
     521        1758 :                             == rTxtNodeOfReferencedItem.FindHeaderStartNode() &&
     522         422 :              rTxtNodeOfField.FindFooterStartNode()
     523         422 :                             == rTxtNodeOfReferencedItem.FindFooterStartNode() )
     524             :         {
     525         422 :             const SwNodeNum* pNodeNumForTxtNodeOfField( 0 );
     526         790 :             if ( rTxtNodeOfField.HasNumber() &&
     527         368 :                  rTxtNodeOfField.GetNumRule() == rTxtNodeOfReferencedItem.GetNumRule() )
     528             :             {
     529         368 :                 pNodeNumForTxtNodeOfField = rTxtNodeOfField.GetNum();
     530             :             }
     531             :             else
     532             :             {
     533             :                 pNodeNumForTxtNodeOfField =
     534          54 :                     rTxtNodeOfReferencedItem.GetNum()->GetPrecedingNodeNumOf( rTxtNodeOfField );
     535             :             }
     536         422 :             if ( pNodeNumForTxtNodeOfField )
     537             :             {
     538         422 :                 const SwNumberTree::tNumberVector rFieldNumVec = pNodeNumForTxtNodeOfField->GetNumberVector();
     539         844 :                 const SwNumberTree::tNumberVector rRefItemNumVec = rTxtNodeOfReferencedItem.GetNum()->GetNumberVector();
     540         422 :                 sal_uInt8 nLevel( 0 );
     541        1004 :                 while ( nLevel < rFieldNumVec.size() && nLevel < rRefItemNumVec.size() )
     542             :                 {
     543         560 :                     if ( rRefItemNumVec[nLevel] == rFieldNumVec[nLevel] )
     544             :                     {
     545         160 :                         nRestrictInclToThisLevel = nLevel + 1;
     546             :                     }
     547             :                     else
     548             :                     {
     549         400 :                         break;
     550             :                     }
     551         160 :                     ++nLevel;
     552         422 :                 }
     553             :             }
     554             :         }
     555             : 
     556             :         // Determine, if superior list labels have to be included
     557             :         const bool bInclSuperiorNumLabels(
     558        1552 :             ( nRestrictInclToThisLevel < rTxtNodeOfReferencedItem.GetActualListLevel() &&
     559        1360 :               ( nRefNumFormat == REF_NUMBER || nRefNumFormat == REF_NUMBER_FULL_CONTEXT ) ) );
     560             : 
     561             :         OSL_ENSURE( rTxtNodeOfReferencedItem.GetNumRule(),
     562             :                 "<SwGetRefField::MakeRefNumStr(..)> - referenced numbered paragraph has no numbering rule set --> please inform OD!" );
     563             :         return rTxtNodeOfReferencedItem.GetNumRule()->MakeRefNumString(
     564         914 :                                             *(rTxtNodeOfReferencedItem.GetNum()),
     565             :                                             bInclSuperiorNumLabels,
     566        1828 :                                             nRestrictInclToThisLevel );
     567             :     }
     568             : 
     569           0 :     return OUString();
     570             : }
     571             : 
     572         344 : SwField* SwGetRefField::Copy() const
     573             : {
     574         344 :     SwGetRefField* pFld = new SwGetRefField( (SwGetRefFieldType*)GetTyp(),
     575             :                                                 sSetRefName, nSubType,
     576         344 :                                                 nSeqNo, GetFormat() );
     577         344 :     pFld->sTxt = sTxt;
     578         344 :     return pFld;
     579             : }
     580             : 
     581             : /// get reference name
     582           0 : OUString SwGetRefField::GetPar1() const
     583             : {
     584           0 :     return sSetRefName;
     585             : }
     586             : 
     587             : /// set reference name
     588           0 : void SwGetRefField::SetPar1( const OUString& rName )
     589             : {
     590           0 :     sSetRefName = rName;
     591           0 : }
     592             : 
     593           0 : OUString SwGetRefField::GetPar2() const
     594             : {
     595           0 :     return Expand();
     596             : }
     597             : 
     598         168 : bool SwGetRefField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
     599             : {
     600         168 :     switch( nWhichId )
     601             :     {
     602             :     case FIELD_PROP_USHORT1:
     603             :         {
     604         120 :             sal_Int16 nPart = 0;
     605         120 :             switch(GetFormat())
     606             :             {
     607          12 :             case REF_PAGE       : nPart = ReferenceFieldPart::PAGE                ; break;
     608           0 :             case REF_CHAPTER    : nPart = ReferenceFieldPart::CHAPTER             ; break;
     609          36 :             case REF_CONTENT    : nPart = ReferenceFieldPart::TEXT                ; break;
     610           0 :             case REF_UPDOWN     : nPart = ReferenceFieldPart::UP_DOWN             ; break;
     611           0 :             case REF_PAGE_PGDESC: nPart = ReferenceFieldPart::PAGE_DESC           ; break;
     612           0 :             case REF_ONLYNUMBER : nPart = ReferenceFieldPart::CATEGORY_AND_NUMBER ; break;
     613           0 :             case REF_ONLYCAPTION: nPart = ReferenceFieldPart::ONLY_CAPTION        ; break;
     614           0 :             case REF_ONLYSEQNO  : nPart = ReferenceFieldPart::ONLY_SEQUENCE_NUMBER; break;
     615             :             // #i81002#
     616          48 :             case REF_NUMBER:              nPart = ReferenceFieldPart::NUMBER;              break;
     617          24 :             case REF_NUMBER_NO_CONTEXT:   nPart = ReferenceFieldPart::NUMBER_NO_CONTEXT;   break;
     618           0 :             case REF_NUMBER_FULL_CONTEXT: nPart = ReferenceFieldPart::NUMBER_FULL_CONTEXT; break;
     619             :             }
     620         120 :             rAny <<= nPart;
     621             :         }
     622         120 :         break;
     623             :     case FIELD_PROP_USHORT2:
     624             :         {
     625          48 :             sal_Int16 nSource = 0;
     626          48 :             switch(nSubType)
     627             :             {
     628           0 :             case  REF_SETREFATTR : nSource = ReferenceFieldSource::REFERENCE_MARK; break;
     629           0 :             case  REF_SEQUENCEFLD: nSource = ReferenceFieldSource::SEQUENCE_FIELD; break;
     630          48 :             case  REF_BOOKMARK   : nSource = ReferenceFieldSource::BOOKMARK; break;
     631           0 :             case  REF_OUTLINE    : OSL_FAIL("not implemented"); break;
     632           0 :             case  REF_FOOTNOTE   : nSource = ReferenceFieldSource::FOOTNOTE; break;
     633           0 :             case  REF_ENDNOTE    : nSource = ReferenceFieldSource::ENDNOTE; break;
     634             :             }
     635          48 :             rAny <<= nSource;
     636             :         }
     637          48 :         break;
     638             :     case FIELD_PROP_PAR1:
     639             :     {
     640           0 :         OUString sTmp(GetPar1());
     641           0 :         if(REF_SEQUENCEFLD == nSubType)
     642             :         {
     643           0 :             sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sTmp, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
     644           0 :             switch( nPoolId )
     645             :             {
     646             :                 case RES_POOLCOLL_LABEL_ABB:
     647             :                 case RES_POOLCOLL_LABEL_TABLE:
     648             :                 case RES_POOLCOLL_LABEL_FRAME:
     649             :                 case RES_POOLCOLL_LABEL_DRAWING:
     650           0 :                     SwStyleNameMapper::FillProgName(nPoolId, sTmp) ;
     651           0 :                 break;
     652             :             }
     653             :         }
     654           0 :         rAny <<= sTmp;
     655             :     }
     656           0 :     break;
     657             :     case FIELD_PROP_PAR3:
     658           0 :         rAny <<= Expand();
     659           0 :         break;
     660             :     case FIELD_PROP_SHORT1:
     661           0 :         rAny <<= (sal_Int16)nSeqNo;
     662           0 :         break;
     663             :     default:
     664             :         OSL_FAIL("illegal property");
     665             :     }
     666         168 :     return true;
     667             : }
     668             : 
     669         300 : bool SwGetRefField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
     670             : {
     671         300 :     switch( nWhichId )
     672             :     {
     673             :     case FIELD_PROP_USHORT1:
     674             :         {
     675         148 :             sal_Int16 nPart = 0;
     676         148 :             rAny >>= nPart;
     677         148 :             switch(nPart)
     678             :             {
     679          14 :             case ReferenceFieldPart::PAGE:                  nPart = REF_PAGE; break;
     680           0 :             case ReferenceFieldPart::CHAPTER:               nPart = REF_CHAPTER; break;
     681          38 :             case ReferenceFieldPart::TEXT:                  nPart = REF_CONTENT; break;
     682           0 :             case ReferenceFieldPart::UP_DOWN:               nPart = REF_UPDOWN; break;
     683           0 :             case ReferenceFieldPart::PAGE_DESC:             nPart = REF_PAGE_PGDESC; break;
     684           0 :             case ReferenceFieldPart::CATEGORY_AND_NUMBER:   nPart = REF_ONLYNUMBER; break;
     685           0 :             case ReferenceFieldPart::ONLY_CAPTION:          nPart = REF_ONLYCAPTION; break;
     686           0 :             case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER : nPart = REF_ONLYSEQNO; break;
     687             :             // #i81002#
     688          48 :             case ReferenceFieldPart::NUMBER:              nPart = REF_NUMBER;              break;
     689          24 :             case ReferenceFieldPart::NUMBER_NO_CONTEXT:   nPart = REF_NUMBER_NO_CONTEXT;   break;
     690          24 :             case ReferenceFieldPart::NUMBER_FULL_CONTEXT: nPart = REF_NUMBER_FULL_CONTEXT; break;
     691           0 :             default: return false;
     692             :             }
     693         148 :             SetFormat(nPart);
     694             :         }
     695         148 :         break;
     696             :     case FIELD_PROP_USHORT2:
     697             :         {
     698          76 :             sal_Int16 nSource = 0;
     699          76 :             rAny >>= nSource;
     700          76 :             switch(nSource)
     701             :             {
     702           0 :             case ReferenceFieldSource::REFERENCE_MARK : nSubType = REF_SETREFATTR ; break;
     703             :             case ReferenceFieldSource::SEQUENCE_FIELD :
     704             :             {
     705           0 :                 if(REF_SEQUENCEFLD == nSubType)
     706           0 :                     break;
     707           0 :                 nSubType = REF_SEQUENCEFLD;
     708           0 :                 ConvertProgrammaticToUIName();
     709             :             }
     710           0 :             break;
     711          76 :             case ReferenceFieldSource::BOOKMARK       : nSubType = REF_BOOKMARK   ; break;
     712           0 :             case ReferenceFieldSource::FOOTNOTE       : nSubType = REF_FOOTNOTE   ; break;
     713           0 :             case ReferenceFieldSource::ENDNOTE        : nSubType = REF_ENDNOTE    ; break;
     714             :             }
     715             :         }
     716          76 :         break;
     717             :     case FIELD_PROP_PAR1:
     718             :     {
     719           0 :         OUString sTmpStr;
     720           0 :         rAny >>= sTmpStr;
     721           0 :         SetPar1(sTmpStr);
     722           0 :         ConvertProgrammaticToUIName();
     723             :     }
     724           0 :     break;
     725             :     case FIELD_PROP_PAR3:
     726             :         {
     727           0 :             OUString sTmpStr;
     728           0 :             rAny >>= sTmpStr;
     729           0 :             SetExpand( sTmpStr );
     730             :         }
     731           0 :         break;
     732             :     case FIELD_PROP_SHORT1:
     733             :         {
     734          76 :             sal_Int16 nSetSeq = 0;
     735          76 :             rAny >>= nSetSeq;
     736          76 :             if(nSetSeq >= 0)
     737          76 :                 nSeqNo = nSetSeq;
     738             :         }
     739          76 :         break;
     740             :     default:
     741             :         OSL_FAIL("illegal property");
     742             :     }
     743         300 :     return true;
     744             : }
     745             : 
     746           0 : void SwGetRefField::ConvertProgrammaticToUIName()
     747             : {
     748           0 :     if(GetTyp() && REF_SEQUENCEFLD == nSubType)
     749             :     {
     750           0 :         SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
     751           0 :         const OUString rPar1 = GetPar1();
     752             :         // don't convert when the name points to an existing field type
     753           0 :         if(!pDoc->getIDocumentFieldsAccess().GetFldType(RES_SETEXPFLD, rPar1, false))
     754             :         {
     755           0 :             sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromProgName( rPar1, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
     756           0 :             sal_uInt16 nResId = USHRT_MAX;
     757           0 :             switch( nPoolId )
     758             :             {
     759             :                 case RES_POOLCOLL_LABEL_ABB:
     760           0 :                     nResId = STR_POOLCOLL_LABEL_ABB;
     761           0 :                 break;
     762             :                 case RES_POOLCOLL_LABEL_TABLE:
     763           0 :                     nResId = STR_POOLCOLL_LABEL_TABLE;
     764           0 :                 break;
     765             :                 case RES_POOLCOLL_LABEL_FRAME:
     766           0 :                     nResId = STR_POOLCOLL_LABEL_FRAME;
     767           0 :                 break;
     768             :                 case RES_POOLCOLL_LABEL_DRAWING:
     769           0 :                     nResId = STR_POOLCOLL_LABEL_DRAWING;
     770           0 :                 break;
     771             :             }
     772           0 :             if( nResId != USHRT_MAX )
     773           0 :                 SetPar1(SW_RESSTR( nResId ));
     774           0 :         }
     775             :     }
     776           0 : }
     777             : 
     778        5052 : SwGetRefFieldType::SwGetRefFieldType( SwDoc* pDc )
     779        5052 :     : SwFieldType( RES_GETREFFLD ), pDoc( pDc )
     780        5052 : {}
     781             : 
     782           0 : SwFieldType* SwGetRefFieldType::Copy() const
     783             : {
     784           0 :     return new SwGetRefFieldType( pDoc );
     785             : }
     786             : 
     787         402 : void SwGetRefFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
     788             : {
     789             :     // update to all GetReference fields
     790         402 :     if( !pNew && !pOld )
     791             :     {
     792         402 :         SwIterator<SwFmtFld,SwFieldType> aIter( *this );
     793        1338 :         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
     794             :         {
     795             :             // update only the GetRef fields
     796             :             //JP 3.4.2001: Task 71231 - we need the correct language
     797         936 :             SwGetRefField* pGRef = (SwGetRefField*)pFmtFld->GetField();
     798             :             const SwTxtFld* pTFld;
     799        1884 :             if( !pGRef->GetLanguage() &&
     800         944 :                 0 != ( pTFld = pFmtFld->GetTxtFld()) &&
     801           8 :                 pTFld->GetpTxtNode() )
     802             :             {
     803             :                 pGRef->SetLanguage( pTFld->GetpTxtNode()->GetLang(
     804           8 :                                                 pTFld->GetStart() ) );
     805             :             }
     806             : 
     807             :             // #i81002#
     808         936 :             pGRef->UpdateField( pFmtFld->GetTxtFld() );
     809         402 :         }
     810             :     }
     811             :     // forward to text fields, they "expand" the text
     812         402 :     NotifyClients( pOld, pNew );
     813         402 : }
     814             : 
     815         936 : SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const OUString& rRefMark,
     816             :                                         sal_uInt16 nSubType, sal_uInt16 nSeqNo,
     817             :                                         sal_Int32* pStt, sal_Int32* pEnd )
     818             : {
     819             :     OSL_ENSURE( pStt, "Why did no one check the StartPos?" );
     820             : 
     821         936 :     SwTxtNode* pTxtNd = 0;
     822         936 :     switch( nSubType )
     823             :     {
     824             :     case REF_SETREFATTR:
     825             :         {
     826           0 :             const SwFmtRefMark *pRef = pDoc->GetRefMark( rRefMark );
     827           0 :             if( pRef && pRef->GetTxtRefMark() )
     828             :             {
     829           0 :                 pTxtNd = (SwTxtNode*)&pRef->GetTxtRefMark()->GetTxtNode();
     830           0 :                 *pStt = pRef->GetTxtRefMark()->GetStart();
     831           0 :                 if( pEnd )
     832           0 :                     *pEnd = *pRef->GetTxtRefMark()->GetAnyEnd();
     833             :             }
     834             :         }
     835           0 :         break;
     836             : 
     837             :     case REF_SEQUENCEFLD:
     838             :         {
     839           0 :             SwFieldType* pFldType = pDoc->getIDocumentFieldsAccess().GetFldType( RES_SETEXPFLD, rRefMark, false );
     840           0 :             if( pFldType && pFldType->GetDepends() &&
     841           0 :                 nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType*)pFldType)->GetType() )
     842             :             {
     843           0 :                 SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
     844           0 :                 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
     845             :                 {
     846           0 :                     if( pFmtFld->GetTxtFld() && nSeqNo ==
     847           0 :                         ((SwSetExpField*)pFmtFld->GetField())->GetSeqNumber() )
     848             :                     {
     849           0 :                         SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
     850           0 :                         pTxtNd = (SwTxtNode*)pTxtFld->GetpTxtNode();
     851           0 :                         *pStt = pTxtFld->GetStart();
     852           0 :                         if( pEnd )
     853           0 :                             *pEnd = (*pStt) + 1;
     854           0 :                         break;
     855             :                     }
     856           0 :                 }
     857             :             }
     858             :         }
     859           0 :         break;
     860             : 
     861             :     case REF_BOOKMARK:
     862             :         {
     863         936 :             IDocumentMarkAccess::const_iterator_t ppMark = pDoc->getIDocumentMarkAccess()->findMark(rRefMark);
     864         936 :             if(ppMark != pDoc->getIDocumentMarkAccess()->getAllMarksEnd())
     865             :             {
     866         922 :                 const ::sw::mark::IMark* pBkmk = ppMark->get();
     867         922 :                 const SwPosition* pPos = &pBkmk->GetMarkStart();
     868             : 
     869         922 :                 pTxtNd = pPos->nNode.GetNode().GetTxtNode();
     870         922 :                 *pStt = pPos->nContent.GetIndex();
     871         922 :                 if(pEnd)
     872             :                 {
     873         922 :                     if(!pBkmk->IsExpanded())
     874             :                     {
     875         920 :                         *pEnd = *pStt;
     876             :                         // #i81002#
     877         920 :                         if(dynamic_cast< ::sw::mark::CrossRefBookmark const *>(pBkmk))
     878             :                         {
     879             :                             OSL_ENSURE( pTxtNd,
     880             :                                     "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" );
     881         920 :                             *pEnd = pTxtNd->Len();
     882             :                         }
     883             :                     }
     884           2 :                     else if(pBkmk->GetOtherMarkPos().nNode == pBkmk->GetMarkPos().nNode)
     885           2 :                         *pEnd = pBkmk->GetMarkEnd().nContent.GetIndex();
     886             :                     else
     887           0 :                         *pEnd = -1;
     888             :                 }
     889             :             }
     890             :         }
     891         936 :         break;
     892             : 
     893             :     case REF_OUTLINE:
     894           0 :         break;
     895             : 
     896             :     case REF_FOOTNOTE:
     897             :     case REF_ENDNOTE:
     898             :         {
     899           0 :             sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().size();
     900             :             SwTxtFtn* pFtnIdx;
     901           0 :             for( n = 0; n < nFtnCnt; ++n )
     902           0 :                 if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
     903             :                 {
     904           0 :                     SwNodeIndex* pIdx = pFtnIdx->GetStartNode();
     905           0 :                     if( pIdx )
     906             :                     {
     907           0 :                         SwNodeIndex aIdx( *pIdx, 1 );
     908           0 :                         if( 0 == ( pTxtNd = aIdx.GetNode().GetTxtNode()))
     909           0 :                             pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
     910             :                     }
     911           0 :                     *pStt = 0;
     912           0 :                     if( pEnd )
     913           0 :                         *pEnd = 0;
     914           0 :                     break;
     915             :                 }
     916             :         }
     917           0 :         break;
     918             :     }
     919             : 
     920         936 :     return pTxtNd;
     921             : }
     922             : 
     923          70 : struct _RefIdsMap
     924             : {
     925             : private:
     926             :     OUString aName;
     927             :     std::set<sal_uInt16> aIds;
     928             :     std::set<sal_uInt16> aDstIds;
     929             :     std::map<sal_uInt16, sal_uInt16> sequencedIds; /// ID numbers sorted by sequence number.
     930             :     bool bInit;
     931             : 
     932             :     void       Init(SwDoc& rDoc, SwDoc& rDestDoc, bool bField );
     933             :     void       GetNoteIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds );
     934             :     void       GetFieldIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds );
     935             :     void       AddId( sal_uInt16 id, sal_uInt16 seqNum );
     936             :     sal_uInt16 GetFirstUnusedId( std::set<sal_uInt16> &rIds );
     937             : 
     938             : public:
     939          70 :     _RefIdsMap( const OUString& rName ) : aName( rName ), bInit( false ) {}
     940             : 
     941             :     void Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld, bool bField );
     942             : 
     943           0 :     OUString GetName() { return aName; }
     944             : };
     945             : 
     946             : typedef boost::ptr_vector<_RefIdsMap> _RefIdsMaps;
     947             : 
     948             : /// Get a sorted list of the field IDs from a document.
     949             : /// @param[in]     rDoc The document to search.
     950             : /// @param[in,out] rIds The list of IDs found in the document.
     951           0 : void _RefIdsMap::GetFieldIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds)
     952             : {
     953           0 :     SwFieldType *const pType = rDoc.getIDocumentFieldsAccess().GetFldType(RES_SETEXPFLD, aName, false);
     954             : 
     955           0 :     if (!pType)
     956           0 :         return;
     957             : 
     958           0 :     SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
     959           0 :     for (SwFmtFld const* pF = aIter.First(); pF; pF = aIter.Next())
     960             :     {
     961           0 :         if (pF->GetTxtFld())
     962             :         {
     963           0 :             SwTxtNode const*const pNd = pF->GetTxtFld()->GetpTxtNode();
     964           0 :             if (pNd && pNd->GetNodes().IsDocNodes())
     965             :             {
     966           0 :                 rIds.insert(static_cast<SwSetExpField const*>(pF->GetField())
     967           0 :                                 ->GetSeqNumber());
     968             :             }
     969             :         }
     970           0 :     }
     971             : }
     972             : 
     973             : /// Get a sorted list of the footnote/endnote IDs from a document.
     974             : /// @param[in]     rDoc The document to search.
     975             : /// @param[in,out] rIds The list of IDs found in the document.
     976           0 : void _RefIdsMap::GetNoteIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds)
     977             : {
     978           0 :     for( sal_uInt16 n = rDoc.GetFtnIdxs().size(); n; )
     979           0 :         rIds.insert( rDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
     980           0 : }
     981             : 
     982             : /// Initialise the aIds and aDestIds collections from the source documents.
     983             : /// @param[in] rDoc     The source document.
     984             : /// @param[in] rDestDoc The destination document.
     985             : /// @param[in] bField   True if we're interested in all fields, false for footnotes.
     986           0 : void _RefIdsMap::Init( SwDoc& rDoc, SwDoc& rDestDoc, bool bField )
     987             : {
     988           0 :     if( bInit )
     989           0 :         return;
     990             : 
     991           0 :     if( bField )
     992             :     {
     993           0 :         GetFieldIdsFromDoc( rDestDoc, aIds );
     994           0 :         GetFieldIdsFromDoc( rDoc, aDstIds );
     995             : 
     996             :         // Map all the new src fields to the next available unused id
     997           0 :         for ( std::set<sal_uInt16>::iterator pIt = aDstIds.begin(); pIt != aDstIds.end(); ++pIt )
     998           0 :             AddId( GetFirstUnusedId(aIds), *pIt );
     999             : 
    1000             :         // Change the Sequence number of all SetExp fields in the source document
    1001           0 :         SwFieldType* pType = rDoc.getIDocumentFieldsAccess().GetFldType( RES_SETEXPFLD, aName, false );
    1002           0 :         if( pType )
    1003             :         {
    1004           0 :             SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
    1005           0 :             for( SwFmtFld* pF = aIter.First(); pF; pF = aIter.Next() )
    1006           0 :                 if( pF->GetTxtFld() )
    1007             :                 {
    1008             :                     SwSetExpField *const pSetExp(
    1009           0 :                             static_cast<SwSetExpField *>(pF->GetField()));
    1010           0 :                     sal_uInt16 const n = pSetExp->GetSeqNumber();
    1011           0 :                     pSetExp->SetSeqNumber( sequencedIds[n] );
    1012           0 :                 }
    1013             :         }
    1014             :     }
    1015             :     else
    1016             :     {
    1017           0 :         GetNoteIdsFromDoc( rDestDoc, aIds );
    1018           0 :         GetNoteIdsFromDoc( rDoc, aDstIds );
    1019             : 
    1020           0 :         for (std::set<sal_uInt16>::iterator pIt = aDstIds.begin(); pIt != aDstIds.end(); ++pIt)
    1021           0 :             AddId( GetFirstUnusedId(aIds), *pIt );
    1022             : 
    1023             :         // Change the footnotes/endnotes in the source doc to the new ID
    1024           0 :         for (sal_uInt16 i = 0, nCnt = rDoc.GetFtnIdxs().size(); i < nCnt; ++i)
    1025             :         {
    1026           0 :             SwTxtFtn *const pFtnIdx = rDoc.GetFtnIdxs()[i];
    1027           0 :             sal_uInt16 const n = pFtnIdx->GetSeqRefNo();
    1028           0 :             pFtnIdx->SetSeqNo(sequencedIds[n]);
    1029             :         }
    1030             :     }
    1031           0 :     bInit = true;
    1032             : }
    1033             : 
    1034             : /// Get the lowest number unused in the passed set.
    1035             : /// @param[in] rIds The set of used ID numbers.
    1036             : /// @returns The lowest number unused by the passed set
    1037           0 : sal_uInt16 _RefIdsMap::GetFirstUnusedId( std::set<sal_uInt16> &rIds )
    1038             : {
    1039           0 :     sal_uInt16 num(0);
    1040           0 :     std::set<sal_uInt16>::iterator it;
    1041             : 
    1042           0 :     for( it = rIds.begin(); it != rIds.end(); ++it )
    1043             :     {
    1044           0 :         if( num != *it )
    1045             :         {
    1046           0 :             return num;
    1047             :         }
    1048           0 :         ++num;
    1049             :     }
    1050           0 :     return num;
    1051             : }
    1052             : 
    1053             : /// Add a new ID and sequence number to the "occupied" collection.
    1054             : /// @param[in] id     The ID number.
    1055             : /// @param[in] seqNum The sequence number.
    1056           0 : void _RefIdsMap::AddId( sal_uInt16 id, sal_uInt16 seqNum )
    1057             : {
    1058           0 :     aIds.insert( id );
    1059           0 :     sequencedIds[ seqNum ] = id;
    1060           0 : }
    1061             : 
    1062           0 : void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
    1063             :                         bool bField )
    1064             : {
    1065           0 :     Init( rDoc, rDestDoc, bField);
    1066             : 
    1067           0 :     sal_uInt16 const nSeqNo = rFld.GetSeqNo();
    1068             : 
    1069             :     // check if it needs to be remapped
    1070             :     // if sequencedIds doesn't contain the number, it means there is no
    1071             :     // SetExp field / footnote in the source document: do not modify
    1072             :     // the number, which works well for copy from/paste to same document
    1073             :     // (and if it is not the same document, there's no "correct" result anyway)
    1074           0 :     if (sequencedIds.count(nSeqNo))
    1075             :     {
    1076           0 :         rFld.SetSeqNo( sequencedIds[nSeqNo] );
    1077             :     }
    1078           0 : }
    1079             : 
    1080             : /// 1. if _both_ SetExp + GetExp / Footnote + GetExp field are copied,
    1081             : ///    enusure that both get a new unused matching number
    1082             : /// 2. if only SetExp / Footnote is copied, it gets a new unused number
    1083             : /// 3. if only GetExp field is copied, for the case of copy from / paste to
    1084             : ///    same document it's desirable to keep the same number;
    1085             : ///    for other cases of copy/paste or master documents it's not obvious
    1086             : ///    what is most desirable since it's going to be wrong anyway
    1087          74 : void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc )
    1088             : {
    1089          74 :     if( &rDestDoc != pDoc )
    1090             :     {
    1091          74 :         if (rDestDoc.IsClipBoard())
    1092             :         {
    1093             :             // when copying _to_ clipboard, expectation is that no fields exist
    1094             :             // so no re-mapping is required to avoid collisions
    1095             :             assert(!rDestDoc.getIDocumentFieldsAccess().GetSysFldType(RES_GETREFFLD)->GetDepends());
    1096          78 :             return; // don't modify the fields in the source doc
    1097             :         }
    1098             : 
    1099             :         // then there are RefFields in the DescDox - so all RefFields in the SourceDoc
    1100             :         // need to be converted to have unique IDs for both documents
    1101          70 :         _RefIdsMap aFntMap( aEmptyOUStr );
    1102         140 :         _RefIdsMaps aFldMap;
    1103             : 
    1104         140 :         SwIterator<SwFmtFld,SwFieldType> aIter( *this );
    1105          70 :         for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
    1106             :         {
    1107           0 :             SwGetRefField& rRefFld = *(SwGetRefField*)pFld->GetField();
    1108           0 :             switch( rRefFld.GetSubType() )
    1109             :             {
    1110             :             case REF_SEQUENCEFLD:
    1111             :                 {
    1112           0 :                     _RefIdsMap* pMap = 0;
    1113           0 :                     for( sal_uInt16 n = aFldMap.size(); n; )
    1114             :                     {
    1115           0 :                         if( aFldMap[ --n ].GetName()==rRefFld.GetSetRefName() )
    1116             :                         {
    1117           0 :                             pMap = &aFldMap[ n ];
    1118           0 :                             break;
    1119             :                         }
    1120             :                     }
    1121           0 :                     if( !pMap )
    1122             :                     {
    1123           0 :                         pMap = new _RefIdsMap( rRefFld.GetSetRefName() );
    1124           0 :                         aFldMap.push_back( pMap );
    1125             :                     }
    1126             : 
    1127           0 :                     pMap->Check( *pDoc, rDestDoc, rRefFld, true );
    1128             :                 }
    1129           0 :                 break;
    1130             : 
    1131             :             case REF_FOOTNOTE:
    1132             :             case REF_ENDNOTE:
    1133           0 :                 aFntMap.Check( *pDoc, rDestDoc, rRefFld, false );
    1134           0 :                 break;
    1135             :             }
    1136          70 :         }
    1137             :     }
    1138         270 : }
    1139             : 
    1140             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10