20#include <com/sun/star/frame/Desktop.hpp>
21#include <com/sun/star/frame/XFrame.hpp>
22#include <com/sun/star/frame/XController.hpp>
23#include <com/sun/star/awt/XTopWindow.hpp>
24#include <com/sun/star/embed/XClassifiedObject.hpp>
25#include <com/sun/star/io/TempFile.hpp>
26#include <com/sun/star/io/XStream.hpp>
27#include <com/sun/star/io/XOutputStream.hpp>
28#include <com/sun/star/io/XSeekable.hpp>
29#include <com/sun/star/task/XInteractionHandler.hpp>
30#include <com/sun/star/ucb/SimpleFileAccess.hpp>
31#include <com/sun/star/util/XCloseable.hpp>
33#include <com/sun/star/document/XEventBroadcaster.hpp>
34#include <com/sun/star/document/XEventListener.hpp>
35#include <com/sun/star/document/XTypeDetection.hpp>
36#include <com/sun/star/container/XNameAccess.hpp>
52class DummyHandler_Impl :
public ::cppu::WeakImplHelper< task::XInteractionHandler >
55 DummyHandler_Impl() {}
57 virtual void SAL_CALL handle(
const uno::Reference< task::XInteractionRequest >& xRequest )
override;
62void SAL_CALL DummyHandler_Impl::handle(
const uno::Reference< task::XInteractionRequest >& )
71 const uno::Reference< io::XInputStream >& xInputStream )
74, m_bUseNative( false )
76 if ( !xContext.is() || !xInputStream.is() )
77 throw uno::RuntimeException();
87 }
catch( uno::Exception& ) {}
92 }
catch( uno::Exception& ) {}
100 if ( !aFileURL.isEmpty() )
103 uno::Reference < frame::XDesktop2 > xDocumentLoader = frame::Desktop::create(
m_xContext);
105 uno::Sequence< beans::PropertyValue > aArgs(
m_aFilterName.isEmpty() ? 4 : 5 );
106 auto pArgs = aArgs.getArray();
108 pArgs[0].Name =
"URL";
109 pArgs[0].Value <<= aFileURL;
111 pArgs[1].Name =
"ReadOnly";
112 pArgs[1].Value <<=
true;
114 pArgs[2].Name =
"InteractionHandler";
115 pArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
new DummyHandler_Impl() );
117 pArgs[3].Name =
"DontEdit";
118 pArgs[3].Value <<=
true;
122 pArgs[4].Name =
"FilterName";
126 uno::Reference< frame::XModel >
xModel( xDocumentLoader->loadComponentFromURL(
135 uno::Reference< document::XEventBroadcaster > xBroadCaster(
xModel, uno::UNO_QUERY );
136 if ( xBroadCaster.is() )
137 xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
this) );
139 uno::Reference< util::XCloseable > xCloseable(
xModel, uno::UNO_QUERY );
140 if ( xCloseable.is() )
142 xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
this) );
144 ::osl::MutexGuard aGuard(
m_aMutex );
150 catch (uno::Exception
const&)
162 bool bResult =
false;
167 catch( uno::Exception& )
176 const css::uno::Reference< css::uno::XComponentContext >& xContext,
177 std::u16string_view aNameWithExtention,
178 const uno::Reference< io::XInputStream >& xInputStream )
180 if ( !xInputStream.is() )
181 throw uno::RuntimeException();
183 uno::Reference< document::XTypeDetection > xTypeDetection(
184 xContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.TypeDetection", xContext),
185 uno::UNO_QUERY_THROW );
189 if ( !aNameWithExtention.empty() )
191 OUString aURLToAnalyze = OUString::Concat(
"file:///") + aNameWithExtention;
192 aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
195 uno::Sequence< beans::PropertyValue > aArgs( aTypeName.isEmpty() ? 2 : 3 );
196 auto pArgs = aArgs.getArray();
197 pArgs[0].Name =
"URL";
198 pArgs[0].Value <<= OUString(
"private:stream" );
199 pArgs[1].Name =
"InputStream";
200 pArgs[1].Value <<= xInputStream;
201 if ( !aTypeName.isEmpty() )
203 pArgs[2].Name =
"TypeName";
204 pArgs[2].Value <<= aTypeName;
207 aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs,
true );
209 OUString aFilterName;
210 for ( beans::PropertyValue
const & prop : std::as_const(aArgs) )
211 if ( prop.Name ==
"FilterName" )
212 prop.Value >>= aFilterName;
214 if ( aFilterName.isEmpty() && !aTypeName.isEmpty() )
217 uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
218 uno::Sequence< beans::PropertyValue >
aTypes;
220 if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>=
aTypes ) )
222 for ( beans::PropertyValue
const & prop : std::as_const(
aTypes) )
224 if ( prop.Name ==
"PreferredFilter" && ( prop.Value >>= aFilterName ) )
226 prop.Value >>= aFilterName;
240 uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
241 xSeekable->seek( 0 );
244 OUString aNativeTempURL;
245 uno::Reference < io::XTempFile > xNativeTempFile(
247 uno::UNO_SET_THROW );
248 uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempFile->getOutputStream();
249 uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempFile->getInputStream();
250 if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
251 throw uno::RuntimeException();
254 xNativeTempFile->setRemoveFile(
false );
255 aNativeTempURL = xNativeTempFile->getUri();
257 catch ( uno::Exception& )
261 bool bFailed =
false;
262 OUString aFileSuffix;
266 uno::Sequence< sal_Int8 > aReadSeq( 4 );
268 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
271 if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
278 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
282 (aReadSeq[0] >=
'0' && aReadSeq[0] <=
'9') ||
283 (aReadSeq[0] >=
'a' && aReadSeq[0] <=
'z') ||
284 (aReadSeq[0] >=
'A' && aReadSeq[0] <=
'Z') ||
288 aFileSuffix += OUStringChar(
sal_Unicode(aReadSeq[0]) );
291 }
while( aReadSeq[0] );
296 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
298 }
while( aReadSeq[0] );
301 if ( xInStream->readBytes( aReadSeq, 4 ) != 4
302 || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
306 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
309 sal_uInt32 nUrlSize =
static_cast<sal_uInt8>(aReadSeq[0])
310 +
static_cast<sal_uInt8>(aReadSeq[1]) * 0x100
311 +
static_cast<sal_uInt8>(aReadSeq[2]) * 0x10000
312 +
static_cast<sal_uInt8>(aReadSeq[3]) * 0x1000000;
313 sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
315 xSeekable->seek( nTargetPos );
318 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
321 sal_uInt32 nDataSize =
static_cast<sal_uInt8>(aReadSeq[0])
322 +
static_cast<sal_uInt8>(aReadSeq[1]) * 0x100
323 +
static_cast<sal_uInt8>(aReadSeq[2]) * 0x10000
324 +
static_cast<sal_uInt8>(aReadSeq[3]) * 0x1000000;
326 aReadSeq.realloc( 32000 );
327 sal_uInt32 nRead = 0;
328 while ( nRead < nDataSize )
330 sal_uInt32 nToRead = std::min<sal_uInt32>( nDataSize - nRead, 32000 );
331 sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
339 else if ( nLocalRead == 32000 )
340 xNativeOutTemp->writeBytes( aReadSeq );
343 uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
344 aToWrite.realloc( nLocalRead );
345 xNativeOutTemp->writeBytes( aToWrite );
353 uno::Sequence< sal_Int8 >
aData( 8 );
354 if ( xInStream->readBytes(
aData, 8 ) == 8
359 xSeekable->seek( 40 );
364 xSeekable->seek( 4 );
370 xNativeOutTemp->closeOutput();
390 uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
391 ucb::SimpleFileAccess::create(
m_xContext ) );
393 uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead(
m_aTempFileURL );
394 if ( !xInStream.is() )
395 throw uno::RuntimeException();
397 uno::Sequence< uno::Any > aArgs{
uno::Any(xInStream) };
398 uno::Reference< container::XNameAccess > xNameAccess(
399 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
400 "com.sun.star.embed.OLESimpleStorage",
402 uno::UNO_QUERY_THROW );
404 OUString aSubStreamName =
"\1Ole10Native";
405 uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
406 uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
408 if ( xNameAccess->hasByName( aSubStreamName ) )
411 { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
413 uno::Sequence< sal_Int8 > aPackageClassID(
reinterpret_cast<sal_Int8 const *
>(
aClassID), 16 );
415 uno::Reference< io::XStream > xSubStream;
416 xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
417 if ( xSubStream.is() )
421 if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
451 catch( uno::Exception& )
458 bool bResult =
false;
460 uno::Reference< frame::XModel > xExistingModel;
463 ::osl::MutexGuard aGuard(
m_aMutex );
471 if ( xExistingModel.is() )
474 uno::Reference< frame::XController >
xController = xExistingModel->getCurrentController();
481 uno::Reference<awt::XTopWindow> xTopWindow(
xFrame->getContainerWindow(), uno::UNO_QUERY );
483 xTopWindow->toFront();
489 catch( uno::Exception& )
523 uno::Reference< frame::XModel >
xModel;
526 ::osl::MutexGuard aGuard(
m_aMutex );
539 uno::Reference< document::XEventBroadcaster > xBroadCaster(
xModel, uno::UNO_QUERY );
540 if ( xBroadCaster.is() )
541 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
this ) );
543 uno::Reference< util::XCloseable > xCloseable(
xModel, uno::UNO_QUERY );
544 if ( xCloseable.is() )
546 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
this ) );
547 xCloseable->close(
true );
550 catch( uno::Exception& )
560 uno::Reference< frame::XModel >
xModel;
563 ::osl::MutexGuard aGuard(
m_aMutex );
576 uno::Reference< document::XEventBroadcaster > xBroadCaster(
xModel, uno::UNO_QUERY );
577 if ( xBroadCaster.is() )
578 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
this ) );
580 uno::Reference< util::XCloseable > xCloseable(
xModel, uno::UNO_QUERY );
581 if ( xCloseable.is() )
582 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
this ) );
584 catch( uno::Exception& )
596 ::osl::MutexGuard aGuard(
m_aMutex );
604 ::osl::MutexGuard aGuard(
m_aMutex );
Reference< XComponentContext > m_xContext
bool CreateModel(bool bUseNative)
OwnView_Impl(const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::io::XInputStream > &xStream)
virtual void SAL_CALL notifyEvent(const css::document::EventObject &Event) override
bool CreateModelFromURL(const OUString &aFileURL)
static OUString GetFilterNameFromExtentionAndInStream(const css::uno::Reference< css::uno::XComponentContext > &xContext, std::u16string_view aNameWithExtention, const css::uno::Reference< css::io::XInputStream > &xInputStream)
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Reference< css::frame::XModel > m_xModel
OUString m_aNativeTempURL
virtual void SAL_CALL notifyClosing(const css::lang::EventObject &Source) override
virtual ~OwnView_Impl() override
virtual void SAL_CALL queryClosing(const css::lang::EventObject &Source, sal_Bool GetsOwnership) override
bool ReadContentsAndGenerateTempFile(const css::uno::Reference< css::io::XInputStream > &xStream, bool bParseHeader)
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
#define TOOLS_WARN_EXCEPTION(area, stream)
constexpr OUStringLiteral aData
bool KillFile_Impl(const OUString &aURL, const uno::Reference< uno::XComponentContext > &xContext)
OUString GetNewFilledTempFile_Impl(const uno::Reference< io::XInputStream > &xInStream, const uno::Reference< uno::XComponentContext > &xContext)
const char *const aClassID
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel