1*bfd08df8SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*bfd08df8SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*bfd08df8SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*bfd08df8SAndrew Rist * distributed with this work for additional information
6*bfd08df8SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*bfd08df8SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*bfd08df8SAndrew Rist * "License"); you may not use this file except in compliance
9*bfd08df8SAndrew Rist * with the License. You may obtain a copy of the License at
10*bfd08df8SAndrew Rist *
11*bfd08df8SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*bfd08df8SAndrew Rist *
13*bfd08df8SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*bfd08df8SAndrew Rist * software distributed under the License is distributed on an
15*bfd08df8SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*bfd08df8SAndrew Rist * KIND, either express or implied. See the License for the
17*bfd08df8SAndrew Rist * specific language governing permissions and limitations
18*bfd08df8SAndrew Rist * under the License.
19*bfd08df8SAndrew Rist *
20*bfd08df8SAndrew Rist *************************************************************/
21*bfd08df8SAndrew Rist
22*bfd08df8SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_embeddedobj.hxx"
26cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
27cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp>
28cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
29cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindow.hpp>
30cdf0e10cSrcweir #include <com/sun/star/embed/XClassifiedObject.hpp>
31cdf0e10cSrcweir #include <com/sun/star/io/XStream.hpp>
32cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
33cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
34cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
35cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
36cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
37cdf0e10cSrcweir #include <com/sun/star/util/XCloseable.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBRODCASTER_HPP_
41cdf0e10cSrcweir #include <com/sun/star/document/XEventBroadcaster.hpp>
42cdf0e10cSrcweir #endif
43cdf0e10cSrcweir #include <com/sun/star/document/XEventListener.hpp>
44cdf0e10cSrcweir #include <com/sun/star/document/XTypeDetection.hpp>
45cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
46cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
47cdf0e10cSrcweir #include <comphelper/storagehelper.hxx>
48cdf0e10cSrcweir #include <comphelper/mimeconfighelper.hxx>
49cdf0e10cSrcweir
50cdf0e10cSrcweir #include "ownview.hxx"
51cdf0e10cSrcweir
52cdf0e10cSrcweir
53cdf0e10cSrcweir using namespace ::com::sun::star;
54cdf0e10cSrcweir using namespace ::comphelper;
55cdf0e10cSrcweir
56cdf0e10cSrcweir ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
57cdf0e10cSrcweir ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
58cdf0e10cSrcweir sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory );
59cdf0e10cSrcweir uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw ( uno::Exception );
60cdf0e10cSrcweir
61cdf0e10cSrcweir //========================================================
62cdf0e10cSrcweir // Dummy interaction handler
63cdf0e10cSrcweir //========================================================
64cdf0e10cSrcweir //--------------------------------------------------------
65cdf0e10cSrcweir class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
66cdf0e10cSrcweir {
67cdf0e10cSrcweir public:
DummyHandler_Impl()68cdf0e10cSrcweir DummyHandler_Impl() {}
69cdf0e10cSrcweir ~DummyHandler_Impl();
70cdf0e10cSrcweir
71cdf0e10cSrcweir virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
72cdf0e10cSrcweir throw( uno::RuntimeException );
73cdf0e10cSrcweir };
74cdf0e10cSrcweir
75cdf0e10cSrcweir //--------------------------------------------------------
~DummyHandler_Impl()76cdf0e10cSrcweir DummyHandler_Impl::~DummyHandler_Impl()
77cdf0e10cSrcweir {
78cdf0e10cSrcweir }
79cdf0e10cSrcweir
80cdf0e10cSrcweir //--------------------------------------------------------
handle(const uno::Reference<task::XInteractionRequest> &)81cdf0e10cSrcweir void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
82cdf0e10cSrcweir throw( uno::RuntimeException )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir return;
85cdf0e10cSrcweir }
86cdf0e10cSrcweir
87cdf0e10cSrcweir //========================================================
88cdf0e10cSrcweir // Object viewer
89cdf0e10cSrcweir //========================================================
90cdf0e10cSrcweir //--------------------------------------------------------
OwnView_Impl(const uno::Reference<lang::XMultiServiceFactory> & xFactory,const uno::Reference<io::XInputStream> & xInputStream)91cdf0e10cSrcweir OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
92cdf0e10cSrcweir const uno::Reference< io::XInputStream >& xInputStream )
93cdf0e10cSrcweir : m_xFactory( xFactory )
94cdf0e10cSrcweir , m_bBusy( sal_False )
95cdf0e10cSrcweir , m_bUseNative( sal_False )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir if ( !xFactory.is() || !xInputStream.is() )
98cdf0e10cSrcweir throw uno::RuntimeException();
99cdf0e10cSrcweir
100cdf0e10cSrcweir m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
101cdf0e10cSrcweir }
102cdf0e10cSrcweir
103cdf0e10cSrcweir //--------------------------------------------------------
~OwnView_Impl()104cdf0e10cSrcweir OwnView_Impl::~OwnView_Impl()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir try {
107cdf0e10cSrcweir KillFile_Impl( m_aTempFileURL, m_xFactory );
108cdf0e10cSrcweir } catch( uno::Exception& ) {}
109cdf0e10cSrcweir
110cdf0e10cSrcweir try {
111cdf0e10cSrcweir if ( m_aNativeTempURL.getLength() )
112cdf0e10cSrcweir KillFile_Impl( m_aNativeTempURL, m_xFactory );
113cdf0e10cSrcweir } catch( uno::Exception& ) {}
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
116cdf0e10cSrcweir //--------------------------------------------------------
CreateModelFromURL(const::rtl::OUString & aFileURL)117cdf0e10cSrcweir sal_Bool OwnView_Impl::CreateModelFromURL( const ::rtl::OUString& aFileURL )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir sal_Bool bResult = sal_False;
120cdf0e10cSrcweir
121cdf0e10cSrcweir if ( aFileURL.getLength() )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir try {
124cdf0e10cSrcweir uno::Reference < frame::XComponentLoader > xDocumentLoader(
125cdf0e10cSrcweir m_xFactory->createInstance (
126cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
127cdf0e10cSrcweir uno::UNO_QUERY );
128cdf0e10cSrcweir
129cdf0e10cSrcweir if ( xDocumentLoader.is() )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.getLength() ? 5 : 4 );
132cdf0e10cSrcweir
133cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
134cdf0e10cSrcweir aArgs[0].Value <<= aFileURL;
135cdf0e10cSrcweir
136cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
137cdf0e10cSrcweir aArgs[1].Value <<= sal_True;
138cdf0e10cSrcweir
139cdf0e10cSrcweir aArgs[2].Name = ::rtl::OUString::createFromAscii( "InteractionHandler" );
140cdf0e10cSrcweir aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
141cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
142cdf0e10cSrcweir
143cdf0e10cSrcweir aArgs[3].Name = ::rtl::OUString::createFromAscii( "DontEdit" );
144cdf0e10cSrcweir aArgs[3].Value <<= sal_True;
145cdf0e10cSrcweir
146cdf0e10cSrcweir if ( m_aFilterName.getLength() )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir aArgs[4].Name = ::rtl::OUString::createFromAscii( "FilterName" );
149cdf0e10cSrcweir aArgs[4].Value <<= m_aFilterName;
150cdf0e10cSrcweir }
151cdf0e10cSrcweir
152cdf0e10cSrcweir uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
153cdf0e10cSrcweir aFileURL,
154cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "_blank" ),
155cdf0e10cSrcweir 0,
156cdf0e10cSrcweir aArgs ),
157cdf0e10cSrcweir uno::UNO_QUERY );
158cdf0e10cSrcweir
159cdf0e10cSrcweir if ( xModel.is() )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
162cdf0e10cSrcweir if ( xBroadCaster.is() )
163cdf0e10cSrcweir xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
164cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
165cdf0e10cSrcweir uno::UNO_QUERY ) );
166cdf0e10cSrcweir
167cdf0e10cSrcweir uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
168cdf0e10cSrcweir if ( xCloseable.is() )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
171cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
172cdf0e10cSrcweir uno::UNO_QUERY ) );
173cdf0e10cSrcweir
174cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
175cdf0e10cSrcweir m_xModel = xModel;
176cdf0e10cSrcweir bResult = sal_True;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir }
179cdf0e10cSrcweir }
180cdf0e10cSrcweir }
181cdf0e10cSrcweir catch( uno::Exception& )
182cdf0e10cSrcweir {
183cdf0e10cSrcweir }
184cdf0e10cSrcweir }
185cdf0e10cSrcweir
186cdf0e10cSrcweir return bResult;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
189cdf0e10cSrcweir //--------------------------------------------------------
CreateModel(sal_Bool bUseNative)190cdf0e10cSrcweir sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir sal_Bool bResult = sal_False;
193cdf0e10cSrcweir
194cdf0e10cSrcweir try {
195cdf0e10cSrcweir bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
196cdf0e10cSrcweir }
197cdf0e10cSrcweir catch( uno::Exception& )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir }
200cdf0e10cSrcweir
201cdf0e10cSrcweir return bResult;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir
204cdf0e10cSrcweir //--------------------------------------------------------
GetFilterNameFromExtentionAndInStream(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & xFactory,const::rtl::OUString & aNameWithExtention,const uno::Reference<io::XInputStream> & xInputStream)205cdf0e10cSrcweir ::rtl::OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
206cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
207cdf0e10cSrcweir const ::rtl::OUString& aNameWithExtention,
208cdf0e10cSrcweir const uno::Reference< io::XInputStream >& xInputStream )
209cdf0e10cSrcweir {
210cdf0e10cSrcweir if ( !xInputStream.is() )
211cdf0e10cSrcweir throw uno::RuntimeException();
212cdf0e10cSrcweir
213cdf0e10cSrcweir uno::Reference< document::XTypeDetection > xTypeDetection(
214cdf0e10cSrcweir xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
215cdf0e10cSrcweir uno::UNO_QUERY_THROW );
216cdf0e10cSrcweir
217cdf0e10cSrcweir ::rtl::OUString aTypeName;
218cdf0e10cSrcweir
219cdf0e10cSrcweir if ( aNameWithExtention.getLength() )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir ::rtl::OUString aURLToAnalyze =
222cdf0e10cSrcweir ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///" ) ) + aNameWithExtention );
223cdf0e10cSrcweir aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
224cdf0e10cSrcweir }
225cdf0e10cSrcweir
226cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aArgs( aTypeName.getLength() ? 3 : 2 );
227cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
228cdf0e10cSrcweir aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
229cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
230cdf0e10cSrcweir aArgs[1].Value <<= xInputStream;
231cdf0e10cSrcweir if ( aTypeName.getLength() )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TypeName" ) );
234cdf0e10cSrcweir aArgs[2].Value <<= aTypeName;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
237cdf0e10cSrcweir aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
238cdf0e10cSrcweir
239cdf0e10cSrcweir ::rtl::OUString aFilterName;
240cdf0e10cSrcweir for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
241cdf0e10cSrcweir if ( aArgs[nInd].Name.equalsAscii( "FilterName" ) )
242cdf0e10cSrcweir aArgs[nInd].Value >>= aFilterName;
243cdf0e10cSrcweir
244cdf0e10cSrcweir if ( !aFilterName.getLength() && aTypeName.getLength() )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir // get the default filter name for the type
247cdf0e10cSrcweir uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
248cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aTypes;
249cdf0e10cSrcweir
250cdf0e10cSrcweir if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir if ( aTypes[nInd].Name.equalsAscii( "PreferredFilter" ) && ( aTypes[nInd].Value >>= aFilterName ) )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir aTypes[nInd].Value >>= aFilterName;
257cdf0e10cSrcweir break;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir }
260cdf0e10cSrcweir }
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir return aFilterName;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir //--------------------------------------------------------
ReadContentsAndGenerateTempFile(const uno::Reference<io::XInputStream> & xInStream,sal_Bool bParseHeader)267cdf0e10cSrcweir sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
268cdf0e10cSrcweir sal_Bool bParseHeader )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
271cdf0e10cSrcweir xSeekable->seek( 0 );
272cdf0e10cSrcweir
273cdf0e10cSrcweir // create m_aNativeTempURL
274cdf0e10cSrcweir ::rtl::OUString aNativeTempURL;
275cdf0e10cSrcweir uno::Reference < beans::XPropertySet > xNativeTempFile(
276cdf0e10cSrcweir m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
277cdf0e10cSrcweir uno::UNO_QUERY_THROW );
278cdf0e10cSrcweir uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
279cdf0e10cSrcweir uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
280cdf0e10cSrcweir uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
281cdf0e10cSrcweir if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
282cdf0e10cSrcweir throw uno::RuntimeException();
283cdf0e10cSrcweir
284cdf0e10cSrcweir try {
285cdf0e10cSrcweir xNativeTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
286cdf0e10cSrcweir uno::Any aUrl = xNativeTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
287cdf0e10cSrcweir aUrl >>= aNativeTempURL;
288cdf0e10cSrcweir }
289cdf0e10cSrcweir catch ( uno::Exception& )
290cdf0e10cSrcweir {
291cdf0e10cSrcweir }
292cdf0e10cSrcweir
293cdf0e10cSrcweir sal_Bool bFailed = sal_False;
294cdf0e10cSrcweir ::rtl::OUString aFileSuffix;
295cdf0e10cSrcweir
296cdf0e10cSrcweir if ( bParseHeader )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir uno::Sequence< sal_Int8 > aReadSeq( 4 );
299cdf0e10cSrcweir // read the complete size of the Object Package
300cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
301cdf0e10cSrcweir return sal_False;
302cdf0e10cSrcweir /*
303cdf0e10cSrcweir sal_uInt32 nLength = (sal_uInt8)aReadSeq[0]
304cdf0e10cSrcweir + (sal_uInt8)aReadSeq[1] * 0x100
305cdf0e10cSrcweir + (sal_uInt8)aReadSeq[2] * 0x10000
306cdf0e10cSrcweir + (sal_uInt8)aReadSeq[3] * 0x1000000;
307cdf0e10cSrcweir */
308cdf0e10cSrcweir // read the first header ( have no idea what does this header mean )
309cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
310cdf0e10cSrcweir return sal_False;
311cdf0e10cSrcweir
312cdf0e10cSrcweir // read file name
313cdf0e10cSrcweir // only extension is interesting so only subset of symbols is accepted
314cdf0e10cSrcweir do
315cdf0e10cSrcweir {
316cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
317cdf0e10cSrcweir return sal_False;
318cdf0e10cSrcweir
319cdf0e10cSrcweir if (
320cdf0e10cSrcweir (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
321cdf0e10cSrcweir (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
322cdf0e10cSrcweir (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
323cdf0e10cSrcweir aReadSeq[0] == '.'
324cdf0e10cSrcweir )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir aFileSuffix += ::rtl::OUString::valueOf( (sal_Unicode) aReadSeq[0] );
327cdf0e10cSrcweir }
328cdf0e10cSrcweir
329cdf0e10cSrcweir } while( aReadSeq[0] );
330cdf0e10cSrcweir
331cdf0e10cSrcweir // skip url
332cdf0e10cSrcweir do
333cdf0e10cSrcweir {
334cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
335cdf0e10cSrcweir return sal_False;
336cdf0e10cSrcweir } while( aReadSeq[0] );
337cdf0e10cSrcweir
338cdf0e10cSrcweir // check the next header
339cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 4 ) != 4
340cdf0e10cSrcweir || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
341cdf0e10cSrcweir return sal_False;
342cdf0e10cSrcweir
343cdf0e10cSrcweir // get the size of the next entry
344cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
345cdf0e10cSrcweir return sal_False;
346cdf0e10cSrcweir
347cdf0e10cSrcweir sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
348cdf0e10cSrcweir + (sal_uInt8)aReadSeq[1] * 0x100
349cdf0e10cSrcweir + (sal_uInt8)aReadSeq[2] * 0x10000
350cdf0e10cSrcweir + (sal_uInt8)aReadSeq[3] * 0x1000000;
351cdf0e10cSrcweir sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
352cdf0e10cSrcweir
353cdf0e10cSrcweir xSeekable->seek( nTargetPos );
354cdf0e10cSrcweir
355cdf0e10cSrcweir // get the size of stored data
356cdf0e10cSrcweir if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
357cdf0e10cSrcweir return sal_False;
358cdf0e10cSrcweir
359cdf0e10cSrcweir sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
360cdf0e10cSrcweir + (sal_uInt8)aReadSeq[1] * 0x100
361cdf0e10cSrcweir + (sal_uInt8)aReadSeq[2] * 0x10000
362cdf0e10cSrcweir + (sal_uInt8)aReadSeq[3] * 0x1000000;
363cdf0e10cSrcweir
364cdf0e10cSrcweir aReadSeq.realloc( 32000 );
365cdf0e10cSrcweir sal_uInt32 nRead = 0;
366cdf0e10cSrcweir while ( nRead < nDataSize )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
369cdf0e10cSrcweir sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
370cdf0e10cSrcweir
371cdf0e10cSrcweir
372cdf0e10cSrcweir if ( !nLocalRead )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir bFailed = sal_True;
375cdf0e10cSrcweir break;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir else if ( nLocalRead == 32000 )
378cdf0e10cSrcweir xNativeOutTemp->writeBytes( aReadSeq );
379cdf0e10cSrcweir else
380cdf0e10cSrcweir {
381cdf0e10cSrcweir uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
382cdf0e10cSrcweir aToWrite.realloc( nLocalRead );
383cdf0e10cSrcweir xNativeOutTemp->writeBytes( aToWrite );
384cdf0e10cSrcweir }
385cdf0e10cSrcweir
386cdf0e10cSrcweir nRead += nLocalRead;
387cdf0e10cSrcweir }
388cdf0e10cSrcweir }
389cdf0e10cSrcweir else
390cdf0e10cSrcweir {
391cdf0e10cSrcweir uno::Sequence< sal_Int8 > aData( 8 );
392cdf0e10cSrcweir if ( xInStream->readBytes( aData, 8 ) == 8
393cdf0e10cSrcweir && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
394cdf0e10cSrcweir && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir // the header has to be removed
397cdf0e10cSrcweir xSeekable->seek( 40 );
398cdf0e10cSrcweir }
399cdf0e10cSrcweir else
400cdf0e10cSrcweir {
401cdf0e10cSrcweir // the usual Ole10Native format
402cdf0e10cSrcweir xSeekable->seek( 4 );
403cdf0e10cSrcweir }
404cdf0e10cSrcweir
405cdf0e10cSrcweir ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
406cdf0e10cSrcweir }
407cdf0e10cSrcweir
408cdf0e10cSrcweir xNativeOutTemp->closeOutput();
409cdf0e10cSrcweir
410cdf0e10cSrcweir // The temporary native file is created, now the filter must be detected
411cdf0e10cSrcweir if ( !bFailed )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
414cdf0e10cSrcweir m_aNativeTempURL = aNativeTempURL;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir
417cdf0e10cSrcweir return !bFailed;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir
420cdf0e10cSrcweir //--------------------------------------------------------
CreateNative()421cdf0e10cSrcweir void OwnView_Impl::CreateNative()
422cdf0e10cSrcweir {
423cdf0e10cSrcweir if ( m_aNativeTempURL.getLength() )
424cdf0e10cSrcweir return;
425cdf0e10cSrcweir
426cdf0e10cSrcweir try
427cdf0e10cSrcweir {
428cdf0e10cSrcweir uno::Reference < ucb::XSimpleFileAccess > xAccess(
429cdf0e10cSrcweir m_xFactory->createInstance (
430cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
431cdf0e10cSrcweir uno::UNO_QUERY_THROW );
432cdf0e10cSrcweir
433cdf0e10cSrcweir uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
434cdf0e10cSrcweir if ( !xInStream.is() )
435cdf0e10cSrcweir throw uno::RuntimeException();
436cdf0e10cSrcweir
437cdf0e10cSrcweir uno::Sequence< uno::Any > aArgs( 1 );
438cdf0e10cSrcweir aArgs[0] <<= xInStream;
439cdf0e10cSrcweir uno::Reference< container::XNameAccess > xNameAccess(
440cdf0e10cSrcweir m_xFactory->createInstanceWithArguments(
441cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
442cdf0e10cSrcweir aArgs ),
443cdf0e10cSrcweir uno::UNO_QUERY_THROW );
444cdf0e10cSrcweir
445cdf0e10cSrcweir ::rtl::OUString aSubStreamName = ::rtl::OUString::createFromAscii( "\1Ole10Native" );
446cdf0e10cSrcweir uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
447cdf0e10cSrcweir uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
448cdf0e10cSrcweir
449cdf0e10cSrcweir if ( xNameAccess->hasByName( aSubStreamName ) )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir sal_uInt8 aClassID[] =
452cdf0e10cSrcweir { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
453cdf0e10cSrcweir uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
454cdf0e10cSrcweir
455cdf0e10cSrcweir uno::Reference< io::XStream > xSubStream;
456cdf0e10cSrcweir xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
457cdf0e10cSrcweir if ( xSubStream.is() )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir sal_Bool bOk = sal_False;
460cdf0e10cSrcweir
461cdf0e10cSrcweir if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir // the storage represents Object Package
464cdf0e10cSrcweir
465cdf0e10cSrcweir bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True );
466cdf0e10cSrcweir
467cdf0e10cSrcweir if ( !bOk && m_aNativeTempURL.getLength() )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir KillFile_Impl( m_aNativeTempURL, m_xFactory );
470cdf0e10cSrcweir m_aNativeTempURL = ::rtl::OUString();
471cdf0e10cSrcweir }
472cdf0e10cSrcweir }
473cdf0e10cSrcweir
474cdf0e10cSrcweir if ( !bOk )
475cdf0e10cSrcweir {
476cdf0e10cSrcweir bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False );
477cdf0e10cSrcweir
478cdf0e10cSrcweir if ( !bOk && m_aNativeTempURL.getLength() )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir KillFile_Impl( m_aNativeTempURL, m_xFactory );
481cdf0e10cSrcweir m_aNativeTempURL = ::rtl::OUString();
482cdf0e10cSrcweir }
483cdf0e10cSrcweir }
484cdf0e10cSrcweir }
485cdf0e10cSrcweir }
486cdf0e10cSrcweir else
487cdf0e10cSrcweir {
488cdf0e10cSrcweir // TODO/LATER: No native stream, needs a new solution
489cdf0e10cSrcweir }
490cdf0e10cSrcweir }
491cdf0e10cSrcweir catch( uno::Exception& )
492cdf0e10cSrcweir {}
493cdf0e10cSrcweir }
494cdf0e10cSrcweir
495cdf0e10cSrcweir //--------------------------------------------------------
Open()496cdf0e10cSrcweir sal_Bool OwnView_Impl::Open()
497cdf0e10cSrcweir {
498cdf0e10cSrcweir sal_Bool bResult = sal_False;
499cdf0e10cSrcweir
500cdf0e10cSrcweir uno::Reference< frame::XModel > xExistingModel;
501cdf0e10cSrcweir
502cdf0e10cSrcweir {
503cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
504cdf0e10cSrcweir xExistingModel = m_xModel;
505cdf0e10cSrcweir if ( m_bBusy )
506cdf0e10cSrcweir return sal_False;
507cdf0e10cSrcweir
508cdf0e10cSrcweir m_bBusy = sal_True;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511cdf0e10cSrcweir if ( xExistingModel.is() )
512cdf0e10cSrcweir {
513cdf0e10cSrcweir try {
514cdf0e10cSrcweir uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
515cdf0e10cSrcweir if ( xController.is() )
516cdf0e10cSrcweir {
517cdf0e10cSrcweir uno::Reference< frame::XFrame > xFrame = xController->getFrame();
518cdf0e10cSrcweir if ( xFrame.is() )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir xFrame->activate();
521cdf0e10cSrcweir uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
522cdf0e10cSrcweir if(xTopWindow.is())
523cdf0e10cSrcweir xTopWindow->toFront();
524cdf0e10cSrcweir
525cdf0e10cSrcweir bResult = sal_True;
526cdf0e10cSrcweir }
527cdf0e10cSrcweir }
528cdf0e10cSrcweir }
529cdf0e10cSrcweir catch( uno::Exception& )
530cdf0e10cSrcweir {
531cdf0e10cSrcweir }
532cdf0e10cSrcweir }
533cdf0e10cSrcweir else
534cdf0e10cSrcweir {
535cdf0e10cSrcweir bResult = CreateModel( m_bUseNative );
536cdf0e10cSrcweir
537cdf0e10cSrcweir if ( !bResult && !m_bUseNative )
538cdf0e10cSrcweir {
539cdf0e10cSrcweir // the original storage can not be recognized
540cdf0e10cSrcweir if ( !m_aNativeTempURL.getLength() )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir // create a temporary file for the native representation if there is no
543cdf0e10cSrcweir CreateNative();
544cdf0e10cSrcweir }
545cdf0e10cSrcweir
546cdf0e10cSrcweir if ( m_aNativeTempURL.getLength() )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir bResult = CreateModel( sal_True );
549cdf0e10cSrcweir if ( bResult )
550cdf0e10cSrcweir m_bUseNative = sal_True;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir }
553cdf0e10cSrcweir }
554cdf0e10cSrcweir
555cdf0e10cSrcweir m_bBusy = sal_False;
556cdf0e10cSrcweir
557cdf0e10cSrcweir return bResult;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir
560cdf0e10cSrcweir //--------------------------------------------------------
Close()561cdf0e10cSrcweir void OwnView_Impl::Close()
562cdf0e10cSrcweir {
563cdf0e10cSrcweir uno::Reference< frame::XModel > xModel;
564cdf0e10cSrcweir
565cdf0e10cSrcweir {
566cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
567cdf0e10cSrcweir if ( !m_xModel.is() )
568cdf0e10cSrcweir return;
569cdf0e10cSrcweir xModel = m_xModel;
570cdf0e10cSrcweir m_xModel = uno::Reference< frame::XModel >();
571cdf0e10cSrcweir
572cdf0e10cSrcweir if ( m_bBusy )
573cdf0e10cSrcweir return;
574cdf0e10cSrcweir
575cdf0e10cSrcweir m_bBusy = sal_True;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir
578cdf0e10cSrcweir try {
579cdf0e10cSrcweir uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
580cdf0e10cSrcweir if ( xBroadCaster.is() )
581cdf0e10cSrcweir xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
582cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
583cdf0e10cSrcweir uno::UNO_QUERY ) );
584cdf0e10cSrcweir
585cdf0e10cSrcweir uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
586cdf0e10cSrcweir if ( xCloseable.is() )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
589cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
590cdf0e10cSrcweir uno::UNO_QUERY ) );
591cdf0e10cSrcweir xCloseable->close( sal_True );
592cdf0e10cSrcweir }
593cdf0e10cSrcweir }
594cdf0e10cSrcweir catch( uno::Exception& )
595cdf0e10cSrcweir {}
596cdf0e10cSrcweir
597cdf0e10cSrcweir m_bBusy = sal_False;
598cdf0e10cSrcweir }
599cdf0e10cSrcweir
600cdf0e10cSrcweir //--------------------------------------------------------
notifyEvent(const document::EventObject & aEvent)601cdf0e10cSrcweir void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
602cdf0e10cSrcweir throw ( uno::RuntimeException )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir
605cdf0e10cSrcweir uno::Reference< frame::XModel > xModel;
606cdf0e10cSrcweir
607cdf0e10cSrcweir {
608cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
609cdf0e10cSrcweir if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAscii( "OnSaveAsDone" ) )
610cdf0e10cSrcweir {
611cdf0e10cSrcweir // SaveAs operation took place, so just forget the model and deregister listeners
612cdf0e10cSrcweir xModel = m_xModel;
613cdf0e10cSrcweir m_xModel = uno::Reference< frame::XModel >();
614cdf0e10cSrcweir }
615cdf0e10cSrcweir }
616cdf0e10cSrcweir
617cdf0e10cSrcweir if ( xModel.is() )
618cdf0e10cSrcweir {
619cdf0e10cSrcweir try {
620cdf0e10cSrcweir uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
621cdf0e10cSrcweir if ( xBroadCaster.is() )
622cdf0e10cSrcweir xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
623cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
624cdf0e10cSrcweir uno::UNO_QUERY ) );
625cdf0e10cSrcweir
626cdf0e10cSrcweir uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
627cdf0e10cSrcweir if ( xCloseable.is() )
628cdf0e10cSrcweir xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
629cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >( this ),
630cdf0e10cSrcweir uno::UNO_QUERY ) );
631cdf0e10cSrcweir }
632cdf0e10cSrcweir catch( uno::Exception& )
633cdf0e10cSrcweir {}
634cdf0e10cSrcweir }
635cdf0e10cSrcweir }
636cdf0e10cSrcweir
637cdf0e10cSrcweir //--------------------------------------------------------
queryClosing(const lang::EventObject &,sal_Bool)638cdf0e10cSrcweir void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
639cdf0e10cSrcweir throw ( util::CloseVetoException,
640cdf0e10cSrcweir uno::RuntimeException )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir //--------------------------------------------------------
notifyClosing(const lang::EventObject & Source)645cdf0e10cSrcweir void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
646cdf0e10cSrcweir throw ( uno::RuntimeException )
647cdf0e10cSrcweir {
648cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
649cdf0e10cSrcweir if ( Source.Source == m_xModel )
650cdf0e10cSrcweir m_xModel = uno::Reference< frame::XModel >();
651cdf0e10cSrcweir }
652cdf0e10cSrcweir
653cdf0e10cSrcweir //--------------------------------------------------------
disposing(const lang::EventObject & Source)654cdf0e10cSrcweir void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
655cdf0e10cSrcweir throw (uno::RuntimeException)
656cdf0e10cSrcweir {
657cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
658cdf0e10cSrcweir if ( Source.Source == m_xModel )
659cdf0e10cSrcweir m_xModel = uno::Reference< frame::XModel >();
660cdf0e10cSrcweir };
661cdf0e10cSrcweir
662