/**************************************************************
 * 
 * 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/embed/Aspects.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/frame/XDispatchHelper.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XControllerBorder.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XView.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
#include <com/sun/star/bridge/ModelDependent.hpp>
#include <com/sun/star/embed/XHatchWindow.hpp>
#include <com/sun/star/embed/XHatchWindowFactory.hpp>
#include <com/sun/star/embed/XInplaceClient.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>
#include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
#include <com/sun/star/ui/XUIElementSettings.hpp>
#ifndef _COM_SUN_STAR_UI_XCONFIGURATIONMANAGER_HPP_
#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#endif
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/embed/StateChangeInProgressException.hpp>

#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <osl/diagnose.h>
#include <rtl/process.h>

#include <comphelper/processfactory.hxx>
#include <comphelper/namedvaluecollection.hxx>

#include "docholder.hxx"
#include "commonembobj.hxx"
#include "intercept.hxx"


// #include <toolkit/helper/vclunohelper.hxx>
// #include <vcl/window.hxx>

#define HATCH_BORDER_WIDTH (((m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) && \
                             m_pEmbedObj->getCurrentState()!=embed::EmbedStates::UI_ACTIVE) ? 0 : 4 )

using namespace ::com::sun::star;

//===========================================================================

class IntCounterGuard {
	sal_Int32& m_nFlag;
public:
	IntCounterGuard( sal_Int32& nFlag )
	: m_nFlag( nFlag )
	{
		m_nFlag++;
	}

	~IntCounterGuard()
	{
		if ( m_nFlag )
			m_nFlag--;
	}
};

//===========================================================================

static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >& xTargetMenu,
							sal_Int32 nTargetIndex,
							const uno::Reference< container::XIndexAccess >& xSourceMenu,
							sal_Int32 nSourceIndex,
							const ::rtl::OUString aContModuleName,
							const uno::Reference< frame::XDispatchProvider >& xSourceDisp )
{
	sal_Int32 nInd = 0;
	::rtl::OUString aModuleIdentPropName( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ) );
	::rtl::OUString aDispProvPropName( RTL_CONSTASCII_USTRINGPARAM( "DispatchProvider" ) );
	sal_Bool bModuleNameSet = sal_False;
	sal_Bool bDispProvSet = sal_False;

	uno::Sequence< beans::PropertyValue > aSourceProps;
	xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps;
	uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() );
	for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ )
	{
		aTargetProps[nInd].Name = aSourceProps[nInd].Name;
		if ( aContModuleName.getLength() && aTargetProps[nInd].Name.equals( aModuleIdentPropName ) )
		{
			aTargetProps[nInd].Value <<= aContModuleName;
			bModuleNameSet = sal_True;
		}
		else if ( aTargetProps[nInd].Name.equals( aDispProvPropName ) )
		{
			aTargetProps[nInd].Value <<= xSourceDisp;
			bDispProvSet = sal_True;
		}
		else
			aTargetProps[nInd].Value = aSourceProps[nInd].Value;
	}

	if ( !bModuleNameSet && aContModuleName.getLength() )
	{
		aTargetProps.realloc( ++nInd );
		aTargetProps[nInd-1].Name = aModuleIdentPropName;
		aTargetProps[nInd-1].Value <<= aContModuleName;
	}

	if ( !bDispProvSet && xSourceDisp.is() )
	{
		aTargetProps.realloc( ++nInd );
		aTargetProps[nInd-1].Name = aDispProvPropName;
		aTargetProps[nInd-1].Value <<= xSourceDisp;
	}

	xTargetMenu->insertByIndex( nTargetIndex, uno::makeAny( aTargetProps ) );
}

//===========================================================================
DocumentHolder::DocumentHolder( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
								OCommonEmbeddedObject* pEmbObj )
: m_pEmbedObj( pEmbObj ),
  m_pInterceptor( NULL ),
  m_xFactory( xFactory ),
  m_bReadOnly( sal_False ),
  m_bWaitForClose( sal_False ),
  m_bAllowClosing( sal_False ),
  m_bDesktopTerminated( sal_False ),
  m_nNoBorderResizeReact( 0 ),
  m_nNoResizeReact( 0 )
{
	m_aOutplaceFrameProps.realloc( 3 );
	beans::NamedValue aArg;

	aArg.Name = ::rtl::OUString::createFromAscii("TopWindow");
	aArg.Value <<= sal_True;
	m_aOutplaceFrameProps[0] <<= aArg;

    aArg.Name = ::rtl::OUString::createFromAscii("MakeVisible");
    aArg.Value <<= sal_False;
    m_aOutplaceFrameProps[1] <<= aArg;

	const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
	uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
	if ( xDesktop.is() )
    {
        m_refCount++;
        try
        {
            xDesktop->addTerminateListener( this );
        }
        catch ( uno::Exception& )
        {
        }
        m_refCount--;

		aArg.Name = ::rtl::OUString::createFromAscii("ParentFrame");
		aArg.Value <<= xDesktop; //TODO/LATER: should use parent document frame
		m_aOutplaceFrameProps[2] <<= aArg;
    }
	else
		m_aOutplaceFrameProps.realloc( 2 );
}

//---------------------------------------------------------------------------
DocumentHolder::~DocumentHolder()
{
	m_refCount++; // to allow deregistration as a listener

	if( m_xFrame.is() )
		CloseFrame();

    if ( m_xComponent.is() )
	{
		try {
			CloseDocument( sal_True, sal_False );
		} catch( uno::Exception& ) {}
	}

	if ( m_pInterceptor )
	{
		m_pInterceptor->DisconnectDocHolder();
		m_pInterceptor->release();
	}

    if ( !m_bDesktopTerminated )
        FreeOffice();
}

//---------------------------------------------------------------------------
void DocumentHolder::CloseFrame()
{
	uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
	if ( xCloseBroadcaster.is() )
		xCloseBroadcaster->removeCloseListener( ( util::XCloseListener* )this );

	uno::Reference<util::XCloseable> xCloseable(
		m_xFrame,uno::UNO_QUERY );
	if( xCloseable.is() )
		try {
			xCloseable->close( sal_True );
		}
		catch( const uno::Exception& ) {
		}
	else {
		uno::Reference<lang::XComponent> xComp( m_xFrame,uno::UNO_QUERY );
		if( xComp.is() )
			xComp->dispose();
	}

	uno::Reference< lang::XComponent > xComp( m_xHatchWindow, uno::UNO_QUERY );
	if ( xComp.is() )
		xComp->dispose();

	m_xHatchWindow = uno::Reference< awt::XWindow >();
	m_xOwnWindow = uno::Reference< awt::XWindow >();
	m_xFrame = uno::Reference< frame::XFrame >();
}

//---------------------------------------------------------------------------
void DocumentHolder::FreeOffice()
{
	const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) );
	uno::Reference< frame::XDesktop > xDesktop( m_xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
	if ( xDesktop.is() )
	{
        xDesktop->removeTerminateListener( this );

		// the following code is commented out since for now there is still no completely correct way to detect
		// whether the office can be terminated, so it is better to have unnecessary process running than
		// to loose any data

//		uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY );
//		if ( xFramesSupplier.is() )
//		{
//			uno::Reference< frame::XFrames > xFrames = xFramesSupplier->getFrames();
//			if ( xFrames.is() && !xFrames->hasElements() )
//			{
//				try
//				{
//					xDesktop->terminate();
//				}
//				catch( uno::Exception & )
//				{}
//			}
//		}
	}
}

//---------------------------------------------------------------------------
void DocumentHolder::CloseDocument( sal_Bool bDeliverOwnership, sal_Bool bWaitForClose )
{
    uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY );
	if ( xBroadcaster.is() )
	{
        uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
		if ( xEventBroadcaster.is() )
			xEventBroadcaster->removeEventListener( ( document::XEventListener* )this );
		else
		{
			// the object does not support document::XEventBroadcaster interface
			// use the workaround, register for modified events
			uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY );
			if ( xModifyBroadcaster.is() )
				xModifyBroadcaster->removeModifyListener( ( util::XModifyListener* )this );
		}

		uno::Reference< util::XCloseable > xCloseable( xBroadcaster, uno::UNO_QUERY );
		if ( xCloseable.is() )
		{
			m_bAllowClosing = sal_True;
			m_bWaitForClose = bWaitForClose;
			xCloseable->close( bDeliverOwnership );
		}
	}

    m_xComponent = 0;
}

//---------------------------------------------------------------------------
void DocumentHolder::PlaceFrame( const awt::Rectangle& aNewRect )
{
    OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is(),
                "The object does not have windows required for inplace mode!" );

	//TODO: may need mutex locking???
    if ( m_xFrame.is() && m_xOwnWindow.is() )
	{
		// the frame can be replaced only in inplace mode
		frame::BorderWidths aOldWidths;
		IntCounterGuard aGuard( m_nNoBorderResizeReact );

		do
		{
			aOldWidths = m_aBorderWidths;

			awt::Rectangle aHatchRect = AddBorderToArea( aNewRect );

			ResizeWindows_Impl( aHatchRect );

		} while ( aOldWidths.Left != m_aBorderWidths.Left
			   || aOldWidths.Top != m_aBorderWidths.Top
			   || aOldWidths.Right != m_aBorderWidths.Right
			   || aOldWidths.Bottom != m_aBorderWidths.Bottom );

		m_aObjRect = aNewRect;
	}
}

//---------------------------------------------------------------------------
void DocumentHolder::ResizeWindows_Impl( const awt::Rectangle& aHatchRect )
{
	OSL_ENSURE( m_xFrame.is() && m_xOwnWindow.is() /*&& m_xHatchWindow.is()*/,
				"The object does not have windows required for inplace mode!" );
	if ( m_xHatchWindow.is() )
	{
		m_xOwnWindow->setPosSize( HATCH_BORDER_WIDTH,
								  HATCH_BORDER_WIDTH,
								  aHatchRect.Width - 2*HATCH_BORDER_WIDTH,
								  aHatchRect.Height - 2*HATCH_BORDER_WIDTH,
								  awt::PosSize::POSSIZE );

		// Window* pWindow = VCLUnoHelper::GetWindow( m_xOwnWindow );

		m_xHatchWindow->setPosSize( aHatchRect.X,
									aHatchRect.Y,
									aHatchRect.Width,
									aHatchRect.Height,
									awt::PosSize::POSSIZE );
	}
	else
		m_xOwnWindow->setPosSize( aHatchRect.X + HATCH_BORDER_WIDTH,
								  aHatchRect.Y + HATCH_BORDER_WIDTH,
								  aHatchRect.Width - 2*HATCH_BORDER_WIDTH,
								  aHatchRect.Height - 2*HATCH_BORDER_WIDTH,
								  awt::PosSize::POSSIZE );
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::SetFrameLMVisibility( const uno::Reference< frame::XFrame >& xFrame, sal_Bool bVisible )
{
	sal_Bool bResult = sal_False;

	try
	{
    	uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
		uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY_THROW );
		xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
		if ( xLayoutManager.is() )
		{
			xLayoutManager->setVisible( bVisible );

            // MBA: locking is done only on the container LM, because it is not about hiding windows, it's about
            // giving up control over the component window (and stopping to listen for resize events of the container window)
            if ( bVisible )
                xLayoutManager->unlock();
            else
                xLayoutManager->lock();

			bResult = sal_True;
		}
	}
	catch( uno::Exception& )
	{}

	return bResult;
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::ShowInplace( const uno::Reference< awt::XWindowPeer >& xParent,
									  const awt::Rectangle& aRectangleToShow,
									  const uno::Reference< frame::XDispatchProvider >& xContDisp )
{
	OSL_ENSURE( !m_xFrame.is(), "A frame exists already!" );

	if ( !m_xFrame.is() )
	{
        uno::Reference < frame::XModel > xModel( GetComponent(), uno::UNO_QUERY );
		awt::Rectangle aHatchRectangle = AddBorderToArea( aRectangleToShow );

        awt::Rectangle aOwnRectangle(  HATCH_BORDER_WIDTH,
                                    HATCH_BORDER_WIDTH,
                                    aHatchRectangle.Width - 2*HATCH_BORDER_WIDTH,
                                    aHatchRectangle.Height - 2*HATCH_BORDER_WIDTH );
        uno::Reference< awt::XWindow > xHWindow;
        uno::Reference< awt::XWindowPeer > xMyParent( xParent );

        if ( xModel.is() )
        {

			uno::Reference< embed::XHatchWindowFactory > xHatchFactory(
					m_xFactory->createInstance(
						::rtl::OUString::createFromAscii( "com.sun.star.embed.HatchWindowFactory" ) ),
					uno::UNO_QUERY );

			if ( !xHatchFactory.is() )
				throw uno::RuntimeException();

			uno::Reference< embed::XHatchWindow > xHatchWindow =
							xHatchFactory->createHatchWindowInstance( xParent,
																	  aHatchRectangle,
																	  awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) );

			uno::Reference< awt::XWindowPeer > xHatchWinPeer( xHatchWindow, uno::UNO_QUERY );
            xHWindow = uno::Reference< awt::XWindow >( xHatchWinPeer, uno::UNO_QUERY );
			if ( !xHWindow.is() )
				throw uno::RuntimeException(); // TODO: can not create own window

            xHatchWindow->setController( uno::Reference< embed::XHatchWindowController >(
												static_cast< embed::XHatchWindowController* >( this ) ) );

            xMyParent = xHatchWinPeer;
		}
        else
        {
            aOwnRectangle.X += aHatchRectangle.X;
            aOwnRectangle.Y += aHatchRectangle.Y;
        }

        awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_TOP,
                                                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("dockingwindow") ),
                                                xMyParent,
												0,
                                                awt::Rectangle(),//aOwnRectangle,
                                                awt::WindowAttribute::SHOW | awt::VclWindowPeerAttribute::CLIPCHILDREN );

		uno::Reference< awt::XToolkit > xToolkit(
							m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ),
							uno::UNO_QUERY );
		if ( !xToolkit.is() )
			throw uno::RuntimeException();

		uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor );
		uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY );
		if ( !xOwnWindow.is() )
			throw uno::RuntimeException(); // TODO: can not create own window

		// create a frame based on the specified window
        uno::Reference< lang::XSingleServiceFactory > xFrameFact(
			m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ),
			uno::UNO_QUERY_THROW );

		uno::Sequence< uno::Any > aArgs( 2 );
		beans::NamedValue aArg;

		aArg.Name    = ::rtl::OUString::createFromAscii("ContainerWindow");
		aArg.Value <<= xOwnWindow;
		aArgs[0] <<= aArg;

		uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY );
		if ( xContFrame.is() )
		{
			aArg.Name    = ::rtl::OUString::createFromAscii("ParentFrame");
			aArg.Value <<= xContFrame;
			aArgs[1] <<= aArg;
		}
		else
			aArgs.realloc( 1 );

		// the call will create, initialize the frame, and register it in the parent
		m_xFrame.set( xFrameFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY_THROW );

		m_xHatchWindow = xHWindow;
		m_xOwnWindow = xOwnWindow;

		if ( !SetFrameLMVisibility( m_xFrame, sal_False ) )
		{
			OSL_ENSURE( sal_False, "Can't deactivate LayoutManager!\n" );
			// TODO/LATER: error handling?
		}

		// m_bIsInplace = sal_True; TODO: ?

		uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
		if ( xCloseBroadcaster.is() )
			xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this );

		// TODO: some listeners to the frame and the window ( resize for example )
	}

    if ( m_xComponent.is() )
	{
        if ( !LoadDocToFrame( sal_True ) )
        {
            CloseFrame();
            return sal_False;
        }

		uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
		if ( xControllerBorder.is() )
		{
			m_aBorderWidths = xControllerBorder->getBorder();
			xControllerBorder->addBorderResizeListener( (frame::XBorderResizeListener*)this );
		}

		PlaceFrame( aRectangleToShow );

        if ( m_xHatchWindow.is() )
            m_xHatchWindow->setVisible( sal_True );

        return sal_True;
	}

	return sal_False;
}

