diff options
author | Serge Krot <Serge.Krot@cib.de> | 2018-11-22 10:05:47 +0100 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2019-01-15 19:02:13 +0100 |
commit | 1898bd6d5642ff81a09c2a9b6397ae145c3cfd8c (patch) | |
tree | e669dedab417c86143238707d063c22eb0e0f12b /writerfilter/source | |
parent | 5661a32a0cb5089e0a26867804911bc482e58af9 (diff) |
tdf#121561: sw: DOCX: add std/stdPr/stdContent around TOC
During export into DOCX from ODT we need to do it
because in this case the TOC title will be recognized
inside MS Word as part of the TOC.
Later we could add support of these keywords in LO import
in order to detect TOC title from DOCX input.
Added unit test for export.
Reviewed-on: https://gerrit.libreoffice.org/63786
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
sw: DOCX: recognize TOC title during import
Change-Id: I7135e91dc04d4c0501e6074a046fc473e041f014
fa4fb59858d61580f76e3d104aa4caa6b5902d1b
Reviewed-on: https://gerrit.libreoffice.org/64735
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Reviewed-on: https://gerrit.libreoffice.org/66355
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'writerfilter/source')
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 159 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 5 |
2 files changed, 138 insertions, 26 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index ae045d57e200..326fb0df9a89 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -514,6 +514,15 @@ void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr) void DomainMapper_Impl::SetSdt(bool bSdt) { m_bSdt = bSdt; + + if (m_bSdt) + { + m_xStdEntryStart = GetTopTextAppend()->getEnd(); + } + else + { + m_xStdEntryStart = uno::Reference< text::XTextRange >(); + } } @@ -3663,6 +3672,42 @@ static uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool return aNewLevel; } +/// Returns title of the TOC placed in paragraph(s) before TOC field inside STD-frame +OUString DomainMapper_Impl::extractTocTitle() +{ + if (!m_xStdEntryStart.is()) + return OUString(); + + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if(!xTextAppend.is()) + return OUString(); + + // try-catch was added in the same way as inside appendTextSectionAfter() + try + { + uno::Reference< text::XParagraphCursor > xCursor( xTextAppend->createTextCursorByRange( m_xStdEntryStart ), uno::UNO_QUERY_THROW); + if (!xCursor.is()) + return OUString(); + + //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls + xCursor->gotoStartOfParagraph( false ); + if (m_aTextAppendStack.top().xInsertPosition.is()) + xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true ); + else + xCursor->gotoEnd( true ); + + //the paragraph after this new section is already inserted + xCursor->goLeft(1, true); + + return xCursor->getString(); + } + catch(const uno::Exception&) + { + } + + return OUString(); +} + void DomainMapper_Impl::handleToc (const FieldContextPtr& pContext, const OUString & sTOCServiceName) @@ -3782,16 +3827,57 @@ void DomainMapper_Impl::handleToc if( !bFromOutline && !bFromEntries && sTemplate.isEmpty() ) bFromOutline = true; + const OUString aTocTitle = extractTocTitle(); + + if (m_xTextFactory.is() && ! m_aTextAppendStack.empty()) + { + if (aTocTitle.isEmpty() || bTableOfFigures) + { + xTOC.set( + m_xTextFactory->createInstance + ( bTableOfFigures ? + "com.sun.star.text.IllustrationsIndex" + : sTOCServiceName), + uno::UNO_QUERY_THROW); + + OUString const sMarker("Y"); + //insert index + uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY ); + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if (xTextAppend.is()) + { + uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor(); + uno::Reference< text::XText > xText = xTextAppend->getText(); + if(xCrsr.is() && xText.is()) + { + xCrsr->gotoEnd(false); + xText->insertString(xCrsr, sMarker, false); + xText->insertTextContent(uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ), xToInsert, false); + xTOCMarkerCursor = xCrsr; + } + } + } + else + { + // create TOC section + css::uno::Reference<css::text::XTextRange> xTextRangeEndOfTocHeader = GetTopTextAppend()->getEnd(); + xTOC = createSectionForRange(m_xStdEntryStart, xTextRangeEndOfTocHeader, sTOCServiceName, false); + + // init [xTOCMarkerCursor] + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + uno::Reference< text::XText > xText = xTextAppend->getText(); + uno::Reference< text::XTextCursor > xCrsr = xText->createTextCursor(); + xTOCMarkerCursor = xCrsr; + + // create header of the TOC with the TOC title inside + const OUString aObjectType("com.sun.star.text.IndexHeaderSection"); + uno::Reference<beans::XPropertySet> xIfc = createSectionForRange(m_xStdEntryStart, xTextRangeEndOfTocHeader, aObjectType, true); + } + } - if (m_xTextFactory.is()) - xTOC.set( - m_xTextFactory->createInstance - ( bTableOfFigures ? - "com.sun.star.text.IllustrationsIndex" - : sTOCServiceName), - uno::UNO_QUERY_THROW); if (xTOC.is()) - xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), uno::makeAny(OUString())); + xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), uno::makeAny(aTocTitle)); + if (!aBookmarkName.isEmpty()) xTOC->setPropertyValue(getPropertyName(PROP_TOC_BOOKMARK), uno::makeAny(aBookmarkName)); if( !bTableOfFigures && xTOC.is() ) @@ -3881,27 +3967,45 @@ void DomainMapper_Impl::handleToc } pContext->SetTOC( xTOC ); m_bParaHadField = false; +} - if (m_aTextAppendStack.empty()) - return; +uno::Reference<beans::XPropertySet> DomainMapper_Impl::createSectionForRange( + uno::Reference< css::text::XTextRange > xStart, + uno::Reference< css::text::XTextRange > xEnd, + const OUString & sObjectType, + bool stepLeft) +{ + if (!xStart.is()) + return uno::Reference<beans::XPropertySet>(); + if (!xEnd.is()) + return uno::Reference<beans::XPropertySet>(); - OUString const sMarker("Y"); - //insert index - uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet > xRet; + if (m_aTextAppendStack.empty()) + return xRet; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is()) + if(xTextAppend.is()) { - uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor(); - - uno::Reference< text::XText > xText = xTextAppend->getText(); - if(xCrsr.is() && xText.is()) + try + { + uno::Reference< text::XParagraphCursor > xCursor( + xTextAppend->createTextCursorByRange( xStart ), uno::UNO_QUERY_THROW); + //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls + xCursor->gotoStartOfParagraph( false ); + xCursor->gotoRange( xEnd, true ); + //the paragraph after this new section is already inserted + if (stepLeft) + xCursor->goLeft(1, true); + uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sObjectType), uno::UNO_QUERY_THROW ); + xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) ); + xRet.set(xSection, uno::UNO_QUERY ); + } + catch(const uno::Exception&) { - xCrsr->gotoEnd(false); - xText->insertString(xCrsr, sMarker, false); - xText->insertTextContent(uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ), xToInsert, false); - xTOCMarkerCursor = xCrsr; } } + + return xRet; } void DomainMapper_Impl::handleBibliography @@ -4988,10 +5092,13 @@ void DomainMapper_Impl::PopFieldContext() } else { - xTOCMarkerCursor->goLeft(1,true); - xTOCMarkerCursor->setString(OUString()); - xTOCMarkerCursor->goLeft(1,true); - xTOCMarkerCursor->setString(OUString()); + if (!m_xStdEntryStart.is()) + { + xTOCMarkerCursor->goLeft(1,true); + xTOCMarkerCursor->setString(OUString()); + xTOCMarkerCursor->goLeft(1,true); + xTOCMarkerCursor->setString(OUString()); + } } } if (m_bStartedTOC || m_bStartIndex || m_bStartBibliography) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 89deb65f1b56..02f029a4732c 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -542,6 +542,7 @@ private: SmartTagHandler m_aSmartTagHandler; css::uno::Reference<css::text::XTextRange> m_xGlossaryEntryStart; + css::uno::Reference<css::text::XTextRange> m_xStdEntryStart; public: css::uno::Reference<css::text::XTextRange> m_xInsertTextRange; @@ -792,6 +793,10 @@ public: /// The end of field is reached (cFieldEnd appeared) - the command might still be open. void PopFieldContext(); + /// Returns title of the TOC placed in paragraph(s) before TOC field inside STD-frame + OUString extractTocTitle(); + css::uno::Reference<css::beans::XPropertySet> createSectionForRange(css::uno::Reference< css::text::XTextRange > xStart, css::uno::Reference< css::text::XTextRange > xEnd, const OUString & sObjectType, bool stepLeft); + void SetBookmarkName( const OUString& rBookmarkName ); void StartOrEndBookmark( const OUString& rId ); |