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