//---------------------------------------------------------------------------
uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl()
{
	uno::Reference< container::XIndexAccess > xResult;

	uno::Reference< ::com::sun::star::ui::XUIConfigurationManagerSupplier > xUIConfSupplier(
				m_xComponent,
				uno::UNO_QUERY );
	uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xUIConfigManager;
    if( xUIConfSupplier.is())
    {
        xUIConfigManager.set(
            xUIConfSupplier->getUIConfigurationManager(),
            uno::UNO_QUERY_THROW );
    }

    try
	{
        if( xUIConfigManager.is())
        {
            xResult = xUIConfigManager->getSettings(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ),
				sal_False );
        }
	}
	catch( uno::Exception )
	{}

	if ( !xResult.is() )
	{
		// no internal document configuration, use the one from the module
		uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleMan(
                m_xFactory->createInstance(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ),
					uno::UNO_QUERY_THROW );
		::rtl::OUString aModuleIdent =
			xModuleMan->identify( uno::Reference< uno::XInterface >( m_xComponent, uno::UNO_QUERY ) );

		if ( aModuleIdent.getLength() )
		{
			uno::Reference< ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier > xModConfSupplier(
					m_xFactory->createInstance( ::rtl::OUString(
						RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) ) ),
					uno::UNO_QUERY_THROW );
			uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > xModUIConfMan(
					xModConfSupplier->getUIConfigurationManager( aModuleIdent ),
					uno::UNO_QUERY_THROW );
			xResult = xModUIConfMan->getSettings(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ),
					sal_False );
		}
	}

	if ( !xResult.is() )
		throw uno::RuntimeException();

	return xResult;
}

