2010-10-12 15:53:47 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-09-27 13:52:10 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
#include <com/sun/star/frame/Desktop.hpp>
|
2005-01-18 14:11:10 +00:00
|
|
|
#include <com/sun/star/frame/XFrame.hpp>
|
|
|
|
#include <com/sun/star/frame/XController.hpp>
|
|
|
|
#include <com/sun/star/frame/XComponentLoader.hpp>
|
|
|
|
#include <com/sun/star/awt/XTopWindow.hpp>
|
|
|
|
#include <com/sun/star/embed/XClassifiedObject.hpp>
|
2012-08-23 17:23:26 +02:00
|
|
|
#include <com/sun/star/io/TempFile.hpp>
|
2005-01-18 14:11:10 +00:00
|
|
|
#include <com/sun/star/io/XStream.hpp>
|
|
|
|
#include <com/sun/star/io/XInputStream.hpp>
|
|
|
|
#include <com/sun/star/io/XOutputStream.hpp>
|
|
|
|
#include <com/sun/star/io/XSeekable.hpp>
|
|
|
|
#include <com/sun/star/task/XInteractionHandler.hpp>
|
2012-05-29 17:17:28 +02:00
|
|
|
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
|
2005-01-18 14:11:10 +00:00
|
|
|
#include <com/sun/star/util/XCloseable.hpp>
|
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
|
|
|
|
|
|
#include <com/sun/star/document/XEventBroadcaster.hpp>
|
|
|
|
#include <com/sun/star/document/XEventListener.hpp>
|
|
|
|
#include <com/sun/star/document/XTypeDetection.hpp>
|
|
|
|
#include <com/sun/star/container/XNameAccess.hpp>
|
|
|
|
#include <cppuhelper/implbase1.hxx>
|
2012-09-19 13:15:15 +02:00
|
|
|
#include <comphelper/processfactory.hxx>
|
2005-01-18 14:11:10 +00:00
|
|
|
#include <comphelper/storagehelper.hxx>
|
2007-07-06 09:11:27 +00:00
|
|
|
#include <comphelper/mimeconfighelper.hxx>
|
|
|
|
|
2005-01-18 14:11:10 +00:00
|
|
|
#include "ownview.hxx"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
2007-07-06 09:11:27 +00:00
|
|
|
using namespace ::comphelper;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
|
|
|
|
OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
|
|
|
|
sal_Bool KillFile_Impl( const OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory );
|
2005-01-18 14:11:10 +00:00
|
|
|
uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw ( uno::Exception );
|
|
|
|
|
|
|
|
//========================================================
|
|
|
|
// Dummy interaction handler
|
|
|
|
//========================================================
|
|
|
|
//--------------------------------------------------------
|
|
|
|
class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DummyHandler_Impl() {}
|
|
|
|
~DummyHandler_Impl();
|
|
|
|
|
|
|
|
virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
|
|
|
|
throw( uno::RuntimeException );
|
|
|
|
};
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
DummyHandler_Impl::~DummyHandler_Impl()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2006-06-19 23:31:21 +00:00
|
|
|
void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
|
2005-01-18 14:11:10 +00:00
|
|
|
throw( uno::RuntimeException )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//========================================================
|
|
|
|
// Object viewer
|
|
|
|
//========================================================
|
|
|
|
//--------------------------------------------------------
|
|
|
|
OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
|
|
|
|
const uno::Reference< io::XInputStream >& xInputStream )
|
|
|
|
: m_xFactory( xFactory )
|
|
|
|
, m_bBusy( sal_False )
|
|
|
|
, m_bUseNative( sal_False )
|
|
|
|
{
|
|
|
|
if ( !xFactory.is() || !xInputStream.is() )
|
|
|
|
throw uno::RuntimeException();
|
|
|
|
|
|
|
|
m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
OwnView_Impl::~OwnView_Impl()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
KillFile_Impl( m_aTempFileURL, m_xFactory );
|
|
|
|
} catch( uno::Exception& ) {}
|
|
|
|
|
|
|
|
try {
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
KillFile_Impl( m_aNativeTempURL, m_xFactory );
|
|
|
|
} catch( uno::Exception& ) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2013-04-07 12:06:47 +02:00
|
|
|
sal_Bool OwnView_Impl::CreateModelFromURL( const OUString& aFileURL )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
sal_Bool bResult = sal_False;
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !aFileURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
try {
|
2012-12-14 12:58:00 +02:00
|
|
|
uno::Reference < frame::XDesktop2 > xDocumentLoader = frame::Desktop::create(comphelper::getComponentContext(m_xFactory));
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.isEmpty() ? 4 : 5 );
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[0].Name = OUString( "URL" );
|
2012-12-14 12:58:00 +02:00
|
|
|
aArgs[0].Value <<= aFileURL;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[1].Name = OUString( "ReadOnly" );
|
2012-12-14 12:58:00 +02:00
|
|
|
aArgs[1].Value <<= sal_True;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[2].Name = OUString( "InteractionHandler" );
|
2012-12-14 12:58:00 +02:00
|
|
|
aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[3].Name = OUString( "DontEdit" );
|
2012-12-14 12:58:00 +02:00
|
|
|
aArgs[3].Value <<= sal_True;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
if ( !m_aFilterName.isEmpty() )
|
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[4].Name = OUString( "FilterName" );
|
2012-12-14 12:58:00 +02:00
|
|
|
aArgs[4].Value <<= m_aFilterName;
|
|
|
|
}
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
|
|
|
|
aFileURL,
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString( "_blank" ),
|
2012-12-14 12:58:00 +02:00
|
|
|
0,
|
|
|
|
aArgs ),
|
|
|
|
uno::UNO_QUERY );
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
if ( xModel.is() )
|
|
|
|
{
|
|
|
|
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xBroadCaster.is() )
|
|
|
|
xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
|
|
|
|
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xCloseable.is() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
2012-12-14 12:58:00 +02:00
|
|
|
xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
m_xModel = xModel;
|
|
|
|
bResult = sal_True;
|
2005-01-18 14:11:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-02-10 00:11:01 +01:00
|
|
|
catch (uno::Exception const& e)
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
2013-02-10 00:11:01 +01:00
|
|
|
SAL_WARN("embeddedobj.ole", "OwnView_Impl::CreateModelFromURL:"
|
|
|
|
" exception caught: " << e.Message);
|
2005-01-18 14:11:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative )
|
|
|
|
{
|
|
|
|
sal_Bool bResult = sal_False;
|
|
|
|
|
|
|
|
try {
|
|
|
|
bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
|
2008-07-22 13:40:00 +00:00
|
|
|
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
|
2013-04-07 12:06:47 +02:00
|
|
|
const OUString& aNameWithExtention,
|
2008-07-22 13:40:00 +00:00
|
|
|
const uno::Reference< io::XInputStream >& xInputStream )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
if ( !xInputStream.is() )
|
|
|
|
throw uno::RuntimeException();
|
|
|
|
|
|
|
|
uno::Reference< document::XTypeDetection > xTypeDetection(
|
2013-06-29 21:24:12 +02:00
|
|
|
xFactory->createInstance("com.sun.star.document.TypeDetection"),
|
2005-01-18 14:11:10 +00:00
|
|
|
uno::UNO_QUERY_THROW );
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aTypeName;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !aNameWithExtention.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aURLToAnalyze =
|
|
|
|
( OUString( "file:///" ) + aNameWithExtention );
|
2005-01-18 14:11:10 +00:00
|
|
|
aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
|
|
|
|
}
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
uno::Sequence< beans::PropertyValue > aArgs( aTypeName.isEmpty() ? 2 : 3 );
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[0].Name = OUString( "URL" );
|
|
|
|
aArgs[0].Value <<= OUString( "private:stream" );
|
|
|
|
aArgs[1].Name = OUString( "InputStream" );
|
2005-01-18 14:11:10 +00:00
|
|
|
aArgs[1].Value <<= xInputStream;
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !aTypeName.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
aArgs[2].Name = OUString( "TypeName" );
|
2005-01-18 14:11:10 +00:00
|
|
|
aArgs[2].Value <<= aTypeName;
|
|
|
|
}
|
|
|
|
|
|
|
|
aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aFilterName;
|
2005-01-18 14:11:10 +00:00
|
|
|
for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
|
2012-04-06 14:28:18 +02:00
|
|
|
if ( aArgs[nInd].Name == "FilterName" )
|
2005-01-18 14:11:10 +00:00
|
|
|
aArgs[nInd].Value >>= aFilterName;
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( aFilterName.isEmpty() && !aTypeName.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
// get the default filter name for the type
|
|
|
|
uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
|
|
|
|
uno::Sequence< beans::PropertyValue > aTypes;
|
|
|
|
|
|
|
|
if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
|
|
|
|
{
|
|
|
|
for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
|
|
|
|
{
|
2011-01-20 11:23:45 +01:00
|
|
|
if ( aTypes[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PreferredFilter" ) ) && ( aTypes[nInd].Value >>= aFilterName ) )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
aTypes[nInd].Value >>= aFilterName;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return aFilterName;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
|
|
|
|
sal_Bool bParseHeader )
|
|
|
|
{
|
|
|
|
uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
|
|
|
|
xSeekable->seek( 0 );
|
|
|
|
|
|
|
|
// create m_aNativeTempURL
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aNativeTempURL;
|
2005-01-18 14:11:10 +00:00
|
|
|
uno::Reference < beans::XPropertySet > xNativeTempFile(
|
2012-09-19 13:15:15 +02:00
|
|
|
io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
|
2005-01-18 14:11:10 +00:00
|
|
|
uno::UNO_QUERY_THROW );
|
|
|
|
uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
|
|
|
|
uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
|
|
|
|
uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
|
|
|
|
if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
|
|
|
|
throw uno::RuntimeException();
|
|
|
|
|
|
|
|
try {
|
2013-06-29 21:24:12 +02:00
|
|
|
xNativeTempFile->setPropertyValue("RemoveFile", uno::makeAny( sal_False ) );
|
|
|
|
uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
|
2005-01-18 14:11:10 +00:00
|
|
|
aUrl >>= aNativeTempURL;
|
|
|
|
}
|
|
|
|
catch ( uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool bFailed = sal_False;
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aFileSuffix;
|
2005-01-18 14:11:10 +00:00
|
|
|
|
|
|
|
if ( bParseHeader )
|
|
|
|
{
|
|
|
|
uno::Sequence< sal_Int8 > aReadSeq( 4 );
|
|
|
|
// read the complete size of the Object Package
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
|
|
|
|
return sal_False;
|
|
|
|
// read the first header ( have no idea what does this header mean )
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
// read file name
|
|
|
|
// only extension is interesting so only subset of symbols is accepted
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
|
|
|
|
return sal_False;
|
|
|
|
|
2008-12-11 07:05:03 +00:00
|
|
|
if (
|
|
|
|
(aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
|
|
|
|
(aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
|
|
|
|
(aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
|
|
|
|
aReadSeq[0] == '.'
|
|
|
|
)
|
|
|
|
{
|
2013-08-21 15:07:31 +02:00
|
|
|
aFileSuffix += OUString( (sal_Unicode) aReadSeq[0] );
|
2008-12-11 07:05:03 +00:00
|
|
|
}
|
2005-01-18 14:11:10 +00:00
|
|
|
|
|
|
|
} while( aReadSeq[0] );
|
|
|
|
|
|
|
|
// skip url
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
|
|
|
|
return sal_False;
|
|
|
|
} while( aReadSeq[0] );
|
|
|
|
|
|
|
|
// check the next header
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 4 ) != 4
|
|
|
|
|| aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
// get the size of the next entry
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
|
|
|
|
+ (sal_uInt8)aReadSeq[1] * 0x100
|
|
|
|
+ (sal_uInt8)aReadSeq[2] * 0x10000
|
|
|
|
+ (sal_uInt8)aReadSeq[3] * 0x1000000;
|
|
|
|
sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
|
|
|
|
|
|
|
|
xSeekable->seek( nTargetPos );
|
|
|
|
|
|
|
|
// get the size of stored data
|
|
|
|
if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
|
|
|
|
+ (sal_uInt8)aReadSeq[1] * 0x100
|
|
|
|
+ (sal_uInt8)aReadSeq[2] * 0x10000
|
|
|
|
+ (sal_uInt8)aReadSeq[3] * 0x1000000;
|
|
|
|
|
|
|
|
aReadSeq.realloc( 32000 );
|
|
|
|
sal_uInt32 nRead = 0;
|
|
|
|
while ( nRead < nDataSize )
|
|
|
|
{
|
|
|
|
sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
|
|
|
|
sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
|
|
|
|
|
|
|
|
|
|
|
|
if ( !nLocalRead )
|
|
|
|
{
|
|
|
|
bFailed = sal_True;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if ( nLocalRead == 32000 )
|
|
|
|
xNativeOutTemp->writeBytes( aReadSeq );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
|
|
|
|
aToWrite.realloc( nLocalRead );
|
|
|
|
xNativeOutTemp->writeBytes( aToWrite );
|
|
|
|
}
|
|
|
|
|
|
|
|
nRead += nLocalRead;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uno::Sequence< sal_Int8 > aData( 8 );
|
|
|
|
if ( xInStream->readBytes( aData, 8 ) == 8
|
|
|
|
&& aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
|
|
|
|
&& ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
|
|
|
|
{
|
|
|
|
// the header has to be removed
|
|
|
|
xSeekable->seek( 40 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// the usual Ole10Native format
|
|
|
|
xSeekable->seek( 4 );
|
|
|
|
}
|
|
|
|
|
|
|
|
::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
|
|
|
|
}
|
|
|
|
|
|
|
|
xNativeOutTemp->closeOutput();
|
|
|
|
|
|
|
|
// The temporary native file is created, now the filter must be detected
|
|
|
|
if ( !bFailed )
|
|
|
|
{
|
2008-07-22 13:40:00 +00:00
|
|
|
m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
|
2005-01-18 14:11:10 +00:00
|
|
|
m_aNativeTempURL = aNativeTempURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !bFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
void OwnView_Impl::CreateNative()
|
|
|
|
{
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2012-11-02 17:46:30 +02:00
|
|
|
uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
|
2012-09-19 13:15:15 +02:00
|
|
|
ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
|
2005-01-18 14:11:10 +00:00
|
|
|
|
|
|
|
uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
|
|
|
|
if ( !xInStream.is() )
|
|
|
|
throw uno::RuntimeException();
|
|
|
|
|
|
|
|
uno::Sequence< uno::Any > aArgs( 1 );
|
|
|
|
aArgs[0] <<= xInStream;
|
|
|
|
uno::Reference< container::XNameAccess > xNameAccess(
|
|
|
|
m_xFactory->createInstanceWithArguments(
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString( "com.sun.star.embed.OLESimpleStorage" ),
|
2005-01-18 14:11:10 +00:00
|
|
|
aArgs ),
|
|
|
|
uno::UNO_QUERY_THROW );
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aSubStreamName = OUString( "\1Ole10Native" );
|
2005-01-18 14:11:10 +00:00
|
|
|
uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
|
|
|
|
uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
|
|
|
|
|
|
|
|
if ( xNameAccess->hasByName( aSubStreamName ) )
|
|
|
|
{
|
|
|
|
sal_uInt8 aClassID[] =
|
|
|
|
{ 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
|
|
|
|
uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
|
|
|
|
|
|
|
|
uno::Reference< io::XStream > xSubStream;
|
|
|
|
xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
|
|
|
|
if ( xSubStream.is() )
|
|
|
|
{
|
|
|
|
sal_Bool bOk = sal_False;
|
|
|
|
|
2007-07-06 09:11:27 +00:00
|
|
|
if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
// the storage represents Object Package
|
|
|
|
|
|
|
|
bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True );
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !bOk && !m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
KillFile_Impl( m_aNativeTempURL, m_xFactory );
|
2013-04-07 12:06:47 +02:00
|
|
|
m_aNativeTempURL = OUString();
|
2005-01-18 14:11:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !bOk )
|
|
|
|
{
|
|
|
|
bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False );
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !bOk && !m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
KillFile_Impl( m_aNativeTempURL, m_xFactory );
|
2013-04-07 12:06:47 +02:00
|
|
|
m_aNativeTempURL = OUString();
|
2005-01-18 14:11:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// TODO/LATER: No native stream, needs a new solution
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
sal_Bool OwnView_Impl::Open()
|
|
|
|
{
|
|
|
|
sal_Bool bResult = sal_False;
|
|
|
|
|
|
|
|
uno::Reference< frame::XModel > xExistingModel;
|
|
|
|
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
xExistingModel = m_xModel;
|
|
|
|
if ( m_bBusy )
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
m_bBusy = sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( xExistingModel.is() )
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
|
|
|
|
if ( xController.is() )
|
|
|
|
{
|
|
|
|
uno::Reference< frame::XFrame > xFrame = xController->getFrame();
|
|
|
|
if ( xFrame.is() )
|
|
|
|
{
|
|
|
|
xFrame->activate();
|
|
|
|
uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
|
|
|
|
if(xTopWindow.is())
|
|
|
|
xTopWindow->toFront();
|
|
|
|
|
|
|
|
bResult = sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bResult = CreateModel( m_bUseNative );
|
|
|
|
|
|
|
|
if ( !bResult && !m_bUseNative )
|
|
|
|
{
|
|
|
|
// the original storage can not be recognized
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
// create a temporary file for the native representation if there is no
|
|
|
|
CreateNative();
|
|
|
|
}
|
|
|
|
|
2011-12-21 19:54:11 -02:00
|
|
|
if ( !m_aNativeTempURL.isEmpty() )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
bResult = CreateModel( sal_True );
|
|
|
|
if ( bResult )
|
|
|
|
m_bUseNative = sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bBusy = sal_False;
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
void OwnView_Impl::Close()
|
|
|
|
{
|
|
|
|
uno::Reference< frame::XModel > xModel;
|
|
|
|
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
if ( !m_xModel.is() )
|
|
|
|
return;
|
|
|
|
xModel = m_xModel;
|
|
|
|
m_xModel = uno::Reference< frame::XModel >();
|
|
|
|
|
|
|
|
if ( m_bBusy )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_bBusy = sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xBroadCaster.is() )
|
|
|
|
xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
|
|
|
|
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xCloseable.is() )
|
|
|
|
{
|
|
|
|
xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
xCloseable->close( sal_True );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{}
|
|
|
|
|
|
|
|
m_bBusy = sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
|
|
|
|
throw ( uno::RuntimeException )
|
|
|
|
{
|
|
|
|
|
|
|
|
uno::Reference< frame::XModel > xModel;
|
|
|
|
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
2011-01-20 11:23:45 +01:00
|
|
|
if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnSaveAsDone" ) ) )
|
2005-01-18 14:11:10 +00:00
|
|
|
{
|
|
|
|
// SaveAs operation took place, so just forget the model and deregister listeners
|
|
|
|
xModel = m_xModel;
|
|
|
|
m_xModel = uno::Reference< frame::XModel >();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( xModel.is() )
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xBroadCaster.is() )
|
|
|
|
xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
|
|
|
|
uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
|
|
|
|
if ( xCloseable.is() )
|
|
|
|
xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
|
|
|
|
static_cast< ::cppu::OWeakObject* >( this ),
|
|
|
|
uno::UNO_QUERY ) );
|
|
|
|
}
|
|
|
|
catch( uno::Exception& )
|
|
|
|
{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2006-06-19 23:31:21 +00:00
|
|
|
void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
|
2005-01-18 14:11:10 +00:00
|
|
|
throw ( util::CloseVetoException,
|
|
|
|
uno::RuntimeException )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
|
|
|
|
throw ( uno::RuntimeException )
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
if ( Source.Source == m_xModel )
|
|
|
|
m_xModel = uno::Reference< frame::XModel >();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
|
|
|
|
throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
if ( Source.Source == m_xModel )
|
|
|
|
m_xModel = uno::Reference< frame::XModel >();
|
|
|
|
};
|
|
|
|
|
2010-10-12 15:53:47 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|