summaryrefslogtreecommitdiff
path: root/writerfilter/source
diff options
context:
space:
mode:
authorSerge Krot <Serge.Krot@cib.de>2018-11-22 10:05:47 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2019-01-15 19:02:13 +0100
commit1898bd6d5642ff81a09c2a9b6397ae145c3cfd8c (patch)
treee669dedab417c86143238707d063c22eb0e0f12b /writerfilter/source
parent5661a32a0cb5089e0a26867804911bc482e58af9 (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.cxx159
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx5
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 );