summaryrefslogtreecommitdiff
path: root/embeddedobj
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2017-07-10 18:47:49 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-07-13 11:21:04 +0200
commit427c763a1ad0ebc85383625f019b405c30828374 (patch)
tree766c2084bbe36fadc6f69a3458c3df4494a8a9a8 /embeddedobj
parenta394d67f374e1b253f288a58113a3cfc8d301743 (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 2beb08e242fc..5df00c5e0a16 100644
--- a/embeddedobj/source/inc/oleembobj.hxx
+++ b/embeddedobj/source/inc/oleembobj.hxx
@@ -279,7 +279,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 f8c2c9903a73..c3acbb687e8b 100644
--- a/embeddedobj/source/msole/oleembed.cxx
+++ b/embeddedobj/source/msole/oleembed.cxx
@@ -248,7 +248,7 @@ OUString OleEmbeddedObject::MoveToTemporarySubstream()
}
-bool OleEmbeddedObject::TryToConvertToOOo()
+bool OleEmbeddedObject::TryToConvertToOOo( const uno::Reference< io::XStream >& xStream )
{
bool bResult = false;
@@ -264,9 +264,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()
@@ -314,7 +314,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 );
@@ -657,7 +657,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)
@@ -679,18 +678,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);
@@ -789,26 +781,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 );
+ }
}
@@ -818,6 +832,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;
@@ -890,7 +907,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;
@@ -917,6 +934,18 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
}
}
+ // it may be the OLE Storage, try to extract stream
+ if ( !m_xOwnView.is() && 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_xOwnView.is() || !m_xOwnView->Open())
{
//Make a RO copy and see if the OS can find something to at