diff options
author | Oliver-Rainer Wittmann <orw@apache.org> | 2012-11-22 11:14:51 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-10-24 09:18:32 +0100 |
commit | 679faffc68bb854af0f55d0f218698e2f372f00b (patch) | |
tree | 5490b0b79b6e647e02b89f495a6bf542d1e6352d /sw | |
parent | 87858e043fe089a816a5787c356c94e7abbddd45 (diff) |
Resolves: #i120879# import "Microsoft Word TOC bookmarks" as...
cross reference bookmarks and suppress the import of unreferenced ones.
Review by: zhengfan
(cherry picked from commit e3a34e95823105fda68fd29a4ded22a9d52523fb)
Conflicts:
sw/source/core/crsr/crossrefbookmark.cxx
sw/source/core/inc/crossrefbookmark.hxx
sw/source/filter/inc/fltshell.hxx
sw/source/filter/ww1/fltshell.cxx
sw/source/filter/ww8/ww8par.cxx
sw/source/filter/ww8/ww8par.hxx
sw/source/filter/ww8/ww8par5.cxx
Change-Id: I5898cbd33c9a17b9517040e19ca8eda4355a1eac
also remove symbol-visibility problems in IDocumentMarkAccess.hxx
(cherry picked from commit de9ea83df087ba3f8e614a69e8b18403d54b9589)
Conflicts:
sw/inc/IDocumentMarkAccess.hxx
Change-Id: I2f51cc4412525c6e62d120df5c7fe1c223e35972
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/IDocumentMarkAccess.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/crsr/crossrefbookmark.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/doc/docbm.cxx | 23 | ||||
-rw-r--r-- | sw/source/core/unocore/unobkm.cxx | 3 | ||||
-rw-r--r-- | sw/source/filter/inc/fltshell.hxx | 36 | ||||
-rw-r--r-- | sw/source/filter/ww1/fltshell.cxx | 89 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1filter.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 36 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.hxx | 41 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par5.cxx | 84 |
10 files changed, 236 insertions, 102 deletions
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx index 4b27357945c9..35f5ec04cd57 100644 --- a/sw/inc/IDocumentMarkAccess.hxx +++ b/sw/inc/IDocumentMarkAccess.hxx @@ -242,6 +242,9 @@ class IDocumentMarkAccess /** Returns the MarkType used to create the mark */ static MarkType SAL_DLLPUBLIC_EXPORT GetType(const ::sw::mark::IMark& rMark); + + static SAL_DLLPUBLIC_EXPORT OUString GetCrossRefHeadingBookmarkNamePrefix(); + static SAL_DLLPUBLIC_EXPORT bool IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPaM ); protected: virtual ~IDocumentMarkAccess() {}; }; diff --git a/sw/source/core/crsr/crossrefbookmark.cxx b/sw/source/core/crsr/crossrefbookmark.cxx index 8ef73ad1d9ea..22438a844ab4 100644 --- a/sw/source/core/crsr/crossrefbookmark.cxx +++ b/sw/source/core/crsr/crossrefbookmark.cxx @@ -17,15 +17,13 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <IDocumentMarkAccess.hxx> #include <crossrefbookmark.hxx> #include <ndtxt.hxx> namespace { - -const char CrossRefHeadingBookmark_NamePrefix[] = "__RefHeading__"; -const char CrossRefNumItemBookmark_NamePrefix[] = "__RefNumPara__"; - + const char CrossRefNumItemBookmark_NamePrefix[] = "__RefNumPara__"; } namespace sw { namespace mark @@ -37,12 +35,9 @@ namespace sw { namespace mark const OUString& rPrefix) : Bookmark(rPaM, rCode, rName, rShortName) { - if(rPaM.HasMark()) - OSL_ENSURE((rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode && - rPaM.Start()->nContent.GetIndex() == 0 && - rPaM.End()->nContent.GetIndex() == rPaM.GetPoint()->nNode.GetNode().GetTxtNode()->Len()), - "<CrossRefBookmark::CrossRefBookmark(..)>" - "- creation of cross-reference bookmark with an expanded PaM that does not expand over exactly one whole paragraph."); + OSL_ENSURE( IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( rPaM ), + "<CrossRefBookmark::CrossRefBookmark(..)>" + "- creation of cross-reference bookmark with an illegal PaM that does not expand over exactly one whole paragraph."); SetMarkPos(*rPaM.Start()); if(rName.isEmpty()) m_aName = MarkBase::GenerateNewName(rPrefix); @@ -71,19 +66,19 @@ namespace sw { namespace mark const KeyCode& rCode, const OUString& rName, const OUString& rShortName) - : CrossRefBookmark(rPaM, rCode, rName, rShortName, OUString(CrossRefHeadingBookmark_NamePrefix)) + : CrossRefBookmark(rPaM, rCode, rName, rShortName, IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()) { } bool CrossRefHeadingBookmark::IsLegalName(const OUString& rName) { - return rName.match(CrossRefHeadingBookmark_NamePrefix); + return rName.match(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()); } CrossRefNumItemBookmark::CrossRefNumItemBookmark(const SwPaM& rPaM, const KeyCode& rCode, const OUString& rName, const OUString& rShortName) - : CrossRefBookmark(rPaM, rCode, rName, rShortName, OUString(CrossRefNumItemBookmark_NamePrefix)) + : CrossRefBookmark(rPaM, rCode, rName, rShortName, IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()) { } bool CrossRefNumItemBookmark::IsLegalName(const OUString& rName) diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index b89917b0803a..dad027e7594c 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -288,6 +288,29 @@ IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk) } } +namespace +{ + const char CrossRefHeadingBookmark_NamePrefix[] = "__RefHeading__"; +} + +OUString IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix() +{ + return OUString("__RefHeading__"); +} + +bool IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPaM ) +{ + bool bRet( false ); + + bRet = rPaM.Start()->nNode.GetNode().IsTxtNode() && + rPaM.Start()->nContent.GetIndex() == 0 && + ( !rPaM.HasMark() || + ( rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode && + rPaM.End()->nContent.GetIndex() == rPaM.End()->nNode.GetNode().GetTxtNode()->Len() ) ); + + return bRet; +} + namespace sw { namespace mark { MarkManager::MarkManager(SwDoc& rDoc) diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx index acffc53f19f4..06467b2209d7 100644 --- a/sw/source/core/unocore/unobkm.cxx +++ b/sw/source/core/unocore/unobkm.cxx @@ -248,7 +248,8 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) eType = IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK; } else if ((eType == IDocumentMarkAccess::BOOKMARK) && - ::sw::mark::CrossRefHeadingBookmark::IsLegalName(m_pImpl->m_sMarkName)) + ::sw::mark::CrossRefHeadingBookmark::IsLegalName(m_pImpl->m_sMarkName) && + IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aPam ) ) { eType = IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK; } diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx index 9dee91c0e57b..584915dcf34e 100644 --- a/sw/source/filter/inc/fltshell.hxx +++ b/sw/source/filter/inc/fltshell.hxx @@ -270,28 +270,32 @@ public: class SW_DLLPUBLIC SwFltBookmark : public SfxPoolItem { +private: friend class SwFltShell; // darf aName und aVal uebersetzen - long nHandle; - OUString aName; - OUString aVal; - sal_Bool bOnlyRef; // "FRAGE"-Feld, Ref/Seitenrf oder nichts - sal_Bool bRef; - sal_Bool bPgRef; + + long mnHandle; + OUString maName; + OUString maVal; + bool mbIsTOCBookmark; + public: - SwFltBookmark( const OUString& rNa, const OUString& rVa, - long nHand, sal_Bool bOnlyR ); + SwFltBookmark( const OUString& rNa, + const OUString& rVa, + long nHand, + const bool bIsTOCBookmark = false ); SwFltBookmark( const SwFltBookmark& ); + // "pure virtual Methoden" vom SfxPoolItem virtual int operator==(const SfxPoolItem&) const; virtual SfxPoolItem* Clone(SfxItemPool* = 0) const; - const OUString& GetName() const { return aName; } - const OUString& GetValSys() const { return aVal; } - sal_Bool IsOnlyRef() const { return bOnlyRef; } - sal_Bool IsRef() const { return bRef; } - void SetRef(sal_Bool b = sal_True) { bRef = b; } - sal_Bool IsPgRef() const { return bPgRef; } - void SetPgRef(sal_Bool b = sal_True) { bPgRef = b; } - long GetHandle() const { return nHandle; } + + long GetHandle() const { return mnHandle; } + const OUString& GetName() const { return maName; } + const OUString& GetValSys() const { return maVal; } + bool IsTOCBookmark() const + { + return mbIsTOCBookmark; + } }; class SW_DLLPUBLIC SwFltTOX : public SfxPoolItem diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx index 1a8b816d6525..9735f8e0aa54 100644 --- a/sw/source/filter/ww1/fltshell.cxx +++ b/sw/source/filter/ww1/fltshell.cxx @@ -549,40 +549,36 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, break; case RES_FLTR_NUMRULE_NUM: break; - case RES_FLTR_BOOKMARK: // eigentlich nur fuer den Ende-Stack + case RES_FLTR_BOOKMARK: { SwFltBookmark* pB = (SwFltBookmark*)rEntry.pAttr; const OUString& rName = ((SwFltBookmark*)rEntry.pAttr)->GetName(); if (IsFlagSet(BOOK_TO_VAR_REF)) { - if (pB->IsPgRef() && !pB->IsRef()) - { - // XRefs und Bookmarks sind bereits geUpcased - MakeBookRegionOrPoint(rEntry, pDoc, aRegion, sal_True); - pDoc->InsertPoolItem(aRegion, SwFmtRefMark(rName), 0); - } - else if( !pB->IsOnlyRef() ) + SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false); + if (!pFT) { - SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false); - if (!pFT) - { // FieldType anlegen - SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING); - pFT = pDoc->InsertFldType(aS); - } - SwSetExpField aFld((SwSetExpFieldType*)pFT, - pB->GetValSys()); - aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE ); - MakePoint(rEntry, pDoc, aRegion); - pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0); - MoveAttrs( *(aRegion.GetPoint()) ); + SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING); + pFT = pDoc->InsertFldType(aS); } + SwSetExpField aFld((SwSetExpFieldType*)pFT, pB->GetValSys()); + aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE ); + MakePoint(rEntry, pDoc, aRegion); + pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0); + MoveAttrs( *(aRegion.GetPoint()) ); } - if( !pB->IsOnlyRef() && - ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && !rEntry.bConsumedByField) + if ( ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && + !rEntry.bConsumedByField ) { MakeBookRegionOrPoint(rEntry, pDoc, aRegion, sal_True); - pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, IDocumentMarkAccess::BOOKMARK); + // #i120879# - create a cross reference heading bookmark if appropriate. + const IDocumentMarkAccess::MarkType eBookmarkType = + ( pB->IsTOCBookmark() && + IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aRegion ) ) + ? IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK + : IDocumentMarkAccess::BOOKMARK; + pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, eBookmarkType ); } } break; @@ -928,32 +924,39 @@ SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const //------ hier stehen die Methoden von SwFltBookmark ----------- SwFltBookmark::SwFltBookmark( const OUString& rNa, const OUString& rVa, - long nHand, sal_Bool bOnlyR ) - : SfxPoolItem(RES_FLTR_BOOKMARK), nHandle(nHand), aName(rNa), aVal(rVa), - bOnlyRef(bOnlyR), bRef(sal_False), bPgRef(sal_False) -{ - // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator << - // Upcase wird immer gemacht. - // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen. - // ansonsten: uebergebener Src-Charset fuer aName - // im Filter eingestellter Src-Charset fuer aVal ( Text ) + long nHand, const bool bIsTOCBookmark ) + : SfxPoolItem( RES_FLTR_BOOKMARK ) + , mnHandle( nHand ) + , maName( rNa ) + , maVal( rVa ) + , mbIsTOCBookmark( bIsTOCBookmark ) +{ + // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator << + // Upcase wird immer gemacht. + // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen. + // ansonsten: uebergebener Src-Charset fuer aName + // im Filter eingestellter Src-Charset fuer aVal ( Text ) + + if ( IsTOCBookmark() ) + { + maName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix(); + maName += rNa; + } } SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy) - : SfxPoolItem(RES_FLTR_BOOKMARK), - nHandle(rCpy.nHandle), - aName(rCpy.aName), - aVal(rCpy.aVal), - bOnlyRef(rCpy.bOnlyRef), - bRef(rCpy.bRef), - bPgRef(rCpy.bPgRef) + : SfxPoolItem( RES_FLTR_BOOKMARK ) + , mnHandle( rCpy.mnHandle ) + , maName( rCpy.maName ) + , maVal( rCpy.maVal ) + , mbIsTOCBookmark( rCpy.mbIsTOCBookmark ) { } int SwFltBookmark::operator==(const SfxPoolItem& rItem) const { - return (aName == ((SwFltBookmark&)rItem).aName) - && (nHandle == ((SwFltBookmark&)rItem).nHandle); + return ( maName == ((SwFltBookmark&)rItem).maName) + && (mnHandle == ((SwFltBookmark&)rItem).mnHandle); } SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const @@ -1255,8 +1258,8 @@ SwFltShell& SwFltShell::SetStyle( sal_uInt16 nStyle ) SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook) { - aBook.aName = ConvertUStr(aBook.aName); - aBook.aVal = QuoteStr(aBook.aVal); + aBook.maName = ConvertUStr( aBook.maName ); + aBook.maVal = QuoteStr(aBook.maVal); aEndStack.NewAttr(*pPaM->GetPoint(), aBook); return *this; } diff --git a/sw/source/filter/ww1/w1filter.cxx b/sw/source/filter/ww1/w1filter.cxx index a5c1e8e38d3c..fa477d7a71f3 100644 --- a/sw/source/filter/ww1/w1filter.cxx +++ b/sw/source/filter/ww1/w1filter.cxx @@ -334,7 +334,7 @@ void Ww1Bookmarks::Out(Ww1Shell& rOut, Ww1Manager& rMan, sal_uInt16) OUString aVal( rMan.GetText().GetText( Where(), nLen ) ); // in 2 Schritten, da OS/2 zu doof ist - SwFltBookmark aBook( rName, aVal, GetHandle(), sal_False ); + SwFltBookmark aBook( rName, aVal, GetHandle() ); rOut << aBook; } diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 160b9e5d1088..2bce444fb10d 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -1057,6 +1057,40 @@ bool SwWW8FltControlStack::CheckSdOD(sal_Int32 nStart,sal_Int32 nEnd) return rReader.IsParaEndInCPs(nStart,nEnd); } +void SwWW8ReferencedFltEndStack::SetAttrInDoc( const SwPosition& rTmpPos, + SwFltStackEntry& rEntry ) +{ + switch( rEntry.pAttr->Which() ) + { + case RES_FLTR_BOOKMARK: + { + // suppress insertion of bookmark, which is recognized as an internal bookmark used for table-of-content + // and which is not referenced. + bool bInsertBookmarkIntoDoc = true; + + SwFltBookmark* pFltBookmark = dynamic_cast<SwFltBookmark*>(rEntry.pAttr); + if ( pFltBookmark != 0 && pFltBookmark->IsTOCBookmark() ) + { + const OUString& rName = pFltBookmark->GetName(); + ::std::set< OUString, SwWW8::ltstr >::const_iterator aResult = aReferencedTOCBookmarks.find(rName); + if ( aResult == aReferencedTOCBookmarks.end() ) + { + bInsertBookmarkIntoDoc = false; + } + } + if ( bInsertBookmarkIntoDoc ) + { + SwFltEndStack::SetAttrInDoc( rTmpPos, rEntry ); + } + break; + } + default: + SwFltEndStack::SetAttrInDoc( rTmpPos, rEntry ); + break; + } + +} + void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry& rEntry) { @@ -4499,7 +4533,7 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos) RefFldStck: Keeps track of bookmarks which may be inserted as variables intstead. */ - pReffedStck = new SwFltEndStack(&rDoc, nFieldFlags); + pReffedStck = new SwWW8ReferencedFltEndStack(&rDoc, nFieldFlags); pReffingStck = new SwWW8FltRefStack(&rDoc, nFieldFlags); pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags); diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index 30ae35f87300..3580f286e9bf 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -408,14 +408,8 @@ private: Position& operator=(const Position&); }; -class SwWW8FltRefStack : public SwFltEndStack +namespace SwWW8 { -public: - SwWW8FltRefStack(SwDoc* pDo, sal_uLong nFieldFl) - : SwFltEndStack( pDo, nFieldFl ) - {} - bool IsFtnEdnBkmField(const SwFmtFld& rFmtFld, sal_uInt16& rBkmNo); - struct ltstr { bool operator()(const OUString &r1, const OUString &r2) const @@ -423,10 +417,37 @@ public: return r1.compareToIgnoreAsciiCase(r2)<0; } }; +}; + +class SwWW8ReferencedFltEndStack : public SwFltEndStack +{ +public: + SwWW8ReferencedFltEndStack( SwDoc* pDo, sal_uLong nFieldFl ) + : SwFltEndStack( pDo, nFieldFl ) + , aReferencedTOCBookmarks() + {} + + // Keep track of referenced TOC bookmarks in order to suppress the import + // of unreferenced ones. + std::set<OUString, SwWW8::ltstr> aReferencedTOCBookmarks; +protected: + virtual void SetAttrInDoc( const SwPosition& rTmpPos, + SwFltStackEntry& rEntry ); +}; + +class SwWW8FltRefStack : public SwFltEndStack +{ +public: + SwWW8FltRefStack(SwDoc* pDo, sal_uLong nFieldFl) + : SwFltEndStack( pDo, nFieldFl ) + , aFieldVarNames() + {} + bool IsFtnEdnBkmField(const SwFmtFld& rFmtFld, sal_uInt16& rBkmNo); + //Keep track of variable names created with fields, and the bookmark //mapped to their position, hopefully the same, but very possibly //an additional pseudo bookmark - std::map<OUString, OUString, ltstr> aFieldVarNames; + std::map<OUString, OUString, SwWW8::ltstr> aFieldVarNames; protected: SwFltStackEntry *RefToVar(const SwField* pFld,SwFltStackEntry& rEntry); virtual void SetAttrInDoc(const SwPosition& rTmpPos, @@ -1013,11 +1034,11 @@ private: sw::util::RedlineStack *mpRedlineStack; /* - This stack is for fields that get referneced later, e.g. BookMarks and TOX. + This stack is for fields that get referenced later, e.g. BookMarks and TOX. They get inserted at the end of the document, it is the same stack for headers/footers/main text/textboxes/tables etc... */ - SwFltEndStack *pReffedStck; + SwWW8ReferencedFltEndStack *pReffedStck; /* This stack is for fields whose true conversion cannot be determined until diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index 23265881d525..a125d725c8ce 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -95,6 +95,17 @@ using namespace nsSwDocInfoSubType; // Bookmarks //---------------------------------------- +namespace +{ + // #120879# - helper method to identify a bookmark name to match the internal TOC bookmark naming convention + bool IsTOCBookmarkName( const ::rtl::OUString& rName ) + { + static const ::rtl::OUString cTOCBookmarkNamePrefix = ::rtl::OUString::createFromAscii("_Toc"); + + return rName.match(cTOCBookmarkNamePrefix); + } +} + long SwWW8ImplReader::Read_Book(WW8PLCFManResult*) { // should also work via pRes.nCo2OrIdx @@ -203,8 +214,9 @@ long SwWW8ImplReader::Read_Book(WW8PLCFManResult*) aStart = rTest.maStartPos; } - pReffedStck->NewAttr(aStart, SwFltBookmark(BookmarkToWriter(*pName), aVal, - pB->GetHandle(), 0)); + const OUString sOrigName = BookmarkToWriter(*pName); + pReffedStck->NewAttr( aStart, + SwFltBookmark( sOrigName, aVal, pB->GetHandle(), IsTOCBookmarkName( sOrigName ) )); return 0; } @@ -1196,7 +1208,7 @@ long SwWW8ImplReader::MapBookmarkVariables(const WW8FieldDesc* pF, nNo += pPlcxMan->GetBook()->GetIMax(); } pReffedStck->NewAttr(*pPaM->GetPoint(), - SwFltBookmark(BookmarkToWriter(sName), rData, nNo, 0)); + SwFltBookmark( BookmarkToWriter(sName), rData, nNo )); pReffingStck->aFieldVarNames[rOrigName] = sName; return nNo; } @@ -1219,7 +1231,7 @@ SwFltStackEntry *SwWW8FltRefStack::RefToVar(const SwField* pFld, { //Get the name of the ref field, and see if actually a variable const OUString sName = pFld->GetPar1(); - ::std::map<OUString, OUString, SwWW8FltRefStack::ltstr>::const_iterator + ::std::map<OUString, OUString, SwWW8::ltstr>::const_iterator aResult = aFieldVarNames.find(sName); if (aResult != aFieldVarNames.end()) @@ -1243,7 +1255,7 @@ OUString SwWW8ImplReader::GetMappedBookmark(const OUString &rOrigName) //See if there has been a variable set with this name, if so get //the pseudo bookmark name that was set with it. - ::std::map<OUString, OUString, SwWW8FltRefStack::ltstr>::const_iterator aResult = + ::std::map<OUString, OUString, SwWW8::ltstr>::const_iterator aResult = pReffingStck->aFieldVarNames.find(sName); return (aResult == pReffingStck->aFieldVarNames.end()) @@ -2039,18 +2051,32 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) } } - OUString sName(GetMappedBookmark(sOrigName)); + const OUString sName(GetMappedBookmark(sOrigName)); - //loading page reference field in TOC + // loading page reference field in TOC if (mbLoadingTOCCache ) { - //Step 1. Insert page ref representation as plain text - //Step 2. If there is no hyperlink settings for current toc, assign link to current ref area - if ( !mbLoadingTOCHyperlink) + // insert page ref representation as plain text --> return FLD_TEXT + // if there is no hyperlink settings for current toc and referenced bookmark is available, + // assign link to current ref area + if ( !mbLoadingTOCHyperlink && !sName.isEmpty() ) { - OUString sURL, sTarget; - if (!sName.isEmpty()) - sURL += OUString(INET_MARK_TOKEN) + sName; + // #i120879# add cross reference bookmark name prefix, if it + // matches internal TOC bookmark naming convention + OUString sBookmarkName; + if ( IsTOCBookmarkName( sName ) ) + { + sBookmarkName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix(); + sBookmarkName += sName; + // track <sBookmarkName> as referenced TOC bookmark. + pReffedStck->aReferencedTOCBookmarks.insert( sBookmarkName ); + } + else + { + sBookmarkName = sName; + } + OUString sURL = OUString(INET_MARK_TOKEN) + sBookmarkName; + const OUString sTarget; SwFmtINetFmt aURL( sURL, sTarget ); OUString sLinkStyle("Index Link"); sal_uInt16 nPoolId = @@ -2064,11 +2090,24 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) return FLD_TEXT; } - SwGetRefField aFld( - (SwGetRefFieldType*)rDoc.GetSysFldType( RES_GETREFFLD ), sName, - REF_BOOKMARK, 0, REF_PAGE ); - + // #i120879# add cross reference bookmark name prefix, if it matches + // internal TOC bookmark naming convention + OUString sPageRefBookmarkName; + if ( IsTOCBookmarkName( sName ) ) + { + sPageRefBookmarkName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix(); + sPageRefBookmarkName += sName; + // track <sPageRefBookmarkName> as referenced TOC bookmark. + pReffedStck->aReferencedTOCBookmarks.insert( sPageRefBookmarkName ); + } + else + { + sPageRefBookmarkName = sName; + } + SwGetRefField aFld( (SwGetRefFieldType*)rDoc.GetSysFldType( RES_GETREFFLD ), + sPageRefBookmarkName, REF_BOOKMARK, 0, REF_PAGE ); rDoc.InsertPoolItem( *pPaM, SwFmtFld( aFld ), 0 ); + return FLD_OK; } @@ -3376,7 +3415,18 @@ eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, OUString& rStr { sMark = aReadParam.GetResult(); if( sMark.endsWith("\"")) + { sMark = sMark.copy( 0, sMark.getLength() - 1 ); + } + // #120879# add cross reference bookmark name prefix, if it matches internal TOC bookmark naming convention + if ( IsTOCBookmarkName( sMark ) ) + { + OUString sTmp = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix(); + sTmp += sMark; + sMark = sTmp; + // track <sMark> as referenced TOC bookmark. + pReffedStck->aReferencedTOCBookmarks.insert( sMark ); + } if (mbLoadingTOCCache) { |