diff options
author | Justin Luth <justin.luth@collabora.com> | 2024-09-24 17:29:59 -0400 |
---|---|---|
committer | Justin Luth <jluth@mail.com> | 2024-09-25 02:06:15 +0200 |
commit | 9112a4a4cc700569f8321b8191abb4238697a404 (patch) | |
tree | 48131360704b8ffaafff791193af0ab5faf62d28 /sw/source | |
parent | fe4687ed174c54f2eb25f8088bf3fb6cb4858175 (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.cxx | 65 |
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 ) ); } } |