[Libreoffice-commits] core.git: sw/CppunitTest_sw_uiwriter.mk sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Mar 28 15:55:41 UTC 2018


 sw/CppunitTest_sw_uiwriter.mk           |    2 +
 sw/qa/extras/uiwriter/data/image.odt    |binary
 sw/qa/extras/uiwriter/uiwriter.cxx      |   35 +++++++++++++++++++++++++++++++-
 sw/source/filter/html/htmlflywriter.cxx |    4 ++-
 sw/source/filter/html/wrthtml.cxx       |    9 ++++++++
 sw/source/filter/html/wrthtml.hxx       |    5 +++-
 6 files changed, 52 insertions(+), 3 deletions(-)

New commits:
commit 6a189b2ac72d5fb83199bdb09e41f7d088440cc9
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Mar 28 15:00:10 2018 +0200

    tdf#108122 HTML export: fix lost images on copy
    
    As in the copy part of copy&paste. The problem was that the document has
    an empty base URL during copy, and this was images were not exported at
    all.
    
    An alternative fix would be to use embedded images, but sadly Word's
    HTML import doesn't understand that markup, so use tempfiles instead.
    
    Change-Id: Iab8c555ac244d943c4958f24f8ac61cba4ec3aba
    Reviewed-on: https://gerrit.libreoffice.org/52003
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/sw/CppunitTest_sw_uiwriter.mk b/sw/CppunitTest_sw_uiwriter.mk
index b657e1999e6c..05ce1b5c90d8 100644
--- a/sw/CppunitTest_sw_uiwriter.mk
+++ b/sw/CppunitTest_sw_uiwriter.mk
@@ -45,6 +45,8 @@ $(eval $(call gb_CppunitTest_set_include,sw_uiwriter,\
     -I$(SRCDIR)/sw/inc \
     -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/source/uibase/inc \
+    -I$(SRCDIR)/sw/source/filter/inc \
+    -I$(SRCDIR)/sw/source/filter/html \
     -I$(SRCDIR)/sw/qa/extras/inc \
     $$(INCLUDE) \
 ))
diff --git a/sw/qa/extras/uiwriter/data/image.odt b/sw/qa/extras/uiwriter/data/image.odt
new file mode 100644
index 000000000000..195f8836cfad
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/image.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 5b97e54f6867..42bdf476b551 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -115,12 +115,15 @@
 #include <sfx2/watermarkitem.hxx>
 #include <sfx2/fcontnr.hxx>
 #include <sfx2/docfile.hxx>
+#include <svtools/htmlout.hxx>
+#include <test/htmltesttools.hxx>
 #include <fmthdft.hxx>
 #include <iodetect.hxx>
+#include <wrthtml.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/extras/uiwriter/data/";
 
-class SwUiWriterTest : public SwModelTestBase
+class SwUiWriterTest : public SwModelTestBase, public HtmlTestTools
 {
 
 public:
@@ -310,6 +313,7 @@ public:
     void testTdf115132();
     void testXDrawPagesSupplier();
     void testTdf116403();
+    void testHtmlCopyImages();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -496,6 +500,7 @@ public:
     CPPUNIT_TEST(testTdf115132);
     CPPUNIT_TEST(testXDrawPagesSupplier);
     CPPUNIT_TEST(testTdf116403);
+    CPPUNIT_TEST(testHtmlCopyImages);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -6098,6 +6103,34 @@ void SwUiWriterTest::testTdf116403()
         static_cast<sal_Int32>(17000 - 2 * 500 - 2 * 1), aTabs[0].Position);
 }
 
+void SwUiWriterTest::testHtmlCopyImages()
+{
+    // Load a document with an image.
+    SwDoc* pDoc = createDoc("image.odt");
+
+    // Trigger the copy part of HTML copy&paste.
+    WriterRef xWrt;
+    xWrt = new SwHTMLWriter( /*rBaseURL=*/OUString() );
+    CPPUNIT_ASSERT(xWrt.is());
+
+    xWrt->bWriteClipboardDoc = true;
+    xWrt->bWriteOnlyFirstTable = false;
+    xWrt->SetShowProgress(false);
+    {
+        SvFileStream aStream(maTempFile.GetURL(), StreamMode::WRITE|StreamMode::TRUNC);
+        SwWriter aWrt(aStream, *pDoc);
+        aWrt.Write(xWrt);
+    }
+    htmlDocPtr pHtmlDoc = parseHtml(maTempFile);
+    CPPUNIT_ASSERT(pHtmlDoc);
+
+    // This failed, image was lost during HTML copy.
+    OUString aImage = getXPath(pHtmlDoc, "/html/body/p/img", "src");
+    // Also make sure that the image is not embedded (e.g. Word doesn't handle
+    // embedded images).
+    CPPUNIT_ASSERT(aImage.startsWith("file:///"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index bd9d8e9cc946..3d349bc1ddb0 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -1221,7 +1221,7 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrameFormat &rFrameFormat,
     }
 
     OUString aGraphicURL( rGraphicURL );
-    if( !rHTMLWrt.mbEmbedImages && !HTMLOutFuncs::PrivateURLToInternalImg(aGraphicURL) )
+    if( !rHTMLWrt.mbEmbedImages && !HTMLOutFuncs::PrivateURLToInternalImg(aGraphicURL) && !rHTMLWrt.mpTempBaseURL )
         aGraphicURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGraphicURL);
 
     const SfxPoolItem* pItem;
@@ -1802,6 +1802,8 @@ static Writer& OutHTML_FrameFormatGrfNode( Writer& rWrt, const SwFrameFormat& rF
             // create a (mirrored) jpeg file
             if( rHTMLWrt.GetOrigFileName() )
                 aGraphicURL = *rHTMLWrt.GetOrigFileName();
+            else
+                aGraphicURL = rHTMLWrt.GetBaseURL();
             pGrfNd->GetGrf( true );
 
             XOutFlags nFlags = XOutFlags::UseGifIfSensible |
diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx
index 0bfd00b08f17..0d993fcde3d6 100644
--- a/sw/source/filter/html/wrthtml.cxx
+++ b/sw/source/filter/html/wrthtml.cxx
@@ -80,6 +80,7 @@
 #include <tools/urlobj.hxx>
 #include <osl/file.hxx>
 #include <comphelper/scopeguard.hxx>
+#include <unotools/tempfile.hxx>
 
 #define MAX_INDENT_LEVEL 20
 
@@ -156,6 +157,14 @@ SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL )
     , m_bParaDotLeaders( false )
 {
     SetBaseURL(rBaseURL);
+
+    if (rBaseURL.isEmpty())
+    {
+        // Paste: set base URL to a tempfile, so images are not lost.
+        mpTempBaseURL.reset(new utl::TempFile());
+        mpTempBaseURL->EnableKillingFile();
+        SetBaseURL(mpTempBaseURL->GetURL());
+    }
 }
 
 SwHTMLWriter::~SwHTMLWriter()
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index c10b8e695b07..8b3725dfce4f 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -59,6 +59,7 @@ class SwHTMLPosFlyFrames;
 class SwTextFootnote;
 enum class HtmlPosition;
 enum class HtmlTokenId : sal_Int16;
+namespace utl { class TempFile; }
 
 extern SwAttrFnTab aHTMLAttrFnTab;
 
@@ -254,7 +255,7 @@ typedef std::set<std::unique_ptr<SwHTMLFormatInfo>,
 
 class IDocumentStylePoolAccess;
 
-class SwHTMLWriter : public Writer
+class SW_DLLPUBLIC SwHTMLWriter : public Writer
 {
     SwHTMLPosFlyFrames *m_pHTMLPosFlyFrames;
     std::unique_ptr<SwHTMLNumRuleInfo> m_pNumRuleInfo;// current numbering
@@ -387,6 +388,8 @@ public:
     /// If HTML header and footer should be written as well, or just the content itself.
     bool mbSkipHeaderFooter : 1;
     bool mbEmbedImages : 1;
+    /// Temporary base URL for paste of images.
+    std::unique_ptr<utl::TempFile> mpTempBaseURL;
     /// If XHTML markup should be written instead of HTML.
     bool mbXHTML = false;
     /// XML namespace, in case of XHTML.


More information about the Libreoffice-commits mailing list