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

Generated by: LCOV version 1.10