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