summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2017-11-23 16:56:38 +0100
committerSzymon Kłos <szymon.klos@collabora.com>2017-11-24 07:34:53 +0100
commit50915bababcf6b645fe3b57c265560a3cd0c6224 (patch)
treeb677cdf76fe1ee1b82dffa15a6499ef47f4ffb0e
parentad83b67128fbfeee20d80889dac432c686bb2cbb (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-xsw/qa/extras/ooxmlexport/data/tdf65955.odtbin0 -> 8827 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport10.cxx18
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx49
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx9
-rw-r--r--sw/source/filter/ww8/docxexport.cxx10
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
new file mode 100755
index 000000000000..e133938e0383
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf65955.odt
Binary files differ
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 )