[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - embeddedobj/source

Szymon Kłos szymon.klos at collabora.com
Thu Jul 13 10:24:35 UTC 2017


 embeddedobj/source/inc/oleembobj.hxx  |    2 -
 embeddedobj/source/msole/oleembed.cxx |   65 ++++++++++++++++++++++++----------
 2 files changed, 48 insertions(+), 19 deletions(-)

New commits:
commit a79214eea7d3d331e823459a0fc059536282c9dd
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Mon Jul 10 18:47:49 2017 +0200

    tdf#108545 tdf#108544: DOCX, XLSX embedded in DOC
    
    When on Windows the MSO wasn't installed DOCX and XLSX
    embedded documents weren't accessible. General OLE error
    was shown after doubleclick on the object.
    
    Linux solution is reused, OLE storage is extracted to
    get the document inside.
    
    Change-Id: If4d00fddad8e127fcf1a222836896d2907549d0c
    Reviewed-on: https://gerrit.libreoffice.org/39814
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/embeddedobj/source/inc/oleembobj.hxx b/embeddedobj/source/inc/oleembobj.hxx
index 4e41552d1a94..31a680c0a0b8 100644
--- a/embeddedobj/source/inc/oleembobj.hxx
+++ b/embeddedobj/source/inc/oleembobj.hxx
@@ -278,7 +278,7 @@ protected:
     void MoveListeners();
     css::uno::Reference< css::embed::XStorage > CreateTemporarySubstorage( OUString& o_aStorageName );
     OUString MoveToTemporarySubstream();
-    bool TryToConvertToOOo();
+    bool TryToConvertToOOo( const css::uno::Reference< css::io::XStream >& xStream );
 
 public:
     // in case a new object must be created the class ID must be specified
diff --git a/embeddedobj/source/msole/oleembed.cxx b/embeddedobj/source/msole/oleembed.cxx
index e26875732ef3..17ba8ed59b8c 100644
--- a/embeddedobj/source/msole/oleembed.cxx
+++ b/embeddedobj/source/msole/oleembed.cxx
@@ -247,7 +247,7 @@ OUString OleEmbeddedObject::MoveToTemporarySubstream()
 }
 
 
-bool OleEmbeddedObject::TryToConvertToOOo()
+bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >& xStream )
 {
     bool bResult = false;
 
@@ -263,9 +263,9 @@ bool OleEmbeddedObject::TryToConvertToOOo()
         changeState( embed::EmbedStates::LOADED );
 
         // the stream must be seekable
-        uno::Reference< io::XSeekable > xSeekable( m_xObjectStream, uno::UNO_QUERY_THROW );
+        uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY_THROW );
         xSeekable->seek( 0 );
