summaryrefslogtreecommitdiffstats
path: root/embeddedobj/source/general/docholder.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /embeddedobj/source/general/docholder.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'embeddedobj/source/general/docholder.cxx')
-rw-r--r--embeddedobj/source/general/docholder.cxx1278
1 files changed, 1278 insertions, 0 deletions
diff --git a/embeddedobj/source/general/docholder.cxx b/embeddedobj/source/general/docholder.cxx
new file mode 100644
index 000000000..ee1a8dfa6
--- /dev/null
+++ b/embeddedobj/source/general/docholder.cxx
@@ -0,0 +1,1278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/frame/TaskCreator.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/TerminationVetoException.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <com/sun/star/util/XCloseBroadcaster.hpp>
+#include <com/sun/star/util/XCloseable.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/Desktop.hpp>
+#include <com/sun/star/frame/XFramesSupplier.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/Toolkit.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
+#include <com/sun/star/embed/XHatchWindow.hpp>
+#include <com/sun/star/embed/HatchWindowFactory.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.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 <vcl/svapp.hxx>
+#include <unotools/resmgr.hxx>
+#include <sfx2/strings.hrc>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <docholder.hxx>
+#include <commonembobj.hxx>
+#include <intercept.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;
+
+namespace {
+
+class IntCounterGuard
+{
+ sal_Int32& m_rFlag;
+public:
+ explicit IntCounterGuard(sal_Int32& rFlag)
+ : m_rFlag(rFlag)
+ {
+ ++m_rFlag;
+ }
+
+ ~IntCounterGuard()
+ {
+ if (m_rFlag)
+ --m_rFlag;
+ }
+};
+
+}
+
+static void InsertMenu_Impl( const uno::Reference< container::XIndexContainer >& xTargetMenu,
+ sal_Int32 nTargetIndex,
+ const uno::Reference< container::XIndexAccess >& xSourceMenu,
+ sal_Int32 nSourceIndex,
+ const OUString& aContModuleName,
+ const uno::Reference< frame::XDispatchProvider >& xSourceDisp )
+{
+ sal_Int32 nInd = 0;
+ OUString aModuleIdentPropName( "ModuleIdentifier" );
+ OUString aDispProvPropName( "DispatchProvider" );
+ bool bModuleNameSet = false;
+ bool bDispProvSet = false;
+
+ uno::Sequence< beans::PropertyValue > aSourceProps;
+ xSourceMenu->getByIndex( nSourceIndex ) >>= aSourceProps;
+ uno::Sequence< beans::PropertyValue > aTargetProps( aSourceProps.getLength() );
+ auto aTargetPropsRange = asNonConstRange(aTargetProps);
+ for ( nInd = 0; nInd < aSourceProps.getLength(); nInd++ )
+ {
+ aTargetPropsRange[nInd].Name = aSourceProps[nInd].Name;
+ if ( !aContModuleName.isEmpty() && aTargetProps[nInd].Name == aModuleIdentPropName )
+ {
+ aTargetPropsRange[nInd].Value <<= aContModuleName;
+ bModuleNameSet = true;
+ }
+ else if ( aTargetProps[nInd].Name == aDispProvPropName )
+ {
+ aTargetPropsRange[nInd].Value <<= xSourceDisp;
+ bDispProvSet = true;
+ }
+ else
+ aTargetPropsRange[nInd].Value = aSourceProps[nInd].Value;
+ }
+
+ if ( !bModuleNameSet && !aContModuleName.isEmpty() )
+ {
+ aTargetProps.realloc( ++nInd );
+ auto pTargetProps = aTargetProps.getArray();
+ pTargetProps[nInd-1].Name = aModuleIdentPropName;
+ pTargetProps[nInd-1].Value <<= aContModuleName;
+ }
+
+ if ( !bDispProvSet && xSourceDisp.is() )
+ {
+ aTargetProps.realloc( ++nInd );
+ auto pTargetProps = aTargetProps.getArray();
+ pTargetProps[nInd-1].Name = aDispProvPropName;
+ pTargetProps[nInd-1].Value <<= xSourceDisp;
+ }
+
+ xTargetMenu->insertByIndex( nTargetIndex, uno::Any( aTargetProps ) );
+}
+
+
+DocumentHolder::DocumentHolder( const uno::Reference< uno::XComponentContext >& xContext,
+ OCommonEmbeddedObject* pEmbObj )
+: m_pEmbedObj( pEmbObj ),
+ m_xContext( xContext ),
+ m_bReadOnly( false ),
+ m_bWaitForClose( false ),
+ m_bAllowClosing( false ),
+ m_bDesktopTerminated( false ),
+ m_nNoBorderResizeReact( 0 ),
+ m_nNoResizeReact( 0 )
+{
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
+ osl_atomic_increment(&m_refCount);
+ try
+ {
+ xDesktop->addTerminateListener( this );
+ }
+ catch ( const uno::Exception& )
+ {
+ }
+ osl_atomic_decrement(&m_refCount);
+
+ m_aOutplaceFrameProps = { uno::Any(beans::NamedValue{ "TopWindow", uno::Any(true) }),
+ uno::Any(beans::NamedValue{ "MakeVisible", uno::Any(false) }),
+ //TODO/LATER: should use parent document frame
+ uno::Any(beans::NamedValue{ "ParentFrame", uno::Any(xDesktop) }) };
+}
+
+
+DocumentHolder::~DocumentHolder()
+{
+ osl_atomic_increment(&m_refCount); // to allow deregistration as a listener
+
+ if( m_xFrame.is() )
+ CloseFrame();
+
+ if ( m_xComponent.is() )
+ {
+ try {
+ CloseDocument( true, false );
+ } catch( const uno::Exception& ) {}
+ }
+
+ if ( m_xInterceptor.is() )
+ {
+ m_xInterceptor->DisconnectDocHolder();
+ m_xInterceptor.clear();
+ }
+
+ if ( !m_bDesktopTerminated )
+ FreeOffice();
+}
+
+
+void DocumentHolder::CloseFrame()
+{
+ uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
+ if ( xCloseBroadcaster.is() )
+ xCloseBroadcaster->removeCloseListener( static_cast<util::XCloseListener*>(this) );
+
+ uno::Reference<util::XCloseable> xCloseable(
+ m_xFrame,uno::UNO_QUERY );
+ if( xCloseable.is() )
+ try {
+ xCloseable->close( true );
+ }
+ catch( const uno::Exception& ) {
+ }
+ else {
+ if( m_xFrame.is() )
+ m_xFrame->dispose();
+ }
+
+ if ( m_xHatchWindow.is() )
+ m_xHatchWindow->dispose();
+
+ m_xHatchWindow.clear();
+ m_xOwnWindow.clear();
+ m_xFrame.clear();
+}
+
+
+void DocumentHolder::FreeOffice()
+{
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
+ 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 lose 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( bool bDeliverOwnership, bool bWaitForClose )
+{
+ if ( m_xComponent.is() )
+ {
+ uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
+ if ( xEventBroadcaster.is() )
+ xEventBroadcaster->removeEventListener( static_cast<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( static_cast<util::XModifyListener*>(this) );
+ }
+
+ m_bAllowClosing = true;
+ m_bWaitForClose = bWaitForClose;
+ m_xComponent->close( bDeliverOwnership );
+ }
+
+ m_xComponent = nullptr;
+}
+
+
+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()) )
+ return;
+
+ // 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 );
+
+
+ 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 );
+}
+
+
+bool DocumentHolder::SetFrameLMVisibility( const uno::Reference< frame::XFrame >& xFrame, bool bVisible )
+{
+ bool bResult = false;
+
+ try
+ {
+ uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue("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 = true;
+ }
+ }
+ catch( const uno::Exception& )
+ {}
+
+ return bResult;
+}
+
+
+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 =
+ embed::HatchWindowFactory::create(m_xContext);
+
+ 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.set( xHatchWinPeer, uno::UNO_QUERY_THROW );
+
+ 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,
+ "dockingwindow",
+ xMyParent,
+ 0,
+ awt::Rectangle(),//aOwnRectangle,
+ awt::WindowAttribute::SHOW | awt::VclWindowPeerAttribute::CLIPCHILDREN );
+
+ uno::Reference< awt::XToolkit2 > xToolkit = awt::Toolkit::create(m_xContext);
+
+ uno::Reference< awt::XWindowPeer > xNewWinPeer = xToolkit->createWindow( aOwnWinDescriptor );
+ uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer, uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFrame > xContFrame( xContDisp, uno::UNO_QUERY );
+
+ // create a frame based on the specified window
+ uno::Reference< lang::XSingleServiceFactory > xFrameFact = frame::TaskCreator::create(m_xContext);
+
+ uno::Sequence< uno::Any > aArgs( xContFrame.is() ? 2 : 1 );
+ auto pArgs = aArgs.getArray();
+ beans::NamedValue aArg;
+
+ aArg.Name = "ContainerWindow";
+ aArg.Value <<= xOwnWindow;
+ pArgs[0] <<= aArg;
+
+ if ( xContFrame.is() )
+ {
+ aArg.Name = "ParentFrame";
+ aArg.Value <<= xContFrame;
+ pArgs[1] <<= aArg;
+ }
+
+ // 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, false ) )
+ {
+ OSL_FAIL( "Can't deactivate LayoutManager!" );
+ // TODO/LATER: error handling?
+ }
+
+ // m_bIsInplace = sal_True; TODO: ?
+
+ uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
+ if ( xCloseBroadcaster.is() )
+ xCloseBroadcaster->addCloseListener( static_cast<util::XCloseListener*>(this) );
+
+ // TODO: some listeners to the frame and the window ( resize for example )
+ }
+
+ if ( !m_xComponent )
+ return false;
+
+ if ( !LoadDocToFrame( true ) )
+ {
+ CloseFrame();
+ return false;
+ }
+
+ uno::Reference< frame::XControllerBorder > xControllerBorder( m_xFrame->getController(), uno::UNO_QUERY );
+ if ( xControllerBorder.is() )
+ {
+ m_aBorderWidths = xControllerBorder->getBorder();
+ xControllerBorder->addBorderResizeListener( static_cast<frame::XBorderResizeListener*>(this) );
+ }
+
+ PlaceFrame( aRectangleToShow );
+
+ if ( m_xHatchWindow.is() )
+ m_xHatchWindow->setVisible( true );
+
+ return true;
+}
+
+
+uno::Reference< container::XIndexAccess > DocumentHolder::RetrieveOwnMenu_Impl()
+{
+ uno::Reference< container::XIndexAccess > xResult;
+
+ uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUIConfSupplier(
+ m_xComponent,
+ uno::UNO_QUERY );
+ uno::Reference< css::ui::XUIConfigurationManager > xUIConfigManager;
+ if( xUIConfSupplier.is())
+ {
+ xUIConfigManager.set(
+ xUIConfSupplier->getUIConfigurationManager(),
+ uno::UNO_SET_THROW );
+ }
+
+ try
+ {
+ if( xUIConfigManager.is())
+ {
+ xResult = xUIConfigManager->getSettings(
+ "private:resource/menubar/menubar",
+ false );
+ }
+ }
+ catch( const uno::Exception& )
+ {}
+
+ if ( !xResult.is() )
+ {
+ // no internal document configuration, use the one from the module
+ uno::Reference< frame::XModuleManager2 > xModuleMan = frame::ModuleManager::create(m_xContext);
+ OUString aModuleIdent =
+ xModuleMan->identify( uno::Reference< uno::XInterface >( m_xComponent, uno::UNO_QUERY ) );
+
+ if ( !aModuleIdent.isEmpty() )
+ {
+ uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModConfSupplier =
+ ui::theModuleUIConfigurationManagerSupplier::get(m_xContext);
+ uno::Reference< css::ui::XUIConfigurationManager > xModUIConfMan(
+ xModConfSupplier->getUIConfigurationManager( aModuleIdent ),
+ uno::UNO_SET_THROW );
+ xResult = xModUIConfMan->getSettings(
+ "private:resource/menubar/menubar",
+ false );
+ }
+ }
+
+ if ( !xResult.is() )
+ throw uno::RuntimeException();
+
+ return xResult;
+}
+
+
+void DocumentHolder::FindConnectPoints(
+ const uno::Reference< container::XIndexAccess >& xMenu,
+ sal_Int32 nConnectPoints[2] )
+{
+ nConnectPoints[0] = -1;
+ nConnectPoints[1] = -1;
+ for ( sal_Int32 nInd = 0; nInd < xMenu->getCount(); nInd++ )
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+ xMenu->getByIndex( nInd ) >>= aProps;
+ OUString aCommand;
+ for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ if ( prop.Name == "CommandURL" )
+ {
+ prop.Value >>= aCommand;
+ break;
+ }
+
+ if ( aCommand.isEmpty() )
+ throw uno::RuntimeException();
+
+ if ( aCommand == ".uno:PickList" )
+ nConnectPoints[0] = nInd;
+ else if ( aCommand == ".uno:WindowList" )
+ nConnectPoints[1] = nInd;
+ }
+}
+
+
+uno::Reference< container::XIndexAccess > DocumentHolder::MergeMenusForInplace(
+ const uno::Reference< container::XIndexAccess >& xContMenu,
+ const uno::Reference< frame::XDispatchProvider >& xContDisp,
+ const OUString& aContModuleName,
+ const uno::Reference< container::XIndexAccess >& xOwnMenu,
+ const uno::Reference< frame::XDispatchProvider >& xOwnDisp )
+{
+ // 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< container::XIndexContainer > xMergedMenu(
+ xIndAccessFact->createInstanceWithContext(
+ comphelper::getProcessComponentContext() ),
+ 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, OUString(), xOwnDisp );
+ }
+
+ return uno::Reference< container::XIndexAccess >( xMergedMenu, uno::UNO_QUERY_THROW );
+}
+
+
+bool DocumentHolder::MergeMenus_Impl( const uno::Reference< css::frame::XLayoutManager >& xOwnLM,
+ const uno::Reference< css::frame::XLayoutManager >& xContLM,
+ const uno::Reference< frame::XDispatchProvider >& xContDisp,
+ const OUString& aContModuleName )
+{
+ bool bMenuMerged = false;
+ try
+ {
+ uno::Reference< css::ui::XUIElementSettings > xUISettings(
+ xContLM->getElement( "private:resource/menubar/menubar" ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xContMenu = xUISettings->getSettings( 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 = MergeMenusForInplace( xContMenu, xContDisp, aContModuleName, xOwnMenu, xOwnDisp );
+ uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM,
+ uno::UNO_QUERY_THROW );
+ bMenuMerged = xMerge->setMergedMenuBar( xMergedMenu );
+ }
+ catch( const uno::Exception& )
+ {}
+
+ return bMenuMerged;
+}
+
+bool DocumentHolder::ShowUI( const uno::Reference< css::frame::XLayoutManager >& xContainerLM,
+ const uno::Reference< frame::XDispatchProvider >& xContainerDP,
+ const OUString& aContModuleName )
+{
+ bool bResult = false;
+ if ( xContainerLM.is() )
+ {
+ // the LM of the embedded frame and its current DockingAreaAcceptor
+ uno::Reference< css::frame::XLayoutManager > xOwnLM;
+ uno::Reference< css::ui::XDockingAreaAcceptor > xDocAreaAcc;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue("LayoutManager") >>= xOwnLM;
+ xDocAreaAcc = xContainerLM->getDockingAreaAcceptor();
+ }
+ catch( const uno::Exception& ){}
+
+ if ( xOwnLM.is() && xDocAreaAcc.is() )
+ {
+ // make sure that lock state of LM is correct even if an exception is thrown in between
+ bool bUnlockContainerLM = false;
+ bool bLockOwnLM = false;
+ 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 menus; don't do anything else if it fails
+ if ( MergeMenus_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 menus as we won't get the container menu otherwise
+ xContainerLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );
+
+ uno::Reference< lang::XServiceInfo> xServiceInfo(m_xComponent, uno::UNO_QUERY);
+ if (!xServiceInfo.is() || !xServiceInfo->supportsService("com.sun.star.chart2.ChartDocument"))
+ {
+ // prevent further changes at this LM
+ xContainerLM->setVisible(false);
+ xContainerLM->lock();
+ bUnlockContainerLM = true;
+ }
+
+ // by unlocking the LM each layout change will now resize the containers window; pending layouts will be processed now
+ xOwnLM->setVisible( true );
+
+ uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
+ if ( xSupp.is() )
+ xSupp->setActiveFrame( m_xFrame );
+
+ xOwnLM->unlock();
+ bLockOwnLM = true;
+ bResult = true;
+
+ // TODO/LATER: The following action should be done only if the window is not hidden
+ // otherwise the activation must fail, unfortunately currently it is not possible
+ // to detect whether the window is hidden using UNO API
+ m_xOwnWindow->setFocus();
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ // activation failed; reestablish old state
+ try
+ {
+ uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
+ if ( xSupp.is() )
+ xSupp->setActiveFrame( nullptr );
+
+ // remove control about containers window from own LM
+ if (bLockOwnLM)
+ xOwnLM->lock();
+ xOwnLM->setVisible( false );
+ xOwnLM->setDockingAreaAcceptor( uno::Reference< css::ui::XDockingAreaAcceptor >() );
+
+ // unmerge menu
+ uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
+ xMerge->removeMergedMenuBar();
+ }
+ catch( const uno::Exception& ) {}
+
+ try
+ {
+ // reestablish control of containers window
+ xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
+ xContainerLM->setVisible( true );
+ if (bUnlockContainerLM)
+ xContainerLM->unlock();
+ }
+ catch( const uno::Exception& ) {}
+ }
+ }
+ }
+
+ return bResult;
+}
+
+
+bool DocumentHolder::HideUI( const uno::Reference< css::frame::XLayoutManager >& xContainerLM )
+{
+ bool bResult = false;
+
+ if ( xContainerLM.is() )
+ {
+ uno::Reference< css::frame::XLayoutManager > xOwnLM;
+
+ try {
+ uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue("LayoutManager") >>= xOwnLM;
+ } catch( const uno::Exception& )
+ {}
+
+ if ( xOwnLM.is() )
+ {
+ try {
+ uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
+ if ( xSupp.is() )
+ xSupp->setActiveFrame( nullptr );
+
+ uno::Reference< css::ui::XDockingAreaAcceptor > xDocAreaAcc = xOwnLM->getDockingAreaAcceptor();
+
+ xOwnLM->setDockingAreaAcceptor( uno::Reference < ui::XDockingAreaAcceptor >() );
+ xOwnLM->lock();
+ xOwnLM->setVisible( false );
+
+ uno::Reference< css::frame::XMenuBarMergingAcceptor > xMerge( xOwnLM, uno::UNO_QUERY_THROW );
+ xMerge->removeMergedMenuBar();
+
+ xContainerLM->setDockingAreaAcceptor( xDocAreaAcc );
+ uno::Reference< lang::XServiceInfo> xServiceInfo(m_xComponent, uno::UNO_QUERY);
+ if (!xServiceInfo.is() || !xServiceInfo->supportsService("com.sun.star.chart2.ChartDocument"))
+ {
+ xContainerLM->setVisible(true);
+ xContainerLM->unlock();
+ }
+
+ xContainerLM->doLayout();
+ bResult = true;
+ }
+ catch( const uno::Exception& )
+ {
+ SetFrameLMVisibility( m_xFrame, true );
+ }
+ }
+ }
+
+ return bResult;
+}
+
+
+uno::Reference< frame::XFrame > const & DocumentHolder::GetDocFrame()
+{
+ // the frame for outplace activation
+ if ( !m_xFrame.is() )
+ {
+ uno::Reference< lang::XSingleServiceFactory > xFrameFact = frame::TaskCreator::create(m_xContext);
+
+ 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_xInterceptor.is() )
+ {
+ m_xInterceptor->DisconnectDocHolder();
+ m_xInterceptor.clear();
+ }
+
+ m_xInterceptor = new Interceptor( this );
+
+ xInterception->registerDispatchProviderInterceptor( m_xInterceptor );
+
+ // register interceptor from outside
+ if ( m_xOutplaceInterceptor.is() )
+ xInterception->registerDispatchProviderInterceptor( m_xOutplaceInterceptor );
+ }
+
+ uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xFrame, uno::UNO_QUERY );
+ if ( xCloseBroadcaster.is() )
+ xCloseBroadcaster->addCloseListener( static_cast<util::XCloseListener*>(this) );
+ }
+
+ if ( m_xComponent.is() )
+ {
+ uno::Reference< css::frame::XLayoutManager > xOwnLM;
+ try {
+ uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue("LayoutManager") >>= xOwnLM;
+ } catch( const uno::Exception& )
+ {}
+
+ if ( xOwnLM.is() )
+ xOwnLM->lock();
+
+ // TODO/LATER: get it for the real aspect
+ awt::Size aSize;
+ LoadDocToFrame(false);
+
+ if ( xOwnLM.is() )
+ {
+ xOwnLM->unlock();
+ xOwnLM->lock();
+ }
+
+ GetExtent(embed::Aspects::MSOLE_CONTENT, &aSize);
+ SetExtent(embed::Aspects::MSOLE_CONTENT, aSize);
+
+ if ( xOwnLM.is() )
+ xOwnLM->unlock();
+ }
+
+ try
+ {
+ uno::Reference< awt::XWindow > xHWindow = m_xFrame->getContainerWindow();
+
+ if( xHWindow.is() )
+ {
+ sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
+
+ tools::Rectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
+ awt::Rectangle aWindowRect = xHWindow->getPosSize();
+
+ if (( aWindowRect.Width < aWorkRect.GetWidth()) && ( aWindowRect.Height < aWorkRect.GetHeight() ))
+ {
+ int OffsetX = ( aWorkRect.GetWidth() - aWindowRect.Width ) / 2 + aWorkRect.Left();
+ int OffsetY = ( aWorkRect.GetHeight() - aWindowRect.Height ) /2 + aWorkRect.Top();
+ xHWindow->setPosSize( OffsetX, OffsetY, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POS );
+ }
+ else
+ {
+ xHWindow->setPosSize( aWorkRect.Left(), aWorkRect.Top(), aWorkRect.GetWidth(), aWorkRect.GetHeight(), awt::PosSize::POSSIZE );
+ }
+
+ xHWindow->setVisible( true );
+ }
+ }
+ catch ( const uno::Exception& )
+ {
+ }
+
+ return m_xFrame;
+}
+
+
+void DocumentHolder::SetComponent( const uno::Reference< util::XCloseable >& xDoc, bool bReadOnly )
+{
+ if ( m_xComponent.is() )
+ {
+ // May be should be improved
+ try {
+ CloseDocument( true, false );
+ } catch( const uno::Exception& )
+ {}
+ }
+
+ m_xComponent = xDoc;
+
+ m_bReadOnly = bReadOnly;
+ m_bAllowClosing = false;
+
+ if ( m_xComponent.is() )
+ m_xComponent->addCloseListener( static_cast<util::XCloseListener*>(this) );
+
+ uno::Reference< document::XEventBroadcaster > xEventBroadcaster( m_xComponent, uno::UNO_QUERY );
+ if ( xEventBroadcaster.is() )
+ xEventBroadcaster->addEventListener( static_cast<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( static_cast<util::XModifyListener*>(this) );
+ }
+
+ if ( m_xFrame.is() )
+ LoadDocToFrame(false);
+}
+
+
+bool DocumentHolder::LoadDocToFrame( bool bInPlace )
+{
+ if ( !m_xFrame || !m_xComponent )
+ return true;
+
+ uno::Reference < frame::XModel > xDoc( m_xComponent, uno::UNO_QUERY );
+ if ( xDoc.is() )
+ {
+ // load new document into 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 );
+
+ // set document title to show in the title bar
+ css::uno::Reference< css::frame::XTitle > xModelTitle( xDoc, css::uno::UNO_QUERY );
+ if( xModelTitle.is() && m_pEmbedObj && !m_pEmbedObj->getContainerName().isEmpty() )
+ {
+ std::locale aResLoc = Translate::Create("sfx");
+ OUString sEmbedded = Translate::get(STR_EMBEDDED_TITLE, aResLoc);
+ xModelTitle->setTitle( m_pEmbedObj->getContainerName() + sEmbedded );
+ m_aContainerName = m_pEmbedObj->getContainerName();
+ // TODO: get real m_aDocumentNamePart
+ m_aDocumentNamePart = sEmbedded;
+ }
+
+ if ( bInPlace )
+ aArgs.put( "PluginMode", sal_Int16(1) );
+ OUString sUrl;
+ uno::Reference< lang::XServiceInfo> xServiceInfo(xDoc,uno::UNO_QUERY);
+ if ( xServiceInfo.is()
+ && xServiceInfo->supportsService("com.sun.star.report.ReportDefinition") )
+ {
+ sUrl = ".component:DB/ReportDesign";
+ }
+ else if( xServiceInfo.is()
+ && xServiceInfo->supportsService("com.sun.star.chart2.ChartDocument"))
+ sUrl = "private:factory/schart";
+ else
+ sUrl = "private:object";
+
+ xComponentLoader->loadComponentFromURL( sUrl,
+ "_self",
+ 0,
+ aArgs.getPropertyValues() );
+
+ return 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 false;
+ }
+
+ return 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();
+}
+
+
+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 true;
+ }
+ catch( const uno::Exception& )
+ {
+ // TODO: Error handling
+ }
+ }
+
+ return false;
+}
+
+
+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 true;
+ }
+ catch( const uno::Exception& )
+ {
+ // TODO: Error handling
+ }
+ }
+
+ return 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( const 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 css::lang::EventObject& aSource )
+{
+ if ( m_xComponent.is() && m_xComponent == aSource.Source )
+ {
+ m_xComponent = nullptr;
+ if ( m_bWaitForClose )
+ {
+ m_bWaitForClose = false;
+ FreeOffice();
+ }
+ }
+
+ if( m_xFrame.is() && m_xFrame == aSource.Source )
+ {
+ m_xHatchWindow.clear();
+ m_xOwnWindow.clear();
+ m_xFrame.clear();
+ }
+}
+
+
+void SAL_CALL DocumentHolder::queryClosing( const lang::EventObject& aSource, sal_Bool /*bGetsOwnership*/ )
+{
+ if ( m_xComponent.is() && m_xComponent == aSource.Source && !m_bAllowClosing )
+ throw util::CloseVetoException("To close an embedded document, close the document holder (document definition), not the document itself.", static_cast< ::cppu::OWeakObject*>(this));
+}
+
+
+void SAL_CALL DocumentHolder::notifyClosing( const lang::EventObject& aSource )
+{
+ if ( m_xComponent.is() && m_xComponent == aSource.Source )
+ {
+ m_xComponent = nullptr;
+ if ( m_bWaitForClose )
+ {
+ m_bWaitForClose = false;
+ FreeOffice();
+ }
+ }
+
+ if( m_xFrame.is() && m_xFrame == aSource.Source )
+ {
+ m_xHatchWindow.clear();
+ m_xOwnWindow.clear();
+ m_xFrame.clear();
+ }
+}
+
+
+void SAL_CALL DocumentHolder::queryTermination( const lang::EventObject& )
+{
+ if ( m_bWaitForClose )
+ throw frame::TerminationVetoException();
+}
+
+
+void SAL_CALL DocumentHolder::notifyTermination( const lang::EventObject& aSource )
+{
+ OSL_ENSURE( !m_xComponent.is(), "Just a disaster..." );
+
+ uno::Reference< frame::XDesktop > xDesktop( aSource.Source, uno::UNO_QUERY );
+ m_bDesktopTerminated = true;
+ if ( xDesktop.is() )
+ xDesktop->removeTerminateListener( static_cast<frame::XTerminateListener*>(this) );
+}
+
+
+void SAL_CALL DocumentHolder::modified( const lang::EventObject& aEvent )
+{
+ // 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( "OnVisAreaChanged" );
+}
+
+
+void SAL_CALL DocumentHolder::notifyEvent( const document::EventObject& Event )
+{
+ if( m_pEmbedObj && Event.Source == m_xComponent )
+ {
+ // for now the ignored events are not forwarded, but sent by the object itself
+ if ( !Event.EventName.startsWith( "OnSave" )
+ && !Event.EventName.startsWith( "OnSaveDone" )
+ && !Event.EventName.startsWith( "OnSaveAs" )
+ && !Event.EventName.startsWith( "OnSaveAsDone" )
+ && !( Event.EventName.startsWith( "OnVisAreaChanged" ) && m_nNoResizeReact ) )
+ m_pEmbedObj->PostEvent_Impl( Event.EventName );
+ }
+}
+
+
+void SAL_CALL DocumentHolder::borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject,
+ const frame::BorderWidths& aNewSize )
+{
+ // 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 )
+{
+ // 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 )
+{
+ // 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( )
+{
+ if ( !(m_pEmbedObj->getStatus(embed::Aspects::MSOLE_CONTENT)&embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) )
+ return;
+
+ 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 ( const css::embed::StateChangeInProgressException& )
+ {
+ // must catch this exception because focus is grabbed while UI activation in doVerb()
+ }
+ catch ( const css::uno::Exception& )
+ {
+ // no outgoing exceptions specified here
+ }
+ }
+ else
+ {
+ uno::Reference< frame::XFramesSupplier > xSupp = m_xFrame->getCreator();
+ 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( )
+{
+ // deactivation is too unspecific to be useful; usually we only trigger code from activation
+ // so UIDeactivation is actively triggered by the container
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */