summaryrefslogtreecommitdiff
path: root/framework/source/services/backingcomp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/services/backingcomp.cxx')
-rw-r--r--framework/source/services/backingcomp.cxx868
1 files changed, 868 insertions, 0 deletions
diff --git a/framework/source/services/backingcomp.cxx b/framework/source/services/backingcomp.cxx
new file mode 100644
index 000000000000..05eb6852c1ba
--- /dev/null
+++ b/framework/source/services/backingcomp.cxx
@@ -0,0 +1,868 @@
+/* -*- 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"
+
+#include "services/backingcomp.hxx"
+
+#include "backingwindow.hxx"
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <classes/droptargetlistener.hxx>
+#include <framework/acceleratorinfo.hxx>
+#include <targets.h>
+#include <properties.h>
+#include <services.h>
+
+#include <helpid.hrc>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+
+//_______________________________________________
+// other includes
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <svl/solar.hrc>
+#include <svl/urihelper.hxx>
+#include <osl/file.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <unotools/bootstrap.hxx>
+
+namespace framework
+{
+
+//_______________________________________________
+
+//_______________________________________________
+
+BackingComp::BackingComp( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR )
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , m_xSMGR (xSMGR )
+{
+}
+
+//_______________________________________________
+
+BackingComp::~BackingComp()
+{
+}
+
+//_______________________________________________
+
+/** return information about supported interfaces.
+
+ Some interfaces are supported by his class directly, but some other ones are
+ used by aggregation. An instance of this class must provide some window interfaces.
+ But it must represent a VCL window behind such interfaces too! So we use an internal
+ saved window member to ask it for it's interfaces and return it. But we must be aware then,
+ that it can be destroyed from outside too ...
+
+ @param aType
+ describe the required interface type
+
+ @return An Any holding the instance, which provides the queried interface.
+ Note: There exist two possible results ... this instance itself and her window member!
+ */
+
+css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Any aResult;
+
+ // first look for own supported interfaces
+ aResult = ::cppu::queryInterface(
+ aType,
+ static_cast< css::lang::XTypeProvider* >(this),
+ static_cast< css::lang::XServiceInfo* >(this),
+ static_cast< css::lang::XInitialization* >(this),
+ static_cast< css::frame::XController* >(this),
+ static_cast< css::lang::XComponent* >(this),
+ static_cast< css::lang::XEventListener* >(this),
+ static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)));
+
+ // then look for supported window interfaces
+ // Note: They exist only, if this instance was initialized
+ // with a valid window reference. It's aggregation on demand ...
+ if (!aResult.hasValue())
+ {
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ if (m_xWindow.is())
+ aResult = m_xWindow->queryInterface(aType);
+ aReadLock.unlock();
+ /* } SAFE */
+ }
+
+ // look for XWeak and XInterface
+ if (!aResult.hasValue())
+ aResult = OWeakObject::queryInterface(aType);
+
+ return aResult;
+}
+
+//_______________________________________________
+
+/** increase ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+//_______________________________________________
+
+/** decrease ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+//_______________________________________________
+
+/** return collection about all supported interfaces.
+
+ Optimize this method !
+ We initialize a static variable only one time.
+ And we don't must use a mutex at every call!
+ For the first call; pTypeCollection is NULL -
+ for the second call pTypeCollection is different from NULL!
+
+ @return A list of all supported interface types.
+*/
+
+css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL;
+ if (!pTypeCollection)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pTypeCollection)
+ {
+ /* LOCAL SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XTypeProvider > xProvider(m_xWindow, css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ /* } LOCAL SAFE */
+
+ css::uno::Sequence< css::uno::Type > lWindowTypes;
+ if (xProvider.is())
+ lWindowTypes = xProvider->getTypes();
+
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XInitialization >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XTypeProvider >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XServiceInfo >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::frame::XController >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XComponent >*)NULL ),
+ lWindowTypes);
+
+ pTypeCollection = &aTypeCollection;
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pTypeCollection->getTypes();
+}
+
+//_______________________________________________
+
+/** create one unique Id for all instances of this class.
+
+ Optimize this method
+ We initialize a static variable only one time. And we don't must use a mutex at every call!
+ For the first call; pID is NULL - for the second call pID is different from NULL!
+
+ @return A byte array, which represent the unique id.
+*/
+
+css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OImplementationId* pID = NULL;
+ if (!pID)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pID)
+ {
+ static ::cppu::OImplementationId aID(sal_False);
+ pID = &aID;
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pID->getImplementationId();
+}
+
+//_______________________________________________
+
+/** returns a static implementation name for this UNO service.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticImplementationName()
+ @see IMPLEMENTATIONNAME
+
+ @return The implementation name of this class.
+*/
+
+::rtl::OUString SAL_CALL BackingComp::getImplementationName()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticImplementationName();
+}
+
+//_______________________________________________
+
+/** returns information about supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return <TRUE/> if the queried service is supported;
+ <br><FALSE/> otherwise.
+*/
+
+sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const ::rtl::OUString& sServiceName )
+ throw(css::uno::RuntimeException)
+{
+ return (
+ sServiceName.equals(SERVICENAME_STARTMODULE ) ||
+ sServiceName.equals(SERVICENAME_FRAMECONTROLLER)
+ );
+}
+
+//_______________________________________________
+
+/** returns collection of supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL BackingComp::getSupportedServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+//_______________________________________________
+
+/** returns static implementation name.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return The implementation name of this class.
+*/
+
+::rtl::OUString BackingComp::impl_getStaticImplementationName()
+{
+ return IMPLEMENTATIONNAME_STARTMODULE;
+}
+
+//_______________________________________________
+
+/** returns static list of supported service names.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< ::rtl::OUString > BackingComp::impl_getStaticSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lNames(1);
+ lNames[0] = SERVICENAME_STARTMODULE;
+ return lNames;
+}
+
+//_______________________________________________
+
+/** returns a new instance of this class.
+
+ This factory method is registered inside the UNO runtime
+ and will be called for every createInstance() request from outside,
+ which wish to use this service.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+ We use it too, to set it at the new created instance.
+
+ @return A new instance as uno reference.
+*/
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL BackingComp::impl_createInstance( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ throw(css::uno::Exception)
+{
+ BackingComp* pObject = new BackingComp(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(pObject), css::uno::UNO_QUERY);
+}
+
+//_______________________________________________
+
+/** returns a new factory instance for instances of this class.
+
+ It uses a helper class of the cppuhelper project as factory.
+ It will be initialized with all neccessary informations and
+ will be able afterwards to create instance of this class.
+ This factory call us back inside our method impl_createInstance().
+ So we can create and initialize ourself. Only filtering of creation
+ requests will be done by this factory.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+
+ @return A new instance of our factory.
+*/
+
+css::uno::Reference< css::lang::XSingleServiceFactory > BackingComp::impl_createFactory( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+{
+ css::uno::Reference< css::lang::XSingleServiceFactory > xReturn(
+ cppu::createSingleFactory(
+ xSMGR,
+ BackingComp::impl_getStaticImplementationName(),
+ BackingComp::impl_createInstance,
+ BackingComp::impl_getStaticSupportedServiceNames()));
+ return xReturn;
+}
+
+//_______________________________________________
+
+/**
+ attach this component to a target frame.
+
+ We has to use the container window of this frame as parent window of our own component window.
+ But it's not allowed to work with it realy. May another component used it too.
+ Currently we need it only to create our child component window and support it's
+ interfaces inside our queryInterface() method. The user of us must have e.g. the
+ XWindow interface of it to be able to call setComponent(xWindow,xController) at the
+ frame!
+
+ May he will do the following things:
+
+ <listing>
+ XController xBackingComp = (XController)UnoRuntime.queryInterface(
+ XController.class,
+ xSMGR.createInstance(SERVICENAME_STARTMODULE));
+
+ // at this time XWindow isn't present at this instance!
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // attach controller to the frame
+ // We will use it's container window, to create
+ // the component window. From now we offer the window interfaces!
+ xBackingComp.attachFrame(xFrame);
+
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // Our user can set us at the frame as new component
+ xFrame.setComponent(xBackingWin, xBackingComp);
+
+ // But that had no effect to our view state.
+ // We must be started to create our UI elements like e.g. menu, title, background ...
+ XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
+ XInitialization.class,
+ xBackingComp);
+
+ xBackingInit.initialize(lArgs);
+ </listing>
+
+ @param xFrame
+ reference to our new target frame
+
+ @throw com::sun::star::uno::RuntimeException
+ if the given frame reference is wrong or component window couldn't be created
+ successfully.
+ We throw it too, if we already attached to a frame. Because we don't support
+ reparenting of our component window on demand!
+*/
+
+void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE */
+ WriteGuard aWriteLock(m_aLock);
+
+ // check some required states
+ if (m_xFrame.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("already attached")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!xFrame.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid frame reference")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("instance seams to be not or wrong initialized")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // safe the frame reference
+ m_xFrame = xFrame;
+
+ // establish drag&drop mode
+ ::framework::DropTargetListener* pDropListener = new ::framework::DropTargetListener(m_xSMGR, m_xFrame);
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >(static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY);
+ if (xTransfer.is())
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->addDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_True);
+ }
+ }
+
+ // initialize the component and it's parent window
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
+ WorkWindow* pParent = (WorkWindow*)VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+
+ // disable full screen mode of the frame!
+ if (pParent && pParent->IsFullScreenMode())
+ {
+ pParent->ShowFullScreenMode(sal_False);
+ pParent->SetMenuBarMode(MENUBAR_MODE_NORMAL);
+ }
+
+ // create the menu bar for the backing component
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ xLayoutManager->createElement( DECLARE_ASCII( "private:resource/menubar/menubar" ));
+ xLayoutManager->unlock();
+ }
+
+ if (pWindow)
+ {
+ // set help ID for our canvas
+ pWindow->SetHelpId(HID_BACKINGWINDOW);
+ }
+
+ // inform BackingWindow about frame
+ BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow );
+ if( pBack )
+ pBack->setOwningFrame( m_xFrame );
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return <FALSE/> everytime.
+ */
+
+sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
+ throw (css::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return An empty reference every time.
+ */
+
+css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Reference< css::frame::XModel >();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ return An empty value.
+ */
+
+css::uno::Any SAL_CALL BackingComp::getViewData()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Any();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param aData
+ not used.
+ */
+
+void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
+ throw (css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/** returns the attached frame for this component.
+
+ @see attachFrame()
+
+ @return The internaly saved frame reference.
+ Can be null, if attachFrame() was not called before.
+ */
+
+css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_xFrame;
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** ask controller for it's current working state.
+
+ If somehwere whish to close this component, it must suspend the controller before.
+ That will be a chance for it to disagree with that AND show any UI for a possible
+ UI user.
+
+ @param bSuspend
+ If its set to sal_True this controller should be suspended.
+ sal_False will resuspend it.
+
+ @return sal_True if the request could be finished successfully; sal_False otherwise.
+ */
+
+sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
+ throw (css::uno::RuntimeException)
+{
+ /* FIXME ... implemented by using default :-( */
+ return sal_True;
+}
+
+//_______________________________________________
+
+/** callback from our window member.
+
+ Our internal saved window wish to die. It will be disposed from outside (may be the frame)
+ and inform us. We must release its reference only here. Of course we check the given reference
+ here and reject callback from unknown sources.
+
+ Note: deregistration as listener isnt neccessary here. The broadcaster do it automaticly.
+
+ @param aEvent
+ describe the broadcaster of this callback
+
+ @throw ::com::sun::star::uno::RuntimeException
+ if the broadcaster doesn't represent the expected window reference.
+*/
+
+void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
+ throw(css::uno::RuntimeException)
+{
+ // Attention: dont free m_pAccExec here! see comments inside dtor and
+ // keyPressed() for further details.
+
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unexpected source or called twice")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** kill this instance.
+
+ It can be called from our owner frame only. But there is no possibility to check the calli.
+ We have to release all our internal used ressources and die. From this point we can throw
+ DisposedExceptions for every further interface request ... but current implementation doesn`t do so ...
+
+*/
+
+void SAL_CALL BackingComp::dispose()
+ throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // kill the menu
+ css::util::URL aURL;
+ aURL.Complete = DECLARE_ASCII(".uno:close");
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ if (xParser.is())
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY);
+ if (xProvider.is())
+ {
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>());
+ }
+
+ // deregister drag&drop helper
+ if (m_xDropTargetListener.is())
+ {
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY);
+ if (xTransfer.is())
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->removeDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_False);
+ }
+ }
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >();
+ }
+
+ // stop listening at the window
+ if (m_xWindow.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ xBroadcaster->removeEventListener(xEventThis);
+ }
+ css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ m_xWindow->removeKeyListener(xKeyThis);
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+
+ // forget all other used references
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+ m_xSMGR = css::uno::Reference< css::lang::XMultiServiceFactory >();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param xListener
+ not used.
+
+ @throw ::com::sun::star::uno::RuntimeException
+ because the listener expect to be holded alive by this container.
+ We must inform it about this unsupported feature.
+ */
+
+void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not supported")),
+ static_cast< ::cppu::OWeakObject* >(this));
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ Because registration is not supported too, we must do nothing here. Nobody can call this method realy.
+
+ @param xListener
+ not used.
+ */
+
+void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ force initialiation for this component.
+
+ Inside attachFrame() we created our component window. But it was not allowed there, to
+ initialitze it. E.g. the menu must be set at the container window of the frame, which
+ is our parent window. But may at that time another component used it.
+ That's why our creator has to inform us, when it's time to initialize us realy.
+ Currently only calling of this method must be done. But further implementatoins
+ can use special in parameter to configure this initialization ...
+
+ @param lArgs
+ currently not used
+
+ @throw com::sun::star::uno::RuntimeException
+ if some ressources are missing
+ Means if may be attachedFrame() wasn't called before.
+ */
+
+void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
+ throw(css::uno::Exception, css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_xWindow.is())
+ throw css::uno::Exception(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("already initialized")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (
+ (lArgs.getLength()!=1 ) ||
+ (!(lArgs[0] >>= xParentWindow)) ||
+ (!xParentWindow.is() )
+ )
+ {
+ throw css::uno::Exception(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong or corrupt argument list")),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ // create the component window
+ Window* pParent = VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = new BackingWindow(pParent);
+ m_xWindow = VCLUnoHelper::GetInterface(pWindow);
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("couldn't create component window")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // start listening for window disposing
+ // It's set at our owner frame as component window later too. So it will may be disposed there ...
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this));
+
+ m_xWindow->setVisible(sal_True);
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+ /* Attention
+ Please use keyPressed() instead of this method. Otherwhise it would be possible, that
+ - a key input may be first switch to the backing mode
+ - and this component register itself as key listener too
+ - and it's first event will be a keyRealeased() for the already well known event, which switched to the backing mode!
+ So it will be handled twice! document => backing mode => exit app ...
+ */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */