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