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