summaryrefslogtreecommitdiff
path: root/framework/source/services/frame.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/services/frame.cxx')
-rw-r--r--framework/source/services/frame.cxx3305
1 files changed, 3305 insertions, 0 deletions
diff --git a/framework/source/services/frame.cxx b/framework/source/services/frame.cxx
new file mode 100644
index 000000000000..e4d5655ca5f0
--- /dev/null
+++ b/framework/source/services/frame.cxx
@@ -0,0 +1,3305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <services/frame.hxx>
+#include <dispatch/dispatchprovider.hxx>
+
+#include <dispatch/interceptionhelper.hxx>
+#include <dispatch/closedispatcher.hxx>
+#include <dispatch/windowcommanddispatch.hxx>
+#include <loadenv/loadenv.hxx>
+#include <helper/oframes.hxx>
+#include <helper/statusindicatorfactory.hxx>
+#include <framework/titlehelper.hxx>
+#include <classes/droptargetlistener.hxx>
+#include <classes/taskcreator.hxx>
+#include <loadenv/targethelper.hxx>
+#include <framework/framelistanalyzer.hxx>
+#include <helper/dockingareadefaultacceptor.hxx>
+#include <dispatch/dispatchinformationprovider.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <pattern/window.hxx>
+#include <services.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/sequenceashashmap.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/proptypehlp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#ifdef ENABLE_ASSERTIONS
+ #ifndef _RTL_STRBUF_HXX_
+ #include <rtl/strbuf.hxx>
+ #endif
+#endif
+
+#include <vcl/menu.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+css::uno::WeakReference< css::frame::XFrame > Frame::m_xCloserFrame = css::uno::WeakReference< css::frame::XFrame >();
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_21 ( Frame ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::frame::XFramesSupplier ),
+ DIRECT_INTERFACE(css::frame::XFrame ),
+ DIRECT_INTERFACE(css::lang::XComponent ),
+ DIRECT_INTERFACE(css::task::XStatusIndicatorFactory ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchInformationProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchProviderInterception ),
+ DIRECT_INTERFACE(css::beans::XPropertySet ),
+ DIRECT_INTERFACE(css::beans::XPropertySetInfo ),
+ DIRECT_INTERFACE(css::awt::XWindowListener ),
+ DIRECT_INTERFACE(css::awt::XTopWindowListener ),
+ DIRECT_INTERFACE(css::awt::XFocusListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener, css::awt::XWindowListener ),
+ DIRECT_INTERFACE(css::document::XActionLockable ),
+ DIRECT_INTERFACE(css::util::XCloseable ),
+ DIRECT_INTERFACE(css::util::XCloseBroadcaster ),
+ DIRECT_INTERFACE(css::frame::XComponentLoader ),
+ DIRECT_INTERFACE(css::frame::XTitle ),
+ DIRECT_INTERFACE(css::frame::XTitleChangeBroadcaster )
+ )
+
+DEFINE_XTYPEPROVIDER_20 ( Frame ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XFramesSupplier ,
+ css::frame::XFrame ,
+ css::lang::XComponent ,
+ css::task::XStatusIndicatorFactory ,
+ css::beans::XPropertySet ,
+ css::beans::XPropertySetInfo ,
+ css::frame::XDispatchProvider ,
+ css::frame::XDispatchInformationProvider ,
+ css::frame::XDispatchProviderInterception ,
+ css::awt::XWindowListener ,
+ css::awt::XTopWindowListener ,
+ css::awt::XFocusListener ,
+ css::lang::XEventListener ,
+ css::util::XCloseable ,
+ css::util::XCloseBroadcaster ,
+ css::frame::XComponentLoader ,
+ css::frame::XTitle ,
+ css::frame::XTitleChangeBroadcaster
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( Frame ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_FRAME ,
+ IMPLEMENTATIONNAME_FRAME
+ )
+
+DEFINE_INIT_SERVICE ( Frame,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY_THROW);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new dispatchhelper-object to handle dispatches.
+ // We use these helper as slave for our interceptor helper ... not directly!
+ // But he is event listener on THIS instance!
+ DispatchProvider* pDispatchHelper = new DispatchProvider( m_xFactory, this );
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ DispatchInformationProvider* pInfoHelper = new DispatchInformationProvider(m_xFactory, this);
+ m_xDispatchInfoHelper = css::uno::Reference< css::frame::XDispatchInformationProvider >( static_cast< ::cppu::OWeakObject* >(pInfoHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
+ // Set created dispatch provider as slowest slave of it.
+ // Hold interception helper by reference only - not by pointer!
+ // So it's easiear to destroy it.
+ InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
+ m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
+ // We hold member as reference ... not as pointer too!
+ // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
+ // But look on dispose() for right order of deinitialization.
+ OFrames* pFramesHelper = new OFrames( m_xFactory, this, &m_aChildFrameContainer );
+ m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a the drop target listener.
+ // We hold member as reference ... not as pointer too!
+ DropTargetListener* pDropListener = new DropTargetListener( m_xFactory, this );
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >( static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY );
+
+ // Safe impossible cases
+ // We can't work without these helpers!
+ LOG_ASSERT2( xDispatchProvider.is ()==sal_False, "Frame::impl_initService()", "Slowest slave for dispatch- and interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" )
+ LOG_ASSERT2( m_xDispatchHelper.is ()==sal_False, "Frame::impl_initService()", "Interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" )
+ LOG_ASSERT2( m_xFramesHelper.is ()==sal_False, "Frame::impl_initService()", "Frames helper isn't valid. XFrames, XIndexAccess and XElementAcces are not supported!" )
+ LOG_ASSERT2( m_xDropTargetListener.is()==sal_False, "Frame::impl_initService()", "DropTarget helper isn't valid. Drag and drop without functionality!" )
+
+ //-------------------------------------------------------------------------------------------------------------
+ // establish notifies for changing of "disabled commands" configuration during runtime
+ m_aCommandOptions.EstablisFrameCallback(this);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Create an initial layout manager
+ // Create layout manager and connect it to the newly created frame
+ m_xLayoutManager = css::uno::Reference< css::frame::XLayoutManager >(m_xFactory->createInstance(SERVICENAME_LAYOUTMANAGER), css::uno::UNO_QUERY);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // set information about all supported properties at the base class helper PropertySetHelper
+ impl_initializePropInfo();
+ }
+ )
+
+/*-****************************************************************************************************//**
+ @short standard constructor to create instance by factory
+ @descr This constructor initialize a new instance of this class by valid factory,
+ and will be set valid values on his member and baseclasses.
+
+ @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
+ will get over this. (e.g. using of your reference as parameter to initialize some member)
+ Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
+ b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
+ The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
+ If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
+ I don't know why! (other compiler not tested .. but it works!)
+
+ @seealso method DEFINE_INIT_SERVICE()
+
+ @param "xFactory" is the multi service manager, which create this instance.
+ The value must be different from NULL!
+ @return -
+
+ @onerror ASSERT in debug version or nothing in relaese version.
+*//*-*****************************************************************************************************/
+Frame::Frame( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , TransactionBase ( )
+ , PropertySetHelper ( xFactory,
+ &m_aLock,
+ &m_aTransactionManager,
+ sal_False) // sal_False => dont release shared mutex on calling us!
+ , ::cppu::OWeakObject ( )
+ // init member
+ , m_xFactory ( xFactory )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_xParent ( )
+ , m_xContainerWindow ( )
+ , m_xComponentWindow ( )
+ , m_xController ( )
+ , m_eActiveState ( E_INACTIVE )
+ , m_sName ( )
+ , m_bIsFrameTop ( sal_True ) // I think we are top without a parent ... and there is no parent yet!
+ , m_bConnected ( sal_False ) // There exist no component inside of use => sal_False, we are not connected!
+ , m_nExternalLockCount ( 0 )
+ , m_bSelfClose ( sal_False ) // Important!
+ , m_bIsHidden ( sal_True )
+ , m_xTitleHelper ( )
+ , m_pWindowCommandDispatch ( 0 )
+ , m_aChildFrameContainer ( )
+{
+ // Check incoming parameter to avoid against wrong initialization.
+ LOG_ASSERT2( implcp_ctor( xFactory ), "Frame::Frame()", "Invalid parameter detected!" )
+
+ /* Please have a look on "@attentions" of description before! */
+}
+
+/*-****************************************************************************************************//**
+ @short standard destructor
+ @descr This one do NOTHING! Use dispose() instaed of this.
+
+ @seealso method dispose()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+Frame::~Frame()
+{
+ LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "Frame::~Frame()", "Who forgot to dispose this service?" )
+}
+
+/*-************************************************************************************************************//**
+ @interface XComponentLoader
+ @short try to load given URL into a task
+ @descr You can give us some informations about the content, which you will load into a frame.
+ We search or create this target for you, make a type detection of given URL and try to load it.
+ As result of this operation we return the new created component or nothing, if loading failed.
+
+ @seealso -
+
+ @param "sURL" , URL, which represant the content
+ @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
+ @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
+ @param "lArguments" , optional arguments for loading
+ @return A valid component reference, if loading was successfully.
+ A null reference otherwise.
+
+ @onerror We return a null reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::lang::XComponent > SAL_CALL Frame::loadComponentFromURL( const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
+ css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException )
+{
+ {
+ // If the frame is closed the call might lead to crash even with target "_blank",
+ // so the DisposedException should be thrown in this case
+ // It still looks to be too dangerous to set the transaction for the whole loading process
+ // so the guard is used in scopes to let the standard check be used
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ }
+
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
+ aReadLock.unlock();
+
+ return LoadEnv::loadComponentFromURL(xThis, xSMGR, sURL, sTargetFrameName, nSearchFlags, lArguments);
+}
+
+/*-****************************************************************************************************//**
+ @short return access to append or remove childs on desktop
+ @descr We don't implement these interface directly. We use a helper class to do this.
+ If you wish to add or delete childs to/from the container, call these method to get
+ a reference to the helper.
+
+ @seealso class OFrames
+
+ @param -
+ @return A reference to the helper which answer your queries.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrames > SAL_CALL Frame::getFrames() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+
+/*TODO
+ This is a temp. HACK!
+ Our parent (a Task!) stand in close/dispose and set working mode to E_BEFOERECLOSE
+ and call dispose on us! We tra to get this xFramesHelper and are reject by an "already closed" pranet instance ....
+ => We use SOFTEXCEPTIONS here ... but we should make it right in further times ....
+ */
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Return access to all child frames to caller.
+ // Ouer childframe container is implemented in helper class OFrames and used as a reference m_xFramesHelper!
+ return m_xFramesHelper;
+}
+
+/*-****************************************************************************************************//**
+ @short get the current active child frame
+ @descr It must be a frameto. Direct childs of a frame are frames only! No task or desktop is accepted.
+ We don't save this information directly in this class. We use ouer container-helper
+ to do that.
+
+ @seealso class OFrameContainer
+ @seealso method setActiveFrame()
+
+ @param -
+ @return A reference to ouer current active childframe, if anyone exist.
+ @return A null reference, if nobody is active.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::getActiveFrame() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Return current active frame.
+ // This information is avaliable on the container.
+ return m_aChildFrameContainer.getActive();
+}
+
+/*-****************************************************************************************************//**
+ @short set the new active direct child frame
+ @descr It must be a frame to. Direct childs of frame are frames only! No task or desktop is accepted.
+ We don't save this information directly in this class. We use ouer container-helper
+ to do that.
+
+ @seealso class OFrameContainer
+ @seealso method getActiveFrame()
+
+ @param "xFrame", reference to new active child. It must be an already existing child!
+ @return -
+
+ @onerror An assertion is thrown and element is ignored, if given frame is'nt already a child of us.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameters.
+ LOG_ASSERT2( implcp_setActiveFrame( xFrame ), "Frame::setActiveFrame()", "Invalid parameter detected!" )
+ // Look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member for threadsafe access!
+ // m_aChildFrameContainer is threadsafe himself and he live if we live!!!
+ // ...and our transaction is non breakable too ...
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
+ EActiveState eActiveState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ // Don't work, if "new" active frame is'nt different from current one!
+ // (xFrame==NULL is allowed to UNSET it!)
+ if( xActiveChild != xFrame )
+ {
+ // ... otherwise set new and deactivate old one.
+ m_aChildFrameContainer.setActive( xFrame );
+ if (
+ ( eActiveState != E_INACTIVE ) &&
+ ( xActiveChild.is() == sal_True )
+ )
+ {
+ xActiveChild->deactivate();
+ }
+ }
+
+ if( xFrame.is() == sal_True )
+ {
+ // If last active frame had focus ...
+ // ... reset state to ACTIVE and send right FrameActionEvent for focus lost.
+ if( eActiveState == E_FOCUS )
+ {
+ aWriteLock.lock();
+ eActiveState = E_ACTIVE ;
+ m_eActiveState = eActiveState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
+ }
+
+ // If last active frame was active ...
+ // but new one isn't it ...
+ // ... set it as active one.
+ if (
+ ( eActiveState == E_ACTIVE ) &&
+ ( xFrame->isActive() == sal_False )
+ )
+ {
+ xFrame->activate();
+ }
+ }
+ else
+ // If this frame is active and has no active subframe anymore it is UI active too
+ if( eActiveState == E_ACTIVE )
+ {
+ aWriteLock.lock();
+ eActiveState = E_FOCUS ;
+ m_eActiveState = eActiveState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
+ }
+}
+
+/*-****************************************************************************************************//**
+ initialize new created layout manager
+**/
+void lcl_enableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ // Provide container window to our layout manager implementation
+ xLayoutManager->attachFrame(xFrame);
+
+ css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xFrame->addFrameActionListener(xListen);
+
+ DockingAreaDefaultAcceptor* pAcceptor = new DockingAreaDefaultAcceptor(xFrame);
+ css::uno::Reference< css::ui::XDockingAreaAcceptor > xDockingAreaAcceptor( static_cast< ::cppu::OWeakObject* >(pAcceptor), css::uno::UNO_QUERY_THROW);
+ xLayoutManager->setDockingAreaAcceptor(xDockingAreaAcceptor);
+}
+
+/*-****************************************************************************************************//**
+ deinitialize layout manager
+**/
+void lcl_disableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xFrame->removeFrameActionListener(xListen);
+ xLayoutManager->setDockingAreaAcceptor(css::uno::Reference< css::ui::XDockingAreaAcceptor >());
+ xLayoutManager->attachFrame(css::uno::Reference< css::frame::XFrame >());
+}
+
+/*-****************************************************************************************************//**
+ @short initialize frame instance
+ @descr A frame needs a window. This method set a new one ... but should called one times only!
+ We use this window to listen for window events and forward it to our set component.
+ Its used as parent of component window too.
+
+ @seealso method getContainerWindow()
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+
+ @param "xWindow", reference to new container window - must be valid!
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ if (!xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Frame::initialize() called without a valid container window reference.")),
+ static_cast< css::frame::XFrame* >(this));
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( m_xContainerWindow.is() )
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Frame::initialized() is called more then once, which isnt usefull nor allowed.")),
+ static_cast< css::frame::XFrame* >(this));
+
+ // Look for rejected calls first!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ // Enable object for real working ... so follow impl methods don't must handle it special! (e.g. E_SOFTEXCEPTIONS for rejected calls)
+ m_aTransactionManager.setWorkingMode( E_WORK );
+
+ // This must be the first call of this method!
+ // We should initialize our object and open it for working.
+ // Set the new window.
+ LOG_ASSERT2( m_xContainerWindow.is()==sal_True, "Frame::initialize()", "Leak detected! This state should never occure ..." )
+ m_xContainerWindow = xWindow;
+
+ // if window is initially visible, we will never get a windowShowing event
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (pWindow && pWindow->IsVisible())
+ m_bIsHidden = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager = m_xLayoutManager;
+
+ // Release lock ... because we call some impl methods, which are threadsafe by himself.
+ // If we hold this lock - we will produce our own deadlock!
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if (xLayoutManager.is())
+ lcl_enableLayoutManager(xLayoutManager, this);
+
+ // create progress helper
+ css::uno::Reference< css::frame::XFrame > xThis (static_cast< css::frame::XFrame* >(this) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xIndicatorFactory(xSMGR->createInstance(IMPLEMENTATIONNAME_STATUSINDICATORFACTORY), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::lang::XInitialization > xIndicatorInit (xIndicatorFactory , css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ css::beans::NamedValue aArg;
+ aArg.Name = STATUSINDICATORFACTORY_PROPNAME_FRAME;
+ aArg.Value <<= xThis;
+ lArgs[0] <<= aArg;
+ aArg.Name = STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW;
+ aArg.Value <<= sal_True;
+ lArgs[1] <<= aArg;
+ xIndicatorInit->initialize(lArgs);
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_xIndicatorFactoryHelper = xIndicatorFactory;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // Start listening for events after setting it on helper class ...
+ // So superflous messages are filtered to NULL :-)
+ implts_startWindowListening();
+
+ impl_enablePropertySet();
+
+ m_pWindowCommandDispatch = new WindowCommandDispatch(xSMGR, this);
+
+ // Initialize title functionality
+ TitleHelper* pTitleHelper = new TitleHelper(xSMGR);
+ m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pTitleHelper), css::uno::UNO_QUERY_THROW);
+ pTitleHelper->setOwner(xThis);
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set container window
+ @descr The ContainerWindow property is used as a container for the component
+ in this frame. So this object implements a container interface too.
+ The instantiation of the container window is done by the user of this class.
+ The frame is the owner of its container window.
+
+ @seealso method initialize()
+
+ @param -
+ @return A reference to current set containerwindow.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getContainerWindow() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xContainerWindow;
+}
+
+/*-****************************************************************************************************//**
+ @short set parent frame
+ @descr We need a parent to support some functionality! e.g. findFrame()
+ By the way we use the chance to set an internal information about our top state.
+ So we must not check this information during every isTop() call.
+ We are top, if our parent is the desktop instance or we havent any parent.
+
+ @seealso getCreator()
+ @seealso findFrame()
+ @seealso isTop()
+ @seealos m_bIsFrameTop
+
+ @param xCreator
+ valid reference to our new owner frame, which should implement a supplier interface
+
+ @threadsafe yes
+ @modified 08.05.2002 09:35, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xParent = xCreator;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDesktop > xIsDesktop( xCreator, css::uno::UNO_QUERY );
+ m_bIsFrameTop = ( xIsDesktop.is() || ! xCreator.is() );
+}
+
+/*-****************************************************************************************************//**
+ @short returns current parent frame
+ @descr The Creator is the parent frame container. If it is NULL, the frame is the uppermost one.
+
+ @seealso method setCreator()
+
+ @param -
+ @return A reference to current set parent frame container.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Frame::getCreator() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xParent;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set name of frame
+ @descr This name is used to find target of findFrame() or queryDispatch() calls.
+
+ @seealso method setName()
+
+ @param -
+ @return Current set name of frame.
+
+ @onerror An empty string is returned.
+*//*-*****************************************************************************************************/
+::rtl::OUString SAL_CALL Frame::getName() throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return m_sName;
+ /* } SAFE */
+}
+
+/*-****************************************************************************************************//**
+ @short set new name for frame
+ @descr This name is used to find target of findFrame() or queryDispatch() calls.
+
+ @attention Special names like "_blank", "_self" aren't allowed ...
+ "_beamer" or "_menubar" excepts this rule!
+
+ @seealso method getName()
+
+ @param "sName", new frame name.
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ // Set new name ... but look for invalid special target names!
+ // They are not allowed to set.
+ if (TargetHelper::isValidNameForFrame(sName))
+ m_sName = sName;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+/*-****************************************************************************************************//**
+ @short search for frames
+ @descr This method searches for a frame with the specified name.
+ Frames may contain other frames (e.g. a frameset) and may
+ be contained in other frames. This hierarchie ist searched by
+ this method.
+ First some special names are taken into account, i.e. "",
+ "_self", "_top", "_blank" etc. The nSearchFlags are ignored
+ when comparing these names with sTargetFrameName, further steps are
+ controlled by the search flags. If allowed, the name of the frame
+ itself is compared with the desired one, then ( again if allowed )
+ the method findFrame() is called for all children, for siblings
+ and as last for the parent frame.
+ If no frame with the given name is found until the top frames container,
+ a new top one is created, if this is allowed by a special
+ flag. The new frame also gets the desired name.
+
+ @param sTargetFrameName
+ special names (_blank, _self) or real name of target frame
+ @param nSearchFlags
+ optional flags which regulate search for non special target frames
+
+ @return A reference to found or may be new created frame.
+ @threadsafe yes
+ @modified 16.05.2002 11:08, as96863
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XFrame > xTarget;
+
+ //-----------------------------------------------------------------------------------------------------
+ // 0) Ignore wrong parameter!
+ // We doesn't support search for following special targets.
+ // If we reject this requests - we mustnt check for such names
+ // in following code again and again. If we do not so -wrong
+ // search results can occure!
+ //-----------------------------------------------------------------------------------------------------
+ if (
+ (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_HELPAGENT) // valid for dispatches - not for findFrame()!
+ )
+ {
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I) check for special defined targets first which must be handled exclusive.
+ // force using of "if() else if() ..."
+ //-----------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ sal_Bool bIsTopFrame = m_bIsFrameTop;
+ sal_Bool bIsTopWindow = WindowHelper::isTopWindow(m_xContainerWindow);
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.I) "_blank"
+ // Not allowed for a normal frame - but for the desktop.
+ // Use helper class to do so. It use the desktop automaticly.
+ //-----------------------------------------------------------------------------------------------------
+ if ( sTargetFrameName==SPECIALTARGET_BLANK )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.II) "_parent"
+ // It doesn't matter if we have a valid parent or not. User ask for him and get it.
+ // An empty result is a valid result too.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_PARENT )
+ {
+ xTarget = xParent;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.III) "_top"
+ // If we are not the top frame in this hierarchy, we must forward request to our parent.
+ // Otherwhise we must return ourself.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_TOP )
+ {
+ if (bIsTopFrame)
+ xTarget = this;
+ else
+ if (xParent.is()) // If we are not top - the parent MUST exist. But may it's better to check it again .-)
+ xTarget = xParent->findFrame(SPECIALTARGET_TOP,0);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.IV) "_self", ""
+ // This mean this frame in every case.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (
+ ( sTargetFrameName==SPECIALTARGET_SELF ) ||
+ ( sTargetFrameName.getLength()<1 )
+ )
+ {
+ xTarget = this;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.V) "_beamer"
+ // This is a special sub frame of any task. We must return it if we found it on our direct childrens
+ // or create it there if it not already exists.
+ // Note: Such beamer exists for task(top) frames only!
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_BEAMER )
+ {
+ // We are a task => search or create the beamer
+ if (bIsTopWindow)
+ {
+ xTarget = m_aChildFrameContainer.searchOnDirectChildrens(SPECIALTARGET_BEAMER);
+ if ( ! xTarget.is() )
+ {
+ /* TODO
+ Creation not supported yet!
+ Wait for new layout manager service because we can't plug it
+ inside already opened document of this frame ...
+ */
+ }
+ }
+ // We arent a task => forward request to our parent or ignore it.
+ else
+ if (xParent.is())
+ xTarget = xParent->findFrame(SPECIALTARGET_BEAMER,0);
+ }
+
+ else
+ {
+ //-------------------------------------------------------------------------------------------------
+ // II) otherwhise use optional given search flags
+ // force using of combinations of such flags. means no "else" part of use if() statements.
+ // But we ust break further searches if target was already found.
+ // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
+ // TASK and CREATE are handled special.
+ //-------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ aReadLock.lock();
+ ::rtl::OUString sOwnName = m_sName;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-------------------------------------------------------------------------------------------------
+ // II.I) SELF
+ // Check for right name. If it's the searched one return ourself - otherwhise
+ // ignore this flag.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
+ (sOwnName == sTargetFrameName )
+ )
+ {
+ xTarget = this;
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.II) CHILDREN
+ // Search on all children for the given target name.
+ // An empty name value can't occure here - because it must be already handled as "_self"
+ // before. Used helper function of container doesn't create any frame.
+ // It makes a deep search only.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
+ )
+ {
+ xTarget = m_aChildFrameContainer.searchOnAllChildrens(sTargetFrameName);
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.III) TASKS
+ // This is a special flag. It regulate search on this task tree only or allow search on
+ // all other ones (which are sibling trees of us) too.
+ // Upper search must stop at this frame if we are the topest one and the TASK flag isn't set
+ // or we can ignore it if we have no valid parent.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( bIsTopFrame && (nSearchFlags & css::frame::FrameSearchFlag::TASKS) ) ||
+ ( ! bIsTopFrame )
+ )
+ {
+ //-------------------------------------------------------------------------------------------------
+ // II.III.I) SIBLINGS
+ // Search on all our direct siblings - means all childrens of our parent.
+ // Use this flag in combination with TASK. We must supress such upper search if
+ // user has not set it and if we are a top frame.
+ // Attention: Don't forward this request to our parent as a findFrame() call.
+ // In such case we must protect us against recursive calls.
+ // Use snapshot of our parent. But don't use queryFrames() of XFrames interface.
+ // Because it's return all siblings and all her childrens including our children too
+ // if we call it with the CHILDREN flag. We doesn't need that - we need the direct container
+ // items of our parent only to start searches there. So we must use the container interface
+ // XIndexAccess instead of XFrames.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::SIBLINGS) &&
+ ( xParent.is() ) // search on siblings is impossible without a parent
+ )
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
+ if (xSupplier.is())
+ {
+ css::uno::Reference< css::container::XIndexAccess > xContainer( xSupplier->getFrames(), css::uno::UNO_QUERY );
+ if (xContainer.is())
+ {
+ sal_Int32 nCount = xContainer->getCount();
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ css::uno::Reference< css::frame::XFrame > xSibling;
+ if (
+ ( !(xContainer->getByIndex(i)>>=xSibling) ) || // control unpacking
+ ( ! xSibling.is() ) || // check for valid items
+ ( xSibling==static_cast< ::cppu::OWeakObject* >(this) ) // ignore ourself! (We are a part of this container too - but search on our children was already done.)
+ )
+ {
+ continue;
+ }
+
+ // Don't allow upper search here! Use rigth flags to regulate it.
+ // And allow deep search on children only - if it was allowed for us too.
+ sal_Int32 nRightFlags = css::frame::FrameSearchFlag::SELF;
+ if (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
+ nRightFlags |= css::frame::FrameSearchFlag::CHILDREN;
+ xTarget = xSibling->findFrame(sTargetFrameName, nRightFlags );
+ // perform search be breaking further search if a result exist.
+ if (xTarget.is())
+ break;
+ }
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.III.II) PARENT
+ // Forward search to our parent (if he exists.)
+ // To prevent us against recursive and superflous calls (which can occure if we allow him
+ // to search on his childrens too) we must change used search flags.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::PARENT) &&
+ ( xParent.is() )
+ )
+ {
+ if (xParent->getName() == sTargetFrameName)
+ xTarget = xParent;
+ else
+ {
+ sal_Int32 nRightFlags = nSearchFlags;
+ nRightFlags &= ~css::frame::FrameSearchFlag::CHILDREN;
+ xTarget = xParent->findFrame(sTargetFrameName, nRightFlags);
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.IV) CREATE
+ // If we haven't found any valid target frame by using normal flags - but user allowed us to create
+ // a new one ... we should do that. Used TaskCreator use Desktop instance automaticly as parent!
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
+ )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+ }
+
+ return xTarget;
+}
+
+/*-****************************************************************************************************//**
+ @short -
+ @descr Returns sal_True, if this frame is a "top frame", otherwise sal_False.
+ The "m_bIsFrameTop" member must be set in the ctor or setCreator() method.
+ A top frame is a member of the top frame container or a member of the
+ task frame container. Both containers can create new frames if the findFrame()
+ method of their css::frame::XFrame interface is called with a frame name not yet known.
+
+ @seealso ctor
+ @seealso method setCreator()
+ @seealso method findFrame()
+
+ @param -
+ @return true, if is it a top frame ... false otherwise.
+
+ @onerror No error should occure!
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::isTop() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // This information is set in setCreator().
+ // We are top, if ouer parent is a task or the desktop or if no parent exist!
+ return m_bIsFrameTop;
+}
+
+/*-****************************************************************************************************//**
+ @short activate frame in hierarchy
+ @descr This feature is used to mark active pathes in our frame hierarchy.
+ You can be a listener for this event to react for it ... change some internal states or something else.
+
+ @seealso method deactivate()
+ @seealso method isActivate()
+ @seealso enum EActiveState
+ @seealso listener mechanism
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::activate() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member and free the lock.
+ // It's not neccessary for m_aChildFrameContainer ... because
+ // he is threadsafe himself and live if we live.
+ // We use a registered transaction to prevent us against
+ // breaks during this operation!
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive() ;
+ css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY ) ;
+ css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( m_xComponentWindow, css::uno::UNO_QUERY ) ;
+ EActiveState eState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ //_________________________________________________________________________________________________________
+ // 1) If I'am not active before ...
+ if( eState == E_INACTIVE )
+ {
+ // ... do it then.
+ aWriteLock.lock();
+ eState = E_ACTIVE;
+ m_eActiveState = eState;
+ aWriteLock.unlock();
+ // Deactivate sibling path and forward activation to parent ... if any parent exist!
+ if( xParent.is() == sal_True )
+ {
+ // Everytime set THIS frame as active child of parent and activate it.
+ // We MUST have a valid path from bottom to top as active path!
+ // But we must deactivate the old active sibling path first.
+
+ // Attention: Deactivation of an active path, deactivate the whole path ... from bottom to top!
+ // But we wish to deactivate founded sibling-tree only.
+ // [ see deactivate() / step 4) for further informations! ]
+
+ xParent->setActiveFrame( xThis );
+
+ // Then we can activate from here to top.
+ // Attention: We are ACTIVE now. And the parent will call activate() at us!
+ // But we do nothing then! We are already activated.
+ xParent->activate();
+ }
+ // Its neccessary to send event NOW - not before.
+ // Activation goes from bottom to top!
+ // Thats the reason to activate parent first and send event now.
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_ACTIVATED );
+ }
+
+ //_________________________________________________________________________________________________________
+ // 2) I was active before or current activated and there is a path from here to bottom, who CAN be active.
+ // But ouer direct child of path is not active yet.
+ // (It can be, if activation occur in the middle of a current path!)
+ // In these case we activate path to bottom to set focus on right frame!
+ if (
+ ( eState == E_ACTIVE ) &&
+ ( xActiveChild.is() == sal_True ) &&
+ ( xActiveChild->isActive() == sal_False )
+ )
+ {
+ xActiveChild->activate();
+ }
+
+ //_________________________________________________________________________________________________________
+ // 3) I was active before or current activated. But if I have no active child => I will get the focus!
+ if (
+ ( eState == E_ACTIVE ) &&
+ ( xActiveChild.is() == sal_False )
+ )
+ {
+ aWriteLock.lock();
+ eState = E_FOCUS;
+ m_eActiveState = eState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short deactivate frame in hierarchy
+ @descr This feature is used to deactive pathes in our frame hierarchy.
+ You can be a listener for this event to react for it ... change some internal states or something else.
+
+ @seealso method activate()
+ @seealso method isActivate()
+ @seealso enum EActiveState
+ @seealso listener mechanism
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::deactivate() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member and free the lock.
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive() ;
+ css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY ) ;
+ css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ EActiveState eState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ // Work only, if there something to do!
+ if( eState != E_INACTIVE )
+ {
+ //_____________________________________________________________________________________________________
+ // 1) Deactivate all active childs.
+ if (
+ ( xActiveChild.is() == sal_True ) &&
+ ( xActiveChild->isActive() == sal_True )
+ )
+ {
+ xActiveChild->deactivate();
+ }
+
+ //_____________________________________________________________________________________________________
+ // 2) If I have the focus - I will lost it now.
+ if( eState == E_FOCUS )
+ {
+ // Set new state INACTIVE(!) and send message to all listener.
+ // Don't set ACTIVE as new state. This frame is deactivated for next time - due to activate().
+ aWriteLock.lock();
+ eState = E_ACTIVE;
+ m_eActiveState = eState ;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
+ }
+
+ //_____________________________________________________________________________________________________
+ // 3) If I'am active - I will be deactivated now.
+ if( eState == E_ACTIVE )
+ {
+ // Set new state and send message to all listener.
+ aWriteLock.lock();
+ eState = E_INACTIVE;
+ m_eActiveState = eState ;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_DEACTIVATING );
+ }
+
+ //_____________________________________________________________________________________________________
+ // 4) If there is a path from here to my parent ...
+ // ... I'am on the top or in the middle of deactivated subtree and action was started here.
+ // I must deactivate all frames from here to top, which are members of current path.
+ // Stop, if THESE frame not the active frame of ouer parent!
+ if (
+ ( xParent.is() == sal_True ) &&
+ ( xParent->getActiveFrame() == xThis )
+ )
+ {
+ // We MUST break the path - otherwise we will get the focus - not ouer parent! ...
+ // Attention: Ouer parent don't call us again - WE ARE NOT ACTIVE YET!
+ // [ see step 3 and condition "if ( m_eActiveState!=INACTIVE ) ..." in this method! ]
+ xParent->deactivate();
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short returns active state
+ @descr Call it to get informations about current active state of this frame.
+
+ @seealso method activate()
+ @seealso method deactivate()
+ @seealso enum EActiveState
+
+ @param -
+ @return true if active, false otherwise.
+
+ @onerror No error should occure.
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::isActive() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return (
+ ( m_eActiveState == E_ACTIVE ) ||
+ ( m_eActiveState == E_FOCUS )
+ );
+}
+
+/*-****************************************************************************************************//**
+ @short ???
+ @descr -
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::contextChanged() throw( css::uno::RuntimeException )
+{
+ // Look for rejected calls!
+ // Sometimes called during closing object... => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+ // Impl-method is threadsafe himself!
+ // Send event to all listener for frame actions.
+ implts_sendFrameActionEvent( css::frame::FrameAction_CONTEXT_CHANGED );
+}
+
+/*-****************************************************************************************************//**
+ @short set new component inside the frame
+ @descr A frame is a container for a component. Use this method to set, change or realease it!
+ We accept null references! The xComponentWindow will be a child of our container window
+ and get all window events from us.
+
+ @attention (a) A current set component can disagree with the suspend() request!
+ We don't set the new one and return with false then.
+ (b) It's possible to set:
+ (b1) a simple component here which supports the window only - no controller;
+ (b2) a full featured component which supports window and controller;
+ (b3) or both to NULL if outside code which to forget this component.
+
+ @seealso method getComponentWindow()
+ @seealso method getController()
+
+ @param xComponentWindow
+ valid reference to new component window which will be a child of internal container window
+ May <NULL/> for releasing.
+ @param xController
+ reference to new component controller
+ (may <NULL/> for relasing or setting of a simple component)
+
+ @return <TRUE/> if operation was successful, <FALSE/> otherwise.
+
+ @onerror We return <FALSE/>.
+ @threadsafe yes
+ @modified 06.05.2002 11:39, as96863
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::setComponent( const css::uno::Reference< css::awt::XWindow >& xComponentWindow ,
+ const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException )
+{
+ //_____________________________________________________________________________________________________
+ // Ignore this HACK of sfx2!
+ // He call us with an valid controller without a valid window ... Thats not allowed!
+ if ( xController.is() && ! xComponentWindow.is() )
+ return sal_True;
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ //_____________________________________________________________________________________________________
+ // Get threadsafe some copies of used members.
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ css::uno::Reference< css::awt::XWindow > xOldComponentWindow = m_xComponentWindow;
+ css::uno::Reference< css::frame::XController > xOldController = m_xController;
+ Window* pOwnWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ sal_Bool bHadFocus = pOwnWindow->HasChildPathFocus();
+ sal_Bool bWasConnected = m_bConnected;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //_____________________________________________________________________________________________________
+ // stop listening on old window
+ // May it produce some trouble.
+ // But don't forget to listen on new window again ... or reactivate listening
+ // if we reject this setComponent() request and leave this method without changing the old window.
+ implts_stopWindowListening();
+
+ // Notify all listener, that this component (if current one exist) will be unloaded.
+ if (bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_DETACHING );
+
+ //_____________________________________________________________________________________________________
+ // otherwhise release old component first
+ // Always release controller before releasing window,
+ // because controller may want to access its window!
+ // But check for real changes - may the new controller is the old one.
+ if (
+ (xOldController.is() ) &&
+ (xOldController != xController)
+ )
+ {
+ /* ATTENTION
+ Don't suspend the old controller here. Because the outside caller must do that
+ by definition. We have to dispose it here only.
+ */
+
+ // Before we dispose this controller we should hide it inside this frame instance.
+ // We hold it alive for next calls by using xOldController!
+ /* SAFE {*/
+ WriteGuard aWriteLock( m_aLock );
+ m_xController = NULL;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XComponent > xDisposable( xOldController, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ {
+ try
+ {
+ xDisposable->dispose();
+ }
+ catch(const css::lang::DisposedException&)
+ {}
+ }
+ xOldController = NULL;
+ }
+
+ //_____________________________________________________________________________________________________
+ // Now it's time to release the component window.
+ // If controller wasn't released successfully - this code line shouldn't be reached.
+ // Because in case of "suspend()==false" we return immediately with false ...
+ // see before
+ // Check for real changes too.
+ if (
+ (xOldComponentWindow.is() ) &&
+ (xOldComponentWindow != xComponentWindow)
+ )
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xComponentWindow = NULL;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XComponent > xDisposable( xOldComponentWindow, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ {
+ try
+ {
+ xDisposable->dispose();
+ }
+ catch(const css::lang::DisposedException&)
+ {}
+ }
+ xOldComponentWindow = NULL;
+ }
+
+ //_____________________________________________________________________________________________________
+ // Now it's time to set the new component ...
+ // By the way - find out our new "load state" - means if we have a valid component inside.
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xComponentWindow = xComponentWindow;
+ m_xController = xController ;
+ m_bConnected = (m_xComponentWindow.is() || m_xController.is());
+ sal_Bool bIsConnected = m_bConnected;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ //_____________________________________________________________________________________________________
+ // notifies all interest listener, that current component was changed or a new one was loaded
+ if (bIsConnected && bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_REATTACHED );
+ else
+ if (bIsConnected && !bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_ATTACHED );
+
+ //_____________________________________________________________________________________________________
+ // A new component window doesn't know anything about current active/focus states.
+ // Set this information on it!
+ if (
+ (bHadFocus ) &&
+ (xComponentWindow.is())
+ )
+ {
+ xComponentWindow->setFocus();
+ }
+
+ // If it was a new component window - we must resize it to fill out
+ // our container window.
+ implts_resizeComponentWindow();
+ // New component should change our current icon ...
+ implts_setIconOnWindow();
+ // OK - start listening on new window again - or do nothing if it is an empty one.
+ implts_startWindowListening();
+
+ /* SAFE { */
+ aWriteLock.lock();
+ impl_checkMenuCloser();
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ return sal_True;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set component window
+ @descr Frames are used to display components. The actual displayed component is
+ held by the m_xComponentWindow property. If the component implements only a
+ XComponent interface, the communication between the frame and the
+ component is very restricted. Better integration is achievable through a
+ XController interface.
+ If the component wants other objects to be able to get information about its
+ ResourceDescriptor it has to implement a XModel interface.
+ This frame is the owner of the component window.
+
+ @seealso method setComponent()
+
+ @param -
+ @return css::uno::Reference to current set component window.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getComponentWindow() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xComponentWindow;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set controller
+ @descr Frames are used to display components. The actual displayed component is
+ held by the m_xComponentWindow property. If the component implements only a
+ XComponent interface, the communication between the frame and the
+ component is very restricted. Better integration is achievable through a
+ XController interface.
+ If the component wants other objects to be able to get information about its
+ ResourceDescriptor it has to implement a XModel interface.
+ This frame is the owner of the component window.
+
+ @seealso method setComponent()
+
+ @param -
+ @return css::uno::Reference to current set controller.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XController > SAL_CALL Frame::getController() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xController;
+}
+
+/*-****************************************************************************************************//**
+ @short add/remove listener for activate/deactivate/contextChanged events
+ @descr -
+
+ @seealso method activate()
+ @seealso method deactivate()
+ @seealso method contextChanged()
+
+ @param "xListener" reference to your listener object
+ @return -
+
+ @onerror Listener is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_addFrameActionListener( xListener ), "Frame::addFrameActionListener()", "Invalid parameter detected." )
+ // Listener container is threadsafe by himself ... but we must look for rejected calls!
+ // Our OMenuDispatch-helper (is a member of ODispatchProvider!) is create at startup of this frame BEFORE initialize!
+ // => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_removeFrameActionListener( xListener ), "Frame::removeFrameActionListener()", "Invalid parameter detected." )
+ // Listener container is threadsafe by himself ... but we must look for rejected calls after disposing!
+ // But we must work with E_SOFTEXCEPTIONS ... because sometimes we are called from our listeners
+ // during dispose! Our work mode is E_BEFORECLOSE then ... and E_HARDEXCEPTIONS whould throw a DisposedException.
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
+}
+
+/*-****************************************************************************************************//**
+ @short support two way mechanism to release a frame
+ @descr This method ask internal component (controller) if he accept this close request.
+ In case of <TRUE/> nothing will be happen (from point of caller of this close method).
+ In case of <FALSE/> a CloseVetoException is thrown. After such exception given parameter
+ <var>bDeliverOwnerShip</var> regulate which will be the new owner of this instance.
+
+ @attention It's the replacement for XTask::close() which is marked as obsolete method.
+
+ @param bDeliverOwnerShip
+ If parameter is set to <FALSE/> the original caller will be the owner after thrown
+ veto exception and must try to close this frame at later time again. Otherwhise the
+ source of throwed exception is the right one. May it will be the frame himself.
+
+ @thrown CloseVetoException
+ if any internal things willn't be closed
+
+ @threadsafe yes
+ @modified 06.05.2002 08:33, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::close( sal_Bool bDeliverOwnerShip ) throw( css::util::CloseVetoException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // At the end of this method may we must dispose ourself ...
+ // and may nobody from outside hold a reference to us ...
+ // then it's a good idea to do that by ourself.
+ css::uno::Reference< css::uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
+
+ // Check any close listener before we look for currently running internal processes.
+ // Because if a listener disagree with this close() request - we hace time to finish this
+ // internal operations too ...
+ // Note: container is threadsafe himself.
+ css::lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((css::util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnerShip );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+
+ // Ok - no listener disagreed with this close() request
+ // check if this frame is used for any load process currently
+ if (isActionLocked())
+ {
+ if (bDeliverOwnerShip)
+ {
+ /* SAFE */
+ WriteGuard aWriteLock( m_aLock );
+ m_bSelfClose = sal_True;
+ aWriteLock.unlock();
+ /* SAFE */
+ }
+
+ throw css::util::CloseVetoException(DECLARE_ASCII("Frame in use for loading document ..."),static_cast< ::cppu::OWeakObject*>(this));
+ }
+
+ if ( ! setComponent(NULL,NULL) )
+ throw css::util::CloseVetoException(DECLARE_ASCII("Component couldn't be deattached ..."),static_cast< ::cppu::OWeakObject*>(this));
+
+ // If closing is allowed ... inform all istener and dispose this frame!
+ pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((css::util::XCloseListener*)pIterator.next())->notifyClosing( aSource );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_bIsHidden = sal_True;
+ aWriteLock.unlock();
+ /* } SAFE */
+ impl_checkMenuCloser();
+
+ // Attention: We must release our own registered transaction here. Otherwhise following dispose() call
+ // wait for us too ....
+ aTransaction.stop();
+ dispose();
+}
+
+/*-****************************************************************************************************//**
+ @short be a listener for close events!
+ @descr Adds/remove a CloseListener at this frame instance. If the close() method is called on
+ this object, the such listener are informed and can disagree with that by throwing
+ a CloseVetoException.
+
+ @seealso Frame::close()
+
+ @param xListener
+ reference to your listener object
+
+ @onerror Listener is ignored.
+
+ @threadsafe yes
+ @modified 06.05.2002 10:03, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ // We doesn't need any lock here ...
+ // Container lives if we live and is threadsafe by himself.
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
+{
+ // Use soft exception mode - moslty this method is called during disposing of this frame ...
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+ // We doesn't need any lock here ...
+ // Container lives if we live and is threadsafe by himself.
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+::rtl::OUString SAL_CALL Frame::getTitle()
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ return xTitle->getTitle();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::setTitle( const ::rtl::OUString& sTitle )
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->setTitle(sTitle);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->addTitleChangeListener(xListener);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->removeTitleChangeListener(xListener);
+}
+
+/*-****************************************************************************************************/
+void Frame::implts_forgetSubFrames()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::container::XIndexAccess > xContainer(m_xFramesHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ sal_Int32 c = xContainer->getCount();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ xContainer->getByIndex(i) >>= xFrame;
+ if (xFrame.is())
+ xFrame->setCreator(css::uno::Reference< css::frame::XFramesSupplier >());
+ }
+ catch(const css::uno::Exception&)
+ {
+ // Ignore errors here.
+ // Nobody can guarantee a stable index in multi threaded environments .-)
+ }
+ }
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xFramesHelper.clear(); // clear uno reference
+ m_aChildFrameContainer.clear(); // clear container content
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+/*-****************************************************************************************************//**
+ @short destroy instance
+ @descr The owner of this object calles the dispose method if the object
+ should be destroyed. All other objects and components, that are registered
+ as an EventListener are forced to release their references to this object.
+ Furthermore this frame is removed from its parent frame container to release
+ this reference. The reference attributes are disposed and released also.
+
+ @attention Look for globale description at beginning of file too!
+ (DisposedException, FairRWLock ..., initialize, dispose)
+
+ @seealso method initialize()
+ @seealso baseclass FairRWLockBase!
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::dispose() throw( css::uno::RuntimeException )
+{
+ // We should hold a reference to ourself ...
+ // because our owner dispose us and release our reference ...
+ // May be we will die before we could finish this method ...
+ css::uno::Reference< css::frame::XFrame > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ LOG_DISPOSEEVENT( "Frame", sName )
+
+ // First operation should be ... "stopp all listening for window events on our container window".
+ // These events are superflous but can make trouble!
+ // We will die, die and die ...
+ implts_stopWindowListening();
+
+ delete m_pWindowCommandDispatch;
+
+ // Send message to all listener and forget her references.
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ // set "end of live" for our property set helper
+ impl_disablePropertySet();
+
+ // interception/dispatch chain must be destructed explicitly
+ // Otherwhise some dispatches and/or interception objects wont die.
+ css::uno::Reference< css::lang::XEventListener > xDispatchHelper(m_xDispatchHelper, css::uno::UNO_QUERY_THROW);
+ xDispatchHelper->disposing(aEvent);
+ xDispatchHelper.clear();
+
+ // Disable this instance for further work.
+ // This will wait for all current running ones ...
+ // and reject all further requests!
+ m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
+
+ // Don't show any dialogs, errors or something else any more!
+ // If somewhere called dispose() whitout close() before - normaly no dialogs
+ // should exist. Otherwhise it's the problem of the outside caller.
+ // Note:
+ // (a) Do it after stopWindowListening(). May that force some active/deactive
+ // notifications which we doesn't need here realy.
+ // (b) Don't forget to save the old value of IsDialogCancelEnabled() to
+ // restore it afterwards. We cannot call EnableDialogCancel( sal_False )
+ // as we would kill the headless mode!
+ sal_Bool bCancelDialogs( Application::IsDialogCancelEnabled() );
+ Application::EnableDialogCancel( sal_True );
+
+ // We should be alone for ever and further dispose calls are rejected by lines before ...
+ // I hope it :-)
+
+ // Free references of our frame tree.
+ // Force parent container to forget this frame too ...
+ // ( It's contained in m_xParent and so no css::lang::XEventListener for m_xParent! )
+ // It's important to do that before we free some other internal structures.
+ // Because if our parent gets an activate and found us as last possible active frame
+ // he try to deactivate us ... and we run into some trouble (DisposedExceptions!).
+ if( m_xParent.is() == sal_True )
+ {
+ m_xParent->getFrames()->remove( xThis );
+ m_xParent = css::uno::Reference< css::frame::XFramesSupplier >();
+ }
+
+ /* } SAFE */
+ // Forget our internal component and her window first.
+ // So we can release our container window later without problems.
+ // Because this container window is the parent of the component window ...
+ // Note: Dispose it hard - because suspending must be done inside close() call!
+ // But try to dispose the controller first befor you destroy the window.
+ // Because the window is used by the controller too ...
+ if (m_xController.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xDisposable( m_xController, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+
+ if (m_xComponentWindow.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xDisposable( m_xComponentWindow, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+
+ impl_checkMenuCloser();
+
+ impl_disposeContainerWindow( m_xContainerWindow );
+
+ /*ATTENTION
+ Clear container after successful removing from parent container ...
+ because our parent could be the desktop which stand in dispose too!
+ If we have already cleared our own container we lost our child before this could be
+ remove himself at this instance ...
+ Release m_xFramesHelper after that ... it's the same problem between parent and child!
+ "m_xParent->getFrames()->remove( xThis );" needs this helper ...
+ Otherwise we get a null reference and could finish removing successfuly.
+ => You see: Order of calling operations is important!!!
+ */
+ implts_forgetSubFrames();
+
+ // Release some other references.
+ // This calls should be easy ... I hope it :-)
+ m_xDispatchHelper.clear();
+ m_xFactory.clear();
+ m_xDropTargetListener.clear();
+ m_xDispatchRecorderSupplier.clear();
+ m_xLayoutManager.clear();
+ m_xIndicatorFactoryHelper.clear();
+
+ // It's important to set default values here!
+ // If may be later somewhere change the disposed-behaviour of this implementation
+ // and doesn't throw any DisposedExceptions we must guarantee best matching default values ...
+ m_eActiveState = E_INACTIVE;
+ m_sName = ::rtl::OUString();
+ m_bIsFrameTop = sal_False;
+ m_bConnected = sal_False;
+ m_nExternalLockCount = 0;
+ m_bSelfClose = sal_False;
+ m_bIsHidden = sal_True;
+
+ // Disable this instance for further working realy!
+ m_aTransactionManager.setWorkingMode( E_CLOSE );
+
+ // Don't forget it restore old value -
+ // otherwhise no dialogs can be shown anymore in other frames.
+ Application::EnableDialogCancel( bCancelDialogs );
+}
+
+/*-****************************************************************************************************//**
+ @short Be a listener for dispose events!
+ @descr Adds/remove an EventListener to this object. If the dispose method is called on
+ this object, the disposing method of the listener is called.
+
+ @seealso -
+
+ @param "xListener" reference to your listener object.
+ @return -
+
+ @onerror Listener is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_addEventListener( xListener ), "Frame::addEventListener()", "Invalid parameter detected." )
+ // Look for rejected calls only!
+ // Container is threadsafe.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_removeEventListener( xListener ), "Frame::removeEventListener()", "Invalid parameter detected." )
+ // Look for rejected calls only!
+ // Container is threadsafe.
+ // Use E_SOFTEXCEPTIONS to allow removing listeners during dispose call!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+/*-****************************************************************************************************//**
+ @short create new status indicator
+ @descr Use returned status indicator to show progresses and some text informations.
+ All created objects share the same dialog! Only the last one can show his information.
+
+ @seealso class StatusIndicatorFactory
+ @seealso class StatusIndicator
+
+ @param -
+ @return A reference to created object.
+
+ @onerror We return a null reference.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::task::XStatusIndicator > SAL_CALL Frame::createStatusIndicator() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+ // Look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Make snapshot of neccessary member and define default return value.
+ css::uno::Reference< css::task::XStatusIndicator > xExternal(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory = m_xIndicatorFactoryHelper;
+
+ aReadLock.unlock();
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+
+ // Was set from outside to intercept any progress activities!
+ if (xExternal.is())
+ return xExternal;
+
+ // Or use our own factory as fallback, to create such progress.
+ if (xFactory.is())
+ return xFactory->createStatusIndicator();
+
+ return css::uno::Reference< css::task::XStatusIndicator >();
+}
+
+/*-****************************************************************************************************//**
+ @short search for target to load URL
+ @descr This method searches for a dispatch for the specified DispatchDescriptor.
+ The FrameSearchFlags and the FrameName of the DispatchDescriptor are
+ treated as described for findFrame.
+
+ @seealso method findFrame()
+ @seealso method queryDispatches()
+ @seealso method set/getName()
+ @seealso class TargetFinder
+
+ @param "aURL" , URL for loading
+ @param "sTargetFrameName" , name of target frame
+ @param "nSearchFlags" , additional flags to regulate search if sTargetFrameName isn't clear
+ @return css::uno::Reference to dispatch handler.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL Frame::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ const char UNO_PROTOCOL[] = ".uno:";
+
+ // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
+ // But look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
+ // in our hash map. All other protocols are stored with the protocol part.
+ String aCommand( aURL.Main );
+ if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
+ aCommand = aURL.Path;
+
+ // Make boost::unordered_map lookup if the current URL is in the disabled list
+ if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
+ return css::uno::Reference< css::frame::XDispatch >();
+ else
+ {
+ // We use a helper to support these interface and an interceptor mechanism.
+ // Our helper is threadsafe by himself!
+ return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short handle more then ones dispatches at same call
+ @descr Returns a sequence of dispatches. For details see the queryDispatch method.
+ For failed dispatches we return empty items in list!
+
+ @seealso method queryDispatch()
+
+ @param "lDescriptor" list of dispatch arguments for queryDispatch()!
+ @return List of dispatch references. Some elements can be NULL!
+
+ @onerror An empty list is returned.
+*//*-*****************************************************************************************************/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Frame::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
+{
+ // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
+ // But look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // We use a helper to support these interface and an interceptor mechanism.
+ // Our helper is threadsafe by himself!
+ return m_xDispatchHelper->queryDispatches( lDescriptor );
+}
+
+/*-****************************************************************************************************//**
+ @short register/unregister interceptor for dispatch calls
+ @descr If you whish to handle some dispatches by himself ... you should be
+ an interceptor for it. Please see class OInterceptionHelper for further informations.
+
+ @seealso class OInterceptionHelper
+
+ @param "xInterceptor", reference to your interceptor implementation.
+ @return -
+
+ @onerror Interceptor is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
+{
+ // We use a helper to support these interface and an interceptor mechanism.
+ // This helper is threadsafe himself and check incoming parameter too.
+ // I think we don't need any lock here!
+ // But we must look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
+{
+ // We use a helper to support these interface and an interceptor mechanism.
+ // This helper is threadsafe himself and check incoming parameter too.
+ // I think we don't need any lock here!
+ // But we must look for rejected calls ...
+ // Sometimes we are called during our dispose() method ... => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
+}
+
+/*-****************************************************************************************************//**
+ @short provides information about all possible dispatch functions
+ inside the currnt frame environment
+*//*-*****************************************************************************************************/
+css::uno::Sequence< sal_Int16 > SAL_CALL Frame::getSupportedCommandGroups()
+ throw(css::uno::RuntimeException)
+{
+ return m_xDispatchInfoHelper->getSupportedCommandGroups();
+}
+
+//*****************************************************************************************************************
+css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL Frame::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
+ throw(css::uno::RuntimeException)
+{
+ return m_xDispatchInfoHelper->getConfigurableDispatchInformation(nCommandGroup);
+}
+
+/*-****************************************************************************************************//**
+ @short notifications for window events
+ @descr We are a listener on our container window to forward it to our component window.
+
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+ @seealso member m_xComponentWindow
+
+ @param "aEvent" describe source of detected event
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowResized( const css::awt::WindowEvent&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowResized( aEvent ), "Frame::windowResized()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Part of dispose-mechanism => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Impl-method is threadsafe!
+ // If we have a current component window - we must resize it!
+ implts_resizeComponentWindow();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::focusGained( const css::awt::FocusEvent&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_focusGained( aEvent ), "Frame::focusGained()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Part of dispose() mechanism ... => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ // Make snapshot of member!
+ css::uno::Reference< css::awt::XWindow > xComponentWindow = m_xComponentWindow;
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xComponentWindow.is() == sal_True )
+ {
+ xComponentWindow->setFocus();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short notifications for window events
+ @descr We are a listener on our container window to forward it to our component window ...
+ but a XTopWindowListener we are only if we are a top frame!
+
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+ @seealso member m_xComponentWindow
+
+ @param "aEvent" describe source of detected event
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowActivated( const css::lang::EventObject&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowActivated( aEvent ), "Frame::windowActivated()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ // Make snapshot of member!
+ EActiveState eState = m_eActiveState;
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Activate the new active path from here to top.
+ if( eState == E_INACTIVE )
+ {
+ setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
+ activate();
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::windowDeactivated( const css::lang::EventObject&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowDeactivated( aEvent ), "Frame::windowDeactivated()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Sometimes called during dispose() => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ EActiveState eActiveState = m_eActiveState ;
+
+ aReadLock.unlock();
+
+ if( eActiveState != E_INACTIVE )
+ {
+ // Deactivation is always done implicitely by activation of another frame.
+ // Only if no activation is done, deactivations have to be processed if the activated window
+ // is a parent window of the last active Window!
+ SolarMutexClearableGuard aSolarGuard;
+ Window* pFocusWindow = Application::GetFocusWindow();
+ if (
+ ( xContainerWindow.is() == sal_True ) &&
+ ( xParent.is() == sal_True ) &&
+ ( (css::uno::Reference< css::frame::XDesktop >( xParent, css::uno::UNO_QUERY )).is() == sal_False )
+ )
+ {
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xParent->getContainerWindow() ;
+ Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
+ //#i70261#: dialogs opend from an OLE object will cause a deactivate on the frame of the OLE object
+ // on Solaris/Linux at that time pFocusWindow is still NULL because the focus handling is different; right after
+ // the deactivation the focus will be set into the dialog!
+ // currently I see no case where a sub frame could get a deactivate with pFocusWindow being NULL permanently
+ // so for now this case is omitted from handled deactivations
+ if( pFocusWindow && pParentWindow->IsChild( pFocusWindow ) )
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
+ if( xSupplier.is() == sal_True )
+ {
+ aSolarGuard.clear();
+ xSupplier->setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::windowClosing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ /* #i62088#
+ Some interceptor objects intercept our "internaly asynchronoues implemented" dispatch call.
+ And they close this frame directly (means synchronous then).
+ Means: Frame::windowClosing()->Frame::close()
+ In such situation its not a good idea to hold this transaction count alive .-)
+ */
+ {
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ // deactivate this frame ...
+ deactivate();
+ }
+
+ // ... and try to close it
+ // But do it asynchron inside the main thread.
+ // VCL has no fun to do such things outside his main thread :-(
+ // Note: The used dispatch make it asynchronous for us .-)
+
+ /*ATTENTION!
+ Don't try to suspend the controller here! Because it's done inside used dispatch().
+ Otherwhise the dialog "would you save your changes?" will be shown more then once ...
+ */
+
+ /* SAFE */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ /* SAFE */
+
+ css::util::URL aURL;
+ aURL.Complete = DECLARE_ASCII(".uno:CloseFrame");
+ css::uno::Reference< css::util::XURLTransformer > xParser(xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference< css::frame::XDispatch > xCloser = queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ if (xCloser.is())
+ xCloser->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+
+ // Attention: If this dispatch works synchronous ... and full fill its job ...
+ // this line of code will never be reached ...
+ // Or if it will be reached it will be for sure that all your member are gone .-)
+}
+
+/*-****************************************************************************************************//**
+ @short react for a show event for the internal container window
+ @descr Normaly we doesn't need this information realy. But we can use it to
+ implement the special feature "trigger first visible task".
+
+ Algorithm: - first we have to check if we are a top (task) frame
+ It's not enough to be a top frame! Because we MUST have the desktop as parent.
+ But frames without a parent are top too. So it's not possible to check isTop() here!
+ We have to look for the type of our parent.
+ - if we are a task frame, then we have to check if we are the first one.
+ We use a static variable to do so. They will be reset to afterwards be shure
+ that further calls of this method doesn't do anything then.
+ - Then we have to trigger the right event string on the global job executor.
+
+ @seealso css::task::JobExecutor
+
+ @param aEvent
+ describes the source of this event
+ We are not interested on this information. We are interested on the visible state only.
+
+ @threadsafe yes
+ @modified 31.07.2002 07:56, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ static sal_Bool bFirstVisibleTask = sal_True;
+
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XDesktop > xDesktopCheck( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ m_bIsHidden = sal_False;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ impl_checkMenuCloser();
+
+ if (xDesktopCheck.is())
+ {
+ /* STATIC SAFE { */
+ WriteGuard aStaticWriteLock( LockHelper::getGlobalLock() );
+ sal_Bool bMustBeTriggered = bFirstVisibleTask;
+ bFirstVisibleTask = sal_False;
+ aStaticWriteLock.unlock();
+ /* } STATIC SAFE */
+
+ if (bMustBeTriggered)
+ {
+ css::uno::Reference< css::task::XJobExecutor > xExecutor( xFactory->createInstance( SERVICENAME_JOBEXECUTOR ), css::uno::UNO_QUERY );
+ if (xExecutor.is())
+ {
+ xExecutor->trigger( DECLARE_ASCII("onFirstVisibleTask") );
+ }
+ }
+ }
+}
+
+void SAL_CALL Frame::windowHidden( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ m_bIsHidden = sal_True;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ impl_checkMenuCloser();
+}
+
+/*-****************************************************************************************************//**
+ @short called by dispose of our windows!
+ @descr This object is forced to release all references to the interfaces given
+ by the parameter source. We are a listener at our container window and
+ should listen for his diposing.
+
+ @seealso XWindowListener
+ @seealso XTopWindowListener
+ @seealso XFocusListener
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_disposing( aEvent ), "Frame::disposing()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // May be we are called during releasing our windows in our in dispose call!? => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if( aEvent.Source == m_xContainerWindow )
+ {
+ // NECCESSARY: Impl-method is threadsafe by himself!
+ aWriteLock.unlock();
+ implts_stopWindowListening();
+ aWriteLock.lock();
+ m_xContainerWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface com.sun.star.document.XActionLockable
+ @short implement locking of frame/task from outside
+ @descr Sometimes we have problems to decide if closing of task is allowed. Because; frame/task
+ could be used for pending loading jobs. So you can lock this object from outside and
+ prevent instance against closing during using! But - don't do it in a wrong or expensive manner.
+ Otherwise task couldn't die anymore!!!
+
+ @seealso interface XActionLockable
+ @seeelso method BaseDispatcher::implts_loadIt()
+ @seeelso method Desktop::loadComponentFromURL()
+
+ @param -
+ @return true if frame/task is locked
+ false otherwise
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+sal_Bool SAL_CALL Frame::isActionLocked() throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ return( m_nExternalLockCount!=0);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::addActionLock() throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ ++m_nExternalLockCount;
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeActionLock() throw( css::uno::RuntimeException )
+{
+ // Register no transaction here! Otherwhise we wait for ever inside possible
+ // implts_checkSuicide()/dispose() request ...
+
+ /* SAFE AREA */{
+ WriteGuard aWriteLock( m_aLock );
+ LOG_ASSERT2( m_nExternalLockCount<=0, "Frame::removeActionLock()", "Frame isn't locked! Possible multithreading problem detected." )
+ --m_nExternalLockCount;
+ }/* SAFE */
+
+ implts_checkSuicide();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::setActionLocks( sal_Int16 nLock ) throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ // Attention: If somewhere called resetActionLocks() before and get e.g. 5 locks ...
+ // and tried to set these 5 ones here after his operations ...
+ // we can't ignore setted requests during these two calls!
+ // So we must add(!) these 5 locks here.
+ m_nExternalLockCount = m_nExternalLockCount + nLock;
+}
+
+//*****************************************************************************************************************
+sal_Int16 SAL_CALL Frame::resetActionLocks() throw( css::uno::RuntimeException )
+{
+ // Register no transaction here! Otherwhise we wait for ever inside possible
+ // implts_checkSuicide()/dispose() request ...
+
+ sal_Int16 nCurrentLocks = 0;
+ /* SAFE */{
+ WriteGuard aWriteLock( m_aLock );
+ nCurrentLocks = m_nExternalLockCount;
+ m_nExternalLockCount = 0;
+ }/* SAFE */
+
+ // Attention:
+ // external lock count is 0 here every time ... but if
+ // member m_bSelfClose is set to true too .... we call our own close()/dispose().
+ // See close() for further informations
+ implts_checkSuicide();
+
+ return nCurrentLocks;
+}
+
+//*****************************************************************************************************************
+void Frame::impl_initializePropInfo()
+{
+ impl_setPropertyChangeBroadcaster(static_cast< css::frame::XFrame* >(this));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_DISPATCHRECORDERSUPPLIER,
+ FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER,
+ ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_INDICATORINTERCEPTION,
+ FRAME_PROPHANDLE_INDICATORINTERCEPTION,
+ ::getCppuType((const css::uno::Reference< css::task::XStatusIndicator >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_ISHIDDEN,
+ FRAME_PROPHANDLE_ISHIDDEN,
+ ::getBooleanCppuType(),
+ css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_LAYOUTMANAGER,
+ FRAME_PROPHANDLE_LAYOUTMANAGER,
+ ::getCppuType((const css::uno::Reference< ::com::sun::star::frame::XLayoutManager >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_TITLE,
+ FRAME_PROPHANDLE_TITLE,
+ ::getCppuType((const ::rtl::OUString*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::impl_setPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 nHandle ,
+ const css::uno::Any& aValue )
+
+{
+ static ::rtl::OUString MATERIALPROP_TITLE(RTL_CONSTASCII_USTRINGPARAM("title"));
+
+ /* There is no need to lock any mutex here. Because we share the
+ solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
+ see ctor of PropertySetHelper for further informations.
+ */
+
+ /* Attention: You can use nHandle only, if you are sure that all supported
+ properties has an unique handle. That must be guaranteed
+ inside method impl_initializePropInfo()!
+ */
+ switch (nHandle)
+ {
+ case FRAME_PROPHANDLE_TITLE :
+ {
+ ::rtl::OUString sExternalTitle;
+ aValue >>= sExternalTitle;
+ setTitle (sExternalTitle);
+ }
+ break;
+
+ case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
+ aValue >>= m_xDispatchRecorderSupplier;
+ break;
+
+ case FRAME_PROPHANDLE_LAYOUTMANAGER :
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xOldLayoutManager = m_xLayoutManager;
+ css::uno::Reference< css::frame::XLayoutManager > xNewLayoutManager;
+ aValue >>= xNewLayoutManager;
+
+ if (xOldLayoutManager != xNewLayoutManager)
+ {
+ m_xLayoutManager = xNewLayoutManager;
+ if (xOldLayoutManager.is())
+ lcl_disableLayoutManager(xOldLayoutManager, this);
+ if (xNewLayoutManager.is())
+ lcl_enableLayoutManager(xNewLayoutManager, this);
+ }
+ }
+ break;
+
+ case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
+ {
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ aValue >>= xProgress;
+ m_xIndicatorInterception = xProgress;
+ }
+ break;
+
+ #ifdef ENABLE_WARNINGS
+ default :
+ LOG_WARNING( "Frame::setFastPropertyValue_NoBroadcast()", "Invalid handle detected!" )
+ break;
+ #endif
+ }
+}
+
+//*****************************************************************************************************************
+css::uno::Any SAL_CALL Frame::impl_getPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 nHandle )
+{
+ /* There is no need to lock any mutex here. Because we share the
+ solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
+ see ctor of PropertySetHelper for further informations.
+ */
+
+ /* Attention: You can use nHandle only, if you are sure that all supported
+ properties has an unique handle. That must be guaranteed
+ inside method impl_initializePropInfo()!
+ */
+ css::uno::Any aValue;
+ switch (nHandle)
+ {
+ case FRAME_PROPHANDLE_TITLE :
+ aValue <<= getTitle ();
+ break;
+
+ case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
+ aValue <<= m_xDispatchRecorderSupplier;
+ break;
+
+ case FRAME_PROPHANDLE_ISHIDDEN :
+ aValue <<= m_bIsHidden;
+ break;
+
+ case FRAME_PROPHANDLE_LAYOUTMANAGER :
+ aValue <<= m_xLayoutManager;
+ break;
+
+ case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
+ {
+ css::uno::Reference< css::task::XStatusIndicator > xProgress(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
+ aValue = css::uno::makeAny(xProgress);
+ }
+ break;
+
+ #ifdef ENABLE_WARNINGS
+ default :
+ LOG_WARNING( "Frame::getFastPropertyValue()", "Invalid handle detected!" )
+ break;
+ #endif
+ }
+
+ return aValue;
+}
+
+/*-****************************************************************************************************//**
+ @short dispose old container window and forget his reference
+ @descr Sometimes we must repair our "modal dialog parent mechanism" too!
+
+ @seealso -
+
+ @param "xWindow", reference to old container window to dispose it
+ @return An empty reference.
+
+ @onerror -
+ @threadsafe NO!
+*//*-*****************************************************************************************************/
+void Frame::impl_disposeContainerWindow( css::uno::Reference< css::awt::XWindow >& xWindow )
+{
+ if( xWindow.is() == sal_True )
+ {
+ xWindow->setVisible( sal_False );
+ // All VclComponents are XComponents; so call dispose before discarding
+ // a css::uno::Reference< XVclComponent >, because this frame is the owner of the window
+ xWindow->dispose();
+ xWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short send frame action event to our listener
+ @descr This method is threadsafe AND can be called by our dispose method too!
+
+ @seealso -
+
+ @param "aAction", describe the event for sending
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void Frame::implts_sendFrameActionEvent( const css::frame::FrameAction& aAction )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Sometimes used by dispose() => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ // Log informations about order of events to file!
+ // (only activated in debug version!)
+ LOG_FRAMEACTIONEVENT( "Frame", m_sName, aAction )
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Send css::frame::FrameAction event to all listener.
+ // Get container for right listener.
+ // FOLLOW LINES ARE THREADSAFE!!!
+ // ( OInterfaceContainerHelper is synchronized with m_aListenerContainer! )
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XFrameActionListener >*) NULL ) );
+
+ if( pContainer != NULL )
+ {
+ // Build action event.
+ css::frame::FrameActionEvent aFrameActionEvent( static_cast< ::cppu::OWeakObject* >(this), this, aAction );
+
+ // Get iterator for access to listener.
+ ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
+ // Send message to all listener.
+ while( aIterator.hasMoreElements() == sal_True )
+ {
+ try
+ {
+ ((css::frame::XFrameActionListener*)aIterator.next())->frameAction( aFrameActionEvent );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ aIterator.remove();
+ }
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to resize our component window
+ @descr A frame contains 2 windows - a container ~ and a component window.
+ This method resize inner component window to full size of outer container window.
+ This method is threadsafe AND can be called by our dispose method too!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void Frame::implts_resizeComponentWindow()
+{
+ // usually the LayoutManager does the resizing
+ // in case there is no LayoutManager resizing has to be done here
+ if ( !m_xLayoutManager.is() )
+ {
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( getComponentWindow() );
+ if( xComponentWindow.is() == sal_True )
+ {
+ css::uno::Reference< css::awt::XDevice > xDevice( getContainerWindow(), css::uno::UNO_QUERY );
+
+ // Convert relativ size to output size.
+ css::awt::Rectangle aRectangle = getContainerWindow()->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ // Resize our component window.
+ xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to set icon on our container window (if it is a system window!)
+ @descr We use our internal set controller (if it exist) to specify which factory he represanted.
+ These information can be used to find right icon. But our controller can say it us directly
+ too ... we should ask his optional property set first ...
+
+ @seealso method Window::SetIcon()
+
+ @param -
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void Frame::implts_setIconOnWindow()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary members and release lock.
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow, css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XController > xController ( m_xController , css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if(
+ ( xContainerWindow.is() == sal_True ) &&
+ ( xController.is() == sal_True )
+ )
+ {
+ //-------------------------------------------------------------------------------------------------------------
+ // a) set default value to an invalid one. So we can start further searches for right icon id, if
+ // first steps failed!
+ // We must reset it to any fallback value - if no search step returns a valid result.
+ sal_Int32 nIcon = -1;
+
+ //-------------------------------------------------------------------------------------------------------------
+ // b) try to find information on controller propertyset directly
+ // Don't forget to catch possible exceptions - because these property is an optional one!
+ css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
+ if( xSet.is() == sal_True )
+ {
+ try
+ {
+ xSet->getPropertyValue( DECLARE_ASCII("IconId") )>>= nIcon;
+ }
+ catch( css::beans::UnknownPropertyException& )
+ {
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // c) if b) failed ... analyze argument list of currently loaded document insde the frame to find the filter.
+ // He can be used to detect right factory - and these can be used to match factory to icon ...
+ if( nIcon == -1 )
+ {
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if( xModel.is() == sal_True )
+ {
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(xModel);
+ if (eFactory != SvtModuleOptions::E_UNKNOWN_FACTORY)
+ nIcon = SvtModuleOptions().GetFactoryIcon( eFactory );
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // d) if all steps failed - use fallback!
+ if( nIcon == -1 )
+ {
+ nIcon = 0;
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // e) set icon on container window now
+ // Don't forget SolarMutex! We use vcl directly :-(
+ // Check window pointer for right WorkWindow class too!!!
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ {
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = (VCLUnoHelper::GetWindow( xContainerWindow ));
+ if(
+ ( pWindow != NULL ) &&
+ ( pWindow->GetType() == WINDOW_WORKWINDOW )
+ )
+ {
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ pWorkWindow->SetIcon( (sal_uInt16)nIcon );
+ }
+ }
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short helper to start/stop listeneing for window events on container window
+ @descr If we get a new container window, we must set it on internal memeber ...
+ and stop listening at old one ... and start listening on new one!
+ But sometimes (in dispose() call!) it's neccessary to stop listeneing without starting
+ on new connections. So we split this functionality to make it easier at use.
+
+ @seealso method initialize()
+ @seealso method dispose()
+
+ @param -
+ @return -
+
+ @onerror We do nothing!
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void Frame::implts_startWindowListening()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary member!
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow ;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory ;
+ css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
+ css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xContainerWindow.is() == sal_True )
+ {
+ xContainerWindow->addWindowListener( xWindowListener);
+ xContainerWindow->addFocusListener ( xFocusListener );
+
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
+ if( xTopWindow.is() == sal_True )
+ {
+ xTopWindow->addTopWindowListener( xTopWindowListener );
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ if( xTransfer.is() == sal_True )
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
+ if( xDropTarget.is() == sal_True )
+ {
+ xDropTarget->addDropTargetListener( xDragDropListener );
+ xDropTarget->setActive( sal_True );
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************************************************
+void Frame::implts_stopWindowListening()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Sometimes used by dispose() => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary member!
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow ;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory ;
+ css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
+ css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xContainerWindow.is() == sal_True )
+ {
+ xContainerWindow->removeWindowListener( xWindowListener);
+ xContainerWindow->removeFocusListener ( xFocusListener );
+
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
+ if( xTopWindow.is() == sal_True )
+ {
+ xTopWindow->removeTopWindowListener( xTopWindowListener );
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ if( xTransfer.is() == sal_True )
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
+ if( xDropTarget.is() == sal_True )
+ {
+ xDropTarget->removeDropTargetListener( xDragDropListener );
+ xDropTarget->setActive( sal_False );
+ }
+ }
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to force breaked close() request again
+ @descr If we self disagree with a close() request, and detect that all external locks are gone ...
+ then we must try to close this frame again.
+
+ @seealso XCloseable::close()
+ @seealso Frame::close()
+ @seealso Frame::removeActionLock()
+ @seealso Frame::resetActionLock()
+ @seealso m_bSelfClose
+ @seealso m_nExternalLockCount
+
+ @threadsafe yes
+ @modified 06.05.2002 09:31, as96863
+*//*-*****************************************************************************************************/
+void Frame::implts_checkSuicide()
+{
+ /* SAFE */
+ ReadGuard aReadLock(m_aLock);
+ // in case of lock==0 and safed state of previous close() request m_bSelfClose
+ // we must force close() again. Because we had disagreed with that before.
+ sal_Bool bSuicide = (m_nExternalLockCount==0 && m_bSelfClose);
+ m_bSelfClose = sal_False;
+ aReadLock.unlock();
+ /* } SAFE */
+ // force close and deliver owner ship to source of possible throwed veto exception
+ // Attention: Because this method isn't designed to throw such exception we must supress
+ // it for outside code!
+ try
+ {
+ if (bSuicide)
+ close(sal_True);
+ }
+ catch(const css::util::CloseVetoException&)
+ {}
+ catch(const css::lang::DisposedException&)
+ {}
+}
+
+//_______________________________________________________________
+
+/** little helper to enable/disable the menu closer at the menubar of the given frame.
+
+ @param xFrame
+ we use its layout manager to set/reset a special callback.
+ Its existence regulate visibility of this closer item.
+
+ @param bState
+ <TRUE/> enable; <FALSE/> disable this state
+ */
+
+void Frame::impl_setCloser( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ /*IN*/ sal_Bool bState )
+{
+ // Note: If start module isnt installed - no closer has to be shown!
+ if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
+ return;
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xFrameProps->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ css::uno::Reference< css::beans::XPropertySet > xLayoutProps(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xLayoutProps->setPropertyValue(LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, css::uno::makeAny(bState));
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//_______________________________________________________________
+
+/** it checks, which of the top level task frames must have the special menu closer for
+ switching to the backing window mode.
+
+ It analyze the current list of visible top level frames. Only the last real document
+ frame can have this symbol. Not the help frame nor the backing task itself.
+ Here we do anything related to this closer. We remove it from the old frame and set it
+ for the new one.
+ */
+
+void Frame::impl_checkMenuCloser()
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ // only top frames, which are part of our desktop hierarchy, can
+ // do so! By the way - we need the desktop instance to have acess
+ // to all other top level frames too.
+ css::uno::Reference< css::frame::XDesktop > xDesktop (m_xParent, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XFramesSupplier > xTaskSupplier(xDesktop , css::uno::UNO_QUERY);
+ if ( !xDesktop.is() || !xTaskSupplier.is() )
+ return;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // analyze the list of current open tasks
+ // Suppress search for other views to the same model ...
+ // It's not needed here and can be very expensive.
+ FrameListAnalyzer aAnalyzer(
+ xTaskSupplier,
+ this,
+ FrameListAnalyzer::E_HIDDEN | FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
+
+ // specify the new frame, which must have this special state ...
+ css::uno::Reference< css::frame::XFrame > xNewCloserFrame;
+
+ // -----------------------------
+ // a)
+ // If there exist ate least one other frame - there are two frames currently open.
+ // But we can enable this closer only, if one of these two tasks includes the help module.
+ // The "other frame" couldn't be the help. Because then it wouldn't be part of this "other list".
+ // In such case it will be seperated to the reference aAnalyzer.m_xHelp!
+ // But we must check, if weself includes the help ...
+ // Check aAnalyzer.m_bReferenceIsHelp!
+ if (
+ (aAnalyzer.m_lOtherVisibleFrames.getLength()==1) &&
+ (
+ (aAnalyzer.m_bReferenceIsHelp ) ||
+ (aAnalyzer.m_bReferenceIsHidden)
+ )
+ )
+ {
+ // others[0] can't be the backing component!
+ // Because it's set at the special member aAnalyzer.m_xBackingComponent ... :-)
+ xNewCloserFrame = aAnalyzer.m_lOtherVisibleFrames[0];
+ }
+ else
+ // -----------------------------
+ // b)
+ // There is no other frame ... means no other document frame. The help module
+ // will be handled seperatly and must(!) be ignored here ... excepting weself includes the help.
+ if (
+ (aAnalyzer.m_lOtherVisibleFrames.getLength()==0) &&
+ (!aAnalyzer.m_bReferenceIsHelp ) &&
+ (!aAnalyzer.m_bReferenceIsHidden ) &&
+ (!aAnalyzer.m_bReferenceIsBacking )
+ )
+ {
+ xNewCloserFrame = this;
+ }
+
+ // Look for neccessary actions ...
+ // Only if the closer state must be moved from one frame to another one
+ // or must be enabled/disabled at all.
+ /* STATIC SAFE { */
+ WriteGuard aStaticWriteLock(LockHelper::getGlobalLock());
+ css::uno::Reference< css::frame::XFrame > xCloserFrame (m_xCloserFrame.get(), css::uno::UNO_QUERY);
+ if (xCloserFrame!=xNewCloserFrame)
+ {
+ if (xCloserFrame.is())
+ impl_setCloser(xCloserFrame, sal_False);
+ if (xNewCloserFrame.is())
+ impl_setCloser(xNewCloserFrame, sal_True);
+ m_xCloserFrame = xNewCloserFrame;
+ }
+ aStaticWriteLock.unlock();
+ /* } STATIC SAFE */
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+// We don't accept null pointer or references!
+sal_Bool Frame::implcp_ctor( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+{
+ return (
+ ( &xFactory == NULL ) ||
+ ( xFactory.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+// Its allowed to reset the active frame membervariable with a NULL-css::uno::Reference but not with a NULL-pointer!
+// And we accept frames only! No tasks and desktops!
+sal_Bool Frame::implcp_setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ return (
+ ( &xFrame == NULL ) ||
+ ( css::uno::Reference< css::frame::XDesktop >( xFrame, css::uno::UNO_QUERY ).is() == sal_True )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowResized( const css::awt::WindowEvent& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_focusGained( const css::awt::FocusEvent& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowActivated( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowDeactivated( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_disposing( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */