[Libreoffice-commits] core.git: Branch 'distro/vector/vector-5.4' - 4 commits - embeddedobj/source filter/source include/filter include/sfx2 sfx2/source sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Thu May 31 07:56:53 UTC 2018


 embeddedobj/source/inc/commonembobj.hxx          |    4 
 embeddedobj/source/inc/dummyobject.hxx           |    4 
 embeddedobj/source/inc/oleembobj.hxx             |    4 
 filter/source/msfilter/msdffimp.cxx              |   16 +-
 include/filter/msfilter/msdffimp.hxx             |    6 
 include/sfx2/docfile.hxx                         |    2 
 sfx2/source/doc/docfile.cxx                      |   11 +
 sfx2/source/doc/objstor.cxx                      |    2 
 sw/qa/extras/htmlexport/data/reqif-ole-odg.ole   |  146 +++++++++++++++++++++++
 sw/qa/extras/htmlexport/data/reqif-ole-odg.png   |binary
 sw/qa/extras/htmlexport/data/reqif-ole-odg.xhtml |    9 +
 sw/qa/extras/htmlexport/htmlexport.cxx           |   15 ++
 sw/qa/extras/uiwriter/data/tdf117225.odt         |binary
 sw/qa/extras/uiwriter/uiwriter.cxx               |   43 ++++++
 sw/source/filter/html/htmlplug.cxx               |   70 ++++++++---
 sw/source/filter/html/htmlreqifreader.cxx        |   36 ++++-
 sw/source/filter/html/htmlreqifreader.hxx        |    8 -
 17 files changed, 350 insertions(+), 26 deletions(-)

New commits:
commit 0eecb1607ef4e67b6651c6bfcc41f9addcb7d874
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed May 30 17:32:45 2018 +0200

    sw HTML filter: handle embedded ODF content in xhtml/reqif mode
    
    Embedded native data (what we don't parse just carry on) and real OLE2
    embedding already worked, this adds the case where the actual content is
    ODF, just inside OLE2.
    
    The DOC import/export had support for handleing ODF content inside OLE2,
    so reuse that code: add new functions to SvxMSDffManager for import
    purposes and reuse SvxMSExportOLEObjects for export purposes.
    
    Change-Id: I0acf65d4bf29af896b8f1dd625e8672050aae350
    Reviewed-on: https://gerrit.libreoffice.org/55088
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 0258bcdedd710d78de99c9cefc9d8c3e2ca85fdf)

diff --git a/embeddedobj/source/inc/oleembobj.hxx b/embeddedobj/source/inc/oleembobj.hxx
index 5e37b3a26c19..1ef712927a8d 100644
--- a/embeddedobj/source/inc/oleembobj.hxx
+++ b/embeddedobj/source/inc/oleembobj.hxx
@@ -105,6 +105,10 @@ public:
 
 class OleComponent;
 class OwnView_Impl;
+/**
+ * Represents an OLE object that has native data and we try to let an external
+ * application handle that data.
+ */
 class OleEmbeddedObject : public ::cppu::WeakImplHelper
                         < css::embed::XEmbeddedObject
                         , css::embed::XEmbeddedOleObject
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index cfcc429c389b..3e3a5fcaf1c3 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -6872,7 +6872,7 @@ const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
     return nullptr;
 }
 
-OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
+OUString SvxMSDffManager::GetFilterNameFromClassID( const SvGlobalName& aGlobName )
 {
     if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
         return OUString( "StarOffice XML (Writer)" );
@@ -6913,6 +6913,13 @@ OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
     return OUString();
 }
 
+void SvxMSDffManager::ExtractOwnStream(SotStorage& rSrcStg, SvMemoryStream& rMemStream)
+{
+    tools::SvRef<SotStorageStream> xStr
+        = rSrcStg.OpenSotStream("package_stream", StreamMode::STD_READ);
+    xStr->ReadStream(rMemStream);
+}
+
 css::uno::Reference < css::embed::XEmbeddedObject >  SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags,
                         SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
                         const Graphic& rGrf,
@@ -6977,8 +6984,7 @@ css::uno::Reference < css::embed::XEmbeddedObject >  SvxMSDffManager::CheckForCo
         if ( pName )
         {
             // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
-            tools::SvRef<SotStorageStream> xStr = rSrcStg.OpenSotStream( "package_stream", StreamMode::STD_READ );
-            xStr->ReadStream( *xMemStream );
+            SvxMSDffManager::ExtractOwnStream(rSrcStg, *xMemStream);
         }
         else
         {
@@ -7013,7 +7019,7 @@ css::uno::Reference < css::embed::XEmbeddedObject >  SvxMSDffManager::CheckForCo
             if ( pFilter )
                 aFilterName = pFilter->GetName();
             else
-                aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
+                aFilterName = SvxMSDffManager::GetFilterNameFromClassID( aStgNm );
 
             uno::Sequence<beans::PropertyValue> aMedium(aFilterName.isEmpty() ? 3 : 4);
             aMedium[0].Name = "InputStream";
diff --git a/include/filter/msfilter/msdffimp.hxx b/include/filter/msfilter/msdffimp.hxx
index 3d4752768a58..be876a557857 100644
--- a/include/filter/msfilter/msdffimp.hxx
+++ b/include/filter/msfilter/msdffimp.hxx
@@ -63,6 +63,7 @@ struct SvxMSDffShapeOrder;
 class SvxMSDffManager;
 class SfxItemSet;
 struct DffObjData;
+class SvGlobalName;
 
 namespace com { namespace sun { namespace star {
     namespace beans { class XPropertySet; }
@@ -721,6 +722,11 @@ public:
         bool bTestPropertyAvailability
     );
 
+    /// Determines an ODF filter name (if there is one) for aGlobName.
+    static OUString GetFilterNameFromClassID(const SvGlobalName& aGlobName);
+    /// Extracts ODF data from rSrcStg.
+    static void ExtractOwnStream(SotStorage& rSrcStg, SvMemoryStream& rMemStream);
+
     void insertShapeId( sal_Int32 nShapeId, SdrObject* pShape );
     void removeShapeId( SdrObject* pShape );
     SdrObject* getShapeForId( sal_Int32 nShapeId );
diff --git a/sw/qa/extras/htmlexport/data/reqif-ole-odg.ole b/sw/qa/extras/htmlexport/data/reqif-ole-odg.ole
new file mode 100644
index 000000000000..de674fe3c631
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/reqif-ole-odg.ole
@@ -0,0 +1,146 @@
+{\object\objemb{\*\objclass }{\*\objdata
+000000000200000000000000000000000000000000240000d0cf11e0a1b11ae1000000000000000000000000000000003b000300feff09000600000000000000
+00000000010000000f00000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffefffffffeffffff05000000060000000700000008000000090000000a000000
+0b0000000c0000000d0000000e000000feffffff10000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff52006f006f007400200045006e007400720079000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000001000000fefffffffefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0100feff030a0000ffffffff71b78b44e2cfc447bcdf1fbf378e202c1b0000004c696272654f6666
+6963652e44726177446f63756d656e742e310010000000456d626564646564204f626a6563740000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000001000002000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000143700000000000010270000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000504b0304140000080000a26dbe4c9f032ec42b0000002b000000080000006d696d65747970656170
+706c69636174696f6e2f766e642e6f617369732e6f70656e646f63756d656e742e6772617068696373504b0304140008080800a26dbe4c000000000000000000
+0000000c00000073657474696e67732e786d6cb5585b6fda30147edfaf405127b50f107ad13a22a02a6d59abb18d15e89e0fc9815875ecc8764af9f73b49a0a2
+102a1af013c2f6f9ce77ee769a57af11afbca0d24c8a96735aab3b1514be0c9898b69cd1b05bfdee5cb5bf34e564c27cf402e927110a53d5680c1dd1151217da
+cbb75b4ea284274133ed0988507bc6f7648c6229e6ad9ef63265f9ca2b67e2b9e584c6c49eebce66b3daecbc26d5d43d6d341a6eb6bb3c1a2bd404052623bc9b
+c2559955b5be141336dd15253fbd2a2fa57c239d0ae48665c4cfeaf50b37ffbf3cad23c677d5959eadfa328a89f398bff3150816ed0a939eddb03a67f531f7c6
+1bf745b05652e4cc692ff3619906ede6c239f94f95198cd21ca92c96538e2d87547a2f0c676fd9e314c9bd9779623a75c0b54218cad8596e9a794c9b4c18a75d
+6fba9b209f02eee1c4d841fec7021316419f5ed41b8dbde1ef914dc342ea54365be00b16d378ec1ec17c2151595e7d2694d771cce7238dea160cac911e4bc911
+84d3362ac1727ee93013413c04f2cde8b1b786af8d22964efbe878ac400463d098287ee2ea1014ba31703203bf9e778e8e13224855179e2c48b8da9000a8a0a6
+e5b81cb31b5202be417543054dad282da421d15ae7184a553eeb6e2497caaaf57e3962b7a043abbc8292bc70020937446d608a3bcbe9d965c960dc45630cba52
+18bd2dcf27c075c944ffa12060d4e3ad3a755a8edb3d18df6eb4c372c41ef44f54e25a3310fd44f826c9da9785e83ce83e99693a523e9341d61574c07f3e7c2f
+7dafa3ab2893ad29a169b0de090fe8a62e337d985a5470cf820045aa636badefeda214fd372dd8b362c838daf5d39059e1df6302ef4460b5e594a52621784408
+a4e0730b96ff42d089c29160ebb5b9b8485c96c3cd922da101a6ba52d1eba168325e9485563055108783248a6c35e02cdbfe26c0995977fb3eb7fa0c16d58308
+307d67d1fcedc15c261bbe5f641c97b32a5df5244f5233f7525950f90b2deece187d88299e4a460334c9fa65e7605e4755084f55f7eda2c304a8f92e9407f082
+4ff973f38fb8e152dbe81b039f8aff969ebd11f1325215defff680a60a427560e0511cd0ac4ca338c428e61fcccded1367ebf3cfdd78d2bbdb3efab4ff03504b
+07089f6ee54e2b03000036120000504b0304140008080800a26dbe4c0000000000000000000000000b000000636f6e74656e742e786d6cbd58518fa336107eef
+af409cd437e290dcdd6ee826275555a54abba753774faaeecd6b0cb8c518d92624fdf53736e09864c9a25eb52f41d8df371e7f339ec1b9fb74e065b0a7523151
+6dc378b10c035a1191b22adf865f9f7e8f6ec34fbb9fee4496314293549086d34a4744541a9e01b02b9574b3dbb0915522b0622aa930a72ad1241135ad0656e2
+a313bb5637a2f4b19c4db7609fade941cf251bec888b9fe7af6cc13e3b95b89d4b365810d5a767622ef9a0ca2813a03aafb166675e1c4a56fdb30d0badeb04a1
+b66d17ed7a21648ee2cd6683ecac7398385cddc8d2a252826849cd620ac58b180d584e359eeb9fc1fa2e550d7fa672b63458e38ba8d6922a80c0764d62ce33e4
+7346f9b5cf6767d73e9f90991458cece330b1ea7ca3a9d9f2aebd4e772ac8b89f8dea20798b43f0ff7a7bc927cee5a063b928a4856cfde6687f6f94208e7aa21
+7487ddbabb5a2edfa3eedd43b757e1ad649a4a0f4eaec2092e89535cf09744035c8c0011d1bd497977888c106a82b042ddb403ab74d2f45f0ff78fa4a01c9fc0
+ec7570c42aa5717552467156ce8e0260279216576c762a18ecc5d19126192615ff8024ad85d42e40d9fc2600abac9c4685e6e5740933b303349769fa2214dc59
+232867504ca23da3edbb70d49dae27e6e62c316da97f8d62417e2fb84a8897c8605c3981543d352e99bbde9a89a64abb387402d2434d253353b8b4b46464c18f
+5629fe83c9be1f7b16464d8ad172a85c6e4b2f9a1122e20a12190eaca8138f3dee79921fe699338754a4d9b9c5b38245945aeb97f2e1e94f64e622d3f2a1a9f5
+2b799f3aab70377cd774754c213790c1f74d946142a3949252edeebafee48683eeddf8bd0def19343b2b6ff0882ba812d04406281ccde336fc19d742fd7286eb
+06c36064dae0a39c562004943a2938ae46889a6902cd608f25b3d987e6bb0626b359be19e05b38f75968715d3187786bad60c9f87f8ca33a2a4df90f39d71096
+e257f2eb8479139f1e692e68f0f58f498706c09b78f3840b61baee852f6ee247574753c5a11fc78d16a68392c8da7155c3fe8e7c4debd82dd67bd9df0fa21ae7
+de562fa9b9bca0e612d70523c3708da5b9a2d997a823996f8b14cb341cecf694a886c24aa5665405c6017b3f023a8e0a21d9bfc254e208972c8782f977a334cb
+8ee119706fe8e404e30cfa33ed5146912897a28d0acaf202ea74864b05b3994838abdc28dc3bdedf10eec65b969a4fde78f1f1c306868df69e1ed3e27cb9d006
+c4c076b36eeb6ec4df3cac6b76346c8250d3732ed7459391ee279e457a742f7d487777560b13d84e95ce57f31ef73af9b1b2b9614739dc8aa8b419d1cffd4633
+dc943aec4d120889e0912a704d2f0dd94c71c11ae5c39761a6c447734f8387687477767aed578bd86a6fc74e715a6f6e864168e36b1f7434a49b9b5b78dfddd9
+8b768d7a476955988fdb144e9c80bba23c5a82f94afb55809965b00c56f1c765ff3b787dacc1554909246fee52ca99aaedade82130e4fb9e3e32139c9ecbe05b
+f0d986f342b761cca87c0ab00b1d1a05164dfc0fb2fb0e504b0708a84c77df6004000048110000504b0304140008080800a26dbe4c0000000000000000000000
+000a0000007374796c65732e786d6ced5c5f73db36127fbf4fa151e7ee8da6484bb6a58bddb9de4d6f3ad3a49dfc79e853072241090d497040d0b2f325eef1be
+df7d92dbc51f1294489ab65527519bccd8117601ecfe76b1582ca0bcfaf62e4b27b754948ce7d7d3e06c369dd03ce231cb37d7d30fefbff7aea6dfdefce5154f
+1216d155cca32aa3b9f44a799fd272029df372a589d7d34ae42b4e4a56ae7292d17225a3152f686e3bad5cee959a4ab7a8c1c67657cc6e6f49efe4d8cec8dbea
+4bd6e36756cc6eef5890ddd8cec80b98badd133eb6f35d997a09f7229e1544b23d29ee52967fbc9e6ea52c56bebfdbedce76e7675c6cfc60b95cfa8a5a0b1cd5
+7c452552c515473e4d294e56fac159e05bde8c4a32563ee47545caab6c4dc56868882407562d042d8105d445bf1c3790dba7e55fb79bd1de75bbe98139da1231
+dacf1473db55cee3f1ae721ebb7d3322b73df6bdf25f0351fd78fd63e357221b3b17f2b6a08a042b46aba9b9ddfe9cf35a54eca017bb12379ccde6befeec70ef
+06d97782492a1cf668903d22695423ceb32ed0802ff081c3a3b7e8f2b5de194b476b0dbc3d4e4272361a7ae43d705581e0f76ab8f0052db8903520c9f8a00bb3
+8475c8d8ca2ced0f1948b5ac1b11c79dac20ceb90fe10316af77cbe8ee9b696b37187684e59e23a8d0fa5017c5e4c6dec10ec1cc479e7af9826b341b85d8d45b
+59c2ab3cd676d000d2bb820a862492aa6eabd608aeb552fe8421cdfee78cd0da14184d6da4a855ea1c86732f2b3d96c302e1c5cae9dd8a5a65792ebbccf7fead
+8f340f774488f9661e271108a73776d74f38ecf80989a817d3282d6f5ee9685d374ff46714f27afa2383d0af949fbc23392c3008a9961516cefdf5f46fa4e0e5
+dff7f874e374d21a1af9bd0dcd416b58f88267246f71144c46101a6f8960ca37fcf1a2c190c928d990f125847bc3251f46ace67869ac60cae088762cef4b49b3
+670957452c260ff857c3f32232bda31b4e271f7ee815c832bc8834efc9163ca043969af0dcd9fdbee060daf509e1e6150661d84548cc206e4dd4272de2f72c4d
+69fc6b38fbf5bbb482b8ae48312b8b94dc7b2ecbc4a19ba30224b59488ba0d922dd890530e29e73797e132891243827db0269c2f16e1c5b2d50783675e3209b8
+04b3d95f9d4edd14926f70f6f3d9cc34acb98831d1050e7f94aaff1694e643baba0c2394bd5c47178b0e6583f0f2220c3fb3b26f693ca46a437e58d124b9882f
+e20e45a3651804f4332bfa0b4d53be1bd2b5c53146dd982e961deaaee79757b3f9efae6e46c4472a5c65ff2104ca8ff104b3bdeff81d7498cc26e16c723ed3ed
+90b6bc0ea02df5026cdc86b34f4d988a6942aad4140e6c68313109c02db62c9a5a5ef3d92b20b1a142325aaaf14b29f847daace7f9c58258281280f92004247c
+b583a13c5ee85364ce3dfcdc08551041d464ada91409f3228f54929705c1da068b29d7ac242db675002daa3c9295dafed4d8103d5956609aaae968636f2d2881
+133ac8cf22d98aab2c8f2926eb585251ac389b2abd24242d698d08a4be801c2f4a0cbcfdb2d7ec28fc814a5549bd1dccc8779e9adcc02545455b42f5254b00a7
+a297ec13d0c37921555b0a0e55910d3461e0828608d25f29c0ae1fde1d8cebc14985e4adddb261c0812d831ede806866b0b44f5b4b315359c23fdf1c4e8807b5
+94de75ee7c6ac29aa173ca9aba65fb93d6a41fde4c1bbbb41cdd1ac4f57a0d2fac5d38238878faf8b560d63e2e061887a72c9ebaeb63c762ac17cca26cfae0b2
+d1ebdcd381c4763c0bb1eb213da278d6b0aed962c068d3df5d05b08eceb8686b0dfa97b1a2a04b135847de960bf689e311085622db80d57fab4ac9927be57b05
+89b174e9c15a4151827081c238843597122b035db494265229b04f106cb37528da005b12abea058be366c7568d1ea4402595de5d1b8d36f1be936875bf9ae15f
+f00255b14c59d98e9c7b3ee4b2a5f496a69ad95b57b0f9c88926623b6c0453fd51933c2c545d4ffff7dfffd40ee70ce2f89cea93b1dc4bc91a28b5ad2f4001bf
+2fecd880617dfb1d58f0dd7db6e6e9744c486ac79bf9426d4ffe90a68fc0217c060e6a4bf0d634e1825a104e0fa1f3a32114683f3f3984e64744e8ea24115a1c
+0da1f06c7e92085d1c0da1f393c4e7f278f89c689cbe3a1a42f3138dd3cb2322749a713a981d0da2c5d715a81db239b1f97d07afc1aa01cc0da79d0d2aac4f11
+e608611aed09a2ddaa4f29edb6fa80629a5559604b757f5dc68156851c538503cdfa20a6aa768bdc391719499b51a42079a9ef8c739ed351483b53f14aa288f5
+c9ce2129d1e556f06ab3f54cd1cb9de29049de177b3c3d150955f9df7797dfef6269cfb5822b53fbd06d56b336aef68078a071056613badae3626287db195bdb
+f1ccfaa312cecf1e1ca773551feaacdad83a48c7e5cd81f686f56998d9de7d570596de00d853e6d148ba44b53a0db50d8183ce0043bbe8d3be293a50a7e67bfc
+9d51d3b717849aa31f869aa507889ade0f450f8b72359a155ba27df66051099a329a74f827bfed72cf2e0613139af8e0d4c11ea87ff1f56f34923b26b71040b0
+ecd35708b3855622ea7767de41f9e33175e399fad32a41290d478bfe93121debfe283efece39fec4b1f03748d534224e5687f6cd801e6682634c723ec1de13e8
+8aff763b1d178f56ed501bf6c938a02f7c055232997e563087b76593ab60e979b44a5b4ae2cfed22a3522153859d873d29ce59188c495d9c0b87d11865949495
+7809880e2bf09d91c62da5d7d7698f29c2d33ceeecd7537b77cc652bcc90ca553993267918097b103e06767dddf9844b8d7181baf7ae20517ffa753a48269de7
+36dd69e4715fdbec833a7713489bf1c139277e2cd4cdfb89ae3da6f580e2b12bc1d8f2c9a1c2de99bbf6b26d5ea70e432eb967e9d3b6a879053260d216c7176a
+532de39f46759fc30c98f46d7fe0fc420c8a12fe69cebd473f03166db37ca1463542fec1edfa932e633d3375a9f3b0d955d0f3fe62e0f8f987495d2cd8c3c98b
+e57a62fa525bf4f94f6906cc695e958e593df601ea891b742077a92dfac4ece5654c6adece8e31a97d667be226edcd5c6a833e29777919739a17c263cc691f13
+9fb839873297daa24fcd5d5ec6a8e61df418a3da27d35fb151fdbdef54988ff83c19bf4218799660adb2a11e989457b2e5033fbf9e4d3b78066a774177e16eaf
+59df78069d379eb655cd670c1b06678ba5db6eaf37c3cbb3a5ba3d36320a06d070c19a2f02e3b71f05616e45cad1a4dffd5fc745b0efcbe62bd91e0e50e3e236
+1eb8ec9a441f3702bfdd678ca89fce8fa84efbbd2633848c94521501ef9b6fcd8052d884d7d4cd67f751bed6ba7eb57f406fe41dc3a3af64ca7ed6083c55f074
+80c3545d3100282e7f5f0f0d8a5116316e59e95ffaed74135d1a1f6d3cd8f90e85e718d7f94ad21e967ef77f5e70f37f504b0708d111d268a1090000fc400000
+504b0304140008080800a26dbe4c000000000000000000000000150000004d4554412d494e462f6d616e69666573742e786d6cad92416ec3201045f73985c5de
+d0765521e3ec7a82f600080f0e121e108c23fbf6c5561cbbaa223552778c66f8fffd81e63c0dbeba42ca2ea062affc85558026740e7bc5be3e3fea77766e4fcd
+a0d159c824b74355ee61be978a8d0965d0d965897a802cc9c81001bb60c60190e4cf79b93addab03c01bbb49fb00d3a69b7ab909d93062a7a94cdf8c608a90dc
+d2d25e066b9d017950589dda53b547b0ce435dc6d3bc03d8d1fb3a6aba28261e72ed4b80cee99ae6088ae918bd332b90b862c7d71df06374de271d2fce64269e
+e1c840545e21f312e68137957c62693f256c02d282f5dfba99660f7fc56dc4af2fd57e03504b070800db977cf10000008d020000504b01021400140000080000
+a26dbe4c9f032ec42b0000002b0000000800000000000000000000000000000000006d696d6574797065504b01021400140008080800a26dbe4c9f6ee54e2b03
+0000361200000c000000000000000000000000005100000073657474696e67732e786d6c504b01021400140008080800a26dbe4ca84c77df6004000048110000
+0b00000000000000000000000000b6030000636f6e74656e742e786d6c504b01021400140008080800a26dbe4cd111d268a1090000fc4000000a000000000000
+000000000000004f0800007374796c65732e786d6c504b01021400140008080800a26dbe4c00db977cf10000008d020000150000000000000000000000000028
+1200004d4554412d494e462f6d616e69666573742e786d6c504b05060000000005000500240100005c1300000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000052006f006f007400200045006e007400720079000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000016000500ffffffffffffffff0100000071b78b44e2cfc447bcdf1fbf378e202c0000000000000000
+000000000000000000000000030000000001000000000000010043006f006d0070004f0062006a00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000120002000200000003000000ffffffff000000000000000000000000000000000000000000000000
+00000000000000000000000000000000530000000000000001004f006c0065000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000a000200ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000020000001400000000000000700072006f0070006500720074006900650073005f00730074007200650061006d00000000000000
+0000000000000000000000000000000000000000000000002400020004000000ffffffffffffffff000000000000000000000000000000000000000000000000
+0000000000000000000000000300000010000000000000007000610063006b006100670065005f00730074007200650061006d00000000000000000000000000
+0000000000000000000000000000000000000000000000001e000200ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+00000000000000000000000004000000961400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+000000000000000000000000feffffff0000000000000000}}
\ No newline at end of file
diff --git a/sw/qa/extras/htmlexport/data/reqif-ole-odg.png b/sw/qa/extras/htmlexport/data/reqif-ole-odg.png
new file mode 100644
index 000000000000..66b76c74a129
Binary files /dev/null and b/sw/qa/extras/htmlexport/data/reqif-ole-odg.png differ
diff --git a/sw/qa/extras/htmlexport/data/reqif-ole-odg.xhtml b/sw/qa/extras/htmlexport/data/reqif-ole-odg.xhtml
new file mode 100644
index 000000000000..9e7be3ae8869
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/reqif-ole-odg.xhtml
@@ -0,0 +1,9 @@
+<reqif-xhtml:div><reqif-xhtml:p><reqif-xhtml:br/>
+
+</reqif-xhtml:p>
+<reqif-xhtml:p><reqif-xhtml:object data="reqif-ole-odg.ole" type="text/rtf">
+<reqif-xhtml:object data="reqif-ole-odg.png" type="image/png" width="533" height="378"/>
+</reqif-xhtml:object><reqif-xhtml:br/>
+
+</reqif-xhtml:p>
+</reqif-xhtml:div>
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index b0ef605c3b38..dddf33b945e7 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -529,6 +529,21 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2, "reqif-ole2.xhtml")
     // exception of type com.sun.star.io.IOException was thrown.
 }
 
+DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2Odg, "reqif-ole-odg.xhtml")
+{
+    uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xObjects(xSupplier->getEmbeddedObjects(),
+                                                     uno::UNO_QUERY);
+    uno::Reference<document::XEmbeddedObjectSupplier> xTextEmbeddedObject(xObjects->getByIndex(0),
+                                                                          uno::UNO_QUERY);
+    uno::Reference<lang::XServiceInfo> xObject(xTextEmbeddedObject->getEmbeddedObject(),
+                                               uno::UNO_QUERY);
+    // This failed, both import and export failed to handle OLE2 that contains
+    // just ODF.
+    CPPUNIT_ASSERT(xObject.is());
+    CPPUNIT_ASSERT(xObject->supportsService("com.sun.star.drawing.DrawingDocument"));
+}
+
 DECLARE_HTMLEXPORT_TEST(testList, "list.html")
 {
     SvStream* pStream = maTempFile.GetStream(StreamMode::READ);
diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx
index 68ad0c0be432..05c9495fd59d 100644
--- a/sw/source/filter/html/htmlplug.cxx
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -62,6 +62,7 @@
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/embed/XEmbedPersist2.hpp>
 
 #include <comphelper/embeddedobjectcontainer.hxx>
 #include <comphelper/classids.hxx>
@@ -69,6 +70,8 @@
 #include <comphelper/storagehelper.hxx>
 #include <vcl/graphicfilter.hxx>
 #include <unotools/ucbstreamhelper.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <filter/msfilter/msoleexp.hxx>
 
 using namespace com::sun::star;
 
@@ -511,11 +514,23 @@ bool SwHTMLParser::InsertEmbed()
                 aFileStream.Seek(0);
                 if (aHeader == aMagic)
                 {
-                    // OLE2 wrapped in RTF.
-                    if (SwReqIfReader::ExtractOleFromRtf(aFileStream, aMemoryStream))
+                    // OLE2 wrapped in RTF: either own format or real OLE2 embedding.
+                    bool bOwnFormat = false;
+                    if (SwReqIfReader::ExtractOleFromRtf(aFileStream, aMemoryStream, bOwnFormat))
                     {
                         xInStream.set(new utl::OStreamWrapper(aMemoryStream));
+                    }
 
+                    if (bOwnFormat)
+                    {
+                        uno::Sequence<beans::PropertyValue> aMedium = comphelper::InitPropertySequence(
+                            { { "InputStream", uno::makeAny(xInStream) },
+                              { "URL", uno::makeAny(OUString("private:stream")) },
+                              { "DocumentBaseURL", uno::makeAny(m_sBaseURL) } });
+                        xObj = aCnt.InsertEmbeddedObject(aMedium, aName, &m_sBaseURL);
+                    }
+                    else
+                    {
                         // The type is now an OLE2 container, not the original XHTML type.
                         aType = "application/vnd.sun.star.oleobject";
                     }
@@ -526,19 +541,24 @@ bool SwHTMLParser::InsertEmbed()
                 // Non-RTF case.
                 xInStream.set(new utl::OStreamWrapper(aFileStream));
 
-            uno::Reference<io::XStream> xOutStream
-                = xStorage->openStreamElement(aObjName, embed::ElementModes::READWRITE);
-            comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream->getOutputStream());
-
-            if (!aType.isEmpty())
+            if (!xObj.is())
             {
-                // Set media type of the native data.
-                uno::Reference<beans::XPropertySet> xOutStreamProps(xOutStream, uno::UNO_QUERY);
-                if (xOutStreamProps.is())
-                    xOutStreamProps->setPropertyValue("MediaType", uno::makeAny(aType));
+                uno::Reference<io::XStream> xOutStream
+                    = xStorage->openStreamElement(aObjName, embed::ElementModes::READWRITE);
+                if (aFileStream.IsOpen())
+                    comphelper::OStorageHelper::CopyInputToOutput(xInStream,
+                                                                  xOutStream->getOutputStream());
+
+                if (!aType.isEmpty())
+                {
+                    // Set media type of the native data.
+                    uno::Reference<beans::XPropertySet> xOutStreamProps(xOutStream, uno::UNO_QUERY);
+                    if (xOutStreamProps.is())
+                        xOutStreamProps->setPropertyValue("MediaType", uno::makeAny(aType));
+                }
             }
+            xObj = aCnt.GetEmbeddedObject(aObjName);
         }
-        xObj = aCnt.GetEmbeddedObject(aObjName);
     }
 
     SfxItemSet aFrameSet( m_xDoc->GetAttrPool(),
@@ -1460,23 +1480,47 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame
         OUString aFileType;
         SvFileStream aOutStream(aFileName, StreamMode::WRITE);
         uno::Reference<io::XActiveDataStreamer> xStreamProvider;
+        uno::Reference<embed::XEmbedPersist2> xOwnEmbedded;
         if (xEmbeddedObject.is())
+        {
             xStreamProvider.set(xEmbeddedObject, uno::UNO_QUERY);
+            xOwnEmbedded.set(xEmbeddedObject, uno::UNO_QUERY);
+        }
         if (xStreamProvider.is())
         {
+            // Real OLE2 case: OleEmbeddedObject.
             uno::Reference<io::XInputStream> xStream(xStreamProvider->getStream(), uno::UNO_QUERY);
             if (xStream.is())
             {
                 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xStream));
                 if (SwReqIfReader::WrapOleInRtf(*pStream, aOutStream))
                 {
-                    // OLE2 is always wrapped in RTF.
+                    // Data always wrapped in RTF.
                     aFileType = "text/rtf";
                 }
             }
         }
+        else if (xOwnEmbedded.is())
+        {
+            // Our own embedded object: OCommonEmbeddedObject.
+            SvxMSExportOLEObjects aOLEExp(0);
+            // Trigger the load of the OLE object if needed, otherwise we can't
+            // export it.
+            pOLENd->GetTwipSize();
+            SvMemoryStream aMemory;
+            tools::SvRef<SotStorage> pStorage = new SotStorage(aMemory);
+            aOLEExp.ExportOLEObject(rOLEObj.GetObject(), *pStorage);
+            pStorage->Commit();
+            aMemory.Seek(0);
+            if (SwReqIfReader::WrapOleInRtf(aMemory, aOutStream))
+            {
+                // Data always wrapped in RTF.
+                aFileType = "text/rtf";
+            }
+        }
         else
         {
+            // Otherwise the native data is just a grab-bag: ODummyEmbeddedObject.
             OUString aStreamName = rOLEObj.GetCurrentPersistName();
             uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage();
             uno::Reference<io::XStream> xInStream
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 077483ab158b..508ef02bfd36 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -18,6 +18,7 @@
 #include <svtools/rtfkeywd.hxx>
 #include <svtools/rtftoken.h>
 #include <tools/stream.hxx>
+#include <filter/msfilter/msdffimp.hxx>
 
 namespace
 {
@@ -110,9 +111,12 @@ OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1)
 
     // ClassName
     rOle1.WriteUInt32(aClassName.getLength());
-    rOle1.WriteOString(aClassName);
-    // Null terminated pascal string.
-    rOle1.WriteChar(0);
+    if (!aClassName.isEmpty())
+    {
+        rOle1.WriteOString(aClassName);
+        // Null terminated pascal string.
+        rOle1.WriteChar(0);
+    }
 
     // TopicName.
     rOle1.WriteUInt32(0);
@@ -134,7 +138,7 @@ OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1)
 
 namespace SwReqIfReader
 {
-bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle)
+bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, bool& bOwnFormat)
 {
     // Add missing header/footer.
     SvMemoryStream aRtf;
@@ -150,7 +154,29 @@ bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle)
         return false;
 
     // Write the OLE2 data.
-    return xReader->WriteObjectData(rOle);
+    if (!xReader->WriteObjectData(rOle))
+        return false;
+
+    tools::SvRef<SotStorage> pStorage = new SotStorage(rOle);
+    OUString aFilterName = SvxMSDffManager::GetFilterNameFromClassID(pStorage->GetClassName());
+    bOwnFormat = !aFilterName.isEmpty();
+    if (!bOwnFormat)
+    {
+        // Real OLE2 data, we're done.
+        rOle.Seek(0);
+        return true;
+    }
+
+    // ODF-in-OLE2 case, extract actual data.
+    SvMemoryStream aMemory;
+    SvxMSDffManager::ExtractOwnStream(*pStorage, aMemory);
+    rOle.Seek(0);
+    aMemory.Seek(0);
+    rOle.WriteStream(aMemory);
+    // Stream length is current position + 1.
+    rOle.SetStreamSize(aMemory.GetSize() + 1);
+    rOle.Seek(0);
+    return true;
 }
 
 bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf)
diff --git a/sw/source/filter/html/htmlreqifreader.hxx b/sw/source/filter/html/htmlreqifreader.hxx
index ad8399edbf0e..84d470ce4db1 100644
--- a/sw/source/filter/html/htmlreqifreader.hxx
+++ b/sw/source/filter/html/htmlreqifreader.hxx
@@ -13,8 +13,12 @@ class SvStream;
 
 namespace SwReqIfReader
 {
-/// Extracts an OLE2 container binary from an RTF fragment.
-bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle);
+/**
+ * Extracts an OLE2 container binary from an RTF fragment.
+ *
+ * @param bOwnFormat if the extracted data has an ODF class ID or not.
+ */
+bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, bool& bOwnFormat);
 
 /// Wraps an OLE2 container binary in an RTF fragment.
 bool WrapOleInRtf(SvStream& rOle, SvStream& rRtf);
commit 77c16dca8d022cfb25c52739b814d4f4f5d82483
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue May 29 16:38:18 2018 +0200

    embeddedobj: document OCommon/DummyEmbeddedObject
    
    Change-Id: Ia0024945fa88c14dce4da571ddfd3281e1e41da7
    Reviewed-on: https://gerrit.libreoffice.org/55022
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 5f4d499493c68e52977543c3abc6713518e5e000)

diff --git a/embeddedobj/source/inc/commonembobj.hxx b/embeddedobj/source/inc/commonembobj.hxx
index 52624c291775..f45dda354382 100644
--- a/embeddedobj/source/inc/commonembobj.hxx
+++ b/embeddedobj/source/inc/commonembobj.hxx
@@ -72,6 +72,10 @@ namespace comphelper {
 
 class Interceptor;
 
+/**
+ * Represents an OLE object that has native data and we loaded that data into a
+ * document model successfully.
+ */
 class OCommonEmbeddedObject : public css::embed::XEmbeddedObject
                             , public css::embed::XEmbedPersist2
                             , public css::embed::XLinkageSupport
diff --git a/embeddedobj/source/inc/dummyobject.hxx b/embeddedobj/source/inc/dummyobject.hxx
index 30505a2b0244..67795190a27a 100644
--- a/embeddedobj/source/inc/dummyobject.hxx
+++ b/embeddedobj/source/inc/dummyobject.hxx
@@ -48,6 +48,10 @@ namespace cppu {
     class OMultiTypeInterfaceContainerHelper;
 }
 
+/**
+ * Represents an OLE object that has native data (next to the replacement
+ * image), but we don't understand that data.
+ */
 class ODummyEmbeddedObject : public ::cppu::WeakImplHelper
                         < css::embed::XEmbeddedObject
                         , css::embed::XEmbedPersist >
commit d546e97a7989bd88368a18e4c183923daa4b3184
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon May 28 17:08:34 2018 +0200

    filter: fix build of embedded ole stream dumper
    
    Change-Id: I7f9f34af52057b35f3778d84cfe98afa37817b6b
    Reviewed-on: https://gerrit.libreoffice.org/54939
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 63ce2fa4835109eeab172ab167dafe4a752b6764)

diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index eadbf3afcc9a..cfcc429c389b 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -7000,7 +7000,7 @@ css::uno::Reference < css::embed::XEmbeddedObject >  SvxMSDffManager::CheckForCo
         aTmpName += ".bin";
         SvFileStream aTmpStream(aTmpName,StreamMode::READ|StreamMode::WRITE|StreamMode::TRUNC);
         xMemStream->Seek(0);
-        *xMemStream >> aTmpStream;
+        aTmpStream.WriteStream(*xMemStream);
         aTmpStream.Close();
 #endif
         if ( pName || pFilter )
commit b2c2f5266eaa0a628619b206e27d7bf232822d52
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon May 14 21:47:10 2018 +0200

    tdf#117225 sfx2: fix leftover temp file when saving doc with embedded objects
    
    Regression from 27938e1bbd5f3405c47b9933be7489eeb03920f3 (sfx2 store:
    create temp files next to local files (storage case), 2018-01-17), the
    optimization to store temp files during save next to the destination
    document (so that it can be renamed and not copied after writing the
    data successfully) causes problems when we have embedded objects.
    
    Avoid the problem by disabling this new optimization when the document
    has embedded objects.
    
    How to fix the actual root cause is not clear to me, I see that:
    
    - the SfxMedium::GetOutputStorage() call in
      SfxObjectShell::SaveTo_Impl() create a temp file
    - the SfxMedium::Commit() call in SfxObjectShell::SaveTo_Impl() tries to
      remove the file, which fails on Windows as there is an open file
      handle to that file
    - SfxObjectShell::SwitchChildrenPersistance() would close the storage,
      owning that open file handle, but it's too late
    
    So just go back to the previous behavior for now.
    
    Reviewed-on: https://gerrit.libreoffice.org/54340
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit c1676204447df942e766c0780c1580e1f0427b73)
    
    Conflicts:
            sw/qa/extras/uiwriter/uiwriter.cxx
    
    Change-Id: I37259100d1ddf963c1f2d3b7bd9f460bc995815c

diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx
index ec78c751524d..dc9eaeb2e17d 100644
--- a/include/sfx2/docfile.hxx
+++ b/include/sfx2/docfile.hxx
@@ -265,6 +265,8 @@ public:
     SAL_DLLPRIVATE SignatureState GetCachedSignatureState_Impl();
     SAL_DLLPRIVATE void       SetCachedSignatureState_Impl( SignatureState nState );
 
+    void SetHasEmbeddedObjects(bool bHasEmbeddedObjects);
+
     static css::uno::Sequence < css::util::RevisionTag > GetVersionList(
                     const css::uno::Reference< css::embed::XStorage >& xStorage );
     static OUString CreateTempCopyWithExt( const OUString& aURL );
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 384178f756c6..fd59da8bc5a2 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -257,6 +257,8 @@ public:
     //             in this case the member will hold this information
     SignatureState             m_nSignatureState;
 
+    bool m_bHasEmbeddedObjects = false;
+
     util::DateTime m_aDateTime;
 
     explicit SfxMedium_Impl();
@@ -3396,6 +3398,10 @@ OUString GetLogicBase(std::unique_ptr<SfxMedium_Impl>& pImpl)
             aLogicBase.clear();
     }
 
+    if (pImpl->m_bHasEmbeddedObjects)
+        // Embedded objects would mean a special base, ignore that.
+        aLogicBase.clear();
+
     return aLogicBase;
 }
 }
@@ -3700,6 +3706,11 @@ void SfxMedium::SetCachedSignatureState_Impl( SignatureState nState )
     pImpl->m_nSignatureState = nState;
 }
 
+void SfxMedium::SetHasEmbeddedObjects(bool bHasEmbeddedObjects)
+{
+    pImpl->m_bHasEmbeddedObjects = bHasEmbeddedObjects;
+}
+
 bool SfxMedium::HasStorage_Impl() const
 {
     return pImpl->xStorage.is();
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 4923b8cc953e..0397b0614054 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -1238,7 +1238,9 @@ bool SfxObjectShell::SaveTo_Impl
                     //             if the url is not provided ( means the document is based on a stream ) this code is not
                     //             reachable.
                     rMedium.CloseAndRelease();
+                    rMedium.SetHasEmbeddedObjects(GetEmbeddedObjectContainer().HasEmbeddedObjects());
                     rMedium.GetOutputStorage();
+                    rMedium.SetHasEmbeddedObjects(false);
                 }
             }
             else if ( !bStorageBasedSource && !bStorageBasedTarget )
diff --git a/sw/qa/extras/uiwriter/data/tdf117225.odt b/sw/qa/extras/uiwriter/data/tdf117225.odt
new file mode 100644
index 000000000000..9e31eb6b2090
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf117225.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 42fda5584ab8..66886a70fa05 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -110,7 +110,29 @@
 #include <test/htmltesttools.hxx>
 #include <wrthtml.hxx>
 
-static const char* const DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
+namespace
+{
+char const DATA_DIRECTORY[] = "/sw/qa/extras/uiwriter/data/";
+
+int CountFilesInDirectory(const OUString &rURL)
+{
+    int nRet = 0;
+
+    osl::Directory aDir(rURL);
+    CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, aDir.open());
+
+    osl::DirectoryItem aItem;
+    osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL|osl_FileStatus_Mask_Type);
+    while (aDir.getNextItem(aItem) == osl::FileBase::E_None)
+    {
+        aItem.getFileStatus(aFileStatus);
+        if (aFileStatus.getFileType() != osl::FileStatus::Directory)
+            ++nRet;
+    }
+
+    return nRet;
+}
+}
 
 class SwUiWriterTest : public SwModelTestBase, public HtmlTestTools
 {
@@ -256,6 +278,7 @@ public:
     void testTdf113790();
     void testHtmlCopyImages();
     void testTdf116789();
+    void testTdf117225();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -396,6 +419,7 @@ public:
     CPPUNIT_TEST(testTdf113790);
     CPPUNIT_TEST(testHtmlCopyImages);
     CPPUNIT_TEST(testTdf116789);
+    CPPUNIT_TEST(testTdf117225);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -5042,6 +5066,23 @@ void SwUiWriterTest::testTdf116789()
     CPPUNIT_ASSERT_EQUAL(xText1, xText2);
 }
 
+void SwUiWriterTest::testTdf117225()
+{
+    // Test that saving a document with an embedded object does not leak
+    // tempfiles in the directory of the target file.
+    OUString aTargetDirectory = m_directories.getURLFromWorkdir("/CppunitTest/sw_uiwriter.test.user/");
+    OUString aTargetFile = aTargetDirectory + "tdf117225.odt";
+    OUString aSourceFile = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf117225.odt";
+    osl::File::copy(aSourceFile, aTargetFile);
+    mxComponent = loadFromDesktop(aTargetFile);
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    int nExpected = CountFilesInDirectory(aTargetDirectory);
+    xStorable->store();
+    int nActual = CountFilesInDirectory(aTargetDirectory);
+    // nActual was nExpected + 1, i.e. we leaked a tempfile.
+    CPPUNIT_ASSERT_EQUAL(nExpected, nActual);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 


More information about the Libreoffice-commits mailing list