summaryrefslogtreecommitdiff
path: root/sd/source/ui/framework/tools/FrameworkHelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/framework/tools/FrameworkHelper.cxx')
-rwxr-xr-xsd/source/ui/framework/tools/FrameworkHelper.cxx1219
1 files changed, 1219 insertions, 0 deletions
diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx
new file mode 100755
index 000000000000..078f86a88d86
--- /dev/null
+++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx
@@ -0,0 +1,1219 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include <osl/time.h>
+
+#include "framework/FrameworkHelper.hxx"
+
+#include "framework/ConfigurationController.hxx"
+#include "framework/ResourceId.hxx"
+#include "framework/ViewShellWrapper.hxx"
+#include "ViewShellBase.hxx"
+#include "FrameView.hxx"
+#include "DrawViewShell.hxx"
+#include "ViewShellHint.hxx"
+#include "DrawController.hxx"
+#include "app.hrc"
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <svl/lstner.hxx>
+
+#include <comphelper/stl_types.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "MutexOwner.hxx"
+#include "vcl/svapp.hxx"
+#include <osl/doublecheckedlocking.h>
+#include <osl/getglobalmutex.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+
+using ::rtl::OUString;
+
+namespace {
+
+
+//----- CallbackCaller --------------------------------------------------------
+
+typedef ::cppu::WeakComponentImplHelper1 <
+ ::com::sun::star::drawing::framework::XConfigurationChangeListener
+ > CallbackCallerInterfaceBase;
+
+/** A CallbackCaller registers as listener at an XConfigurationController
+ object and waits for the notification of one type of event. When that
+ event is received, or when the CallbackCaller detects at its
+ construction that the event will not be sent in the near future, the
+ actual callback object is called and the CallbackCaller destroys itself.
+*/
+class CallbackCaller
+ : public ::sd::MutexOwner,
+ public CallbackCallerInterfaceBase
+{
+public:
+ /** Create a new CallbackCaller object. This object controls its own
+ lifetime by acquiring a reference to itself in the constructor.
+ When it detects that the event will not be notified in the near
+ future (because the queue of pending configuration change operations
+ is empty and therefore no event will be sent int the near future, it
+ does not acquires a reference and thus initiates its destruction in
+ the constructor.)
+ @param rBase
+ This ViewShellBase object is used to determine the
+ XConfigurationController at which to register.
+ @param rsEventType
+ The event type which the callback is waiting for.
+ @param pCallback
+ The callback object which is to be notified. The caller will
+ typically release his reference to the caller so that when the
+ CallbackCaller dies (after having called the callback) the
+ callback is destroyed.
+ */
+ CallbackCaller (
+ ::sd::ViewShellBase& rBase,
+ const OUString& rsEventType,
+ const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter,
+ const ::sd::framework::FrameworkHelper::Callback& rCallback);
+ virtual ~CallbackCaller (void);
+
+ virtual void SAL_CALL disposing (void);
+ virtual void SAL_CALL disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException);
+ virtual void SAL_CALL notifyConfigurationChange (const ConfigurationChangeEvent& rEvent)
+ throw (RuntimeException);
+
+private:
+ OUString msEventType;
+ Reference<XConfigurationController> mxConfigurationController;
+ ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter maFilter;
+ ::sd::framework::FrameworkHelper::Callback maCallback;
+};
+
+
+
+
+//----- LifetimeController ----------------------------------------------------
+
+typedef ::cppu::WeakComponentImplHelper1 <
+ ::com::sun::star::lang::XEventListener
+ > LifetimeControllerInterfaceBase;
+
+/** This class helps controling the lifetime of the
+ FrameworkHelper. Register at a ViewShellBase object and an XController
+ object and call Dispose() at the associated FrameworkHelper object when
+ one of them and Release() when both of them are destroyed.
+*/
+class LifetimeController
+ : public ::sd::MutexOwner,
+ public LifetimeControllerInterfaceBase,
+ public SfxListener
+{
+public:
+ explicit LifetimeController (::sd::ViewShellBase& rBase);
+ virtual ~LifetimeController (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ /** XEventListener. This method is called when the frame::XController
+ is being destroyed.
+ */
+ virtual void SAL_CALL disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException);
+
+ /** This method is called when the ViewShellBase is being destroyed.
+ */
+ virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
+
+private:
+ ::sd::ViewShellBase& mrBase;
+ bool mbListeningToViewShellBase;
+ bool mbListeningToController;
+
+ /** When one or both of the mbListeningToViewShellBase and
+ mbListeningToController members were modified then call this method
+ to either dispose or release the associated FrameworkHelper.
+ */
+ void Update (void);
+};
+
+
+
+} // end of anonymous namespace
+
+namespace sd { namespace framework {
+
+// Pane URLS.
+
+const OUString FrameworkHelper::msPaneURLPrefix(
+ OUString::createFromAscii("private:resource/pane/"));
+const OUString FrameworkHelper::msCenterPaneURL(
+ msPaneURLPrefix + OUString::createFromAscii("CenterPane"));
+const OUString FrameworkHelper::msFullScreenPaneURL(
+ msPaneURLPrefix + OUString::createFromAscii("FullScreenPane"));
+const OUString FrameworkHelper::msLeftImpressPaneURL(
+ msPaneURLPrefix + OUString::createFromAscii("LeftImpressPane"));
+const OUString FrameworkHelper::msLeftDrawPaneURL(
+ msPaneURLPrefix + OUString::createFromAscii("LeftDrawPane"));
+const OUString FrameworkHelper::msRightPaneURL(
+ msPaneURLPrefix + OUString::createFromAscii("RightPane"));
+
+
+// View URLs.
+
+const OUString FrameworkHelper::msViewURLPrefix(
+ OUString::createFromAscii("private:resource/view/"));
+const OUString FrameworkHelper::msImpressViewURL(
+ msViewURLPrefix + OUString::createFromAscii("ImpressView"));
+const OUString FrameworkHelper::msDrawViewURL(
+ msViewURLPrefix + OUString::createFromAscii("GraphicView"));
+const OUString FrameworkHelper::msOutlineViewURL(
+ msViewURLPrefix + OUString::createFromAscii("OutlineView"));
+const OUString FrameworkHelper::msNotesViewURL(
+ msViewURLPrefix + OUString::createFromAscii("NotesView"));
+const OUString FrameworkHelper::msHandoutViewURL(
+ msViewURLPrefix + OUString::createFromAscii("HandoutView"));
+const OUString FrameworkHelper::msSlideSorterURL(
+ msViewURLPrefix + OUString::createFromAscii("SlideSorter"));
+const OUString FrameworkHelper::msPresentationViewURL(
+ msViewURLPrefix + OUString::createFromAscii("PresentationView"));
+const OUString FrameworkHelper::msTaskPaneURL(
+ msViewURLPrefix + OUString::createFromAscii("TaskPane"));
+
+
+// Tool bar URLs.
+
+const OUString FrameworkHelper::msToolBarURLPrefix(
+ OUString::createFromAscii("private:resource/toolbar/"));
+const OUString FrameworkHelper::msViewTabBarURL(
+ msToolBarURLPrefix + OUString::createFromAscii("ViewTabBar"));
+
+
+// Task panel URLs.
+const ::rtl::OUString FrameworkHelper::msTaskPanelURLPrefix(
+ OUString::createFromAscii("private:resource/toolpanel/DrawingFramework/"));
+const ::rtl::OUString FrameworkHelper::msMasterPagesTaskPanelURL(
+ msTaskPanelURLPrefix + OUString::createFromAscii("MasterPages"));
+const ::rtl::OUString FrameworkHelper::msLayoutTaskPanelURL(
+ msTaskPanelURLPrefix + OUString::createFromAscii("Layouts"));
+const ::rtl::OUString FrameworkHelper::msTableDesignPanelURL(
+ msTaskPanelURLPrefix + OUString::createFromAscii("TableDesign"));
+const ::rtl::OUString FrameworkHelper::msCustomAnimationTaskPanelURL(
+ msTaskPanelURLPrefix + OUString::createFromAscii("CustomAnimations"));
+const ::rtl::OUString FrameworkHelper::msSlideTransitionTaskPanelURL(
+ msTaskPanelURLPrefix + OUString::createFromAscii("SlideTransitions"));
+
+
+// Event URLs.
+const OUString FrameworkHelper::msResourceActivationRequestEvent(
+ OUString::createFromAscii("ResourceActivationRequested"));
+const OUString FrameworkHelper::msResourceDeactivationRequestEvent(
+ OUString::createFromAscii("ResourceDeactivationRequest"));
+const OUString FrameworkHelper::msResourceActivationEvent(
+ OUString::createFromAscii("ResourceActivation"));
+const OUString FrameworkHelper::msResourceDeactivationEvent(
+ OUString::createFromAscii("ResourceDeactivation"));
+const OUString FrameworkHelper::msConfigurationUpdateStartEvent(
+ OUString::createFromAscii("ConfigurationUpdateStart"));
+const OUString FrameworkHelper::msConfigurationUpdateEndEvent(
+ OUString::createFromAscii("ConfigurationUpdateEnd"));
+
+
+// Service names of controllers.
+const OUString FrameworkHelper::msModuleControllerService(
+ OUString::createFromAscii("com.sun.star.drawing.framework.ModuleController"));
+const OUString FrameworkHelper::msConfigurationControllerService(
+ OUString::createFromAscii("com.sun.star.drawing.framework.ConfigurationController"));
+
+//----- helper ----------------------------------------------------------------
+namespace
+{
+ static ::boost::shared_ptr< ViewShell > lcl_getViewShell( const Reference< XResource >& i_rViewShellWrapper )
+ {
+ ::boost::shared_ptr< ViewShell > pViewShell;
+ if ( !i_rViewShellWrapper.is() )
+ return pViewShell;
+
+ try
+ {
+ Reference<lang::XUnoTunnel> xViewTunnel( i_rViewShellWrapper, UNO_QUERY_THROW );
+ pViewShell = reinterpret_cast< ViewShellWrapper* >(
+ xViewTunnel->getSomething( ViewShellWrapper::getUnoTunnelId() ) )->GetViewShell();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return pViewShell;
+ }
+ Reference< XResource > lcl_getFirstViewInPane( const Reference< XConfigurationController >& i_rConfigController,
+ const Reference< XResourceId >& i_rPaneId )
+ {
+ try
+ {
+ Reference< XConfiguration > xConfiguration( i_rConfigController->getRequestedConfiguration(), UNO_SET_THROW );
+ Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources(
+ i_rPaneId, FrameworkHelper::msViewURLPrefix, AnchorBindingMode_DIRECT ) );
+ if ( aViewIds.getLength() > 0 )
+ return i_rConfigController->getResource( aViewIds[0] );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return NULL;
+ }
+}
+
+
+//----- FrameworkHelper::ViewURLMap -------------------------------------------
+
+/** The ViewURLMap is used to translate between the view URLs used by the
+ drawing framework and the enums defined in the ViewShell class.
+*/
+class FrameworkHelper::ViewURLMap
+ : public ::std::hash_map<
+ rtl::OUString,
+ ViewShell::ShellType,
+ ::comphelper::UStringHash,
+ ::comphelper::UStringEqual>
+{
+public:
+ ViewURLMap (void) {}
+};
+
+
+
+
+//----- Framework::DiposeListener ---------------------------------------------
+
+namespace {
+ typedef ::cppu::WeakComponentImplHelper1 <
+ ::com::sun::star::lang::XEventListener
+ > FrameworkHelperDisposeListenerInterfaceBase;
+}
+
+class FrameworkHelper::DisposeListener
+ : public ::sd::MutexOwner,
+ public FrameworkHelperDisposeListenerInterfaceBase
+{
+public:
+ DisposeListener (const ::boost::shared_ptr<FrameworkHelper>& rpHelper);
+ ~DisposeListener (void);
+
+ virtual void SAL_CALL disposing (void);
+
+ virtual void SAL_CALL disposing (const lang::EventObject& rEventObject)
+ throw(RuntimeException);
+
+private:
+ ::boost::shared_ptr<FrameworkHelper> mpHelper;
+};
+
+
+
+
+//----- FrameworkHelper -------------------------------------------------------
+
+::boost::scoped_ptr<FrameworkHelper::ViewURLMap> FrameworkHelper::mpViewURLMap(new ViewURLMap());
+
+
+FrameworkHelper::InstanceMap FrameworkHelper::maInstanceMap;
+
+
+
+::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance (
+ const Reference<frame::XController>& rxController)
+{
+ // Tunnel through the controller to obtain a ViewShellBase.
+ Reference<lang::XUnoTunnel> xTunnel (rxController, UNO_QUERY);
+ if (xTunnel.is())
+ {
+ ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>(
+ xTunnel->getSomething(sd::DrawController::getUnoTunnelId()));
+ if (pController != NULL)
+ {
+ ViewShellBase* pBase = pController->GetViewShellBase();
+ if (pBase != NULL)
+ return Instance(*pBase);
+ }
+ }
+
+ return ::boost::shared_ptr<FrameworkHelper>();
+}
+
+
+
+
+::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance (ViewShellBase& rBase)
+{
+
+ ::boost::shared_ptr<FrameworkHelper> pHelper;
+
+ InstanceMap::const_iterator iHelper (maInstanceMap.find(&rBase));
+ if (iHelper == maInstanceMap.end())
+ {
+ ::osl::GetGlobalMutex aMutexFunctor;
+ ::osl::MutexGuard aGuard (aMutexFunctor());
+ if (iHelper == maInstanceMap.end())
+ {
+ pHelper = ::boost::shared_ptr<FrameworkHelper>(new FrameworkHelper(rBase));
+ pHelper->Initialize();
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ SdGlobalResourceContainer::Instance().AddResource(pHelper);
+ maInstanceMap[&rBase] = pHelper;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pHelper = iHelper->second;
+ }
+
+ return pHelper;
+}
+
+
+
+
+void FrameworkHelper::DisposeInstance (ViewShellBase& rBase)
+{
+ InstanceMap::iterator iHelper (maInstanceMap.find(&rBase));
+ if (iHelper != maInstanceMap.end())
+ {
+ iHelper->second->Dispose();
+ }
+}
+
+
+
+
+void FrameworkHelper::ReleaseInstance (ViewShellBase& rBase)
+{
+ InstanceMap::iterator iHelper (maInstanceMap.find(&rBase));
+ if (iHelper != maInstanceMap.end())
+ maInstanceMap.erase(iHelper);
+}
+
+
+
+
+FrameworkHelper::FrameworkHelper (ViewShellBase& rBase)
+ : mrBase(rBase),
+ mxConfigurationController(),
+ mxDisposeListener()
+
+{
+ Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY);
+ if (xControllerManager.is())
+ {
+ mxConfigurationController = xControllerManager->getConfigurationController();
+ }
+
+ new LifetimeController(mrBase);
+}
+
+
+
+
+void FrameworkHelper::Initialize (void)
+{
+ mxDisposeListener = new DisposeListener(shared_from_this());
+}
+
+
+
+
+FrameworkHelper::~FrameworkHelper (void)
+{
+}
+
+
+
+
+void FrameworkHelper::Dispose (void)
+{
+ if (mxDisposeListener.is())
+ mxDisposeListener->dispose();
+ mxConfigurationController = NULL;
+}
+
+
+
+
+bool FrameworkHelper::IsValid (void)
+{
+ return mxConfigurationController.is();
+}
+
+
+
+
+::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const OUString& rsPaneURL)
+{
+ if ( !mxConfigurationController.is() )
+ return ::boost::shared_ptr<ViewShell>();
+
+ Reference<XResourceId> xPaneId( CreateResourceId( rsPaneURL ) );
+ return lcl_getViewShell( lcl_getFirstViewInPane( mxConfigurationController, xPaneId ) );
+}
+
+
+
+
+::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const Reference<XView>& rxView)
+{
+ return lcl_getViewShell( rxView.get() );
+}
+
+
+
+
+Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneOrViewId)
+{
+ Reference<XView> xView;
+
+ if ( ! rxPaneOrViewId.is() || ! mxConfigurationController.is())
+ return NULL;
+
+ try
+ {
+ if (rxPaneOrViewId->getResourceURL().match(msViewURLPrefix))
+ {
+ xView.set( mxConfigurationController->getResource( rxPaneOrViewId ), UNO_QUERY );
+ }
+ else
+ {
+ xView.set( lcl_getFirstViewInPane( mxConfigurationController, rxPaneOrViewId ), UNO_QUERY );
+ }
+ }
+ catch (lang::DisposedException&)
+ {
+ Dispose();
+ }
+ catch (RuntimeException&)
+ {
+ }
+
+ return xView;
+}
+
+
+
+
+Reference<XResourceId> FrameworkHelper::RequestView (
+ const OUString& rsResourceURL,
+ const OUString& rsAnchorURL)
+{
+ Reference<XResourceId> xViewId;
+
+ try
+ {
+ if (mxConfigurationController.is())
+ {
+ mxConfigurationController->requestResourceActivation(
+ CreateResourceId(rsAnchorURL),
+ ResourceActivationMode_ADD);
+ xViewId = CreateResourceId(rsResourceURL, rsAnchorURL);
+ mxConfigurationController->requestResourceActivation(
+ xViewId,
+ ResourceActivationMode_REPLACE);
+ }
+ }
+ catch (lang::DisposedException&)
+ {
+ Dispose();
+ xViewId = NULL;
+ }
+ catch (RuntimeException&)
+ {
+ xViewId = NULL;
+ }
+
+ return xViewId;
+}
+
+
+
+
+void FrameworkHelper::RequestTaskPanel (
+ const OUString& rsTaskPanelURL)
+{
+ try
+ {
+ if (mxConfigurationController.is())
+ {
+ // Create the resource id from URLs for the pane, the task pane
+ // view, and the task panel.
+ mxConfigurationController->requestResourceActivation(
+ CreateResourceId(msRightPaneURL),
+ ResourceActivationMode_ADD);
+ mxConfigurationController->requestResourceActivation(
+ CreateResourceId(msTaskPaneURL, msRightPaneURL),
+ ResourceActivationMode_REPLACE);
+ mxConfigurationController->requestResourceActivation(
+ CreateResourceId(rsTaskPanelURL, msTaskPaneURL, msRightPaneURL),
+ ResourceActivationMode_REPLACE);
+ }
+ }
+ catch (lang::DisposedException&)
+ {
+ Dispose();
+ }
+ catch (RuntimeException&)
+ {}
+}
+
+
+
+
+ViewShell::ShellType FrameworkHelper::GetViewId (const rtl::OUString& rsViewURL)
+{
+ if (mpViewURLMap->empty())
+ {
+ (*mpViewURLMap)[msImpressViewURL] = ViewShell::ST_IMPRESS;
+ (*mpViewURLMap)[msDrawViewURL] = ViewShell::ST_DRAW;
+ (*mpViewURLMap)[msOutlineViewURL] = ViewShell::ST_OUTLINE;
+ (*mpViewURLMap)[msNotesViewURL] = ViewShell::ST_NOTES;
+ (*mpViewURLMap)[msHandoutViewURL] = ViewShell::ST_HANDOUT;
+ (*mpViewURLMap)[msSlideSorterURL] = ViewShell::ST_SLIDE_SORTER;
+ (*mpViewURLMap)[msPresentationViewURL] = ViewShell::ST_PRESENTATION;
+ (*mpViewURLMap)[msTaskPaneURL] = ViewShell::ST_TASK_PANE;
+ }
+ ViewURLMap::const_iterator iView (mpViewURLMap->find(rsViewURL));
+ if (iView != mpViewURLMap->end())
+ return iView->second;
+ else
+ return ViewShell::ST_NONE;
+}
+
+
+
+
+::rtl::OUString FrameworkHelper::GetViewURL (ViewShell::ShellType eType)
+{
+ switch (eType)
+ {
+ case ViewShell::ST_IMPRESS : return msImpressViewURL;
+ case ViewShell::ST_DRAW : return msDrawViewURL;
+ case ViewShell::ST_OUTLINE : return msOutlineViewURL;
+ case ViewShell::ST_NOTES : return msNotesViewURL;
+ case ViewShell::ST_HANDOUT : return msHandoutViewURL;
+ case ViewShell::ST_SLIDE_SORTER : return msSlideSorterURL;
+ case ViewShell::ST_PRESENTATION : return msPresentationViewURL;
+ case ViewShell::ST_TASK_PANE : return msTaskPaneURL;
+ default:
+ return OUString();
+ }
+}
+
+
+
+
+void FrameworkHelper::HandleModeChangeSlot (
+ ULONG nSlotId,
+ SfxRequest& rRequest)
+{
+ BOOL bIsActive = TRUE;
+
+ if ( ! mxConfigurationController.is())
+ return;
+
+ switch (nSlotId)
+ {
+ case SID_DRAWINGMODE:
+ case SID_NOTESMODE:
+ case SID_HANDOUTMODE:
+ case SID_DIAMODE:
+ case SID_OUTLINEMODE:
+ {
+ const SfxItemSet* pRequestArguments = rRequest.GetArgs();
+ if (pRequestArguments)
+ {
+ SFX_REQUEST_ARG (rRequest,
+ pIsActive,
+ SfxBoolItem,
+ (USHORT)nSlotId,
+ FALSE);
+ bIsActive = pIsActive->GetValue ();
+ }
+ }
+ break;
+ }
+
+ try
+ {
+ if ( ! mxConfigurationController.is())
+ throw RuntimeException();
+
+
+ Reference<XResourceId> xPaneId (
+ CreateResourceId(framework::FrameworkHelper::msCenterPaneURL));
+ Reference<XView> xView (GetView(xPaneId));
+ ::boost::shared_ptr<ViewShell> pCenterViewShell (GetViewShell(xView));
+
+ ::rtl::OUString sRequestedView;
+ if (bIsActive)
+ {
+ switch (nSlotId)
+ {
+ case SID_NORMAL_MULTI_PANE_GUI:
+ case SID_DRAWINGMODE:
+ sRequestedView = FrameworkHelper::msImpressViewURL;
+ break;
+
+ case SID_NOTESMODE:
+ sRequestedView = FrameworkHelper::msNotesViewURL;
+ break;
+
+ case SID_HANDOUTMODE:
+ sRequestedView = FrameworkHelper::msHandoutViewURL;
+ break;
+
+ case SID_SLIDE_SORTER_MULTI_PANE_GUI:
+ case SID_DIAMODE:
+ sRequestedView = FrameworkHelper::msSlideSorterURL;
+ break;
+
+ case SID_OUTLINEMODE:
+ sRequestedView = FrameworkHelper::msOutlineViewURL;
+ break;
+ }
+ }
+
+ if (xView.is()
+ && xView->getResourceId()->getResourceURL().equals(sRequestedView))
+ {
+ // We do not have to switch the view shell but maybe the edit mode
+ // has changed.
+ DrawViewShell* pDrawViewShell
+ = dynamic_cast<DrawViewShell*>(pCenterViewShell.get());
+ if (pDrawViewShell != NULL)
+ {
+ pCenterViewShell->Broadcast (
+ ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START));
+
+ pDrawViewShell->ChangeEditMode (
+ EM_PAGE, pDrawViewShell->IsLayerModeActive());
+
+ pCenterViewShell->Broadcast (
+ ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END));
+ }
+ }
+ else
+ {
+ mxConfigurationController->requestResourceActivation(
+ CreateResourceId(sRequestedView, msCenterPaneURL),
+ ResourceActivationMode_REPLACE);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+
+
+
+void FrameworkHelper::RunOnConfigurationEvent(
+ const ::rtl::OUString& rsEventType,
+ const Callback& rCallback)
+{
+ RunOnEvent(
+ rsEventType,
+ FrameworkHelperAllPassFilter(),
+ rCallback);
+}
+
+
+
+
+void FrameworkHelper::RunOnResourceActivation(
+ const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
+ const Callback& rCallback)
+{
+ if (mxConfigurationController.is()
+ && mxConfigurationController->getResource(rxResourceId).is())
+ {
+ rCallback(false);
+ }
+ else
+ {
+ RunOnEvent(
+ msResourceActivationEvent,
+ FrameworkHelperResourceIdFilter(rxResourceId),
+ rCallback);
+ }
+}
+
+
+
+
+/** A callback that sets a flag to a specified value when the callback is
+ called.
+*/
+class FlagUpdater
+{
+public:
+ FlagUpdater (bool& rFlag) : mrFlag(rFlag) {}
+ void operator() (bool) {mrFlag = true;}
+private:
+ bool& mrFlag;
+};
+
+
+
+
+void FrameworkHelper::RequestSynchronousUpdate (void)
+{
+ rtl::Reference<ConfigurationController> pCC (
+ dynamic_cast<ConfigurationController*>(mxConfigurationController.get()));
+ if (pCC.is())
+ pCC->RequestSynchronousUpdate();
+}
+
+
+
+
+void FrameworkHelper::WaitForEvent (const OUString& rsEventType) const
+{
+ bool bConfigurationUpdateSeen (false);
+
+ RunOnEvent(
+ rsEventType,
+ FrameworkHelperAllPassFilter(),
+ FlagUpdater(bConfigurationUpdateSeen));
+
+ sal_uInt32 nStartTime = osl_getGlobalTimer();
+ while ( ! bConfigurationUpdateSeen)
+ {
+ Application::Reschedule();
+
+ if( (osl_getGlobalTimer() - nStartTime) > 60000 )
+ {
+ DBG_ERROR("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!");
+ break;
+ }
+ }
+}
+
+
+
+
+void FrameworkHelper::WaitForUpdate (void) const
+{
+ WaitForEvent(msConfigurationUpdateEndEvent);
+}
+
+
+
+
+void FrameworkHelper::RunOnEvent(
+ const ::rtl::OUString& rsEventType,
+ const ConfigurationChangeEventFilter& rFilter,
+ const Callback& rCallback) const
+{
+ new CallbackCaller(mrBase,rsEventType,rFilter,rCallback);
+}
+
+
+
+
+void FrameworkHelper::disposing (const lang::EventObject& rEventObject)
+{
+ if (rEventObject.Source == mxConfigurationController)
+ mxConfigurationController = NULL;
+}
+
+
+
+
+void FrameworkHelper::UpdateConfiguration (void)
+{
+ if (mxConfigurationController.is())
+ {
+ try
+ {
+ if (mxConfigurationController.is())
+ mxConfigurationController->update();
+ }
+ catch (lang::DisposedException&)
+ {
+ Dispose();
+ }
+ catch (RuntimeException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+
+
+
+OUString FrameworkHelper::ResourceIdToString (const Reference<XResourceId>& rxResourceId)
+{
+ OUString sString;
+ if (rxResourceId.is())
+ {
+ sString += rxResourceId->getResourceURL();
+ if (rxResourceId->hasAnchor())
+ {
+ Sequence<OUString> aAnchorURLs (rxResourceId->getAnchorURLs());
+ for (sal_Int32 nIndex=0; nIndex<aAnchorURLs.getLength(); ++nIndex)
+ {
+ sString += OUString::createFromAscii(" | ");
+ sString += aAnchorURLs[nIndex];
+ }
+ }
+ }
+ return sString;
+}
+
+
+
+
+Reference<XResourceId> FrameworkHelper::CreateResourceId (const ::rtl::OUString& rsResourceURL)
+{
+ return new ::sd::framework::ResourceId(rsResourceURL);
+}
+
+
+
+
+Reference<XResourceId> FrameworkHelper::CreateResourceId (
+ const OUString& rsResourceURL,
+ const OUString& rsAnchorURL)
+{
+ return new ::sd::framework::ResourceId(rsResourceURL, rsAnchorURL);
+}
+
+
+
+
+Reference<XResourceId> FrameworkHelper::CreateResourceId (
+ const OUString& rsResourceURL,
+ const OUString& rsFirstAnchorURL,
+ const OUString& rsSecondAnchorURL)
+{
+ ::std::vector<OUString> aAnchorURLs (2);
+ aAnchorURLs[0] = rsFirstAnchorURL;
+ aAnchorURLs[1] = rsSecondAnchorURL;
+ return new ::sd::framework::ResourceId(rsResourceURL, aAnchorURLs);
+}
+
+
+
+
+Reference<XResourceId> FrameworkHelper::CreateResourceId (
+ const ::rtl::OUString& rsResourceURL,
+ const Reference<XResourceId>& rxAnchorId)
+{
+ if (rxAnchorId.is())
+ return new ::sd::framework::ResourceId(
+ rsResourceURL,
+ rxAnchorId->getResourceURL(),
+ rxAnchorId->getAnchorURLs());
+ else
+ return new ::sd::framework::ResourceId(rsResourceURL);
+}
+
+
+
+
+Reference<XConfigurationController> FrameworkHelper::GetConfigurationController (void) const
+{
+ return mxConfigurationController;
+}
+
+
+
+
+//----- FrameworkHelper::DisposeListener --------------------------------------
+
+FrameworkHelper::DisposeListener::DisposeListener (
+ const ::boost::shared_ptr<FrameworkHelper>& rpHelper)
+ : FrameworkHelperDisposeListenerInterfaceBase(maMutex),
+ mpHelper(rpHelper)
+{
+ Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(this);
+}
+
+
+
+
+FrameworkHelper::DisposeListener::~DisposeListener (void)
+{
+}
+
+
+
+
+void SAL_CALL FrameworkHelper::DisposeListener::disposing (void)
+{
+ Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->removeEventListener(this);
+
+ mpHelper.reset();
+}
+
+
+
+
+void SAL_CALL FrameworkHelper::DisposeListener::disposing (const lang::EventObject& rEventObject)
+ throw(RuntimeException)
+{
+ if (mpHelper.get() != NULL)
+ mpHelper->disposing(rEventObject);
+}
+
+
+
+
+//===== FrameworkHelperResourceIdFilter =======================================
+
+FrameworkHelperResourceIdFilter::FrameworkHelperResourceIdFilter (
+ const Reference<XResourceId>& rxResourceId)
+ : mxResourceId(rxResourceId)
+{
+}
+
+
+} } // end of namespace sd::framework
+
+namespace {
+
+//===== CallbackCaller ========================================================
+
+CallbackCaller::CallbackCaller (
+ ::sd::ViewShellBase& rBase,
+ const OUString& rsEventType,
+ const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter,
+ const ::sd::framework::FrameworkHelper::Callback& rCallback)
+ : CallbackCallerInterfaceBase(MutexOwner::maMutex),
+ msEventType(rsEventType),
+ mxConfigurationController(),
+ maFilter(rFilter),
+ maCallback(rCallback)
+{
+ try
+ {
+ Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY_THROW);
+ mxConfigurationController = xControllerManager->getConfigurationController();
+ if (mxConfigurationController.is())
+ {
+ if (mxConfigurationController->hasPendingRequests())
+ mxConfigurationController->addConfigurationChangeListener(this,msEventType,Any());
+ else
+ {
+ // There are no requests waiting to be processed. Therefore
+ // no event, especially not the one we are waiting for, will
+ // be sent in the near future and the callback would never be
+ // called.
+ // Call the callback now and tell him that the event it is
+ // waiting for was not sent.
+ mxConfigurationController = NULL;
+ maCallback(false);
+ }
+ }
+ }
+ catch (RuntimeException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+
+
+
+CallbackCaller::~CallbackCaller (void)
+{
+}
+
+
+
+
+void CallbackCaller::disposing (void)
+{
+ try
+ {
+ if (mxConfigurationController.is())
+ {
+ Reference<XConfigurationController> xCC (mxConfigurationController);
+ mxConfigurationController = NULL;
+ xCC->removeConfigurationChangeListener(this);
+ }
+ }
+ catch (RuntimeException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+
+
+
+void SAL_CALL CallbackCaller::disposing (const lang::EventObject& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Source == mxConfigurationController)
+ {
+ mxConfigurationController = NULL;
+ maCallback(false);
+ }
+}
+
+
+
+
+void SAL_CALL CallbackCaller::notifyConfigurationChange (
+ const ConfigurationChangeEvent& rEvent)
+ throw (RuntimeException)
+{
+ if (rEvent.Type.equals(msEventType) && maFilter(rEvent))
+ {
+ maCallback(true);
+ if (mxConfigurationController.is())
+ {
+ // Reset the reference to the configuration controller so that
+ // dispose() will not try to remove the listener a second time.
+ Reference<XConfigurationController> xCC (mxConfigurationController);
+ mxConfigurationController = NULL;
+
+ // Removing this object from the controller may very likely lead
+ // to its destruction, so no calls after that.
+ xCC->removeConfigurationChangeListener(this);
+ }
+ }
+}
+
+
+
+
+//----- LifetimeController -------------------------------------------------
+
+LifetimeController::LifetimeController (::sd::ViewShellBase& rBase)
+ : LifetimeControllerInterfaceBase(maMutex),
+ mrBase(rBase),
+ mbListeningToViewShellBase(false),
+ mbListeningToController(false)
+{
+ // Register as listener at the ViewShellBase. Because that is not done
+ // via a reference we have to increase the reference count manually.
+ // This is necessary even though listening to the XController did
+ // increase the reference count because the controller may release its
+ // reference to us before the ViewShellBase is destroyed.
+ StartListening(mrBase);
+ acquire();
+ mbListeningToViewShellBase = true;
+
+ Reference<XComponent> xComponent (rBase.GetController(), UNO_QUERY);
+ if (xComponent.is())
+ {
+ xComponent->addEventListener(this);
+ mbListeningToController = true;
+ }
+}
+
+
+
+
+LifetimeController::~LifetimeController (void)
+{
+ OSL_ASSERT(!mbListeningToController && !mbListeningToViewShellBase);
+}
+
+
+
+
+void LifetimeController::disposing (void)
+{
+}
+
+
+
+
+void SAL_CALL LifetimeController::disposing (const lang::EventObject& rEvent)
+ throw(RuntimeException)
+{
+ (void)rEvent;
+ mbListeningToController = false;
+ Update();
+}
+
+
+
+
+void LifetimeController::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
+{
+ (void)rBroadcaster;
+ const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
+ if (pSimpleHint != NULL && pSimpleHint->GetId() == SFX_HINT_DYING)
+ {
+ mbListeningToViewShellBase = false;
+ Update();
+ release();
+ }
+}
+
+
+
+
+void LifetimeController::Update (void)
+{
+ if (mbListeningToViewShellBase && mbListeningToController)
+ {
+ // Both the controller and the ViewShellBase are alive. Keep
+ // waiting for their destruction.
+ }
+ else if (mbListeningToViewShellBase)
+ {
+ // The controller has been destroyed but the ViewShellBase is still
+ // alive. Dispose the associated FrameworkHelper but keep it around
+ // so that no new instance is created for the dying framework.
+ ::sd::framework::FrameworkHelper::DisposeInstance(mrBase);
+ }
+ else
+ {
+ // Both the controller and the ViewShellBase have been destroyed.
+ // Remove the FrameworkHelper so that the next call its Instance()
+ // method can create a new instance.
+ ::sd::framework::FrameworkHelper::ReleaseInstance(mrBase);
+ }
+}
+
+
+
+} // end of anonymous namespace.