diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-01-28 19:59:35 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-02-02 18:16:43 +0100 |
commit | 7685c0746cf0db6f51c6a7a488f4a960f8eab3c9 (patch) | |
tree | 9e68984782579ae58f685354b7f816a60f4807e9 /sw/source/core | |
parent | a2e533767bed88f293d2129aca9dfd9c4c60226b (diff) |
tdf#121842 sw: add hyperlinks to toxmarks in ToC/User-Defined Index
The toxmark is identified by the type of index, the name of the index
type (only for user-defined; there is only one ToC type), the text
(either text:string-value or text content of the toxmark),
and a counter to distinguish marks with the same text.
Both text and type name can contain arbitrary characters so use U+0019
control character as separator.
Links look like: #1%19text%19Utypename|toxmark
Change-Id: I5aeec727e2cd3a02d676cf3ea4c302bf7c77d319
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110091
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw/source/core')
-rw-r--r-- | sw/source/core/doc/doctxm.cxx | 10 | ||||
-rw-r--r-- | sw/source/core/inc/txmsrt.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/tox/ToxTextGenerator.cxx | 16 | ||||
-rw-r--r-- | sw/source/core/tox/txmsrt.cxx | 44 |
4 files changed, 57 insertions, 20 deletions
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index d367ce54a482..d8e7d30e80e1 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -229,11 +229,8 @@ const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, SwTOXSearch eDir, bool bInReadOnly ) { const SwTextTOXMark* pMark = rCurTOXMark.GetTextTOXMark(); - OSL_ENSURE(pMark, "pMark==0 invalid TextTOXMark"); - const SwTextNode *pTOXSrc = pMark->GetpTextNd(); - - CompareNodeContent aAbsIdx( pTOXSrc->GetIndex(), pMark->GetStart() ); + CompareNodeContent aAbsIdx(pMark ? pMark->GetpTextNd()->GetIndex() : 0, pMark ? pMark->GetStart() : 0); CompareNodeContent aPrevPos( 0, 0 ); CompareNodeContent aNextPos( ULONG_MAX, SAL_MAX_INT32 ); CompareNodeContent aMax( 0, 0 ); @@ -256,7 +253,7 @@ const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, if (!pMark) continue; - pTOXSrc = pMark->GetpTextNd(); + SwTextNode const*const pTOXSrc = pMark->GetpTextNd(); if (!pTOXSrc) continue; @@ -982,6 +979,7 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr, // Sort the List of all TOC Marks and TOC Sections std::vector<SwTextFormatColl*> aCollArr( GetTOXForm().GetFormMax(), nullptr ); + std::unordered_map<OUString, int> markURLs; SwNodeIndex aInsPos( *pFirstEmptyNd, 1 ); for( size_t nCnt = 0; nCnt < m_aSortArr.size(); ++nCnt ) { @@ -1034,7 +1032,7 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr, sw::DefaultToxTabStopTokenHandler::TABSTOPS_RELATIVE_TO_INDENT : sw::DefaultToxTabStopTokenHandler::TABSTOPS_RELATIVE_TO_PAGE); sw::ToxTextGenerator ttgn(GetTOXForm(), tabStopTokenHandler); - ttgn.GenerateText(GetFormat()->GetDoc(), m_aSortArr, nCnt, nRange, pLayout); + ttgn.GenerateText(GetFormat()->GetDoc(), markURLs, m_aSortArr, nCnt, nRange, pLayout); nCnt += nRange - 1; } diff --git a/sw/source/core/inc/txmsrt.hxx b/sw/source/core/inc/txmsrt.hxx index dd8cc50412f0..c4c91b734a00 100644 --- a/sw/source/core/inc/txmsrt.hxx +++ b/sw/source/core/inc/txmsrt.hxx @@ -148,7 +148,7 @@ struct SwTOXSortTabBase virtual bool equivalent( const SwTOXSortTabBase& ); virtual bool sort_lt( const SwTOXSortTabBase& ); - virtual OUString GetURL() const; + virtual std::pair<OUString, bool> GetURL(SwRootFrame const*const pLayout) const; virtual bool IsFullPara() const; @@ -251,7 +251,7 @@ struct SwTOXPara final : public SwTOXSortTabBase sal_uInt16 nAuthField, SwRootFrame const* pLayout) const override; virtual sal_uInt16 GetLevel() const override; - virtual OUString GetURL() const override; + virtual std::pair<OUString, bool> GetURL(SwRootFrame const*const pLayout) const override; virtual bool IsFullPara() const override; private: virtual TextAndReading GetText_Impl(SwRootFrame const* pLayout) const override; @@ -271,7 +271,8 @@ struct SwTOXTable final : public SwTOXSortTabBase virtual sal_uInt16 GetLevel() const override; - virtual OUString GetURL() const override; + virtual std::pair<OUString, bool> GetURL(SwRootFrame const*const pLayout) const override; + private: virtual TextAndReading GetText_Impl(SwRootFrame const* pLayout) const override; diff --git a/sw/source/core/tox/ToxTextGenerator.cxx b/sw/source/core/tox/ToxTextGenerator.cxx index ba76ecdaaa62..d836ec60f238 100644 --- a/sw/source/core/tox/ToxTextGenerator.cxx +++ b/sw/source/core/tox/ToxTextGenerator.cxx @@ -164,7 +164,9 @@ ToxTextGenerator::GenerateTextForChapterToken(const SwFormToken& chapterToken, c // Add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> in order to control, // which page description is used, no appropriate one is found. void -ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<std::unique_ptr<SwTOXSortTabBase>> &entries, +ToxTextGenerator::GenerateText(SwDoc* pDoc, + std::unordered_map<OUString, int> & rMarkURLs, + const std::vector<std::unique_ptr<SwTOXSortTabBase>> &entries, sal_uInt16 indexOfEntryToProcess, sal_uInt16 numberOfEntriesToProcess, SwRootFrame const*const pLayout) { @@ -239,7 +241,17 @@ ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<std::unique_ptr<Sw break; case TOKEN_LINK_END: - mLinkProcessor->CloseLink(rText.getLength(), rBase.GetURL()); + { + auto [url, isMark] = rBase.GetURL(pLayout); + if (isMark) + { + auto [iter, _] = rMarkURLs.emplace(url, 0); + (void) _; // sigh... ignore it more explicitly + ++iter->second; + url = "#" + OUString::number(iter->second) + url; + } + mLinkProcessor->CloseLink(rText.getLength(), url); + } break; case TOKEN_AUTHORITY: diff --git a/sw/source/core/tox/txmsrt.cxx b/sw/source/core/tox/txmsrt.cxx index 7aefd76721a9..f626f09afc40 100644 --- a/sw/source/core/tox/txmsrt.cxx +++ b/sw/source/core/tox/txmsrt.cxx @@ -19,6 +19,7 @@ #include <unotools/charclass.hxx> #include <osl/diagnose.h> +#include <rtl/uri.hxx> #include <txtfld.hxx> #include <doc.hxx> #include <IDocumentLayoutAccess.hxx> @@ -179,9 +180,34 @@ SwTOXSortTabBase::SwTOXSortTabBase( TOXSortType nTyp, const SwContentNode* pNd, } } -OUString SwTOXSortTabBase::GetURL() const +std::pair<OUString, bool> SwTOXSortTabBase::GetURL(SwRootFrame const*const pLayout) const { - return OUString(); + OUString typeName; + SwTOXType const& rType(*pTextMark->GetTOXMark().GetTOXType()); + switch (rType.GetType()) + { + case TOX_INDEX: + typeName = "A"; + break; + case TOX_CONTENT: + typeName = "C"; + break; + case TOX_USER: + typeName = "U" + rType.GetTypeName(); + break; + default: + assert(false); // other tox can't have toxmarks as source + break; + } + OUString const decodedUrl( // counter will be added by caller! + OUStringChar(toxMarkSeparator) + pTextMark->GetTOXMark().GetText(pLayout) + + OUStringChar(toxMarkSeparator) + typeName + + OUStringChar(cMarkSeparator) + "toxmark" ); + + OUString const uri(rtl::Uri::encode(decodedUrl, rtl_UriCharClassUricNoSlash, + rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8)); + + return std::make_pair(uri, true); } bool SwTOXSortTabBase::IsFullPara() const @@ -645,7 +671,7 @@ sal_uInt16 SwTOXPara::GetLevel() const return nRet; } -OUString SwTOXPara::GetURL() const +std::pair<OUString, bool> SwTOXPara::GetURL(SwRootFrame const*const) const { OUString aText; const SwContentNode* pNd = aTOXSources[0].pNd; @@ -696,7 +722,7 @@ OUString SwTOXPara::GetURL() const break; default: break; } - return aText; + return std::make_pair(aText, false); } bool SwTOXPara::IsFullPara() const @@ -741,21 +767,21 @@ sal_uInt16 SwTOXTable::GetLevel() const return nLevel; } -OUString SwTOXTable::GetURL() const +std::pair<OUString, bool> SwTOXTable::GetURL(SwRootFrame const*const) const { const SwNode* pNd = aTOXSources[0].pNd; if (!pNd) - return OUString(); + return std::make_pair(OUString(), false); pNd = pNd->FindTableNode(); if (!pNd) - return OUString(); + return std::make_pair(OUString(), false); const OUString sName = static_cast<const SwTableNode*>(pNd)->GetTable().GetFrameFormat()->GetName(); if ( sName.isEmpty() ) - return OUString(); + return std::make_pair(OUString(), false); - return "#" + sName + OUStringChar(cMarkSeparator) + "table"; + return std::make_pair("#" + sName + OUStringChar(cMarkSeparator) + "table", false); } SwTOXAuthority::SwTOXAuthority( const SwContentNode& rNd, |