[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 2 commits - sw/CppunitTest_sw_ooxmllinks.mk sw/Module_sw.mk sw/qa sw/source writerfilter/source
Szymon Kłos
szymon.klos at collabora.com
Tue Nov 21 21:40:10 UTC 2017
sw/CppunitTest_sw_ooxmllinks.mk | 45 +++++
sw/Module_sw.mk | 1
sw/qa/extras/ooxmlexport/data/absolute-link.docx |binary
sw/qa/extras/ooxmlexport/data/relative-link.docx |binary
sw/qa/extras/ooxmlexport/ooxmllinks.cxx | 197 ++++++++++++++++++++++
sw/source/filter/ww8/attributeoutputbase.hxx | 6
sw/source/filter/ww8/wrtw8nds.cxx | 68 +++++++
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 2
writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2
9 files changed, 320 insertions(+), 1 deletion(-)
New commits:
commit 3f3aeed128df08bdd6a432ee915af5c19aefc3dd
Author: Szymon Kłos <szymon.klos at collabora.com>
Date: Fri Nov 10 19:04:35 2017 +0100
tdf#86087 Save relative links in DOCX
Save links depending on preferences set
Options -> Load/Save -> General -> Save URLs relative to ...
Change-Id: I96d06cfdc405d1e1254515106926374aee279f6c
Reviewed-on: https://gerrit.libreoffice.org/44785
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/45050
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/CppunitTest_sw_ooxmllinks.mk b/sw/CppunitTest_sw_ooxmllinks.mk
new file mode 100755
index 000000000000..78b81d4a14b4
--- /dev/null
+++ b/sw/CppunitTest_sw_ooxmllinks.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_ooxmllinks))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_ooxmllinks, \
+ sw/qa/extras/ooxmlexport/ooxmllinks \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_ooxmllinks, \
+ $(sw_ooxmlexport_libraries) \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_ooxmllinks,\
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_ooxmllinks,\
+ -I$(SRCDIR)/sw/inc \
+ -I$(SRCDIR)/sw/source/core/inc \
+ -I$(SRCDIR)/sw/qa/extras/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sw_ooxmllinks))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_ooxmllinks))
+$(eval $(call gb_CppunitTest_use_vcl,sw_ooxmllinks))
+
+$(eval $(call gb_CppunitTest_use_components,sw_ooxmllinks,\
+ $(sw_ooxmlexport_components) \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_ooxmllinks))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 39b466fc616f..f4371dfa20cf 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -60,6 +60,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
CppunitTest_sw_ooxmlexport6 \
CppunitTest_sw_ooxmlexport7 \
CppunitTest_sw_ooxmlfieldexport \
+ CppunitTest_sw_ooxmllinks \
CppunitTest_sw_ooxmlw14export \
CppunitTest_sw_ooxmlimport \
CppunitTest_sw_ww8export \
diff --git a/sw/qa/extras/ooxmlexport/data/absolute-link.docx b/sw/qa/extras/ooxmlexport/data/absolute-link.docx
new file mode 100755
index 000000000000..34480d0a2b94
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/absolute-link.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/relative-link.docx b/sw/qa/extras/ooxmlexport/data/relative-link.docx
new file mode 100755
index 000000000000..c3688f3e8726
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/relative-link.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmllinks.cxx b/sw/qa/extras/ooxmlexport/ooxmllinks.cxx
new file mode 100755
index 000000000000..5d1c8f6a2d56
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/ooxmllinks.cxx
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+#include <unotools/tempfile.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <unotools/saveopt.hxx>
+
+ // This file contains tests to check relative/absolute hyperlinks handling
+
+#define USE_TEMP_DIR true
+#define DONT_MODIFY_LINK false
+
+#define USE_ABSOLUTE true
+#define USE_RELATIVE false
+
+// bAbsolute - decide if output link should be converted to absolute
+// bUseTempDir - decide if link should be modified to be placed in temp dir - for testing relative links
+#define DECLARE_LINKS_EXPORT_TEST(TestName, FileName, bAbsolute, bUseTempDir) \
+class TestName : public Test { \
+protected: \
+ virtual OUString getTestName() override { return OUString(#TestName); } \
+ virtual void postLoad(const char*) override \
+ { \
+ if(!bUseTempDir) return; \
+ \
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(1); \
+ /* can be changed only after import */ \
+ uno::Reference<text::XTextRange> xText = getRun(xParagraph, 1); \
+ \
+ /* Get original link */ \
+ OUString sOriginalFileName = getProperty<OUString>(xText, "HyperLinkURL"); \
+ INetURLObject aOriginalURL; \
+ aOriginalURL.setFSysPath(sOriginalFileName, INetURLObject::FSYS_DETECT); \
+ OUString sFileName = aOriginalURL.GetName().isEmpty() ? sOriginalFileName : aOriginalURL.GetName(); \
+ \
+ /* Get temp path */ \
+ OUString sTempDir = utl::TempFile::CreateTempName(); \
+ INetURLObject aTempURL; \
+ aTempURL.setFSysPath(sTempDir, INetURLObject::FSYS_DETECT); \
+ /* remove file name */ \
+ aTempURL.removeSegment(); \
+ sTempDir = INetURLObject::GetScheme(aTempURL.GetProtocol()) + aTempURL.GetURLPath(); \
+ \
+ /* Create & apply new URL */ \
+ OUString sOriginalFileInTempDir = sTempDir + sFileName; \
+ uno::Reference<beans::XPropertySet> xPropertySet(xText, css::uno::UNO_QUERY); \
+ xPropertySet->setPropertyValue("HyperLinkURL", css::uno::makeAny(sOriginalFileInTempDir)); \
+ } \
+public: \
+ CPPUNIT_TEST_SUITE(TestName); \
+ CPPUNIT_TEST(Import_Export_Import); \
+ CPPUNIT_TEST_SUITE_END(); \
+ void Import_Export_Import() \
+ { \
+ SvtSaveOptions aOpt; \
+ if (bAbsolute) { \
+ aOpt.SetSaveRelFSys(false); \
+ CPPUNIT_ASSERT(!aOpt.IsSaveRelFSys()); \
+ } else { \
+ aOpt.SetSaveRelFSys(true); \
+ CPPUNIT_ASSERT(aOpt.IsSaveRelFSys()); \
+ } \
+ executeImportExportImportTest(FileName); \
+ } \
+ void verify() override; \
+}; \
+CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
+void TestName::verify()
+
+// bAbsolute - decide if relative link should be converted to absolute on import
+#define DECLARE_LINKS_IMPORT_TEST(TestName, FileName, bAbsolute) \
+class TestName : public Test { \
+protected: \
+ virtual OUString getTestName() override { return OUString(#TestName); } \
+public: \
+ CPPUNIT_TEST_SUITE(TestName); \
+ CPPUNIT_TEST(Import); \
+ CPPUNIT_TEST_SUITE_END(); \
+ void Import() \
+ { \
+ SvtSaveOptions aOpt; \
+ if (bAbsolute) { \
+ aOpt.SetSaveRelFSys(false); \
+ CPPUNIT_ASSERT(!aOpt.IsSaveRelFSys()); \
+ } else { \
+ aOpt.SetSaveRelFSys(true); \
+ CPPUNIT_ASSERT(aOpt.IsSaveRelFSys()); \
+ } \
+ executeImportTest(FileName); \
+ } \
+ void verify() override; \
+}; \
+CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
+void TestName::verify()
+
+class Test : public SwModelTestBase
+{
+public:
+ Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
+
+protected:
+ /**
+ * Blacklist handling
+ */
+ bool mustTestImportOf(const char* filename) const override {
+ // If the testcase is stored in some other format, it's pointless to test.
+ return OString(filename).endsWith(".docx");
+ }
+};
+
+/* IMPORT */
+
+DECLARE_LINKS_IMPORT_TEST(testRelativeToRelativeImport, "relative-link.docx", USE_RELATIVE)
+{
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
+ uno::Reference<text::XTextRange> xText = getRun(xParagraph, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString("relative.docx"), getProperty<OUString>(xText, "HyperLinkURL"));
+}
+
+DECLARE_LINKS_IMPORT_TEST(testRelativeToAbsoluteImport, "relative-link.docx", USE_ABSOLUTE)
+{
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
+ uno::Reference<text::XTextRange> xText = getRun(xParagraph, 1);
+ OUString sTarget = getProperty<OUString>(xText, "HyperLinkURL");
+ CPPUNIT_ASSERT(sTarget.startsWith("file:///"));
+ CPPUNIT_ASSERT(sTarget.endsWith("relative.docx"));
+}
+
+DECLARE_LINKS_IMPORT_TEST(testAbsoluteToAbsoluteImport, "absolute-link.docx", USE_ABSOLUTE)
+{
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
+ uno::Reference<text::XTextRange> xText = getRun(xParagraph, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString("file:///B:\\Users\\user\\Desktop\\test.docx"), getProperty<OUString>(xText, "HyperLinkURL"));
+}
+
+DECLARE_LINKS_IMPORT_TEST(testAbsoluteToRelativeImport, "absolute-link.docx", USE_RELATIVE)
+{
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
+ uno::Reference<text::XTextRange> xText = getRun(xParagraph, 1);
+ // when target file (B:\\...) & document with link (temp dir) are placed on different partitions, absolute path will be loaded
+ CPPUNIT_ASSERT_EQUAL(OUString("file:///B:\\Users\\user\\Desktop\\test.docx"), getProperty<OUString>(xText, "HyperLinkURL"));
+}
+
+/* EXPORT */
+
+DECLARE_LINKS_EXPORT_TEST(testRelativeToRelativeExport, "relative-link.docx", USE_RELATIVE, DONT_MODIFY_LINK)
+{
+ xmlDocPtr pXmlDoc = parseExport("word/_rels/document.xml.rels");
+ if (!pXmlDoc)
+ return;
+
+ assertXPath(pXmlDoc, "/rels:Relationships/rels:Relationship[2]", "Target", "relative.docx");
+}
+
+DECLARE_LINKS_EXPORT_TEST(testRelativeToAbsoluteExport, "relative-link.docx", USE_ABSOLUTE, DONT_MODIFY_LINK)
+{
+ xmlDocPtr pXmlDoc = parseExport("word/_rels/document.xml.rels");
+ if (!pXmlDoc)
+ return;
+
+ OUString sTarget = getXPath(pXmlDoc, "/rels:Relationships/rels:Relationship[2]", "Target");
+ CPPUNIT_ASSERT(sTarget.startsWith("file:///"));
+ CPPUNIT_ASSERT(sTarget.endsWith("relative.docx"));
+}
+
+DECLARE_LINKS_EXPORT_TEST(testAbsoluteToRelativeExport, "absolute-link.docx", USE_RELATIVE, USE_TEMP_DIR)
+{
+ xmlDocPtr pXmlDoc = parseExport("word/_rels/document.xml.rels");
+ if (!pXmlDoc)
+ return;
+
+ assertXPath(pXmlDoc, "/rels:Relationships/rels:Relationship[2]", "Target", "test.docx");
+}
+
+DECLARE_LINKS_EXPORT_TEST(testAbsoluteToAbsoluteExport, "absolute-link.docx", USE_ABSOLUTE, DONT_MODIFY_LINK)
+{
+ xmlDocPtr pXmlDoc = parseExport("word/_rels/document.xml.rels");
+ if (!pXmlDoc)
+ return;
+
+ OUString sTarget = getXPath(pXmlDoc, "/rels:Relationships/rels:Relationship[2]", "Target");
+ CPPUNIT_ASSERT(sTarget.startsWith("file:///"));
+ CPPUNIT_ASSERT(sTarget.endsWith("test.docx"));
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 86b468198ed9..75759bc33aff 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -34,6 +34,7 @@
#include <wrtswtbl.hxx>
#include <fldbas.hxx>
#include <IDocumentRedlineAccess.hxx>
+#include <unotools/saveopt.hxx>
#include <vector>
@@ -146,6 +147,11 @@ enum StyleType
class AttributeOutputBase
{
+private:
+ SvtSaveOptions m_aSaveOpt;
+
+ OUString ConvertURL( const OUString& rUrl, bool bAbsoluteOut );
+
public:
/// Export the state of RTL/CJK.
virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) = 0;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index cbc0a777154f..bc98076f174c 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -24,6 +24,10 @@
#include <functional>
#include <iostream>
+#include <oox/core/filterbase.hxx>
+#include "docxexport.hxx"
+#include "docxexportfilter.hxx"
+
#include <i18nlangtag/mslangid.hxx>
#include <hintids.hxx>
#include <comphelper/string.hxx>
@@ -904,6 +908,62 @@ OUString &TruncateBookmark( OUString &rRet )
return rRet;
}
+OUString AttributeOutputBase::ConvertURL( const OUString& rUrl, bool bAbsoluteOut )
+{
+ OUString sURL = rUrl;
+ OUString sExportedDocumentURL = "";
+ {
+ DocxExport* pDocxExport = dynamic_cast<DocxExport*>(&GetExport());
+ if ( pDocxExport )
+ {
+ // DOCX
+ DocxExportFilter& rFilter = pDocxExport->GetFilter();
+ sExportedDocumentURL = rFilter.getFileUrl();
+ }
+ else
+ {
+ // DOC
+ WW8Export* pWW8Export = dynamic_cast<WW8Export*>(&GetExport());
+ if ( pWW8Export )
+ {
+ SwWW8Writer& rWriter = pWW8Export->GetWriter();
+ sExportedDocumentURL = rWriter.GetMedia()->GetURLObject().GetPath();
+ }
+ }
+ }
+
+ INetURLObject anAbsoluteParent( sExportedDocumentURL );
+ if ( anAbsoluteParent.GetURLPath().isEmpty() )
+ {
+ // DOC filter returns system path (without file:///)
+ anAbsoluteParent.setFSysPath( sExportedDocumentURL, INetURLObject::FSYS_DETECT );
+ anAbsoluteParent.setFinalSlash();
+ }
+ OUString sConvertedParent = INetURLObject::GetScheme( anAbsoluteParent.GetProtocol() ) + anAbsoluteParent.GetURLPath();
+ OUString sParentPath = sConvertedParent.isEmpty() ? sExportedDocumentURL : sConvertedParent;
+
+ if ( bAbsoluteOut )
+ {
+ INetURLObject anAbsoluteNew;
+
+ if ( anAbsoluteParent.GetNewAbsURL( rUrl, &anAbsoluteNew ) )
+ sURL = anAbsoluteNew.GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
+ else
+ sURL = rUrl;
+ }
+ else
+ {
+ OUString sToConvert = rUrl.replaceAll( "\\", "/" );
+ INetURLObject aURL( sToConvert );
+ sToConvert = INetURLObject::GetScheme( aURL.GetProtocol() ) + aURL.GetURLPath();
+ OUString sRelative = INetURLObject::GetRelURL( sParentPath, sToConvert, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
+ if ( !sRelative.isEmpty() )
+ sURL = sRelative;
+ }
+
+ return sURL;
+}
+
bool AttributeOutputBase::AnalyzeURL( const OUString& rUrl, const OUString& /*rTarget*/, OUString* pLinkURL, OUString* pMark )
{
bool bBookMarkOnly = false;
@@ -940,6 +1000,14 @@ bool AttributeOutputBase::AnalyzeURL( const OUString& rUrl, const OUString& /*rT
INetURLObject aURL( rUrl, INetProtocol::NotValid );
sURL = aURL.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS );
sMark = aURL.GetMark( INetURLObject::DECODE_UNAMBIGUOUS );
+ INetProtocol aProtocol = aURL.GetProtocol();
+
+ if ( aProtocol == INetProtocol::File || aProtocol == INetProtocol::NotValid )
+ {
+ // INetProtocol::NotValid - may be a relative link
+ bool bExportRelative = m_aSaveOpt.IsSaveRelFSys();
+ sURL = ConvertURL( rUrl, !bExportRelative );
+ }
}
if ( !sMark.isEmpty() && sURL.isEmpty() )
commit 92b8bbe6b0e77d3cb4aac52a1597e7ec936c7d6f
Author: Szymon Kłos <szymon.klos at collabora.com>
Date: Tue Nov 14 19:55:42 2017 +0100
tdf#86087 DOCX Import link as relative if preferred
Change-Id: I92e273aa57db8b4b9779d8d784c5bbad42d720e5
Reviewed-on: https://gerrit.libreoffice.org/44735
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/45049
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 142739559a6f..f41e406409dc 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -3901,7 +3901,7 @@ void DomainMapper_Impl::CloseFieldCommand()
// Try to make absolute any relative URLs, except
// for relative same-document URLs that only contain
// a fragment part:
- if (!sURL.startsWith("#")) {
+ if (!sURL.startsWith("#") && !m_aSaveOpt.IsSaveRelFSys()) {
try {
sURL = rtl::Uri::convertRelToAbs(
m_aBaseUrl, sURL);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 4886ad1e3800..4738d0322642 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -27,6 +27,7 @@
#include <com/sun/star/text/XTextFrame.hpp>
#include <com/sun/star/style/TabStop.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
+#include <unotools/saveopt.hxx>
#include <queue>
#include <stack>
#include <tuple>
@@ -394,6 +395,7 @@ public:
private:
SourceDocumentType m_eDocumentType;
DomainMapper& m_rDMapper;
+ SvtSaveOptions m_aSaveOpt;
OUString m_aBaseUrl;
css::uno::Reference<css::text::XTextDocument> m_xTextDocument;
css::uno::Reference<css::beans::XPropertySet> m_xDocumentSettings;
More information about the Libreoffice-commits
mailing list