xref: /AOO41X/main/embeddedobj/source/msole/ownview.cxx (revision bfd08df8d53be340829eb05b5154718deb4e1b3d)
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