-        m_aFilterName = OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory, OUString(), m_xObjectStream->getInputStream() );
+        m_aFilterName = OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory, OUString(), xStream->getInputStream() );
 
         // use the solution only for OOXML format currently
         if ( !m_aFilterName.isEmpty()
@@ -313,7 +313,7 @@ bool OleEmbeddedObject::TryToConvertToOOo()
                 aArgs[3].Name = "URL";
                 aArgs[3].Value <<= OUString( "private:stream" );
                 aArgs[4].Name = "InputStream";
-                aArgs[4].Value <<= m_xObjectStream->getInputStream();
+                aArgs[4].Value <<= xStream->getInputStream();
 
                 xSeekable->seek( 0 );
                 xLoadable->load( aArgs );
@@ -664,7 +664,6 @@ sal_Int32 SAL_CALL OleEmbeddedObject::getCurrentState()
 
 namespace
 {
-#ifndef _WIN32
     bool lcl_CopyStream(const uno::Reference<io::XInputStream>& xIn, const uno::Reference<io::XOutputStream>& xOut, sal_Int32 nMaxCopy = SAL_MAX_INT32)
     {
         if (nMaxCopy == 0)
@@ -686,18 +685,11 @@ namespace
         } while (nRead == nChunkSize && nTotalRead <= nMaxCopy);
         return nTotalRead != 0;
     }
-#endif
 
-    //Dump the objects content to a tempfile, just the "CONTENTS" stream if
-    //there is one for non-compound documents, otherwise the whole content.
-    //On success a file is returned which must be removed by the caller
-    OUString lcl_ExtractObject(const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
-        const css::uno::Reference< css::io::XStream >& xObjectStream)
+    uno::Reference < io::XStream > lcl_GetExtractedStream( OUString& rUrl,
+        const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
+        const css::uno::Reference< css::io::XStream >& xObjectStream )
     {
-        OUString sUrl;
-
-        // the solution is only active for Unix systems
-#ifndef _WIN32
         uno::Reference <beans::XPropertySet> xNativeTempFile(
             io::TempFile::create(comphelper::getComponentContext(xFactory)),
             uno::UNO_QUERY_THROW);
@@ -796,26 +788,48 @@ namespace
             xNativeTempFile->setPropertyValue("RemoveFile",
                 uno::makeAny(false));
             uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
-            aUrl >>= sUrl;
+            aUrl >>= rUrl;
 
             xNativeTempFile.clear();
 
             uno::Reference < ucb::XSimpleFileAccess3 > xSimpleFileAccess(
                     ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory) ) );
 
-            xSimpleFileAccess->setReadOnly(sUrl, true);
+            xSimpleFileAccess->setReadOnly(rUrl, true);
         }
         else
         {
             xNativeTempFile->setPropertyValue("RemoveFile",
                 uno::makeAny(true));
         }
+
+        return xStream;
+    }
+
+    //Dump the objects content to a tempfile, just the "CONTENTS" stream if
+    //there is one for non-compound documents, otherwise the whole content.
+    //On success a file is returned which must be removed by the caller
+    OUString lcl_ExtractObject(const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
+        const css::uno::Reference< css::io::XStream >& xObjectStream)
+    {
+        OUString sUrl;
+
+        // the solution is only active for Unix systems
+#ifndef _WIN32
+        lcl_GetExtractedStream(sUrl, xFactory, xObjectStream);
 #else
         (void) xFactory;
         (void) xObjectStream;
 #endif
         return sUrl;
     }
+
+    uno::Reference < io::XStream > lcl_ExtractObjectStream( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
+        const css::uno::Reference< css::io::XStream >& xObjectStream )
+    {
+        OUString sUrl;
+        return lcl_GetExtractedStream( sUrl, xFactory, xObjectStream );
+    }
 }
 
 
@@ -830,6 +844,9 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
     uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
     if ( xWrappedObject.is() )
     {
+        // open content in the window not in-place
+        nVerbID = embed::EmbedVerbs::MS_OLEVERB_OPEN;
+
         // the object was converted to OOo embedded object, the current implementation is now only a wrapper
         xWrappedObject->doVerb( nVerbID );
         return;
@@ -902,7 +919,7 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
             if ( !m_bTriedConversion )
             {
                 m_bTriedConversion = true;
-                if ( TryToConvertToOOo() )
+                if ( TryToConvertToOOo( m_xObjectStream ) )
                 {
                     changeState( embed::EmbedStates::UI_ACTIVE );
                     return;
@@ -930,6 +947,18 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
                 }
             }
 
+            // it may be the OLE Storage, try to extract stream
+            if ( !m_pOwnView && m_xObjectStream.is() && m_aFilterName == "Text" )
+            {
+                uno::Reference< io::XStream > xStream = lcl_ExtractObjectStream( m_xFactory, m_xObjectStream );
+
+                if ( TryToConvertToOOo( xStream ) )
+                {
+                    changeState( embed::EmbedStates::ACTIVE );
+                    return;
+                }
+            }
+
             if (!m_pOwnView || !m_pOwnView->Open())
             {
                 //Make a RO copy and see if the OS can find something to at


More information about the Libreoffice-commits mailing list