summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2013-08-26 11:35:48 +0200
committerMiklos Vajna <vmiklos@suse.cz>2013-08-26 13:11:09 +0200
commite9275c08acc2f4f1c925f78b56a1089515cd9a37 (patch)
treea03a1d4c26d45452eb5d0909a6332e446bb4c1e9 /sw
parent750f0ebf97d19d1cf305dabe72d52ad6e90adf70 (diff)
bnc#834035 DOCX export: fix hyperlinks of illustration index
We used to export raw Writer bookmarks, but that's not valid in OOXML. Instead, it has normal bookmarks around the sequence fields, so use them if they are available. Change-Id: I0ef2ff7967c2802b53752c9505ef6db4cc2b8265
Diffstat (limited to 'sw')
-rw-r--r--sw/CppunitTest_sw_ooxmlexport.mk1
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx14
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx31
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx7
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;