//---------------------------------------------------------------------------
void DocumentHolder::FindConnectPoints(
		const uno::Reference< container::XIndexAccess >& xMenu,
		sal_Int32 nConnectPoints[2] )
	throw ( uno::Exception )
{
	nConnectPoints[0] = -1;
	nConnectPoints[1] = -1;
	for ( sal_Int32 nInd = 0; nInd < xMenu->getCount(); nInd++ )
	{
		uno::Sequence< beans::PropertyValue > aProps;
		xMenu->getByIndex( nInd ) >>= aProps;
		rtl::OUString aCommand;
		for ( sal_Int32 nSeqInd = 0; nSeqInd < aProps.getLength(); nSeqInd++ )
			if ( aProps[nSeqInd].Name.equalsAscii( "CommandURL" ) )
			{
				aProps[nSeqInd].Value >>= aCommand;
				break;
			}

		if ( !aCommand.getLength() )
			throw uno::RuntimeException();

		if ( aCommand.equalsAscii( ".uno:PickList" ) )
			nConnectPoints[0] = nInd;
		else if ( aCommand.equalsAscii( ".uno:WindowList" ) )
			nConnectPoints[1] = nInd;
	}
}

//---------------------------------------------------------------------------
uno::Reference< container::XIndexAccess > DocumentHolder::MergeMenuesForInplace(
		const uno::Reference< container::XIndexAccess >& xContMenu,
		const uno::Reference< frame::XDispatchProvider >& xContDisp,
		const ::rtl::OUString& aContModuleName,
		const uno::Reference< container::XIndexAccess >& xOwnMenu,
		const uno::Reference< frame::XDispatchProvider >& xOwnDisp )
	throw ( uno::Exception )
{
	// TODO/LATER: use dispatch providers on merge

	sal_Int32 nContPoints[2];
	sal_Int32 nOwnPoints[2];

	uno::Reference< lang::XSingleComponentFactory > xIndAccessFact( xContMenu, uno::UNO_QUERY_THROW );

	uno::Reference< uno::XComponentContext > xComponentContext;

	uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
	if ( xProps.is() )
        xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
            xComponentContext;

	uno::Reference< container::XIndexContainer > xMergedMenu(
			xIndAccessFact->createInstanceWithContext( xComponentContext ),
			uno::UNO_QUERY_THROW );

	FindConnectPoints( xContMenu, nContPoints );
	FindConnectPoints( xOwnMenu, nOwnPoints );

	for ( sal_Int32 nInd = 0; nInd < xOwnMenu->getCount(); nInd++ )
	{
		if ( nOwnPoints[0] == nInd )
		{
			if ( nContPoints[0] >= 0 && nContPoints[0] < xContMenu->getCount() )
			{
				InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[0], aContModuleName, xContDisp );
			}
		}
		else if ( nOwnPoints[1] == nInd )
		{
			if ( nContPoints[1] >= 0 && nContPoints[1] < xContMenu->getCount() )
			{
				InsertMenu_Impl( xMergedMenu, nInd, xContMenu, nContPoints[1], aContModuleName, xContDisp );
			}
		}
		else
			InsertMenu_Impl( xMergedMenu, nInd, xOwnMenu, nInd, ::rtl::OUString(), xOwnDisp );
	}

	return uno::Reference< container::XIndexAccess >( xMergedMenu, uno::UNO_QUERY_THROW );
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::MergeMenues_Impl( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xOwnLM,
	   										const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContLM,
											const uno::Reference< frame::XDispatchProvider >& xContDisp,
											const ::rtl::OUString& aContModuleName )
{
	sal_Bool bMenuMerged = sal_False;
	try
	{
        uno::Reference< ::com::sun::star::ui::XUIElementSettings > xUISettings(
			xContLM->getElement(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ) ) ),
			uno::UNO_QUERY_THROW );
		uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( sal_True );
		if ( !xContMenu.is() )
			throw uno::RuntimeException();

		uno::Reference< container::XIndexAccess > xOwnMenu = RetrieveOwnMenu_Impl();
		uno::Reference< frame::XDispatchProvider > xOwnDisp( m_xFrame, uno::UNO_QUERY_THROW );

		uno::Reference< container::XIndexAccess > xMergedMenu = MergeMenuesForInplace( xContMenu, xContDisp, aContModuleName, xOwnMenu, xOwnDisp );
		uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM,
																						 uno::UNO_QUERY_THROW );
		bMenuMerged = xMerge->setMergedMenuBar( xMergedMenu );
	}
	catch( uno::Exception& )
	{}

	return bMenuMerged;
}

sal_Bool DocumentHolder::ShowUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM,
								 const uno::Reference< frame::XDispatchProvider >& xContainerDP,
								 const ::rtl::OUString& aContModuleName )
{
	sal_Bool bResult = sal_False;
	if ( xContainerLM.is() )
	{
        // the LM of the embedded frame and its current DockingAreaAcceptor
	   	uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM;
   		uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc;

        try
        {
			uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
			xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM;
            xDocAreaAcc = xContainerLM->getDockingAreaAcceptor();
        }
        catch( uno::Exception& ){}

        // make sure that lock state of LM is correct even if an exception is thrown in between
        sal_Bool bUnlock = sal_False;
        sal_Bool bLock = sal_False;
        if ( xOwnLM.is() && xDocAreaAcc.is() )
		{
			try
			{
                // take over the control over the containers window
                // as long as the LM is invisible and locked an empty tool space will be used on resizing
                xOwnLM->setDockingAreaAcceptor( xDocAreaAcc );

                // try to merge menues; don't do anything else if it fails
				if ( MergeMenues_Impl( xOwnLM, xContainerLM, xContainerDP, aContModuleName ) )
				{
                    // make sure that the container LM does not control the size of the containers window anymore
                    // this must be done after merging menues as we won't get the container menu otherwise
                    xContainerLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );

                    // prevent further changes at this LM
                    xContainerLM->setVisible( sal_False );
               		xContainerLM->lock();
                    bUnlock = sal_True;

                    // by unlocking the LM each layout change will now resize the containers window; pending layouts will be processed now
                    xOwnLM->setVisible( sal_True );

                    uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY );
                    if ( xSupp.is() )
                        xSupp->setActiveFrame( m_xFrame );

                    xOwnLM->unlock();
                    bLock = sal_True;
               		bResult = sal_True;

                    // TODO/LATER: The following action should be done only if the window is not hidden
                    // otherwise the activation must fail, unfortunatelly currently it is not possible
                    // to detect whether the window is hidden using UNO API
                    m_xOwnWindow->setFocus();
                }
			}
			catch( uno::Exception& )
			{
                // activation failed; reestablish old state
                try
                {
                    uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY );
                    if ( xSupp.is() )
                        xSupp->setActiveFrame( 0 );

                    // remove control about containers window from own LM
                    if ( bLock )
                        xOwnLM->lock();
                    xOwnLM->setVisible( sal_False );
                    xOwnLM->setDockingAreaAcceptor( uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor >() );

                    // unmerge menu
                    uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
                    xMerge->removeMergedMenuBar();
                }
                catch( uno::Exception& ) {}

                try
                {
                    // reestablish control of containers window
                    xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
					xContainerLM->setVisible( sal_True );
                    if ( bUnlock )
                        xContainerLM->unlock();
                }
                catch( uno::Exception& ) {}
			}
		}
	}

	return bResult;
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::HideUI( const uno::Reference< ::com::sun::star::frame::XLayoutManager >& xContainerLM )
{
	sal_Bool bResult = sal_False;

	if ( xContainerLM.is() )
	{
	   	uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM;

		try {
			uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
			xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM;
		} catch( uno::Exception& )
		{}

		if ( xOwnLM.is() )
		{
			try {
                uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY );
                if ( xSupp.is() )
                    xSupp->setActiveFrame( 0 );

                uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xDocAreaAcc = xOwnLM->getDockingAreaAcceptor();

                xOwnLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );
                xOwnLM->lock();
				xOwnLM->setVisible( sal_False );

                uno::Reference< ::com::sun::star::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
				xMerge->removeMergedMenuBar();

                xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
				xContainerLM->setVisible( sal_True );
				xContainerLM->unlock();

            	xContainerLM->doLayout();
				bResult = sal_True;
			}
			catch( uno::Exception& )
			{
				SetFrameLMVisibility( m_xFrame, sal_True );
			}
		}
	}

	return bResult;
}

//---------------------------------------------------------------------------
uno::Reference< frame::XFrame > DocumentHolder::GetDocFrame()
{
	// the frame for outplace activation
	if ( !m_xFrame.is() )
	{
        uno::Reference< lang::XSingleServiceFactory > xFrameFact(
			m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.TaskCreator" ) ),
			uno::UNO_QUERY_THROW );

		m_xFrame.set(xFrameFact->createInstanceWithArguments( m_aOutplaceFrameProps ), uno::UNO_QUERY_THROW);

		uno::Reference< frame::XDispatchProviderInterception > xInterception( m_xFrame, uno::UNO_QUERY );
		if ( xInterception.is() )
		{
			if ( m_pInterceptor )
			{
				m_pInterceptor->DisconnectDocHolder();
				m_pInterceptor->release();
				m_pInterceptor = NULL;
			}

			m_pInterceptor = new Interceptor( this );
			m_pInterceptor->acquire();

			// register interceptor from outside
			if ( m_xOutplaceInterceptor.is() )
				xInterception->registerDispatchProviderInterceptor( m_xOutplaceInterceptor );

			xInterception->registerDispatchProviderInterceptor( m_pInterceptor );
		}

		uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
		if ( xCloseBroadcaster.is() )
			xCloseBroadcaster->addCloseListener( ( util::XCloseListener* )this );
	}

    if ( m_xComponent.is() )
    {
		uno::Reference< ::com::sun::star::frame::XLayoutManager > xOwnLM;
		try {
			uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
			xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xOwnLM;
		} catch( uno::Exception& )
		{}

		if ( xOwnLM.is() )
			xOwnLM->lock();

        // TODO/LATER: get it for the real aspect
        awt::Size aSize;
        GetExtent( embed::Aspects::MSOLE_CONTENT, &aSize );
        LoadDocToFrame(sal_False);

		if ( xOwnLM.is() )
		{
			xOwnLM->unlock();
			xOwnLM->lock();
		}

        SetExtent( embed::Aspects::MSOLE_CONTENT, aSize );

		if ( xOwnLM.is() )
			xOwnLM->unlock();
    }

    try
    {
        uno::Reference< awt::XWindow > xHWindow = m_xFrame->getContainerWindow();

        if( xHWindow.is() )
        {
            uno::Reference< beans::XPropertySet > xMonProps( m_xFactory->createInstance(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), uno::UNO_QUERY_THROW );
            const rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "DefaultDisplay" ) );
            sal_Int32 nDisplay = 0;
            xMonProps->getPropertyValue( sPropName ) >>= nDisplay;

            uno::Reference< container::XIndexAccess > xMultiMon( xMonProps, uno::UNO_QUERY_THROW );
            uno::Reference< beans::XPropertySet > xMonitor( xMultiMon->getByIndex( nDisplay ), uno::UNO_QUERY_THROW );
            awt::Rectangle aWorkRect;
            xMonitor->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WorkArea" ) ) ) >>= aWorkRect;
            awt::Rectangle aWindowRect = xHWindow->getPosSize();

            if (( aWindowRect.Width < aWorkRect.Width) && ( aWindowRect.Height < aWorkRect.Height ))
            {
                int OffsetX = ( aWorkRect.Width - aWindowRect.Width ) / 2 + aWorkRect.X;
                int OffsetY = ( aWorkRect.Height - aWindowRect.Height ) /2 + aWorkRect.Y;
                xHWindow->setPosSize( OffsetX, OffsetY, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POS );
            }
            else
            {
                xHWindow->setPosSize( aWorkRect.X, aWorkRect.Y, aWorkRect.Width, aWorkRect.Height, awt::PosSize::POSSIZE );
            }

            xHWindow->setVisible( sal_True );
        }
    }
    catch ( uno::Exception& )
    {    	
    }
    
	return m_xFrame;
}

