summaryrefslogtreecommitdiff
path: root/embeddedobj
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2017-07-10 18:47:49 +0200
committerSzymon Kłos <szymon.klos@collabora.com>2017-07-13 11:46:16 +0200
commita79214eea7d3d331e823459a0fc059536282c9dd (patch)
tree4a19bb816bedad0a536bc634b2c946d909e4a6e1 /embeddedobj
parent891f6cd2008e71c9c515f2f7b3ab5f22e377b548 (diff)
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@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'embeddedobj')
-rw-r--r--embeddedobj/source/inc/oleembobj.hxx2
-rw-r--r--embeddedobj/source/msole/oleembed.cxx65
2 files changed, 48 insertions, 19 deletions
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