summaryrefslogtreecommitdiff
path: root/sw/source/core
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2021-01-28 19:59:35 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2021-02-02 18:16:43 +0100
commit7685c0746cf0db6f51c6a7a488f4a960f8eab3c9 (patch)
tree9e68984782579ae58f685354b7f816a60f4807e9 /sw/source/core
parenta2e533767bed88f293d2129aca9dfd9c4c60226b (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.cxx10
-rw-r--r--sw/source/core/inc/txmsrt.hxx7
-rw-r--r--sw/source/core/tox/ToxTextGenerator.cxx16
-rw-r--r--sw/source/core/tox/txmsrt.cxx44
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,