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