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