diff options
-rw-r--r-- | sw/CppunitTest_sw_ooxmlexport.mk | 1 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 14 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 31 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 7 |
4 files changed, 53 insertions, 0 deletions
diff --git a/sw/CppunitTest_sw_ooxmlexport.mk b/sw/CppunitTest_sw_ooxmlexport.mk index e96961fade5b..2e90beca897c 100644 --- a/sw/CppunitTest_sw_ooxmlexport.mk +++ b/sw/CppunitTest_sw_ooxmlexport.mk @@ -76,6 +76,7 @@ $(eval $(call gb_CppunitTest_use_components,sw_ooxmlexport,\ ucb/source/ucp/file/ucpfile1 \ unotools/util/utl \ unoxml/source/service/unoxml \ + uui/util/uui \ writerfilter/util/writerfilter \ xmloff/util/xo \ )) diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index d5cb1cb0003d..e4347ddcc609 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -112,6 +112,7 @@ public: void testFdo44689_start_page_7(); void testFdo67737(); void testTransparentShadow(); + void testBnc834035(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -200,6 +201,7 @@ void Test::run() {"fdo44689_start_page_7.docx", &Test::testFdo44689_start_page_7}, {"fdo67737.docx", &Test::testFdo67737}, {"transparent-shadow.docx", &Test::testTransparentShadow}, + {"bnc834035.odt", &Test::testBnc834035}, }; // Don't test the first import of these, for some reason those tests fail const char* aBlacklist[] = { @@ -1233,6 +1235,18 @@ void Test::testTransparentShadow() CPPUNIT_ASSERT_EQUAL(sal_Int32(0x7f808080), aShadow.Color); } +void Test::testBnc834035() +{ + // This is tricky, when saving manually, there are 2 hyperlinks, here only + // one, no idea why. That one still shows that we're not using bookmarks, though. + + // Illustration index had wrong hyperlinks: anchor was using Writer's + // <seqname>!<index>|sequence syntax, not a bookmark name. + xmlDocPtr pXmlDoc = parseExport(); + // This was Figure!1|sequence. + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:hyperlink", "anchor", "_Toc363553908"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 5fa97132d180..2cf7058cabe3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -706,6 +706,7 @@ void DocxAttributeOutput::DoWriteBookmarks() FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ), FSNS( XML_w, XML_name ), rName.getStr(), FSEND ); + m_sLastOpenedMark = rName; } m_rMarksStart.clear(); @@ -835,6 +836,12 @@ void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, bool bWriteRun ) void DocxAttributeOutput::DoWriteCmd( String& rCmd ) { + OUString sCmd = OUString(rCmd).trim(); + if (sCmd.startsWith("SEQ")) + { + OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\').trim(); + m_aSeqMarksNames[sSeqName].push_back(m_sLastOpenedMark); + } // Write the Field command m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND ); m_pSerializer->writeEscaped( OUString( rCmd ) ); @@ -1309,8 +1316,32 @@ bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget ) m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr()); } else + { + // Is this a link to a sequence? Then try to replace that with a + // normal bookmark, as Word won't understand our special + // <seqname>!<index>|sequence syntax. + if (sMark.endsWith("|sequence")) + { + sal_Int32 nPos = sMark.indexOf('!'); + if (nPos != -1) + { + // Extract <seqname>, the field instruction text has the name quoted. + OUString aSequenceName = OUString('"') + sMark.copy(0, nPos) + OUString('"'); + // Extract <index>. + sal_uInt32 nIndex = sMark.copy(nPos + 1, sMark.getLength() - nPos - sizeof("|sequence")).toInt32(); + std::map<OUString, std::vector<OString> >::iterator it = m_aSeqMarksNames.find(aSequenceName); + if (it != m_aSeqMarksNames.end()) + { + std::vector<OString>& rNames = it->second; + if (rNames.size() > nIndex) + // We know the bookmark name for this sequence and this index, do the replacement. + sMark = OStringToOUString(rNames[nIndex], RTL_TEXTENCODING_UTF8); + } + } + } m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ), OUStringToOString( sMark, RTL_TEXTENCODING_UTF8 ).getStr( ) ); + } OUString sTarget( rTarget ); if ( !sTarget.isEmpty() ) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index a6c4532f36ce..5e297aab59c9 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -649,6 +649,13 @@ private: /// Maps of the bookmarks ids std::map<OString, sal_uInt16> m_rOpenedMarksIds; + /// Name of the last opened bookmark. + OString m_sLastOpenedMark; + + /// If there are bookmarks around sequence fields, this map contains the + /// names of these bookmarks for each sequence. + std::map<OUString, std::vector<OString> > m_aSeqMarksNames; + /// The current table helper SwWriteTable *m_pTableWrt; |