summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2024-09-24 17:29:59 -0400
committerJustin Luth <jluth@mail.com>2024-09-25 02:06:15 +0200
commit9112a4a4cc700569f8321b8191abb4238697a404 (patch)
tree48131360704b8ffaafff791193af0ab5faf62d28 /sw/source
parentfe4687ed174c54f2eb25f8088bf3fb6cb4858175 (diff)
tdf#162916 writerfilter TOC: import "no page number" flag
The field command "TOC \n 2-2" means that level 2 entries should not display the page number, so in LO just exclude those portions from the definitions. The impact only becomes noticable when you update the TOC, because the initial content is just read from document.xml. The export part was already handled at LO initial import, since DOC format needed the proper sFieldCmd string. DOC format already imports this just fine. Note that the unit test also specifies 'TOC \o "2-3"' which means that the first level should not show, but I don't think LO supports skipping earlier levels. make CppunitTest_sw_ooxmlexport10 \ CPPUNIT_TEST_NAME=testTdf162916_nastyTOC Change-Id: I9661c56c84bcd28bf1664d808a0e9c38051cf67b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173885 Tested-by: Jenkins Reviewed-by: Justin Luth <jluth@mail.com>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx65
1 files changed, 54 insertions, 11 deletions
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 31137ba9757b..4147155a4e55 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -7018,7 +7018,8 @@ void DomainMapper_Impl::handleDocProperty
}
static uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool bHyperlinks, const OUString& sChapterNoSeparator,
- const uno::Sequence< beans::PropertyValues >& aLevel, const std::optional<style::TabStop> numtab)
+ const uno::Sequence< beans::PropertyValues >& aLevel, const std::optional<style::TabStop> numtab,
+ bool bSkipPageNumberAndTab)
{
//create a copy of the level and add new entries
@@ -7028,8 +7029,8 @@ static uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool
static constexpr OUString tokType(u"TokenType"_ustr);
static constexpr OUString tokHStart(u"TokenHyperlinkStart"_ustr);
static constexpr OUString tokHEnd(u"TokenHyperlinkEnd"_ustr);
- static constexpr OUStringLiteral tokPNum(u"TokenPageNumber");
- static constexpr OUStringLiteral tokENum(u"TokenEntryNumber");
+ static constexpr OUString tokPNum(u"TokenPageNumber"_ustr);
+ static constexpr OUString tokENum(u"TokenEntryNumber"_ustr);
if (bHyperlinks)
aNewLevel.push_back({ comphelper::makePropertyValue(tokType, tokHStart) });
@@ -7055,7 +7056,23 @@ static uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool
comphelper::makePropertyValue(u"Text"_ustr, sChapterNoSeparator) });
}
- aNewLevel.push_back(item);
+ if (bSkipPageNumberAndTab && tokenType == tokPNum)
+ {
+ // also skip the preceding tabstop
+ if (aNewLevel.size())
+ {
+ OUString aPrevTokenType;
+ const auto& rPrevLevel = aNewLevel.back();
+ auto it = std::find_if(rPrevLevel.begin(), rPrevLevel.end(),
+ [](const auto& p) { return p.Name == tokType; });
+ if (it != rPrevLevel.end())
+ it->Value >>= aPrevTokenType;
+ if (aPrevTokenType == u"TokenTabStop"_ustr)
+ aNewLevel.pop_back();
+ }
+ }
+ else
+ aNewLevel.push_back(item);
if (numtab && tokenType == tokENum)
{
@@ -7218,6 +7235,10 @@ void DomainMapper_Impl::handleToc
bool bIsTabEntry = false ;
bool bNewLine = false ;
bool bParagraphOutlineLevel = false;
+ // some levels (optionally specified via a single range) might not display the page number
+ sal_uInt8 nStartNoPageNumber = 0;
+ sal_uInt8 nEndNoPageNumber = 0;
+
sal_Int16 nMaxLevel = 10;
OUString sTemplate;
@@ -7267,10 +7288,32 @@ void DomainMapper_Impl::handleToc
//todo: entries can only be included completely
// }
// \n Builds a table of contents or a range of entries, such as 1-9 in a table of contents without page numbers
-// if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
-// {
- //todo: what does the description mean?
-// }
+ if (lcl_FindInCommand(pContext->GetCommand(), 'n', sValue))
+ {
+ // skip the tabstop and page-number on the specified levels
+ sValue = sValue.replaceAll("\"", "").trim();
+ if (sValue.isEmpty())
+ {
+ nStartNoPageNumber = 1;
+ nEndNoPageNumber = WW_OUTLINE_MAX;
+ }
+ else
+ {
+ // valid command format is fairly strict, requiring # <dash> #: TOC \n "2-3"
+ sal_Int32 nIndex = 0;
+ o3tl::getToken(sValue, 0, '-', nIndex);
+ if (nIndex > 1)
+ {
+ const sal_Int32 nStartLevel = o3tl::toInt32(sValue.subView(0, nIndex - 1));
+ const sal_Int32 nEndLevel = o3tl::toInt32(sValue.subView(nIndex));
+ if (nStartLevel > 0 && nStartLevel <= nEndLevel && nEndLevel <= WW_OUTLINE_MAX)
+ {
+ nStartNoPageNumber = static_cast<sal_uInt8>(nStartLevel);
+ nEndNoPageNumber = static_cast<sal_uInt8>(nEndLevel);
+ }
+ }
+ }
+ }
// \o Builds a table of contents by using outline levels instead of TC entries
if( lcl_FindInCommand( pContext->GetCommand(), 'o', sValue ))
{
@@ -7497,10 +7540,10 @@ void DomainMapper_Impl::handleToc
}
}
}
-
+ bool bSkipPageNumberAndTab = nLevel >= nStartNoPageNumber && nLevel <= nEndNoPageNumber;
uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
bHyperlinks, sChapterNoSeparator,
- aLevel, numTab);
+ aLevel, numTab, bSkipPageNumberAndTab);
xLevelFormats->replaceByIndex( nLevel, uno::Any( aNewLevel ) );
}
}
@@ -7525,7 +7568,7 @@ void DomainMapper_Impl::handleToc
uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
bHyperlinks, sChapterNoSeparator,
- aLevel, {});
+ aLevel, {}, /*SkipPageNumberAndTab=*/false);
xLevelFormats->replaceByIndex( 1, uno::Any( aNewLevel ) );
}
}