update dev300-m58
[ooovba.git] / embeddedobj / source / msole / ownview.cxx
blob2be4a3f9d4680192560d9d4805514f7f6e7c2c8d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ownview.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_embeddedobj.hxx"
33 #include <com/sun/star/frame/XFrame.hpp>
34 #include <com/sun/star/frame/XController.hpp>
35 #include <com/sun/star/frame/XComponentLoader.hpp>
36 #include <com/sun/star/awt/XTopWindow.hpp>
37 #include <com/sun/star/embed/XClassifiedObject.hpp>
38 #include <com/sun/star/io/XStream.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/io/XSeekable.hpp>
42 #include <com/sun/star/task/XInteractionHandler.hpp>
43 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
44 #include <com/sun/star/util/XCloseable.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
47 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBRODCASTER_HPP_
48 #include <com/sun/star/document/XEventBroadcaster.hpp>
49 #endif
50 #include <com/sun/star/document/XEventListener.hpp>
51 #include <com/sun/star/document/XTypeDetection.hpp>
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #include <cppuhelper/implbase1.hxx>
54 #include <comphelper/storagehelper.hxx>
55 #include <comphelper/mimeconfighelper.hxx>
57 #include "ownview.hxx"
60 using namespace ::com::sun::star;
61 using namespace ::comphelper;
63 ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
64 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
65 sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory );
66 uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw ( uno::Exception );
68 //========================================================
69 // Dummy interaction handler
70 //========================================================
71 //--------------------------------------------------------
72 class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
74 public:
75 DummyHandler_Impl() {}
76 ~DummyHandler_Impl();
78 virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
79 throw( uno::RuntimeException );
82 //--------------------------------------------------------
83 DummyHandler_Impl::~DummyHandler_Impl()
87 //--------------------------------------------------------
88 void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
89 throw( uno::RuntimeException )
91 return;
94 //========================================================
95 // Object viewer
96 //========================================================
97 //--------------------------------------------------------
98 OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
99 const uno::Reference< io::XInputStream >& xInputStream )
100 : m_xFactory( xFactory )
101 , m_bBusy( sal_False )
102 , m_bUseNative( sal_False )
104 if ( !xFactory.is() || !xInputStream.is() )
105 throw uno::RuntimeException();
107 m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
110 //--------------------------------------------------------
111 OwnView_Impl::~OwnView_Impl()
113 try {
114 KillFile_Impl( m_aTempFileURL, m_xFactory );
115 } catch( uno::Exception& ) {}
117 try {
118 if ( m_aNativeTempURL.getLength() )
119 KillFile_Impl( m_aNativeTempURL, m_xFactory );
120 } catch( uno::Exception& ) {}
123 //--------------------------------------------------------
124 sal_Bool OwnView_Impl::CreateModelFromURL( const ::rtl::OUString& aFileURL )
126 sal_Bool bResult = sal_False;
128 if ( aFileURL.getLength() )
130 try {
131 uno::Reference < frame::XComponentLoader > xDocumentLoader(
132 m_xFactory->createInstance (
133 ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
134 uno::UNO_QUERY );
136 if ( xDocumentLoader.is() )
138 uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.getLength() ? 5 : 4 );
140 aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
141 aArgs[0].Value <<= aFileURL;
143 aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
144 aArgs[1].Value <<= sal_True;
146 aArgs[2].Name = ::rtl::OUString::createFromAscii( "InteractionHandler" );
147 aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
148 static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
150 aArgs[3].Name = ::rtl::OUString::createFromAscii( "DontEdit" );
151 aArgs[3].Value <<= sal_True;
153 if ( m_aFilterName.getLength() )
155 aArgs[4].Name = ::rtl::OUString::createFromAscii( "FilterName" );
156 aArgs[4].Value <<= m_aFilterName;
159 uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
160 aFileURL,
161 ::rtl::OUString::createFromAscii( "_blank" ),
163 aArgs ),
164 uno::UNO_QUERY );
166 if ( xModel.is() )
168 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
169 if ( xBroadCaster.is() )
170 xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
171 static_cast< ::cppu::OWeakObject* >( this ),
172 uno::UNO_QUERY ) );
174 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
175 if ( xCloseable.is() )
177 xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
178 static_cast< ::cppu::OWeakObject* >( this ),
179 uno::UNO_QUERY ) );
181 ::osl::MutexGuard aGuard( m_aMutex );
182 m_xModel = xModel;
183 bResult = sal_True;
188 catch( uno::Exception& )
193 return bResult;
196 //--------------------------------------------------------
197 sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative )
199 sal_Bool bResult = sal_False;
201 try {
202 bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
204 catch( uno::Exception& )
208 return bResult;
211 //--------------------------------------------------------
212 ::rtl::OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
213 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
214 const ::rtl::OUString& aNameWithExtention,
215 const uno::Reference< io::XInputStream >& xInputStream )
217 if ( !xInputStream.is() )
218 throw uno::RuntimeException();
220 uno::Reference< document::XTypeDetection > xTypeDetection(
221 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
222 uno::UNO_QUERY_THROW );
224 ::rtl::OUString aTypeName;
226 if ( aNameWithExtention.getLength() )
228 ::rtl::OUString aURLToAnalyze =
229 ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///" ) ) + aNameWithExtention );
230 aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
233 uno::Sequence< beans::PropertyValue > aArgs( aTypeName.getLength() ? 3 : 2 );
234 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
235 aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
236 aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
237 aArgs[1].Value <<= xInputStream;
238 if ( aTypeName.getLength() )
240 aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TypeName" ) );
241 aArgs[2].Value <<= aTypeName;
244 aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
246 ::rtl::OUString aFilterName;
247 for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
248 if ( aArgs[nInd].Name.equalsAscii( "FilterName" ) )
249 aArgs[nInd].Value >>= aFilterName;
251 if ( !aFilterName.getLength() && aTypeName.getLength() )
253 // get the default filter name for the type
254 uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
255 uno::Sequence< beans::PropertyValue > aTypes;
257 if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
259 for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
261 if ( aTypes[nInd].Name.equalsAscii( "PreferredFilter" ) && ( aTypes[nInd].Value >>= aFilterName ) )
263 aTypes[nInd].Value >>= aFilterName;
264 break;
270 return aFilterName;
273 //--------------------------------------------------------
274 sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
275 sal_Bool bParseHeader )
277 uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
278 xSeekable->seek( 0 );
280 // create m_aNativeTempURL
281 ::rtl::OUString aNativeTempURL;
282 uno::Reference < beans::XPropertySet > xNativeTempFile(
283 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
284 uno::UNO_QUERY_THROW );
285 uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
286 uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
287 uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
288 if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
289 throw uno::RuntimeException();
291 try {
292 xNativeTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
293 uno::Any aUrl = xNativeTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
294 aUrl >>= aNativeTempURL;
296 catch ( uno::Exception& )
300 sal_Bool bFailed = sal_False;
301 ::rtl::OUString aFileSuffix;
303 if ( bParseHeader )
305 uno::Sequence< sal_Int8 > aReadSeq( 4 );
306 // read the complete size of the Object Package
307 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
308 return sal_False;
310 sal_uInt32 nLength = (sal_uInt8)aReadSeq[0]
311 + (sal_uInt8)aReadSeq[1] * 0x100
312 + (sal_uInt8)aReadSeq[2] * 0x10000
313 + (sal_uInt8)aReadSeq[3] * 0x1000000;
315 // read the first header ( have no idea what does this header mean )
316 if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
317 return sal_False;
319 // read file name
320 // only extension is interesting so only subset of symbols is accepted
323 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
324 return sal_False;
326 if (
327 (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
328 (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
329 (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
330 aReadSeq[0] == '.'
333 aFileSuffix += ::rtl::OUString::valueOf( (sal_Unicode) aReadSeq[0] );
336 } while( aReadSeq[0] );
338 // skip url
341 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
342 return sal_False;
343 } while( aReadSeq[0] );
345 // check the next header
346 if ( xInStream->readBytes( aReadSeq, 4 ) != 4
347 || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
348 return sal_False;
350 // get the size of the next entry
351 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
352 return sal_False;
354 sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
355 + (sal_uInt8)aReadSeq[1] * 0x100
356 + (sal_uInt8)aReadSeq[2] * 0x10000
357 + (sal_uInt8)aReadSeq[3] * 0x1000000;
358 sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
360 xSeekable->seek( nTargetPos );
362 // get the size of stored data
363 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
364 return sal_False;
366 sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
367 + (sal_uInt8)aReadSeq[1] * 0x100
368 + (sal_uInt8)aReadSeq[2] * 0x10000
369 + (sal_uInt8)aReadSeq[3] * 0x1000000;
371 aReadSeq.realloc( 32000 );
372 sal_uInt32 nRead = 0;
373 while ( nRead < nDataSize )
375 sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
376 sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
379 if ( !nLocalRead )
381 bFailed = sal_True;
382 break;
384 else if ( nLocalRead == 32000 )
385 xNativeOutTemp->writeBytes( aReadSeq );
386 else
388 uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
389 aToWrite.realloc( nLocalRead );
390 xNativeOutTemp->writeBytes( aToWrite );
393 nRead += nLocalRead;
396 else
398 uno::Sequence< sal_Int8 > aData( 8 );
399 if ( xInStream->readBytes( aData, 8 ) == 8
400 && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
401 && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
403 // the header has to be removed
404 xSeekable->seek( 40 );
406 else
408 // the usual Ole10Native format
409 xSeekable->seek( 4 );
412 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
415 xNativeOutTemp->closeOutput();
417 // The temporary native file is created, now the filter must be detected
418 if ( !bFailed )
420 m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
421 m_aNativeTempURL = aNativeTempURL;
424 return !bFailed;
427 //--------------------------------------------------------
428 void OwnView_Impl::CreateNative()
430 if ( m_aNativeTempURL.getLength() )
431 return;
435 uno::Reference < ucb::XSimpleFileAccess > xAccess(
436 m_xFactory->createInstance (
437 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
438 uno::UNO_QUERY_THROW );
440 uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
441 if ( !xInStream.is() )
442 throw uno::RuntimeException();
444 uno::Sequence< uno::Any > aArgs( 1 );
445 aArgs[0] <<= xInStream;
446 uno::Reference< container::XNameAccess > xNameAccess(
447 m_xFactory->createInstanceWithArguments(
448 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
449 aArgs ),
450 uno::UNO_QUERY_THROW );
452 ::rtl::OUString aSubStreamName = ::rtl::OUString::createFromAscii( "\1Ole10Native" );
453 uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
454 uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
456 if ( xNameAccess->hasByName( aSubStreamName ) )
458 sal_uInt8 aClassID[] =
459 { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
460 uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
462 uno::Reference< io::XStream > xSubStream;
463 xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
464 if ( xSubStream.is() )
466 sal_Bool bOk = sal_False;
468 if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
470 // the storage represents Object Package
472 bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True );
474 if ( !bOk && m_aNativeTempURL.getLength() )
476 KillFile_Impl( m_aNativeTempURL, m_xFactory );
477 m_aNativeTempURL = ::rtl::OUString();
481 if ( !bOk )
483 bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False );
485 if ( !bOk && m_aNativeTempURL.getLength() )
487 KillFile_Impl( m_aNativeTempURL, m_xFactory );
488 m_aNativeTempURL = ::rtl::OUString();
493 else
495 // TODO/LATER: No native stream, needs a new solution
498 catch( uno::Exception& )
502 //--------------------------------------------------------
503 sal_Bool OwnView_Impl::Open()
505 sal_Bool bResult = sal_False;
507 uno::Reference< frame::XModel > xExistingModel;
510 ::osl::MutexGuard aGuard( m_aMutex );
511 xExistingModel = m_xModel;
512 if ( m_bBusy )
513 return sal_False;
515 m_bBusy = sal_True;
518 if ( xExistingModel.is() )
520 try {
521 uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
522 if ( xController.is() )
524 uno::Reference< frame::XFrame > xFrame = xController->getFrame();
525 if ( xFrame.is() )
527 xFrame->activate();
528 uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
529 if(xTopWindow.is())
530 xTopWindow->toFront();
532 bResult = sal_True;
536 catch( uno::Exception& )
540 else
542 bResult = CreateModel( m_bUseNative );
544 if ( !bResult && !m_bUseNative )
546 // the original storage can not be recognized
547 if ( !m_aNativeTempURL.getLength() )
549 // create a temporary file for the native representation if there is no
550 CreateNative();
553 if ( m_aNativeTempURL.getLength() )
555 bResult = CreateModel( sal_True );
556 if ( bResult )
557 m_bUseNative = sal_True;
562 m_bBusy = sal_False;
564 return bResult;
567 //--------------------------------------------------------
568 void OwnView_Impl::Close()
570 uno::Reference< frame::XModel > xModel;
573 ::osl::MutexGuard aGuard( m_aMutex );
574 if ( !m_xModel.is() )
575 return;
576 xModel = m_xModel;
577 m_xModel = uno::Reference< frame::XModel >();
579 if ( m_bBusy )
580 return;
582 m_bBusy = sal_True;
585 try {
586 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
587 if ( xBroadCaster.is() )
588 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
589 static_cast< ::cppu::OWeakObject* >( this ),
590 uno::UNO_QUERY ) );
592 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
593 if ( xCloseable.is() )
595 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
596 static_cast< ::cppu::OWeakObject* >( this ),
597 uno::UNO_QUERY ) );
598 xCloseable->close( sal_True );
601 catch( uno::Exception& )
604 m_bBusy = sal_False;
607 //--------------------------------------------------------
608 void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
609 throw ( uno::RuntimeException )
612 uno::Reference< frame::XModel > xModel;
615 ::osl::MutexGuard aGuard( m_aMutex );
616 if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAscii( "OnSaveAsDone" ) )
618 // SaveAs operation took place, so just forget the model and deregister listeners
619 xModel = m_xModel;
620 m_xModel = uno::Reference< frame::XModel >();
624 if ( xModel.is() )
626 try {
627 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
628 if ( xBroadCaster.is() )
629 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
630 static_cast< ::cppu::OWeakObject* >( this ),
631 uno::UNO_QUERY ) );
633 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
634 if ( xCloseable.is() )
635 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
636 static_cast< ::cppu::OWeakObject* >( this ),
637 uno::UNO_QUERY ) );
639 catch( uno::Exception& )
644 //--------------------------------------------------------
645 void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
646 throw ( util::CloseVetoException,
647 uno::RuntimeException )
651 //--------------------------------------------------------
652 void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
653 throw ( uno::RuntimeException )
655 ::osl::MutexGuard aGuard( m_aMutex );
656 if ( Source.Source == m_xModel )
657 m_xModel = uno::Reference< frame::XModel >();
660 //--------------------------------------------------------
661 void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
662 throw (uno::RuntimeException)
664 ::osl::MutexGuard aGuard( m_aMutex );
665 if ( Source.Source == m_xModel )
666 m_xModel = uno::Reference< frame::XModel >();