//---------------------------------------------------------------------------
void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDoc, sal_Bool bReadOnly )
{
    if ( m_xComponent.is() )
	{
		// May be should be improved
		try {
			CloseDocument( sal_True, sal_False );
		} catch( uno::Exception& )
		{}
	}

    m_xComponent = xDoc;
    // done outside currently uno::Reference < container::XChild > xChild( m_xComponent, uno::UNO_QUERY );
    // done outside currently if ( xChild.is() && m_pEmbedObj )
    // done outside currently 	xChild->setParent( m_pEmbedObj->getParent() );

	m_bReadOnly = bReadOnly;
    m_bAllowClosing = sal_False;

    uno::Reference< util::XCloseBroadcaster > xBroadcaster( m_xComponent, uno::UNO_QUERY );
	if ( xBroadcaster.is() )
		xBroadcaster->addCloseListener( ( util::XCloseListener* )this );

    uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
	if ( xEventBroadcaster.is() )
		xEventBroadcaster->addEventListener( ( document::XEventListener* )this );
	else
	{
		// the object does not support document::XEventBroadcaster interface
		// use the workaround, register for modified events
		uno::Reference< util::XModifyBroadcaster > xModifyBroadcaster( m_xComponent, uno::UNO_QUERY );
		if ( xModifyBroadcaster.is() )
			xModifyBroadcaster->addModifyListener( ( util::XModifyListener* )this );
	}

	if ( m_xFrame.is() )
        LoadDocToFrame(sal_False);
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::LoadDocToFrame( sal_Bool bInPlace )
{
    if ( m_xFrame.is() && m_xComponent.is() )
	{
        uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY );
        if ( xDoc.is() )
        {
            // load new document in to the frame
            uno::Reference< frame::XComponentLoader > xComponentLoader( m_xFrame, uno::UNO_QUERY_THROW );

            ::comphelper::NamedValueCollection aArgs;
            aArgs.put( "Model", m_xComponent );
            aArgs.put( "ReadOnly", m_bReadOnly );
            //aArgs.put( "Hidden", sal_True );
            if ( bInPlace )
                aArgs.put( "PluginMode", sal_Int16(1) );
			::rtl::OUString sUrl;
			uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY);
			if (	xServiceInfo.is() 
				&&	xServiceInfo->supportsService(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.ReportDefinition"))) )
			{
				sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB/ReportDesign"));
			}
            else if( xServiceInfo.is() 
				&&   xServiceInfo->supportsService( ::rtl::OUString::createFromAscii("com.sun.star.chart2.ChartDocument")) )
				sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/schart"));
			else
				sUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:object"));

            xComponentLoader->loadComponentFromURL( sUrl,
                                                        rtl::OUString::createFromAscii( "_self" ),
                                                        0,
                                                        aArgs.getPropertyValues() );

            return sal_True;
        }
        else
        {
            uno::Reference < frame::XSynchronousFrameLoader > xLoader( m_xComponent, uno::UNO_QUERY );
            if ( xLoader.is() )
                return xLoader->load( uno::Sequence < beans::PropertyValue >(), m_xFrame );
            else
                return sal_False;
        }
	}

    return sal_True;
}

//---------------------------------------------------------------------------
void DocumentHolder::Show()
{
	if( m_xFrame.is() )
	{
		m_xFrame->activate();
		uno::Reference<awt::XTopWindow> xTopWindow( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
		if( xTopWindow.is() )
			xTopWindow->toFront();
	}
	else
		GetDocFrame();
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::SetExtent( sal_Int64 nAspect, const awt::Size& aSize )
{
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
	if ( xDocVis.is() )
	{
		try
		{
			xDocVis->setVisualAreaSize( nAspect, aSize );
			return sal_True;
		}
		catch( uno::Exception& )
		{
			// TODO: Error handling
		}
	}

	return sal_False;
}

//---------------------------------------------------------------------------
sal_Bool DocumentHolder::GetExtent( sal_Int64 nAspect, awt::Size *pSize )
{
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
	if ( pSize && xDocVis.is() )
	{
		try
		{
			*pSize = xDocVis->getVisualAreaSize( nAspect );
			return sal_True;
		}
		catch( uno::Exception& )
		{
			// TODO: Error handling
		}
	}

	return sal_False;
}

//---------------------------------------------------------------------------
sal_Int32 DocumentHolder::GetMapUnit( sal_Int64 nAspect )
{
    uno::Reference< embed::XVisualObject > xDocVis( m_xComponent, uno::UNO_QUERY );
	if ( xDocVis.is() )
	{
		try
		{
            return xDocVis->getMapUnit( nAspect );
		}
		catch( uno::Exception& )
		{
			// TODO: Error handling
		}
	}

	return 0;
}

//---------------------------------------------------------------------------
awt::Rectangle DocumentHolder::CalculateBorderedArea( const awt::Rectangle& aRect )
{
	return awt::Rectangle( aRect.X + m_aBorderWidths.Left + HATCH_BORDER_WIDTH,
							 aRect.Y + m_aBorderWidths.Top + HATCH_BORDER_WIDTH,
							 aRect.Width - m_aBorderWidths.Left - m_aBorderWidths.Right - 2*HATCH_BORDER_WIDTH,
							 aRect.Height - m_aBorderWidths.Top - m_aBorderWidths.Bottom - 2*HATCH_BORDER_WIDTH );
}

//---------------------------------------------------------------------------
awt::Rectangle DocumentHolder::AddBorderToArea( const awt::Rectangle& aRect )
{
	return awt::Rectangle( aRect.X - m_aBorderWidths.Left - HATCH_BORDER_WIDTH,
							 aRect.Y - m_aBorderWidths.Top - HATCH_BORDER_WIDTH,
							 aRect.Width + m_aBorderWidths.Left + m_aBorderWidths.Right + 2*HATCH_BORDER_WIDTH,
							 aRect.Height + m_aBorderWidths.Top + m_aBorderWidths.Bottom + 2*HATCH_BORDER_WIDTH );
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::disposing( const com::sun::star::lang::EventObject& aSource )
		throw (uno::RuntimeException)
{
    if ( m_xComponent.is() && m_xComponent == aSource.Source )
	{
        m_xComponent = 0;
		if ( m_bWaitForClose )
		{
			m_bWaitForClose = sal_False;
			FreeOffice();
		}
	}

	if( m_xFrame.is() && m_xFrame == aSource.Source )
	{
		m_xHatchWindow = uno::Reference< awt::XWindow >();
		m_xOwnWindow = uno::Reference< awt::XWindow >();
		m_xFrame = uno::Reference< frame::XFrame >();
	}
}


//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::queryClosing( const lang::EventObject& aSource, sal_Bool /*bGetsOwnership*/ )
		throw (util::CloseVetoException, uno::RuntimeException)
{
    if ( m_xComponent.is() && m_xComponent == aSource.Source && !m_bAllowClosing )
		throw util::CloseVetoException();
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::notifyClosing( const lang::EventObject& aSource )
		throw (uno::RuntimeException)
{
    if ( m_xComponent.is() && m_xComponent == aSource.Source )
	{
        m_xComponent = 0;
		if ( m_bWaitForClose )
		{
			m_bWaitForClose = sal_False;
			FreeOffice();
		}
	}

	if( m_xFrame.is() && m_xFrame == aSource.Source )
	{
		m_xHatchWindow = uno::Reference< awt::XWindow >();
		m_xOwnWindow = uno::Reference< awt::XWindow >();
		m_xFrame = uno::Reference< frame::XFrame >();
	}
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::queryTermination( const lang::EventObject& )
		throw (frame::TerminationVetoException, uno::RuntimeException)
{
	if ( m_bWaitForClose )
		throw frame::TerminationVetoException();
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSource )
		throw (uno::RuntimeException)
{
    OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." );

	uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY );
    m_bDesktopTerminated = sal_True;
	if ( xDesktop.is() )
		xDesktop->removeTerminateListener( ( frame::XTerminateListener* )this );
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::modified( const lang::EventObject& aEvent )
	throw ( uno::RuntimeException )
{
	// if the component does not support document::XEventBroadcaster
	// the modify notifications are used as workaround, but only for running state
	if( aEvent.Source == m_xComponent && m_pEmbedObj && m_pEmbedObj->getCurrentState() == embed::EmbedStates::RUNNING )
		m_pEmbedObj->PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ), aEvent.Source );
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::notifyEvent( const document::EventObject& Event )
	throw ( uno::RuntimeException )
{
    if( m_pEmbedObj && Event.Source == m_xComponent )
	{
		// for now the ignored events are not forwarded, but sent by the object itself
		if ( !Event.EventName.equalsAscii( "OnSave" )
		  && !Event.EventName.equalsAscii( "OnSaveDone" )
		  && !Event.EventName.equalsAscii( "OnSaveAs" )
		  && !Event.EventName.equalsAscii( "OnSaveAsDone" )
		  && !( Event.EventName.equalsAscii( "OnVisAreaChanged" ) && m_nNoResizeReact ) )
			m_pEmbedObj->PostEvent_Impl( Event.EventName, Event.Source );
	}
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject,
													const frame::BorderWidths& aNewSize )
	throw ( uno::RuntimeException )
{
	// TODO: may require mutex introduction ???
	if ( m_pEmbedObj && m_xFrame.is() && aObject == m_xFrame->getController() )
	{
		if ( m_aBorderWidths.Left != aNewSize.Left
		  || m_aBorderWidths.Right != aNewSize.Right
		  || m_aBorderWidths.Top != aNewSize.Top
		  || m_aBorderWidths.Bottom != aNewSize.Bottom )
		{
			m_aBorderWidths = aNewSize;
			if ( !m_nNoBorderResizeReact )
				PlaceFrame( m_aObjRect );
		}
	}
}

//---------------------------------------------------------------------------
void SAL_CALL DocumentHolder::requestPositioning( const awt::Rectangle& aRect )
	throw (uno::RuntimeException)
{
	// TODO: may require mutex introduction ???
	if ( m_pEmbedObj )
	{
		// borders should not be counted
		awt::Rectangle aObjRect = CalculateBorderedArea( aRect );
		IntCounterGuard aGuard( m_nNoResizeReact );
		m_pEmbedObj->requestPositioning( aObjRect );
	}
}

//---------------------------------------------------------------------------
awt::Rectangle SAL_CALL DocumentHolder::calcAdjustedRectangle( const awt::Rectangle& aRect )
	throw (uno::RuntimeException)
{
	// Solar mutex should be locked already since this is a call from HatchWindow with focus
	awt::Rectangle aResult( aRect );

	if ( m_xFrame.is() )
	{
		// borders should not be counted
		uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
		if ( xControllerBorder.is() )
		{
			awt::Rectangle aObjRect = CalculateBorderedArea( aRect );
			aObjRect = xControllerBorder->queryBorderedArea( aObjRect );
			aResult = AddBorderToArea( aObjRect );
		}
	}

	awt::Rectangle aMinRectangle = AddBorderToArea( awt::Rectangle() );
	if ( aResult.Width < aMinRectangle.Width + 2 )
		aResult.Width = aMinRectangle.Width + 2;
	if ( aResult.Height < aMinRectangle.Height + 2 )
		aResult.Height = aMinRectangle.Height + 2;

	return aResult;
}

void SAL_CALL DocumentHolder::activated(  ) throw (::com::sun::star::uno::RuntimeException)
{
    if ( (m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) )
    {
        if ( m_pEmbedObj->getCurrentState() != embed::EmbedStates::UI_ACTIVE &&
        !(m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) )
        {
            try
            {
                m_pEmbedObj->changeState( embed::EmbedStates::UI_ACTIVE );
            }
            catch ( com::sun::star::embed::StateChangeInProgressException& )
            {
                // must catch this exception because focus is grabbed while UI activation in doVerb()
            }
            catch ( com::sun::star::uno::Exception& )
            {
                // no outgoing exceptions specified here
            }
        }
        else
        {
            uno::Reference< frame::XFramesSupplier > xSupp( m_xFrame->getCreator(), uno::UNO_QUERY );
            if ( xSupp.is() )
                xSupp->setActiveFrame( m_xFrame );
        }
    }
}

void DocumentHolder::ResizeHatchWindow()
{
    awt::Rectangle aHatchRect = AddBorderToArea( m_aObjRect );
    ResizeWindows_Impl( aHatchRect );
    uno::Reference< embed::XHatchWindow > xHatchWindow( m_xHatchWindow, uno::UNO_QUERY );
    xHatchWindow->setHatchBorderSize( awt::Size( HATCH_BORDER_WIDTH, HATCH_BORDER_WIDTH ) );
}

void SAL_CALL DocumentHolder::deactivated(  ) throw (::com::sun::star::uno::RuntimeException)
{
    // deactivation is too unspecific to be useful; usually we only trigger code from activation
    // so UIDeactivation is actively triggered by the container
}
