text: /**************************************************************
   * 
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   * 
   *************************************************************/
  
  
  
  // MARKER(update_precomp.py): autogen include statement, do not remove
  #include "precompiled_embeddedobj.hxx"
  #include <com/sun/star/frame/XFrame.hpp>
  #include <com/sun/star/frame/XController.hpp>
  #include <com/sun/star/frame/XComponentLoader.hpp>
  #include <com/sun/star/awt/XTopWindow.hpp>
  #include <com/sun/star/embed/XClassifiedObject.hpp>
  #include <com/sun/star/io/XStream.hpp>
  #include <com/sun/star/io/XInputStream.hpp>
  #include <com/sun/star/io/XOutputStream.hpp>
  #include <com/sun/star/io/XSeekable.hpp>
  #include <com/sun/star/task/XInteractionHandler.hpp>
  #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
  #include <com/sun/star/util/XCloseable.hpp>
  #include <com/sun/star/beans/XPropertySet.hpp>
  
  #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBRODCASTER_HPP_
  #include <com/sun/star/document/XEventBroadcaster.hpp>
  #endif
  #include <com/sun/star/document/XEventListener.hpp>
  #include <com/sun/star/document/XTypeDetection.hpp>
  #include <com/sun/star/container/XNameAccess.hpp>
  #include <cppuhelper/implbase1.hxx>
  #include <comphelper/storagehelper.hxx>
  #include <comphelper/mimeconfighelper.hxx>
  
  #include "ownview.hxx"
  
  
  using namespace ::com::sun::star;
  using namespace ::comphelper;
  
  ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
  ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw( io::IOException );
  sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory );
  uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) throw ( uno::Exception );
  
  //========================================================
  // Dummy interaction handler
  //========================================================
  //--------------------------------------------------------
  class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
  {
  public:
  	DummyHandler_Impl() {}
  	~DummyHandler_Impl();
  
  	virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
  			throw( uno::RuntimeException );
  };
  
  //--------------------------------------------------------
  DummyHandler_Impl::~DummyHandler_Impl()
  {
  }
  
  //--------------------------------------------------------
  void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
  		throw( uno::RuntimeException )
  {
  	return;
  }
  
  //========================================================
  // Object viewer
  //========================================================
  //--------------------------------------------------------
  OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
  							const uno::Reference< io::XInputStream >& xInputStream )
  : m_xFactory( xFactory )
  , m_bBusy( sal_False )
  , m_bUseNative( sal_False )
  {
  	if ( !xFactory.is() || !xInputStream.is() )
  		throw uno::RuntimeException();
  
  	m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
  }
  
  //--------------------------------------------------------
  OwnView_Impl::~OwnView_Impl()
  {
  	try {
  		KillFile_Impl( m_aTempFileURL, m_xFactory );
  	} catch( uno::Exception& ) {}
  
  	try {
  		if ( m_aNativeTempURL.getLength() )
  			KillFile_Impl( m_aNativeTempURL, m_xFactory );
  	} catch( uno::Exception& ) {}
  }
  
  //--------------------------------------------------------
  sal_Bool OwnView_Impl::CreateModelFromURL( const ::rtl::OUString& aFileURL )
  {
  	sal_Bool bResult = sal_False;
  
  	if ( aFileURL.getLength() )
  	{
  		try {
  			uno::Reference < frame::XComponentLoader > xDocumentLoader( 
  							m_xFactory->createInstance ( 
  										::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
  							uno::UNO_QUERY );
  
  			if ( xDocumentLoader.is() )
  			{
  				uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.getLength() ? 5 : 4 );
  	
  				aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
  				aArgs[0].Value <<= aFileURL;
  	
  				aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
  				aArgs[1].Value <<= sal_True;
  	
  				aArgs[2].Name = ::rtl::OUString::createFromAscii( "InteractionHandler" );
  				aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
  									static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
  
  				aArgs[3].Name = ::rtl::OUString::createFromAscii( "DontEdit" );
  				aArgs[3].Value <<= sal_True;
  				
  				if ( m_aFilterName.getLength() )
  				{
  					aArgs[4].Name = ::rtl::OUString::createFromAscii( "FilterName" );
  					aArgs[4].Value <<= m_aFilterName;
  				}
  
  				uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
  																aFileURL,
  																::rtl::OUString::createFromAscii( "_blank" ),
  																0,
  																aArgs ),
  															uno::UNO_QUERY );
  	
  				if ( xModel.is() )
  				{
  					uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
  					if ( xBroadCaster.is() )
  						xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
  																static_cast< ::cppu::OWeakObject* >( this ),
  									 							uno::UNO_QUERY ) );
  	
  					uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
  					if ( xCloseable.is() )
  					{
  						xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
  																		static_cast< ::cppu::OWeakObject* >( this ),
  										  								uno::UNO_QUERY ) );
  	
  						::osl::MutexGuard aGuard( m_aMutex );
  						m_xModel = xModel;	
  						bResult = sal_True;
  					}
  				}
  			}
  		}
  		catch( uno::Exception& )
  		{
  		}
  	}
  
  	return bResult;
  }
  
  //--------------------------------------------------------
  sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative )
  {
  	sal_Bool bResult = sal_False;
  
  	try {
  		bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
  	}
  	catch( uno::Exception& )
  	{
  	}
  
  	return bResult;
  }
  
  //--------------------------------------------------------
  ::rtl::OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
                                                      const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
                                                      const ::rtl::OUString& aNameWithExtention,
                                                      const uno::Reference< io::XInputStream >& xInputStream )
  {
  	if ( !xInputStream.is() )
  		throw uno::RuntimeException();
  
  	uno::Reference< document::XTypeDetection > xTypeDetection(
  			xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
  			uno::UNO_QUERY_THROW );
  
  	::rtl::OUString aTypeName;
  
  	if ( aNameWithExtention.getLength() )
  	{
  		::rtl::OUString aURLToAnalyze =
  				( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///" ) ) + aNameWithExtention );
  		aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
  	}
  
  	uno::Sequence< beans::PropertyValue > aArgs( aTypeName.getLength() ? 3 : 2 );
  	aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
  	aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
  	aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
  	aArgs[1].Value <<= xInputStream;
  	if ( aTypeName.getLength() )
  	{
  		aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TypeName" ) );
  		aArgs[2].Value <<= aTypeName;
  	}
  
  	aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
  
  	::rtl::OUString aFilterName;
  	for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
  		if ( aArgs[nInd].Name.equalsAscii( "FilterName" ) )
  			aArgs[nInd].Value >>= aFilterName;
  
  	if ( !aFilterName.getLength() && aTypeName.getLength() )
  	{
  		// get the default filter name for the type
  		uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
  		uno::Sequence< beans::PropertyValue > aTypes;
  
  		if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
  		{
  			for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
  			{
  				if ( aTypes[nInd].Name.equalsAscii( "PreferredFilter" ) && ( aTypes[nInd].Value >>= aFilterName ) )
  				{
  					aTypes[nInd].Value >>= aFilterName;
  					break;
  				}
  			}
  		}
  	}
  
  	return aFilterName;
  }
  
  //--------------------------------------------------------
  sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
  														sal_Bool bParseHeader )
  {
  	uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
  	xSeekable->seek( 0 );
  
  	// create m_aNativeTempURL
  	::rtl::OUString aNativeTempURL;
  	uno::Reference < beans::XPropertySet > xNativeTempFile(
  			m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
  			uno::UNO_QUERY_THROW );
  	uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
  	uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
  	uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
  	if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
  		throw uno::RuntimeException();
  
  	try {
  		xNativeTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
  		uno::Any aUrl = xNativeTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
  		aUrl >>= aNativeTempURL;
  	}
  	catch ( uno::Exception& )
  	{
  	}
  
  	sal_Bool bFailed = sal_False;
  	::rtl::OUString aFileSuffix;
  
  	if ( bParseHeader )
  	{
  		uno::Sequence< sal_Int8 > aReadSeq( 4 );
  		// read the complete size of the Object Package
  		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
  			return sal_False;
  /*
  		sal_uInt32 nLength = (sal_uInt8)aReadSeq[0]
  							+ (sal_uInt8)aReadSeq[1] * 0x100
  							+ (sal_uInt8)aReadSeq[2] * 0x10000
  							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
  */
  		// read the first header ( have no idea what does this header mean )
  		if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
  			return sal_False;
  
  		// read file name
  		// only extension is interesting so only subset of symbols is accepted
  		do
  		{
  			if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
  				return sal_False;
  
  			if (
                  (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
                  (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
                  (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
                  aReadSeq[0] == '.' 
                 )
              {
  				aFileSuffix += ::rtl::OUString::valueOf( (sal_Unicode) aReadSeq[0] );
              }
  
  		} while( aReadSeq[0] );
  
  		// skip url
  		do
  		{
  			if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
  				return sal_False;
  		} while( aReadSeq[0] );
  
  		// check the next header
  		if ( xInStream->readBytes( aReadSeq, 4 ) != 4
  	  	|| aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
  			return sal_False;
  
  		// get the size of the next entry
  		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
  			return sal_False;
  
  		sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
  							+ (sal_uInt8)aReadSeq[1] * 0x100
  							+ (sal_uInt8)aReadSeq[2] * 0x10000
  							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
  		sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
  
  		xSeekable->seek( nTargetPos );
  	
  		// get the size of stored data
  		if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
  			return sal_False;
  
  		sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
  							+ (sal_uInt8)aReadSeq[1] * 0x100
  							+ (sal_uInt8)aReadSeq[2] * 0x10000
  							+ (sal_uInt8)aReadSeq[3] * 0x1000000;
  
  		aReadSeq.realloc( 32000 );
  		sal_uInt32 nRead = 0;
  		while ( nRead < nDataSize )
  		{
  			sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
  			sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
  			
  	
  			if ( !nLocalRead )
  			{
  				bFailed = sal_True;
  				break;
  			}
  			else if ( nLocalRead == 32000 )
  				xNativeOutTemp->writeBytes( aReadSeq );
  			else
  			{
  				uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
  				aToWrite.realloc( nLocalRead );
  				xNativeOutTemp->writeBytes( aToWrite );
  			}
  	
  			nRead += nLocalRead;
  		}
  	}
  	else
  	{
  		uno::Sequence< sal_Int8 > aData( 8 );
  		if ( xInStream->readBytes( aData, 8 ) == 8
  		  && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
  		  && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
  		{
  			// the header has to be removed
  			xSeekable->seek( 40 );
  		}
  		else
  		{
  			// the usual Ole10Native format
  			xSeekable->seek( 4 );
  		}
  
  		::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
  	}
  	
  	xNativeOutTemp->closeOutput();
  
  	// The temporary native file is created, now the filter must be detected
  	if ( !bFailed )
  	{
  		m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
  		m_aNativeTempURL = aNativeTempURL;
  	}
  
  	return !bFailed;
  }
  
  //--------------------------------------------------------
  void OwnView_Impl::CreateNative()
  {
  	if ( m_aNativeTempURL.getLength() )
  		return;
  
  	try
  	{
  		uno::Reference < ucb::XSimpleFileAccess > xAccess(
  				m_xFactory->createInstance (
  						::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
  				uno::UNO_QUERY_THROW );
  
  		uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
  		if ( !xInStream.is() )
  			throw uno::RuntimeException();
  
  		uno::Sequence< uno::Any > aArgs( 1 );
  		aArgs[0] <<= xInStream;
  		uno::Reference< container::XNameAccess > xNameAccess(
  				m_xFactory->createInstanceWithArguments( 
  						::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
  						aArgs ),
  				uno::UNO_QUERY_THROW );
  
  		::rtl::OUString aSubStreamName = ::rtl::OUString::createFromAscii( "\1Ole10Native" );
  		uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
  		uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
  
  		if ( xNameAccess->hasByName( aSubStreamName ) )
  		{
  			sal_uInt8 aClassID[] =
  				{ 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
  			uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
  
  			uno::Reference< io::XStream > xSubStream;
  			xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
  			if ( xSubStream.is() )
  			{
  				sal_Bool bOk = sal_False;
  
  				if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
  				{
  					// the storage represents Object Package
  	
  					bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True );
  
  					if ( !bOk && m_aNativeTempURL.getLength() )
  					{
  						KillFile_Impl( m_aNativeTempURL, m_xFactory );
  						m_aNativeTempURL = ::rtl::OUString();
  					}
  				}
  
  				if ( !bOk )
  				{
  					bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False );
  
  					if ( !bOk && m_aNativeTempURL.getLength() )
  					{
  						KillFile_Impl( m_aNativeTempURL, m_xFactory );
  						m_aNativeTempURL = ::rtl::OUString();
  					}
  				}
  			}
  		}
  		else
  		{
  			// TODO/LATER: No native stream, needs a new solution
  		}
  	}
  	catch( uno::Exception& )
  	{}
  }
  
  //--------------------------------------------------------
  sal_Bool OwnView_Impl::Open()
  {
  	sal_Bool bResult = sal_False;
  
  	uno::Reference< frame::XModel > xExistingModel;
  
  	{
  		::osl::MutexGuard aGuard( m_aMutex );
  		xExistingModel = m_xModel;
  		if ( m_bBusy )
  			return sal_False;
  
  		m_bBusy = sal_True;
  	}
  
  	if ( xExistingModel.is() )
  	{
  		try {
  			uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
  			if ( xController.is() )
  			{
  				uno::Reference< frame::XFrame > xFrame = xController->getFrame();
  				if ( xFrame.is() )
  				{
  					xFrame->activate();
  					uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
  					if(xTopWindow.is())
  						xTopWindow->toFront();
  
  					bResult = sal_True;
  				}
  			}
  		}
  		catch( uno::Exception& )
  		{
  		}
  	}
  	else
  	{
  		bResult = CreateModel( m_bUseNative );
  
  		if ( !bResult && !m_bUseNative )
  		{
  			// the original storage can not be recognized
  			if ( !m_aNativeTempURL.getLength() )
  			{
  				// create a temporary file for the native representation if there is no
  				CreateNative();
  			}
  
  			if ( m_aNativeTempURL.getLength() )
  			{
  				bResult = CreateModel( sal_True );
  				if ( bResult )
  					m_bUseNative = sal_True;
  			}
  		}
  	}
  
  	m_bBusy = sal_False;
  
  	return bResult;
  }
  
  //--------------------------------------------------------
  void OwnView_Impl::Close()
  {
  	uno::Reference< frame::XModel > xModel;
  
  	{
  		::osl::MutexGuard aGuard( m_aMutex );
  		if ( !m_xModel.is() )
  			return;
  		xModel = m_xModel;
  		m_xModel = uno::Reference< frame::XModel >();
  
  		if ( m_bBusy )
  			return;
  
  		m_bBusy = sal_True;
  	}
  
  	try {
  		uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
  		if ( xBroadCaster.is() )
  			xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
  																	static_cast< ::cppu::OWeakObject* >( this ),
  											 						uno::UNO_QUERY ) );
  
  		uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
  		if ( xCloseable.is() )
  		{
  			xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
  																	static_cast< ::cppu::OWeakObject* >( this ),
  											 						uno::UNO_QUERY ) );
  			xCloseable->close( sal_True );
  		}
  	}
  	catch( uno::Exception& )
  	{}
  
  	m_bBusy = sal_False;
  }
  
  //--------------------------------------------------------
  void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
  		throw ( uno::RuntimeException )
  {
  
  	uno::Reference< frame::XModel > xModel;
  
  	{
  		::osl::MutexGuard aGuard( m_aMutex );
  		if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAscii( "OnSaveAsDone" ) )
  		{
  			// SaveAs operation took place, so just forget the model and deregister listeners
  			xModel = m_xModel;
  			m_xModel = uno::Reference< frame::XModel >();
  		}
  	}
  
  	if ( xModel.is() )
  	{
  		try {
  			uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
  			if ( xBroadCaster.is() )
  				xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
  																		static_cast< ::cppu::OWeakObject* >( this ),
  											 							uno::UNO_QUERY ) );
  	
  			uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
  			if ( xCloseable.is() )
  				xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
  																		static_cast< ::cppu::OWeakObject* >( this ),
  											 							uno::UNO_QUERY ) );
  		}
  		catch( uno::Exception& )
  		{}
  	}
  }
  
  //--------------------------------------------------------
  void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
  		throw ( util::CloseVetoException,
  				uno::RuntimeException )
  {
  }
  
  //--------------------------------------------------------
  void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
  		throw ( uno::RuntimeException )
  {
  	::osl::MutexGuard aGuard( m_aMutex );
  	if ( Source.Source == m_xModel )
  		m_xModel = uno::Reference< frame::XModel >();
  }
  
  //--------------------------------------------------------
  void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
  		throw (uno::RuntimeException)
  {
  	::osl::MutexGuard aGuard( m_aMutex );
  	if ( Source.Source == m_xModel )
  		m_xModel = uno::Reference< frame::XModel >();
  };
  
  