[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