diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2017-11-23 16:56:38 +0100 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2017-11-24 07:34:53 +0100 |
commit | 50915bababcf6b645fe3b57c265560a3cd0c6224 (patch) | |
tree | b677cdf76fe1ee1b82dffa15a6499ef47f4ffb0e | |
parent | ad83b67128fbfeee20d80889dac432c686bb2cbb (diff) |
tdf#65955 DOCX: bookmarks at the end of paragraph
End of line handling was incorrect and all bookmark
tags placed at the end were exported before last text.
I added additional collection to separate final marks
and export them after last piece of text.
Change-Id: Icc8f89164619c85405a846fda9871430c91dcbe1
Reviewed-on: https://gerrit.libreoffice.org/45168
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
-rwxr-xr-x | sw/qa/extras/ooxmlexport/data/tdf65955.odt | bin | 0 -> 8827 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport10.cxx | 18 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 49 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 9 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 10 |
5 files changed, 75 insertions, 11 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf65955.odt b/sw/qa/extras/ooxmlexport/data/tdf65955.odt Binary files differnew file mode 100755 index 000000000000..e133938e0383 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf65955.odt diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx index 725209aab686..199aac5398a4 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx @@ -741,6 +741,24 @@ DECLARE_OOXMLEXPORT_TEST(testFdo85542, "fdo85542.docx") CPPUNIT_ASSERT_EQUAL(xTextNeighborhood->getString(), OUString("AB")); } +DECLARE_OOXMLEXPORT_TEST(testTdf65955, "tdf65955.odt") +{ + uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(xBookmarksByIdx->getCount(), static_cast<sal_Int32>(2)); + uno::Reference<container::XNameAccess> xBookmarksByName(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("a")); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("b")); + // a + uno::Reference<text::XTextContent> xContent3(xBookmarksByName->getByName("a"), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xRange3(xContent3->getAnchor(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(xRange3->getString(), OUString()); + // b + uno::Reference<text::XTextContent> xContent2(xBookmarksByName->getByName("b"), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xRange2(xContent2->getAnchor(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("r"), xRange2->getString()); +} + DECLARE_OOXMLEXPORT_TEST(testChtOutlineNumberingOoxml, "chtoutline.docx") { const sal_Unicode aExpectedPrefix[2] = { 0x7b2c, 0x0020 }; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 6a0f2adec4ee..9bb78246e2a6 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1242,8 +1242,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / // XML_r node should be surrounded with bookmark-begin and bookmark-end nodes if it has bookmarks. // The same is applied for permission ranges. // But due to unit test "testFdo85542" let's output bookmark-begin with bookmark-end. - DoWriteBookmarksStart(); - DoWriteBookmarksEnd(); + DoWriteBookmarksStart(m_rBookmarksStart); + DoWriteBookmarksEnd(m_rBookmarksEnd); DoWritePermissionsStart(); DoWriteAnnotationMarks(); @@ -1384,6 +1384,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / m_nFieldsInHyperlink = 0; } + DoWriteBookmarksStart(m_rFinalBookmarksStart); + DoWriteBookmarksEnd(m_rFinalBookmarksEnd); DoWriteBookmarkEndIfExist(nPos); } @@ -1441,9 +1443,9 @@ void DocxAttributeOutput::DoWriteBookmarkEndIfExist(sal_Int32 nRunPos) } /// Write the start bookmarks -void DocxAttributeOutput::DoWriteBookmarksStart() +void DocxAttributeOutput::DoWriteBookmarksStart(std::vector<OUString>& rStarts) { - for (const OUString & bookmarkName : m_rBookmarksStart) + for (const OUString & bookmarkName : rStarts) { // Output the bookmark DoWriteBookmarkTagStart(bookmarkName); @@ -1452,13 +1454,13 @@ void DocxAttributeOutput::DoWriteBookmarksStart() m_sLastOpenedBookmark = OUStringToOString(BookmarkToWord(bookmarkName), RTL_TEXTENCODING_UTF8).getStr(); m_nNextBookmarkId++; } - m_rBookmarksStart.clear(); + rStarts.clear(); } /// export the end bookmarks -void DocxAttributeOutput::DoWriteBookmarksEnd() +void DocxAttributeOutput::DoWriteBookmarksEnd(std::vector<OUString>& rEnds) { - for (const OUString & bookmarkName : m_rBookmarksEnd) + for (const OUString & bookmarkName : rEnds) { // Get the id of the bookmark auto pPos = m_rOpenedBookmarksIds.find(bookmarkName); @@ -1470,7 +1472,7 @@ void DocxAttributeOutput::DoWriteBookmarksEnd() m_rOpenedBookmarksIds.erase(bookmarkName); } } - m_rBookmarksEnd.clear(); + rEnds.clear(); } // For construction of the special bookmark name template for permissions: @@ -7323,6 +7325,37 @@ void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, rEnds.clear(); } +void DocxAttributeOutput::WriteFinalBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ) +{ + for ( const OUString & name : rStarts ) + { + if (name.startsWith("permission-for-group:") || + name.startsWith("permission-for-user:")) + { + m_rPermissionsStart.push_back(name); + } + else + { + m_rFinalBookmarksStart.push_back(name); + } + } + rStarts.clear(); + + for ( const OUString & name : rEnds ) + { + if (name.startsWith("permission-for-group:") || + name.startsWith("permission-for-user:")) + { + m_rPermissionsEnd.push_back(name); + } + else + { + m_rFinalBookmarksEnd.push_back(name); + } + } + rEnds.clear(); +} + void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ) { diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 8a4a565b0a9a..c61b8b3ac6d7 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -370,6 +370,7 @@ public: void WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark ); void WriteBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ); + void WriteFinalBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ); void WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds ); void PushRelIdCache(); void PopRelIdCache(); @@ -699,8 +700,8 @@ private: void DoWriteBookmarkTagStart(const OUString & bookmarkName); void DoWriteBookmarkTagEnd(const OUString & bookmarkName); - void DoWriteBookmarksStart(); - void DoWriteBookmarksEnd(); + void DoWriteBookmarksStart(std::vector<OUString>& rStarts); + void DoWriteBookmarksEnd(std::vector<OUString>& rEnds); void DoWriteBookmarkStartIfExist(sal_Int32 nRunPos); void DoWriteBookmarkEndIfExist(sal_Int32 nRunPos); @@ -791,6 +792,10 @@ private: std::vector<OUString> m_rBookmarksStart; std::vector<OUString> m_rBookmarksEnd; + /// Bookmarks to output at the end + std::vector<OUString> m_rFinalBookmarksStart; + std::vector<OUString> m_rFinalBookmarksEnd; + /// Bookmarks of the current paragraph std::multimap<sal_Int32, OUString> m_aBookmarksOfParagraphStart; std::multimap<sal_Int32, OUString> m_aBookmarksOfParagraphEnd; diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 2cab3777a532..78b116ab920f 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -167,7 +167,15 @@ void DocxExport::AppendBookmarks( const SwTextNode& rNode, sal_Int32 nAktPos, sa } } - m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds ); + SwWW8AttrIter aAttrIter( *this, rNode ); + const sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos ); + const OUString& aStr( rNode.GetText() ); + const sal_Int32 nEnd = aStr.getLength(); + + if ( nNextAttr == nEnd && nAktPos == nEnd ) + m_pAttrOutput->WriteFinalBookmarks_Impl( aStarts, aEnds ); + else + m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds ); } void DocxExport::AppendBookmark( const OUString& rName ) |