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