diff options
Diffstat (limited to 'sd/source/ui/framework')
65 files changed, 13805 insertions, 0 deletions
diff --git a/sd/source/ui/framework/configuration/ChangeRequestQueue.cxx b/sd/source/ui/framework/configuration/ChangeRequestQueue.cxx new file mode 100644 index 000000000000..3bc276268e0e --- /dev/null +++ b/sd/source/ui/framework/configuration/ChangeRequestQueue.cxx @@ -0,0 +1,41 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ChangeRequestQueue.hxx" + +namespace sd { namespace framework { + +ChangeRequestQueue::ChangeRequestQueue (void) +{ +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ChangeRequestQueue.hxx b/sd/source/ui/framework/configuration/ChangeRequestQueue.hxx new file mode 100644 index 000000000000..16d1eb4bfa50 --- /dev/null +++ b/sd/source/ui/framework/configuration/ChangeRequestQueue.hxx @@ -0,0 +1,58 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CHANGE_OPERATION_QUEUE_HXX +#define SD_FRAMEWORK_CHANGE_OPERATION_QUEUE_HXX + +#include <com/sun/star/drawing/framework/XConfigurationChangeRequest.hpp> + +#include <list> + +namespace sd { namespace framework { + + +/** The ChangeRequestQueue stores the pending requests for changes to the + requested configuration. It is the task of the + ChangeRequestQueueProcessor to process these requests. +*/ +class ChangeRequestQueue + : public ::std::list<com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfigurationChangeRequest> > +{ +public: + /** Create an empty queue. + */ + ChangeRequestQueue (void); +}; + + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx new file mode 100644 index 000000000000..8f83f86128c3 --- /dev/null +++ b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx @@ -0,0 +1,239 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ChangeRequestQueueProcessor.hxx" +#include "ConfigurationTracer.hxx" + +#include "framework/ConfigurationController.hxx" +#include "ConfigurationUpdater.hxx" + +#include <vcl/svapp.hxx> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +#undef VERBOSE +//#define VERBOSE 1 + +namespace { + +#ifdef VERBOSE + +void TraceRequest (const Reference<XConfigurationChangeRequest>& rxRequest) +{ + Reference<container::XNamed> xNamed (rxRequest, UNO_QUERY); + if (xNamed.is()) + OSL_TRACE(" %s\n", + ::rtl::OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8).getStr()); +} + +#endif + +} // end of anonymous namespace + + +namespace sd { namespace framework { + +ChangeRequestQueueProcessor::ChangeRequestQueueProcessor ( + const ::rtl::Reference<ConfigurationController>& rpConfigurationController, + const ::boost::shared_ptr<ConfigurationUpdater>& rpConfigurationUpdater) + : maMutex(), + maQueue(), + mnUserEventId(0), + mxConfiguration(), + mpConfigurationController(rpConfigurationController), + mpConfigurationUpdater(rpConfigurationUpdater) +{ +} + + + + +ChangeRequestQueueProcessor::~ChangeRequestQueueProcessor (void) +{ + if (mnUserEventId != 0) + Application::RemoveUserEvent(mnUserEventId); +} + + + + +void ChangeRequestQueueProcessor::SetConfiguration ( + const Reference<XConfiguration>& rxConfiguration) +{ + ::osl::MutexGuard aGuard (maMutex); + + mxConfiguration = rxConfiguration; + StartProcessing(); +} + + + + +void ChangeRequestQueueProcessor::AddRequest ( + const Reference<XConfigurationChangeRequest>& rxRequest) +{ + ::osl::MutexGuard aGuard (maMutex); + +#ifdef VERBOSE + if (maQueue.empty()) + { + OSL_TRACE("Adding requests to empty queue\n"); + ConfigurationTracer::TraceConfiguration( + mxConfiguration, "current configuration of queue processor"); + } + OSL_TRACE("Adding request\n"); + TraceRequest(rxRequest); +#endif + + maQueue.push_back(rxRequest); + StartProcessing(); +} + + + + +void ChangeRequestQueueProcessor::StartProcessing (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + if (mnUserEventId == 0 + && mxConfiguration.is() + && ! maQueue.empty()) + { +#ifdef VERBOSE + OSL_TRACE("ChangeRequestQueueProcessor scheduling processing\n"); +#endif + mnUserEventId = Application::PostUserEvent( + LINK(this,ChangeRequestQueueProcessor,ProcessEvent)); + } +} + + + + +IMPL_LINK(ChangeRequestQueueProcessor, ProcessEvent, void*, pUnused) +{ + (void)pUnused; + + ::osl::MutexGuard aGuard (maMutex); + + mnUserEventId = 0; + + ProcessOneEvent(); + + if ( ! maQueue.empty()) + { + // Schedule the processing of the next event. + StartProcessing(); + } + + return 0; +} + + + + +void ChangeRequestQueueProcessor::ProcessOneEvent (void) +{ + ::osl::MutexGuard aGuard (maMutex); + +#ifdef VERBOSE + OSL_TRACE("ProcessOneEvent\n"); +#endif + + if (mxConfiguration.is() + && ! maQueue.empty()) + { + // Get and remove the first entry from the queue. + Reference<XConfigurationChangeRequest> xRequest (maQueue.front()); + maQueue.pop_front(); + + // Execute the change request. + if (xRequest.is()) + { +#ifdef VERBOSE + TraceRequest(xRequest); +#endif + xRequest->execute(mxConfiguration); + } + + if (maQueue.empty()) + { +#ifdef VERBOSE + OSL_TRACE("All requests are processed\n"); +#endif + // The queue is empty so tell the ConfigurationManager to update + // its state. + if (mpConfigurationUpdater.get() != NULL) + { + ConfigurationTracer::TraceConfiguration ( + mxConfiguration, "updating to configuration"); + + mpConfigurationUpdater->RequestUpdate(mxConfiguration); + } + } + } +} + + + + +bool ChangeRequestQueueProcessor::IsEmpty (void) const +{ + return maQueue.empty(); +} + + + + +void ChangeRequestQueueProcessor::ProcessUntilEmpty (void) +{ + while ( ! IsEmpty()) + ProcessOneEvent(); +} + + + + +void ChangeRequestQueueProcessor::Clear (void) +{ + ::osl::MutexGuard aGuard (maMutex); + maQueue.clear(); +} + + +} } // end of namespace sd::framework::configuration + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.hxx b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.hxx new file mode 100644 index 000000000000..abbadd3dcc31 --- /dev/null +++ b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.hxx @@ -0,0 +1,139 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CHANGE_REQUEST_QUEUE_PROCESSOR_HXX +#define SD_FRAMEWORK_CHANGE_REQUEST_QUEUE_PROCESSOR_HXX + +#include "ChangeRequestQueue.hxx" +#include <osl/mutex.hxx> +#include <rtl/ref.hxx> +#include <com/sun/star/drawing/framework/XConfigurationChangeRequest.hpp> +#include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp> + +#include <cppuhelper/interfacecontainer.hxx> +#include <tools/link.hxx> + +#include <boost/shared_ptr.hpp> + +namespace sd { namespace framework { + +class ConfigurationController; +class ConfigurationUpdater; + +/** The ChangeRequestQueueProcessor ownes the ChangeRequestQueue and + processes the configuration change requests. + + When after processing one entry the queue is empty then the + XConfigurationController::update() method is called so that the changes + made to the local XConfiguration reference are reflected by the UI. + + Queue entries are processed asynchronously by calling PostUserEvent(). +*/ +class ChangeRequestQueueProcessor +{ +public: + /** The queue processor is created with a reference to an + ConfigurationController so that its UpdateConfiguration() method can + be called when the queue becomes empty. + */ + ChangeRequestQueueProcessor ( + const ::rtl::Reference<ConfigurationController>& rxController, + const ::boost::shared_ptr<ConfigurationUpdater>& rpUpdater); + ~ChangeRequestQueueProcessor (void); + + /** Sets the configuration who will be changed by subsequent change + requests. This method should be called only by the configuration + controller who owns the configuration. + */ + void SetConfiguration ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration); + + /** The given request is appended to the end of the queue and will + eventually be processed when all other entries in front of it have + been processed. + */ + void AddRequest (const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfigurationChangeRequest>& rxRequest); + + /** Returns </TRUE> when the queue is empty. + */ + bool IsEmpty (void) const; + + /** Process all events in the queue synchronously. + + <p>This method is typically called when the framework is shut down + to establish an empty configuration.</p> + */ + void ProcessUntilEmpty (void); + + /** Process the first event in queue. + */ + void ProcessOneEvent (void); + + /** Remove all events from the queue. + + <p>This method is typically called when the framework is shut down + to avoid the processing of still pending activation requests.</p> + */ + void Clear (void); + +private: + mutable ::osl::Mutex maMutex; + + ChangeRequestQueue maQueue; + + /** The id returned by the last PostUserEvent() call. This id is stored + so that a pending user event can be removed whent he queue processor + is destroyed. + */ + sal_uIntPtr mnUserEventId; + + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration; + + ::rtl::Reference<ConfigurationController> mpConfigurationController; + + ::boost::shared_ptr<ConfigurationUpdater> mpConfigurationUpdater; + + /** Initiate the processing of the entries in the queue. The actual + processing starts asynchronously. + */ + void StartProcessing (void); + + /** Callback function for the PostUserEvent() call. + */ + DECL_LINK(ProcessEvent,void*); +}; + + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/Configuration.cxx b/sd/source/ui/framework/configuration/Configuration.cxx new file mode 100644 index 000000000000..82a23affae4c --- /dev/null +++ b/sd/source/ui/framework/configuration/Configuration.cxx @@ -0,0 +1,423 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/Configuration.hxx" + +#include "framework/FrameworkHelper.hxx" +#include <comphelper/stl_types.hxx> + + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::sd::framework::FrameworkHelper; +using ::rtl::OUString; + +#undef VERBOSE + +namespace { +/** Use the XResourceId::compareTo() method to implement a compare operator + for STL containers. +*/ +class XResourceIdLess + : public ::std::binary_function <Reference<XResourceId>, Reference<XResourceId>, bool> +{ +public: + bool operator () (const Reference<XResourceId>& rId1, const Reference<XResourceId>& rId2) const + { + return rId1->compareTo(rId2) == -1; + } +}; + +} // end of anonymous namespace + + + + +namespace sd { namespace framework { + + +class Configuration::ResourceContainer + : public ::std::set<Reference<XResourceId>, XResourceIdLess> +{ +public: + ResourceContainer (void) {} +}; + + + + +//----- Service --------------------------------------------------------------- + +Reference<XInterface> SAL_CALL Configuration_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + (void)rxContext; + return Reference<XInterface>(static_cast<XWeak*>(new Configuration(NULL,false))); +} + + + + +OUString Configuration_getImplementationName (void) throw(RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.comp.Draw.framework.configuration.Configuration")); +} + + + + +Sequence<rtl::OUString> SAL_CALL Configuration_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const OUString sServiceName(OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.drawing.framework.Configuration"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== Configuration ========================================================= + +Configuration::Configuration ( + const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster, + bool bBroadcastRequestEvents) + : ConfigurationInterfaceBase(MutexOwner::maMutex), + mpResourceContainer(new ResourceContainer()), + mxBroadcaster(rxBroadcaster), + mbBroadcastRequestEvents(bBroadcastRequestEvents) +{ +} + + + +Configuration::Configuration ( + const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster, + bool bBroadcastRequestEvents, + const ResourceContainer& rResourceContainer) + : ConfigurationInterfaceBase(MutexOwner::maMutex), + mpResourceContainer(new ResourceContainer(rResourceContainer)), + mxBroadcaster(rxBroadcaster), + mbBroadcastRequestEvents(bBroadcastRequestEvents) +{ +} + + + + +Configuration::~Configuration (void) +{ +} + + + + +void SAL_CALL Configuration::disposing (void) +{ + ::osl::MutexGuard aGuard (maMutex); + mpResourceContainer->clear(); + mxBroadcaster = NULL; +} + + + + +//----- XConfiguration -------------------------------------------------------- + +void SAL_CALL Configuration::addResource (const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0) + throw ::com::sun::star::lang::IllegalArgumentException(); + + if (mpResourceContainer->find(rxResourceId) == mpResourceContainer->end()) + { +#ifdef VERBOSE + OSL_TRACE("Configuration::addResource() %s", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + mpResourceContainer->insert(rxResourceId); + PostEvent(rxResourceId, true); + } +} + + + + +void SAL_CALL Configuration::removeResource (const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0) + throw ::com::sun::star::lang::IllegalArgumentException(); + + ResourceContainer::iterator iResource (mpResourceContainer->find(rxResourceId)); + if (iResource != mpResourceContainer->end()) + { +#ifdef VERBOSE + OSL_TRACE("Configuration::removeResource() %s", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + PostEvent(rxResourceId,false); + mpResourceContainer->erase(iResource); + } +} + + + + +Sequence<Reference<XResourceId> > SAL_CALL Configuration::getResources ( + const Reference<XResourceId>& rxAnchorId, + const ::rtl::OUString& rsResourceURLPrefix, + AnchorBindingMode eMode) + throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + bool bFilterResources (rsResourceURLPrefix.getLength() > 0); + + // Collect the matching resources in a vector. + ::std::vector<Reference<XResourceId> > aResources; + ResourceContainer::const_iterator iResource; + for (iResource=mpResourceContainer->begin(); + iResource!=mpResourceContainer->end(); + ++iResource) + { + if ( ! (*iResource)->isBoundTo(rxAnchorId,eMode)) + continue; + + + if (bFilterResources) + { + // Apply the given resource prefix as filter. + + // Make sure that the resource is bound directly to the anchor. + if (eMode != AnchorBindingMode_DIRECT + && ! (*iResource)->isBoundTo(rxAnchorId, AnchorBindingMode_DIRECT)) + { + continue; + } + + // Make sure that the resource URL matches the given prefix. + if ( ! (*iResource)->getResourceURL().match(rsResourceURLPrefix)) + { + continue; + } + } + + aResources.push_back(*iResource); + } + + // Copy the resources from the vector into a new sequence. + Sequence<Reference<XResourceId> > aResult (aResources.size()); + for (sal_uInt32 nIndex=0; nIndex<aResources.size(); ++nIndex) + aResult[nIndex] = aResources[nIndex]; + + return aResult; +} + + + + +sal_Bool SAL_CALL Configuration::hasResource (const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + return rxResourceId.is() + && mpResourceContainer->find(rxResourceId) != mpResourceContainer->end(); +} + + + + +//----- XCloneable ------------------------------------------------------------ + +Reference<util::XCloneable> SAL_CALL Configuration::createClone (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + Configuration* pConfiguration = new Configuration( + mxBroadcaster, + mbBroadcastRequestEvents, + *mpResourceContainer); + + return Reference<util::XCloneable>(pConfiguration); +} + + + + +//----- XNamed ---------------------------------------------------------------- + +OUString SAL_CALL Configuration::getName (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + OUString aString; + + if (rBHelper.bDisposed || rBHelper.bInDispose) + aString += OUString(RTL_CONSTASCII_USTRINGPARAM("DISPOSED ")); + aString += OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration[")); + + ResourceContainer::const_iterator iResource; + for (iResource=mpResourceContainer->begin(); + iResource!=mpResourceContainer->end(); + ++iResource) + { + if (iResource != mpResourceContainer->begin()) + aString += OUString(RTL_CONSTASCII_USTRINGPARAM(", ")); + aString += FrameworkHelper::ResourceIdToString(*iResource); + } + aString += OUString(RTL_CONSTASCII_USTRINGPARAM("]")); + + return aString; +} + + + + +void SAL_CALL Configuration::setName (const OUString& rsName) + throw (RuntimeException) +{ + (void)rsName; // rsName is ignored. +} + + + + + +// ---------------------------------------------------------------------------- + +void Configuration::PostEvent ( + const Reference<XResourceId>& rxResourceId, + const bool bActivation) +{ + OSL_ASSERT(rxResourceId.is()); + + if (mxBroadcaster.is()) + { + ConfigurationChangeEvent aEvent; + aEvent.ResourceId = rxResourceId; + if (bActivation) + if (mbBroadcastRequestEvents) + aEvent.Type = FrameworkHelper::msResourceActivationRequestEvent; + else + aEvent.Type = FrameworkHelper::msResourceActivationEvent; + else + if (mbBroadcastRequestEvents) + aEvent.Type = FrameworkHelper::msResourceDeactivationRequestEvent; + else + aEvent.Type = FrameworkHelper::msResourceDeactivationEvent; + aEvent.Configuration = this; + + mxBroadcaster->notifyEvent(aEvent); + } +} + + + + +void Configuration::ThrowIfDisposed (void) const + throw (::com::sun::star::lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "Configuration object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + + + +//============================================================================= + +bool AreConfigurationsEquivalent ( + const Reference<XConfiguration>& rxConfiguration1, + const Reference<XConfiguration>& rxConfiguration2) +{ + if (rxConfiguration1.is() != rxConfiguration2.is()) + return false; + if ( ! rxConfiguration1.is() && ! rxConfiguration2.is()) + return true; + + // Get the lists of resources from the two given configurations. + const Sequence<Reference<XResourceId> > aResources1( + rxConfiguration1->getResources( + NULL, OUString(), AnchorBindingMode_INDIRECT)); + const Sequence<Reference<XResourceId> > aResources2( + rxConfiguration2->getResources( + NULL, OUString(), AnchorBindingMode_INDIRECT)); + + // When the number of resources differ then the configurations can not + // be equivalent. + const sal_Int32 nCount (aResources1.getLength()); + const sal_Int32 nCount2 (aResources2.getLength()); + if (nCount != nCount2) + return false; + + // Comparison of the two lists of resource ids relies on their + // ordering. + for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) + { + const Reference<XResourceId> xResource1 (aResources1[nIndex]); + const Reference<XResourceId> xResource2 (aResources2[nIndex]); + if (xResource1.is() && xResource2.is()) + { + if (xResource1->compareTo(xResource2) != 0) + return false; + } + else if (xResource1.is() != xResource2.is()) + { + return false; + } + } + + return true; +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationClassifier.cxx b/sd/source/ui/framework/configuration/ConfigurationClassifier.cxx new file mode 100644 index 000000000000..f2b7384e4658 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationClassifier.cxx @@ -0,0 +1,241 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ConfigurationClassifier.hxx" + +#include "framework/FrameworkHelper.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +#undef VERBOSE +//#define VERBOSE 2 + + +namespace sd { namespace framework { + +ConfigurationClassifier::ConfigurationClassifier ( + const Reference<XConfiguration>& rxConfiguration1, + const Reference<XConfiguration>& rxConfiguration2) + : mxConfiguration1(rxConfiguration1), + mxConfiguration2(rxConfiguration2), + maC1minusC2(), + maC2minusC1(), + maC1andC2() +{ +} + + + + +bool ConfigurationClassifier::Partition (void) +{ + maC1minusC2.clear(); + maC2minusC1.clear(); + maC1andC2.clear(); + + PartitionResources( + mxConfiguration1->getResources(NULL, OUString(), AnchorBindingMode_DIRECT), + mxConfiguration2->getResources(NULL, OUString(), AnchorBindingMode_DIRECT)); + + return !maC1minusC2.empty() || !maC2minusC1.empty(); +} + + + + +const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1minusC2 (void) const +{ + return maC1minusC2; +} + + + + +const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC2minusC1 (void) const +{ + return maC2minusC1; +} + + + +const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1andC2 (void) const +{ + return maC1andC2; +} + + +void ConfigurationClassifier::PartitionResources ( + const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, + const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2) +{ + ResourceIdVector aC1minusC2; + ResourceIdVector aC2minusC1; + ResourceIdVector aC1andC2; + + // Classify the resources in the configurations that are not bound to + // other resources. + ClassifyResources( + rS1, + rS2, + aC1minusC2, + aC2minusC1, + aC1andC2); + +#if defined VERBOSE && VERBOSE >= 2 + OSL_TRACE("copying resource ids to C1-C2\r"); +#endif + CopyResources(aC1minusC2, mxConfiguration1, maC1minusC2); +#if defined VERBOSE && VERBOSE >= 2 + OSL_TRACE("copying resource ids to C2-C1\r"); +#endif + CopyResources(aC2minusC1, mxConfiguration2, maC2minusC1); + + // Process the unique resources that belong to both configurations. + ResourceIdVector::const_iterator iResource; + for (iResource=aC1andC2.begin(); iResource!=aC1andC2.end(); ++iResource) + { + maC1andC2.push_back(*iResource); + PartitionResources( + mxConfiguration1->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT), + mxConfiguration2->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT)); + } +} + + + + +void ConfigurationClassifier::ClassifyResources ( + const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, + const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2, + ResourceIdVector& rS1minusS2, + ResourceIdVector& rS2minusS1, + ResourceIdVector& rS1andS2) +{ + // Get arrays from the sequences for faster iteration. + const Reference<XResourceId>* aA1 = rS1.getConstArray(); + const Reference<XResourceId>* aA2 = rS2.getConstArray(); + sal_Int32 nL1 (rS1.getLength()); + sal_Int32 nL2 (rS2.getLength()); + + // Find all elements in rS1 and place them in rS1minusS2 or rS1andS2 + // depending on whether they are in rS2 or not. + for (sal_Int32 i=0; i<nL1; ++i) + { + bool bFound (false); + for (sal_Int32 j=0; j<nL2 && !bFound; ++j) + if (aA1[i]->getResourceURL().equals(aA2[j]->getResourceURL())) + bFound = true; + + if (bFound) + rS1andS2.push_back(aA1[i]); + else + rS1minusS2.push_back(aA1[i]); + } + + // Find all elements in rS2 that are not in rS1. The elements that are + // in both rS1 and rS2 have been handled above and are therefore ignored + // here. + for (sal_Int32 j=0; j<nL2; ++j) + { + bool bFound (false); + for (sal_Int32 i=0; i<nL1 && !bFound; ++i) + if (aA2[j]->getResourceURL().equals(aA1[i]->getResourceURL())) + bFound = true; + + if ( ! bFound) + rS2minusS1.push_back(aA2[j]); + } +} + + + + +void ConfigurationClassifier::CopyResources ( + const ResourceIdVector& rSource, + const Reference<XConfiguration>& rxConfiguration, + ResourceIdVector& rTarget) +{ + // Copy all resources bound to the ones in aC1minusC2Unique to rC1minusC2. + ResourceIdVector::const_iterator iResource (rSource.begin()); + ResourceIdVector::const_iterator iEnd(rSource.end()); + for ( ; iResource!=iEnd; ++iResource) + { + const Sequence<Reference<XResourceId> > aBoundResources ( + rxConfiguration->getResources( + *iResource, + OUString(), + AnchorBindingMode_INDIRECT)); + const sal_Int32 nL (aBoundResources.getLength()); + + rTarget.reserve(rTarget.size() + 1 + nL); + rTarget.push_back(*iResource); + +#if defined VERBOSE && VERBOSE >= 2 + OSL_TRACE(" copying %s\r", + OUStringToOString(FrameworkHelper::ResourceIdToString(*iResource), + RTL_TEXTENCODING_UTF8).getStr()); +#endif + + const Reference<XResourceId>* aA = aBoundResources.getConstArray(); + for (sal_Int32 i=0; i<nL; ++i) + { + rTarget.push_back(aA[i]); +#if defined VERBOSE && VERBOSE >= 2 + OSL_TRACE(" copying %s\r", + OUStringToOString(FrameworkHelper::ResourceIdToString(aA[i]), + RTL_TEXTENCODING_UTF8).getStr()); +#endif + } + } +} + + +void ConfigurationClassifier::TraceResourceIdVector ( + const sal_Char* pMessage, + const ResourceIdVector& rResources) const +{ + + OSL_TRACE(pMessage); + ResourceIdVector::const_iterator iResource; + for (iResource=rResources.begin(); iResource!=rResources.end(); ++iResource) + { + OUString sResource (FrameworkHelper::ResourceIdToString(*iResource)); + OSL_TRACE(" %s\r", + OUStringToOString(sResource, RTL_TEXTENCODING_UTF8).getStr()); + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationClassifier.hxx b/sd/source/ui/framework/configuration/ConfigurationClassifier.hxx new file mode 100644 index 000000000000..e8cfecd8d1f6 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationClassifier.hxx @@ -0,0 +1,186 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CONFIGURATION_CLASSIFIER_HXX +#define SD_FRAMEWORK_CONFIGURATION_CLASSIFIER_HXX + +#include <com/sun/star/drawing/framework/XConfiguration.hpp> + +#include <vector> + +namespace sd { namespace framework { + +/** A ConfigurationClassifier object compares two configurations of + resources and gives access to the differences. It is used mainly when + changes to the current configuration have been requested and the various + resource controllers have to be supplied with the set of resources that + are to be activated or deactivated. +*/ +class ConfigurationClassifier +{ +public: + /** Create a new ConfigurationClassifier object that will compare the + two given configurations. + */ + ConfigurationClassifier ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration1, + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration2); + + /** Calculate three lists of resource ids. These contain the resources + that belong to one configuration but not the other, or that belong + to both configurations. + @return + When the two configurations differ then return <TRUE/>. When + they are equivalent then return <FALSE/>. + */ + bool Partition (void); + + typedef ::std::vector<com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId> > ResourceIdVector; + + /** Return the resources that belong to the configuration given as + rxConfiguration1 to the constructor but that do not belong to + rxConfiguration2. + @return + A reference to the, possibly empty, list of resources is + returned. This reference remains valid as long as the called + ConfigurationClassifier object stays alive. + */ + const ResourceIdVector& GetC1minusC2 (void) const; + + /** Return the resources that belong to the configuration given as + rxConfiguration2 to the constructor but that do not belong to + rxConfiguration1. + @return + A reference to the, possibly empty, list of resources is + returned. This reference remains valid as long as the called + ConfigurationClassifier object stays alive. + */ + const ResourceIdVector& GetC2minusC1 (void) const; + + /** Return the resources that belong to both the configurations that + where given to the constructor. + @return + A reference to the, possibly empty, list of resources is + returned. This reference remains valid as long as the called + ConfigurationClassifier object stays alive. + */ + const ResourceIdVector& GetC1andC2 (void) const; + + void TraceResourceIdVector ( + const sal_Char* pMessage, + const ResourceIdVector& rResources) const; + +private: + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration1; + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration2; + + /** After the call to Classify() this vector holds all elements from + mxConfiguration1 that are not in mxConfiguration2. + */ + ResourceIdVector maC1minusC2; + + /** After the call to Classify() this vector holds all elements from + mxConfiguration2 that are not in mxConfiguration1. + */ + ResourceIdVector maC2minusC1; + + /** After the call to Classify() this vector holds all elements that are + member both of mxConfiguration1 and mxConfiguration2. + */ + ResourceIdVector maC1andC2; + + /** Put all the elements in the two gven sequences of resource ids and + copy them into one of the resource id result vectors maC1minusC2, + maC2minusC1, and maC1andC2. This is done by using only the resource + URLs for classification. Therefor this method calls itself + recursively. + @param rS1 + One sequence of XResourceId objects. + @param rS2 + Another sequence of XResourceId objects. + */ + void PartitionResources ( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId> >& rS1, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId> >& rS2); + + /** Compare the given sequences of resource ids and put their elements + in one of three vectors depending on whether an element belongs to + both sequences or to one but not the other. Note that only the + resource URLs of the XResourceId objects are used for the + classification. + @param rS1 + One sequence of XResourceId objects. + @param rS2 + Another sequence of XResourceId objects. + */ + void ClassifyResources ( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId> >& rS1, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId> >& rS2, + ResourceIdVector& rS1minusS2, + ResourceIdVector& rS2minusS1, + ResourceIdVector& rS1andS2); + + + /** Copy the resources given in rSource to the list of resources + specified by rTarget. Resources bound to the ones in rSource, + either directly or indirectly, are copied as well. + @param rSource + All resources and the ones bound to them, either directly or + indirectly, are copied. + @param rxConfiguration + This configuration is used to determine the resources bound to + the ones in rSource. + @param rTarget + This list is filled with resources from rSource and the ones + bound to them. + */ + void CopyResources ( + const ResourceIdVector& rSource, + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration, + ResourceIdVector& rTarget); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationController.cxx b/sd/source/ui/framework/configuration/ConfigurationController.cxx new file mode 100644 index 000000000000..1724e764d506 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationController.cxx @@ -0,0 +1,729 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/ConfigurationController.hxx" + +#include "framework/Configuration.hxx" +#include "framework/FrameworkHelper.hxx" +#include "ConfigurationUpdater.hxx" +#include "ConfigurationControllerBroadcaster.hxx" +#include "ConfigurationTracer.hxx" +#include "GenericConfigurationChangeRequest.hxx" +#include "ResourceFactoryManager.hxx" +#include "UpdateRequest.hxx" +#include "ChangeRequestQueueProcessor.hxx" +#include "ConfigurationClassifier.hxx" +#include "ViewShellBase.hxx" +#include "UpdateLockManager.hxx" +#include "DrawController.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> + +#include <comphelper/stl_types.hxx> +#include <osl/mutex.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using rtl::OUString; +using ::sd::framework::FrameworkHelper; + +#undef VERBOSE +//#define VERBOSE 3 + + +namespace sd { namespace framework { + +Reference<XInterface> SAL_CALL ConfigurationController_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + (void)rxContext; + return static_cast<XWeak*>(new ConfigurationController()); +} + + + + +OUString ConfigurationController_getImplementationName (void) throw(RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.comp.Draw.framework.configuration.ConfigurationController")); +} + + + + +Sequence<rtl::OUString> SAL_CALL ConfigurationController_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const OUString sServiceName(OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.drawing.framework.ConfigurationController"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//----- ConfigurationController::Implementation ------------------------------- + +class ConfigurationController::Implementation +{ +public: + Implementation ( + ConfigurationController& rController, + const Reference<frame::XController>& rxController); + ~Implementation (void); + + Reference<XControllerManager> mxControllerManager; + + /** The Broadcaster class implements storing and calling of listeners. + */ + ::boost::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster; + + /** The requested configuration which is modifed (asynchronously) by + calls to requestResourceActivation() and + requestResourceDeactivation(). The mpConfigurationUpdater makes the + current configuration reflect the content of this one. + */ + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration> mxRequestedConfiguration; + + ViewShellBase* mpBase; + + ::boost::shared_ptr<ResourceFactoryManager> mpResourceFactoryContainer; + + ::boost::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager; + + ::boost::shared_ptr<ConfigurationUpdater> mpConfigurationUpdater; + + /** The queue processor ownes the queue of configuration change request + objects and processes the objects. + */ + ::boost::scoped_ptr<ChangeRequestQueueProcessor> mpQueueProcessor; + + ::boost::shared_ptr<ConfigurationUpdaterLock> mpConfigurationUpdaterLock; + + sal_Int32 mnLockCount; +}; + + + + +//===== ConfigurationController::Lock ========================================= + +ConfigurationController::Lock::Lock (const Reference<XConfigurationController>& rxController) + : mxController(rxController) +{ + OSL_ASSERT(mxController.is()); + + if (mxController.is()) + mxController->lock(); +} + + + + +ConfigurationController::Lock::~Lock (void) +{ + if (mxController.is()) + mxController->unlock(); +} + + + + +//===== ConfigurationController =============================================== + +ConfigurationController::ConfigurationController (void) throw() + : ConfigurationControllerInterfaceBase(MutexOwner::maMutex), + mpImplementation(), + mbIsDisposed(false) +{ +} + + + + +ConfigurationController::~ConfigurationController (void) throw() +{ +} + + + + +void SAL_CALL ConfigurationController::disposing (void) +{ + if (mpImplementation.get() == NULL) + return; + +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("ConfigurationController::disposing\n"); + OSL_TRACE(" requesting empty configuration\n"); +#endif + // To destroy all resources an empty configuration is requested and then, + // synchronously, all resulting requests are processed. + mpImplementation->mpQueueProcessor->Clear(); + restoreConfiguration(new Configuration(this,false)); + mpImplementation->mpQueueProcessor->ProcessUntilEmpty(); +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE(" all requests processed\n"); +#endif + + // Now that all resources have been deactivated, mark the controller as + // disposed. + mbIsDisposed = true; + + // Release the listeners. + lang::EventObject aEvent; + aEvent.Source = uno::Reference<uno::XInterface>((cppu::OWeakObject*)this); + + { + const SolarMutexGuard aSolarGuard; + mpImplementation->mpBroadcaster->DisposeAndClear(); + } + + mpImplementation->mpQueueProcessor.reset(); + mpImplementation->mxRequestedConfiguration = NULL; + mpImplementation.reset(); +} + + + + +void ConfigurationController::ProcessEvent (void) +{ + if (mpImplementation.get() != NULL) + { + OSL_ASSERT(mpImplementation->mpQueueProcessor.get()!=NULL); + + mpImplementation->mpQueueProcessor->ProcessOneEvent(); + } +} + + + + +void ConfigurationController::RequestSynchronousUpdate (void) +{ + if (mpImplementation.get() == NULL) + return; + if (mpImplementation->mpQueueProcessor.get() == 0) + return; + mpImplementation->mpQueueProcessor->ProcessUntilEmpty(); +} + + + + +//----- XConfigurationControllerBroadcaster ----------------------------------- + +void SAL_CALL ConfigurationController::addConfigurationChangeListener ( + const Reference<XConfigurationChangeListener>& rxListener, + const ::rtl::OUString& rsEventType, + const Any& rUserData) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + + ThrowIfDisposed(); + OSL_ASSERT(mpImplementation.get()!=NULL); + mpImplementation->mpBroadcaster->AddListener(rxListener, rsEventType, rUserData); +} + + + + +void SAL_CALL ConfigurationController::removeConfigurationChangeListener ( + const Reference<XConfigurationChangeListener>& rxListener) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + + ThrowIfDisposed(); + mpImplementation->mpBroadcaster->RemoveListener(rxListener); +} + + + + +void SAL_CALL ConfigurationController::notifyEvent ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + ThrowIfDisposed(); + mpImplementation->mpBroadcaster->NotifyListeners(rEvent); +} + + + + + +//----- XConfigurationController ---------------------------------------------- + +void SAL_CALL ConfigurationController::lock (void) + throw (RuntimeException) +{ + OSL_ASSERT(mpImplementation.get()!=NULL); + OSL_ASSERT(mpImplementation->mpConfigurationUpdater.get()!=NULL); + + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + + ++mpImplementation->mnLockCount; + if (mpImplementation->mpConfigurationUpdaterLock.get()==NULL) + mpImplementation->mpConfigurationUpdaterLock + = mpImplementation->mpConfigurationUpdater->GetLock(); +} + + + + +void SAL_CALL ConfigurationController::unlock (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + + // Allow unlocking while the ConfigurationController is being disposed + // (but not when that is done and the controller is disposed.) + if (rBHelper.bDisposed) + ThrowIfDisposed(); + + OSL_ASSERT(mpImplementation->mnLockCount>0); + --mpImplementation->mnLockCount; + if (mpImplementation->mnLockCount == 0) + mpImplementation->mpConfigurationUpdaterLock.reset(); +} + + + + +void SAL_CALL ConfigurationController::requestResourceActivation ( + const Reference<XResourceId>& rxResourceId, + ResourceActivationMode eMode) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + // Check whether we are being disposed. This is handled differently + // then being completely disposed because the first thing disposing() + // does is to deactivate all remaining resources. This is done via + // regular methods which must not throw DisposedExceptions. Therefore + // we just return silently during that stage. + if (rBHelper.bInDispose) + { +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("ConfigurationController::requestResourceActivation(): ignoring %s\n", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + return; + } + +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationController::requestResourceActivation() %s\n", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + + if (rxResourceId.is()) + { + if (eMode == ResourceActivationMode_REPLACE) + { + // Get a list of the matching resources and create deactivation + // requests for them. + Sequence<Reference<XResourceId> > aResourceList ( + mpImplementation->mxRequestedConfiguration->getResources( + rxResourceId->getAnchor(), + rxResourceId->getResourceTypePrefix(), + AnchorBindingMode_DIRECT)); + + for (sal_Int32 nIndex=0; nIndex<aResourceList.getLength(); ++nIndex) + { + // Do not request the deactivation of the resource for which + // this method was called. Doing it would not change the + // outcome but would result in unnecessary work. + if (rxResourceId->compareTo(aResourceList[nIndex]) == 0) + continue; + + // Request the deactivation of a resource and all resources + // linked to it. + requestResourceDeactivation(aResourceList[nIndex]); + } + } + + Reference<XConfigurationChangeRequest> xRequest( + new GenericConfigurationChangeRequest( + rxResourceId, + GenericConfigurationChangeRequest::Activation)); + postChangeRequest(xRequest); + } +} + + + + +void SAL_CALL ConfigurationController::requestResourceDeactivation ( + const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationController::requestResourceDeactivation() %s\n", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + + if (rxResourceId.is()) + { + // Request deactivation of all resources linked to the specified one + // as well. + const Sequence<Reference<XResourceId> > aLinkedResources ( + mpImplementation->mxRequestedConfiguration->getResources( + rxResourceId, + OUString(), + AnchorBindingMode_DIRECT)); + const sal_Int32 nCount (aLinkedResources.getLength()); + for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) + { + // We do not add deactivation requests directly but call this + // method recursively, so that when one time there are resources + // linked to linked resources, these are handled correctly, too. + requestResourceDeactivation(aLinkedResources[nIndex]); + } + + // Add a deactivation request for the specified resource. + Reference<XConfigurationChangeRequest> xRequest( + new GenericConfigurationChangeRequest( + rxResourceId, + GenericConfigurationChangeRequest::Deactivation)); + postChangeRequest(xRequest); + } +} + + + + +Reference<XResource> SAL_CALL ConfigurationController::getResource ( + const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + ConfigurationControllerResourceManager::ResourceDescriptor aDescriptor ( + mpImplementation->mpResourceManager->GetResource(rxResourceId)); + return aDescriptor.mxResource; +} + + + + +void SAL_CALL ConfigurationController::update (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + if (mpImplementation->mpQueueProcessor->IsEmpty()) + { + // The queue is empty. Add another request that does nothing but + // asynchronously trigger a request for an update. + mpImplementation->mpQueueProcessor->AddRequest(new UpdateRequest()); + } + else + { + // The queue is not empty, so we rely on the queue processor to + // request an update automatically when the queue becomes empty. + } +} + + + + +sal_Bool SAL_CALL ConfigurationController::hasPendingRequests (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + return ! mpImplementation->mpQueueProcessor->IsEmpty(); +} + + + + + +void SAL_CALL ConfigurationController::postChangeRequest ( + const Reference<XConfigurationChangeRequest>& rxRequest) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + mpImplementation->mpQueueProcessor->AddRequest(rxRequest); +} + + + + +Reference<XConfiguration> SAL_CALL ConfigurationController::getRequestedConfiguration (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + if (mpImplementation->mxRequestedConfiguration.is()) + return Reference<XConfiguration>( + mpImplementation->mxRequestedConfiguration->createClone(), UNO_QUERY); + else + return Reference<XConfiguration>(); +} + + + + +Reference<XConfiguration> SAL_CALL ConfigurationController::getCurrentConfiguration (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + Reference<XConfiguration> xCurrentConfiguration( + mpImplementation->mpConfigurationUpdater->GetCurrentConfiguration()); + if (xCurrentConfiguration.is()) + return Reference<XConfiguration>(xCurrentConfiguration->createClone(), UNO_QUERY); + else + return Reference<XConfiguration>(); +} + + + + +/** The given configuration is restored by generating the appropriate set of + activation and deactivation requests. +*/ +void SAL_CALL ConfigurationController::restoreConfiguration ( + const Reference<XConfiguration>& rxNewConfiguration) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + // We will probably be making a couple of activation and deactivation + // requests so lock the configuration controller and let it later update + // all changes at once. + ::boost::shared_ptr<ConfigurationUpdaterLock> pLock ( + mpImplementation->mpConfigurationUpdater->GetLock()); + + // Get lists of resources that are to be activated or deactivated. + Reference<XConfiguration> xCurrentConfiguration (mpImplementation->mxRequestedConfiguration); +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("ConfigurationController::restoreConfiguration(\n"); + ConfigurationTracer::TraceConfiguration(rxNewConfiguration, "requested configuration"); + ConfigurationTracer::TraceConfiguration(xCurrentConfiguration, "current configuration"); +#endif + ConfigurationClassifier aClassifier (rxNewConfiguration, xCurrentConfiguration); + aClassifier.Partition(); +#if defined VERBOSE && VERBOSE>=3 + aClassifier.TraceResourceIdVector( + "requested but not current resources:\n", aClassifier.GetC1minusC2()); + aClassifier.TraceResourceIdVector( + "current but not requested resources:\n", aClassifier.GetC2minusC1()); + aClassifier.TraceResourceIdVector( + "requested and current resources:\n", aClassifier.GetC1andC2()); +#endif + + ConfigurationClassifier::ResourceIdVector::const_iterator iResource; + + // Request the deactivation of resources that are not requested in the + // new configuration. + const ConfigurationClassifier::ResourceIdVector& rResourcesToDeactivate ( + aClassifier.GetC2minusC1()); + for (iResource=rResourcesToDeactivate.begin(); + iResource!=rResourcesToDeactivate.end(); + ++iResource) + { + requestResourceDeactivation(*iResource); + } + + // Request the activation of resources that are requested in the + // new configuration but are not part of the current configuration. + const ConfigurationClassifier::ResourceIdVector& rResourcesToActivate ( + aClassifier.GetC1minusC2()); + for (iResource=rResourcesToActivate.begin(); + iResource!=rResourcesToActivate.end(); + ++iResource) + { + requestResourceActivation(*iResource, ResourceActivationMode_ADD); + } + + pLock.reset(); +} + + + + +//----- XResourceFactoryManager ----------------------------------------------- + +void SAL_CALL ConfigurationController::addResourceFactory( + const OUString& sResourceURL, + const Reference<XResourceFactory>& rxResourceFactory) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + mpImplementation->mpResourceFactoryContainer->AddFactory(sResourceURL, rxResourceFactory); +} + + + + +void SAL_CALL ConfigurationController::removeResourceFactoryForURL( + const OUString& sResourceURL) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + mpImplementation->mpResourceFactoryContainer->RemoveFactoryForURL(sResourceURL); +} + + + + +void SAL_CALL ConfigurationController::removeResourceFactoryForReference( + const Reference<XResourceFactory>& rxResourceFactory) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + mpImplementation->mpResourceFactoryContainer->RemoveFactoryForReference(rxResourceFactory); +} + + + + +Reference<XResourceFactory> SAL_CALL ConfigurationController::getResourceFactory ( + const OUString& sResourceURL) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + return mpImplementation->mpResourceFactoryContainer->GetFactory(sResourceURL); +} + + + + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL ConfigurationController::initialize (const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + + if (aArguments.getLength() == 1) + { + const SolarMutexGuard aSolarGuard; + + mpImplementation.reset(new Implementation( + *this, + Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW))); + } +} + + + + +//----------------------------------------------------------------------------- + +void ConfigurationController::ThrowIfDisposed (void) const + throw (::com::sun::star::lang::DisposedException) +{ + if (mbIsDisposed) + { + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "ConfigurationController object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } + + if (mpImplementation.get() == NULL) + { + OSL_ASSERT(mpImplementation.get() != NULL); + throw RuntimeException( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "ConfigurationController not initialized")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + + + +//===== ConfigurationController::Implementation =============================== + +ConfigurationController::Implementation::Implementation ( + ConfigurationController& rController, + const Reference<frame::XController>& rxController) + : mxControllerManager(rxController, UNO_QUERY_THROW), + mpBroadcaster(new ConfigurationControllerBroadcaster(&rController)), + mxRequestedConfiguration(new Configuration(&rController, true)), + mpBase(NULL), + mpResourceFactoryContainer(new ResourceFactoryManager(mxControllerManager)), + mpResourceManager( + new ConfigurationControllerResourceManager(mpResourceFactoryContainer,mpBroadcaster)), + mpConfigurationUpdater( + new ConfigurationUpdater(mpBroadcaster, mpResourceManager,mxControllerManager)), + mpQueueProcessor(new ChangeRequestQueueProcessor(&rController,mpConfigurationUpdater)), + mpConfigurationUpdaterLock(), + mnLockCount(0) +{ + mpQueueProcessor->SetConfiguration(mxRequestedConfiguration); +} + + + + +ConfigurationController::Implementation::~Implementation (void) +{ +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.cxx b/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.cxx new file mode 100644 index 000000000000..7c8141da4cab --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.cxx @@ -0,0 +1,233 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ConfigurationControllerBroadcaster.hxx" +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <tools/debug.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 sd { namespace framework { + +ConfigurationControllerBroadcaster::ConfigurationControllerBroadcaster ( + const Reference<XConfigurationController>& rxController) + : mxConfigurationController(rxController), + maListenerMap() +{ +} + + + + +void ConfigurationControllerBroadcaster::AddListener( + const Reference<XConfigurationChangeListener>& rxListener, + const ::rtl::OUString& rsEventType, + const Any& rUserData) +{ + if ( ! rxListener.is()) + throw lang::IllegalArgumentException( + OUString(RTL_CONSTASCII_USTRINGPARAM("invalid listener")), + mxConfigurationController, + 0); + + if (maListenerMap.find(rsEventType) == maListenerMap.end()) + maListenerMap[rsEventType] = ListenerList(); + ListenerDescriptor aDescriptor; + aDescriptor.mxListener = rxListener; + aDescriptor.maUserData = rUserData; + maListenerMap[rsEventType].push_back(aDescriptor); +} + + + + +void ConfigurationControllerBroadcaster::RemoveListener( + const Reference<XConfigurationChangeListener>& rxListener) +{ + if ( ! rxListener.is()) + throw lang::IllegalArgumentException( + OUString(RTL_CONSTASCII_USTRINGPARAM("invalid listener")), + mxConfigurationController, + 0); + + ListenerMap::iterator iMap; + ListenerList::iterator iList; + for (iMap=maListenerMap.begin(); iMap!=maListenerMap.end(); ++iMap) + { + for (iList=iMap->second.begin(); iList!=iMap->second.end(); ++iList) + { + if (iList->mxListener == rxListener) + { + iMap->second.erase(iList); + break; + } + } + } +} + + + + +void ConfigurationControllerBroadcaster::NotifyListeners ( + const ListenerList& rList, + const ConfigurationChangeEvent& rEvent) +{ + // Create a local copy of the event in which the user data is modified + // for every listener. + ConfigurationChangeEvent aEvent (rEvent); + + ListenerList::const_iterator iListener; + for (iListener=rList.begin(); iListener!=rList.end(); ++iListener) + { + try + { + aEvent.UserData = iListener->maUserData; + iListener->mxListener->notifyConfigurationChange(aEvent); + } + catch (lang::DisposedException& rException) + { + // When the exception comes from the listener itself then + // unregister it. + if (rException.Context == iListener->mxListener) + RemoveListener(iListener->mxListener); + } + catch(RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } +} + + + + +void ConfigurationControllerBroadcaster::NotifyListeners (const ConfigurationChangeEvent& rEvent) +{ + // Notify the specialized listeners. + ListenerMap::const_iterator iMap (maListenerMap.find(rEvent.Type)); + if (iMap != maListenerMap.end()) + { + // Create a local list of the listeners to avoid problems with + // concurrent changes and to be able to remove disposed listeners. + ListenerList aList (iMap->second.begin(), iMap->second.end()); + NotifyListeners(aList,rEvent); + } + + // Notify the universal listeners. + iMap = maListenerMap.find(OUString()); + if (iMap != maListenerMap.end()) + { + // Create a local list of the listeners to avoid problems with + // concurrent changes and to be able to remove disposed listeners. + ListenerList aList (iMap->second.begin(), iMap->second.end()); + NotifyListeners(aList,rEvent); + } +} + + + + +void ConfigurationControllerBroadcaster::NotifyListeners ( + const OUString& rsEventType, + const Reference<XResourceId>& rxResourceId, + const Reference<XResource>& rxResourceObject) +{ + ConfigurationChangeEvent aEvent; + aEvent.Type = rsEventType; + aEvent.ResourceId = rxResourceId; + aEvent.ResourceObject = rxResourceObject; + try + { + NotifyListeners(aEvent); + } + catch (lang::DisposedException) + { + } +} + + + + + +void ConfigurationControllerBroadcaster::DisposeAndClear (void) +{ + lang::EventObject aEvent; + aEvent.Source = mxConfigurationController; + while (maListenerMap.size() > 0) + { + ListenerMap::iterator iMap (maListenerMap.begin()); + if (iMap == maListenerMap.end()) + break; + + // When the first vector is empty then remove it from the map. + if (iMap->second.size() == 0) + { + maListenerMap.erase(iMap); + continue; + } + else + { + Reference<lang::XEventListener> xListener ( + iMap->second.front().mxListener, UNO_QUERY); + if (xListener.is()) + { + // Tell the listener that the configuration controller is + // being disposed and remove the listener (for all event + // types). + try + { + RemoveListener(iMap->second.front().mxListener); + xListener->disposing(aEvent); + } + catch (RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + else + { + // Remove just this reference to the listener. + iMap->second.erase(iMap->second.begin()); + } + } + } +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.hxx b/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.hxx new file mode 100644 index 000000000000..c15abbbb7eb2 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.hxx @@ -0,0 +1,154 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CONFIGURATION_CONTROLLER_BROADCASTER_HXX +#define SD_FRAMEWORK_CONFIGURATION_CONTROLLER_BROADCASTER_HXX + +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp> + +#include <comphelper/stl_types.hxx> +#include <vector> +#include <hash_map> + +namespace css = ::com::sun::star; + +namespace sd { namespace framework { + +/** This class manages the set of XConfigurationChangeListeners and + calls them when the ConfigurationController wants to broadcast an + event. + + For every registered combination of listener and event type a user data + object is stored. This user data object is then given to the listener + whenever it is called for an event. With this the listener can use + a switch statement to handle different event types. +*/ +class ConfigurationControllerBroadcaster +{ +public: + /** The given controller is used as origin of thrown exceptions. + */ + ConfigurationControllerBroadcaster ( + const css::uno::Reference< + css::drawing::framework::XConfigurationController>& rxController); + + /** Add a listener for one type of event. When one listener is + interested in more than one event type this method has to be called + once for every event type. Alternatively it can register as + universal listener that will be called for all event types. + @param rxListener + A valid reference to a listener. + @param rsEventType + The type of event that the listener will be called for. The + empty string is a special value in that the listener will be + called for all event types. + @param rUserData + This object is passed to the listener whenever it is called for + the specified event type. For different event types different + user data objects can be provided. + @throws IllegalArgumentException + when an empty listener reference is given. + */ + void AddListener( + const css::uno::Reference< + css::drawing::framework::XConfigurationChangeListener>& rxListener, + const ::rtl::OUString& rsEventType, + const css::uno::Any& rUserData); + + /** Remove all references to the given listener. When one listener has + been registered for more than one type of event then it is removed + for all of them. + @param rxListener + A valid reference to a listener. + @throws IllegalArgumentException + when an empty listener reference is given. + */ + void RemoveListener( + const css::uno::Reference< + css::drawing::framework::XConfigurationChangeListener>& rxListener); + + /** Broadcast the given event to all listeners that have been registered + for its type of event as well as all universal listeners. + + When calling a listener results in a DisposedException being thrown + the listener is unregistered automatically. + */ + void NotifyListeners ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent); + + /** This convenience variant of NotifyListeners create the event from + the given arguments. + */ + void NotifyListeners ( + const ::rtl::OUString& rsEventType, + const ::css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, + const ::css::uno::Reference<css::drawing::framework::XResource>& rxResourceObject); + + /** Call all listeners and inform them that the + ConfigurationController is being disposed. When this method returns + the list of registered listeners is empty. Further calls to + RemoveListener() are not necessary but do not result in an error. + */ + void DisposeAndClear (void); + +private: + css::uno::Reference< + com::sun::star::drawing::framework::XConfigurationController> mxConfigurationController; + class ListenerDescriptor {public: + css::uno::Reference< + css::drawing::framework::XConfigurationChangeListener> mxListener; + css::uno::Any maUserData; + }; + typedef ::std::vector<ListenerDescriptor> ListenerList; + typedef ::std::hash_map + <rtl::OUString, + ListenerList, + ::comphelper::UStringHash, + ::comphelper::UStringEqual> ListenerMap; + ListenerMap maListenerMap; + + /** Broadcast the given event to all listeners in the given list. + + When calling a listener results in a DisposedException being thrown + the listener is unregistered automatically. + */ + void NotifyListeners ( + const ListenerList& rList, + const css::drawing::framework::ConfigurationChangeEvent& rEvent); +}; + + + + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx new file mode 100644 index 000000000000..e1c285f149af --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx @@ -0,0 +1,358 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ConfigurationControllerResourceManager.hxx" +#include "ConfigurationControllerBroadcaster.hxx" +#include "ResourceFactoryManager.hxx" +#include "framework/FrameworkHelper.hxx" +#include <com/sun/star/lang/DisposedException.hpp> +#include <tools/diagnose_ex.h> +#include <algorithm> +#include <boost/bind.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +#undef VERBOSE +//#define VERBOSE 1 + +namespace sd { namespace framework { + +//===== ConfigurationControllerResourceManager ================================ + +ConfigurationControllerResourceManager::ConfigurationControllerResourceManager ( + const ::boost::shared_ptr<ResourceFactoryManager>& rpResourceFactoryContainer, + const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster) + : maResourceMap(ResourceComparator()), + mpResourceFactoryContainer(rpResourceFactoryContainer), + mpBroadcaster(rpBroadcaster) +{ +} + + + + +ConfigurationControllerResourceManager::~ConfigurationControllerResourceManager (void) +{ +} + + + + +ConfigurationControllerResourceManager::ResourceDescriptor + ConfigurationControllerResourceManager::GetResource ( + const Reference<XResourceId>& rxResourceId) +{ + ::osl::MutexGuard aGuard (maMutex); + ResourceMap::const_iterator iResource (maResourceMap.find(rxResourceId)); + if (iResource != maResourceMap.end()) + return iResource->second; + else + return ResourceDescriptor(); +} + + + + +void ConfigurationControllerResourceManager::ActivateResources ( + const ::std::vector<Reference<XResourceId> >& rResources, + const Reference<XConfiguration>& rxConfiguration) +{ + ::osl::MutexGuard aGuard (maMutex); + // Iterate in normal order over the resources that are to be + // activated so that resources on which others depend are activated + // beforet the depending resources are activated. + ::std::for_each( + rResources.begin(), + rResources.end(), + ::boost::bind(&ConfigurationControllerResourceManager::ActivateResource, + this, _1, rxConfiguration)); +} + + + + +void ConfigurationControllerResourceManager::DeactivateResources ( + const ::std::vector<Reference<XResourceId> >& rResources, + const Reference<XConfiguration>& rxConfiguration) +{ + ::osl::MutexGuard aGuard (maMutex); + // Iterate in reverese order over the resources that are to be + // deactivated so that resources on which others depend are deactivated + // only when the depending resources have already been deactivated. + ::std::for_each( + rResources.rbegin(), + rResources.rend(), + ::boost::bind(&ConfigurationControllerResourceManager::DeactivateResource, + this, _1, rxConfiguration)); +} + + + + +/* In this method we do following steps. + 1. Get the factory with which the resource will be created. + 2. Create the resource. + 3. Add the resource to the URL->Object map of the configuration + controller. + 4. Add the resource id to the current configuration. + 5. Notify listeners. +*/ +void ConfigurationControllerResourceManager::ActivateResource ( + const Reference<XResourceId>& rxResourceId, + const Reference<XConfiguration>& rxConfiguration) +{ + if ( ! rxResourceId.is()) + { + OSL_ASSERT(rxResourceId.is()); + return; + } + +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("activating resource %s\n", OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif + + // 1. Get the factory. + const OUString sResourceURL (rxResourceId->getResourceURL()); + Reference<XResourceFactory> xFactory (mpResourceFactoryContainer->GetFactory(sResourceURL)); + if ( ! xFactory.is()) + { +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE(" no factory found fo %s\n", + OUStringToOString(sResourceURL, RTL_TEXTENCODING_UTF8).getStr()); +#endif + return; + } + + try + { + // 2. Create the resource. + Reference<XResource> xResource; + try + { + xResource = xFactory->createResource(rxResourceId); + } + catch (lang::DisposedException&) + { + // The factory is disposed and can be removed from the list + // of registered factories. + mpResourceFactoryContainer->RemoveFactoryForReference(xFactory); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if (xResource.is()) + { +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE(" successfully created\n"); +#endif + // 3. Add resource to URL->Object map. + AddResource(xResource, xFactory); + + // 4. Add resource id to current configuration. + rxConfiguration->addResource(rxResourceId); + + // 5. Notify the new resource to listeners of the ConfigurationController. + mpBroadcaster->NotifyListeners( + FrameworkHelper::msResourceActivationEvent, + rxResourceId, + xResource); + } + else + { +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE(" resource creation failed\n"); +#endif + } + } + catch (RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + + + + +/* In this method we do following steps. + 1. Remove the resource from the URL->Object map of the configuration + controller. + 2. Notify listeners. + 3. Remove the resource id from the current configuration. + 4. Release the resource. +*/ +void ConfigurationControllerResourceManager::DeactivateResource ( + const Reference<XResourceId>& rxResourceId, + const Reference<XConfiguration>& rxConfiguration) +{ + if ( ! rxResourceId.is()) + return; + +#if defined VERBOSE && VERBOSE>=1 + bool bSuccess (false); +#endif + try + { + // 1. Remove resource from URL->Object map. + ResourceDescriptor aDescriptor (RemoveResource(rxResourceId)); + + if (aDescriptor.mxResource.is() && aDescriptor.mxResourceFactory.is()) + { + // 2. Notifiy listeners that the resource is being deactivated. + mpBroadcaster->NotifyListeners( + FrameworkHelper::msResourceDeactivationEvent, + rxResourceId, + aDescriptor.mxResource); + + // 3. Remove resource id from current configuration. + rxConfiguration->removeResource(rxResourceId); + + // 4. Release the resource. + try + { + aDescriptor.mxResourceFactory->releaseResource(aDescriptor.mxResource); + } + catch (lang::DisposedException& rException) + { + if ( ! rException.Context.is() + || rException.Context == aDescriptor.mxResourceFactory) + { + // The factory is disposed and can be removed from the + // list of registered factories. + mpResourceFactoryContainer->RemoveFactoryForReference( + aDescriptor.mxResourceFactory); + } + } + +#if defined VERBOSE && VERBOSE>=1 + bSuccess = true; +#endif + } + } + catch (RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + +#if defined VERBOSE && VERBOSE>=1 + if (bSuccess) + OSL_TRACE("successfully deactivated %s\n", OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); + else + OSL_TRACE("activating resource %s failed\n", OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); +#endif +} + + + + +void ConfigurationControllerResourceManager::AddResource ( + const Reference<XResource>& rxResource, + const Reference<XResourceFactory>& rxFactory) +{ + if ( ! rxResource.is()) + { + OSL_ASSERT(rxResource.is()); + return; + } + + // Add the resource to the resource container. + ResourceDescriptor aDescriptor; + aDescriptor.mxResource = rxResource; + aDescriptor.mxResourceFactory = rxFactory; + maResourceMap[rxResource->getResourceId()] = aDescriptor; + +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationControllerResourceManager::AddResource(): added %s -> %x\n", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResource->getResourceId()), + RTL_TEXTENCODING_UTF8).getStr(), + rxResource.get()); +#endif +} + + + + +ConfigurationControllerResourceManager::ResourceDescriptor + ConfigurationControllerResourceManager::RemoveResource ( + const Reference<XResourceId>& rxResourceId) +{ + ResourceDescriptor aDescriptor; + + ResourceMap::iterator iResource (maResourceMap.find(rxResourceId)); + if (iResource != maResourceMap.end()) + { +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationControllerResourceManager::RemoveResource(): removing %s -> %x\n", + OUStringToOString( + FrameworkHelper::ResourceIdToString(rxResourceId), + RTL_TEXTENCODING_UTF8).getStr(), + *iResource); +#endif + + aDescriptor = iResource->second; + maResourceMap.erase(rxResourceId); + } + + return aDescriptor; +} + + + + +//===== ConfigurationControllerResourceManager::ResourceComparator ============ + +bool ConfigurationControllerResourceManager::ResourceComparator::operator() ( + const Reference<XResourceId>& rxId1, + const Reference<XResourceId>& rxId2) const +{ + if (rxId1.is() && rxId2.is()) + return rxId1->compareTo(rxId2)<0; + else if (rxId1.is()) + return true; + else if (rxId2.is()) + return false; + else + return false; +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.hxx b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.hxx new file mode 100644 index 000000000000..34d58c46ee47 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.hxx @@ -0,0 +1,148 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_RESOURCE_MANAGER_HXX +#define SD_FRAMEWORK_RESOURCE_MANAGER_HXX + +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/XResource.hpp> +#include <com/sun/star/drawing/framework/XResourceFactory.hpp> +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> +#include <map> +#include <vector> + +namespace css = ::com::sun::star; + +namespace sd { namespace framework { + +class ConfigurationControllerBroadcaster; +class ResourceFactoryManager; + +/** Manage the set of active resources. Activate and deactivate resources. +*/ +class ConfigurationControllerResourceManager + : ::boost::noncopyable +{ +public: + /** For every active resource both the resource itself as well as its + creating factory are remembered, so that on deactivation, the + resource can be deactivated by this factory. + */ + class ResourceDescriptor + { + public: + css::uno::Reference<css::drawing::framework::XResource> mxResource; + css::uno::Reference<css::drawing::framework::XResourceFactory> mxResourceFactory; + }; + + /** A new ResourceManager object is created with the resource factory + container for creating resources and the event broadcaster for + notifying ConfigurationChangeListeners of activated or deactivated + resources. + */ + ConfigurationControllerResourceManager ( + const ::boost::shared_ptr<ResourceFactoryManager>& rpResourceFactoryContainer, + const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster); + + ~ConfigurationControllerResourceManager (void); + + /** Activate all the resources that are specified by resource ids in + rResources. The resource ids of activated resources are added to + the given configuration. Activated resources are notified to all + interested ConfigurationChangeListeners. + */ + void ActivateResources ( + const ::std::vector< + css::uno::Reference<css::drawing::framework::XResourceId> >& rResources, + const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration); + + /** Deactivate all the resources that are specified by resource ids in + rResources. The resource ids of deactivated resources are removed + from the given configuration. Activated resources are notified to all + interested ConfigurationChangeListeners. + */ + void DeactivateResources ( + const ::std::vector< + css::uno::Reference<css::drawing::framework::XResourceId> >& rResources, + const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration); + + /** Return the descriptor for the specified resource. + @return + When there is no active resource for the given resource id then + an empty descriptor is returned. + */ + ResourceDescriptor GetResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId); + +private: + osl::Mutex maMutex; + + class ResourceComparator + { + public: + bool operator() ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxId1, + const css::uno::Reference<css::drawing::framework::XResourceId>& rxId2) const; + }; + + typedef ::std::map< + css::uno::Reference<css::drawing::framework::XResourceId>, + ResourceDescriptor, + ResourceComparator> ResourceMap; + ResourceMap maResourceMap; + + ::boost::shared_ptr<ResourceFactoryManager> mpResourceFactoryContainer; + + /** This broadcaster is used to notify the activation and deactivation + of resources. + */ + ::boost::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster; + + void ActivateResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, + const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration); + + void DeactivateResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, + const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration); + + void AddResource ( + const css::uno::Reference<css::drawing::framework::XResource>& rxResource, + const css::uno::Reference<css::drawing::framework::XResourceFactory>& rxFactory); + + ResourceDescriptor RemoveResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId); +}; + + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationTracer.cxx b/sd/source/ui/framework/configuration/ConfigurationTracer.cxx new file mode 100644 index 000000000000..5e1150c16eb2 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationTracer.cxx @@ -0,0 +1,86 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ConfigurationTracer.hxx" + +#include <cstdio> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +namespace sd { namespace framework { + +void ConfigurationTracer::TraceConfiguration ( + const Reference<XConfiguration>& rxConfiguration, + const char* pMessage) +{ +#ifdef DEBUG + OSL_TRACE("%s at %p {", pMessage, rxConfiguration.get()); + if (rxConfiguration.is()) + { + TraceBoundResources(rxConfiguration, NULL, 0); + } + else + { + OSL_TRACE(" empty"); + } + OSL_TRACE("}"); +#else + (void)rxConfiguration; + (void)pMessage; +#endif +} + + + + +#ifdef DEBUG +void ConfigurationTracer::TraceBoundResources ( + const Reference<XConfiguration>& rxConfiguration, + const Reference<XResourceId>& rxResourceId, + const int nIndentation) +{ + Sequence<Reference<XResourceId> > aResourceList ( + rxConfiguration->getResources(rxResourceId, ::rtl::OUString(), AnchorBindingMode_DIRECT)); + const ::rtl::OUString sIndentation (RTL_CONSTASCII_USTRINGPARAM(" ")); + for (sal_Int32 nIndex=0; nIndex<aResourceList.getLength(); ++nIndex) + { + ::rtl::OUString sLine (aResourceList[nIndex]->getResourceURL()); + for (int i=0; i<nIndentation; ++i) + sLine = sIndentation + sLine; + OSL_TRACE("%s", OUStringToOString(sLine, RTL_TEXTENCODING_UTF8).getStr()); + TraceBoundResources(rxConfiguration, aResourceList[nIndex], nIndentation+1); + } +} +#endif + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationTracer.hxx b/sd/source/ui/framework/configuration/ConfigurationTracer.hxx new file mode 100644 index 000000000000..fce1751b2aba --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationTracer.hxx @@ -0,0 +1,60 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CONFIGURATION_TRACER_HXX +#define SD_FRAMEWORK_CONFIGURATION_TRACER_HXX + +#include <com/sun/star/drawing/framework/XConfiguration.hpp> + +namespace sd { namespace framework { + +/** Print debug information about configurations to the standard error + output channel. +*/ +class ConfigurationTracer +{ +public: + static void TraceConfiguration ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration, + const char* pMessage); +#ifdef DEBUG + static void TraceBoundResources ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration, + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId>& rxResourceId, + const int nIndentation); +#endif +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx b/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx new file mode 100644 index 000000000000..dd24374002e2 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx @@ -0,0 +1,471 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ConfigurationUpdater.hxx" +#include "ConfigurationTracer.hxx" +#include "ConfigurationClassifier.hxx" +#include "ConfigurationControllerBroadcaster.hxx" +#include "framework/Configuration.hxx" +#include "framework/FrameworkHelper.hxx" + +#include <comphelper/scopeguard.hxx> +#include <tools/diagnose_ex.h> + +#include <boost/bind.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::sd::framework::FrameworkHelper; +using ::rtl::OUString; +using ::std::vector; + +#undef VERBOSE +//#define VERBOSE 2 + +namespace { +static const sal_Int32 snShortTimeout (100); +static const sal_Int32 snNormalTimeout (1000); +static const sal_Int32 snLongTimeout (10000); +static const sal_Int32 snShortTimeoutCountThreshold (1); +static const sal_Int32 snNormalTimeoutCountThreshold (5); +} + +namespace sd { namespace framework { + + +//===== ConfigurationUpdaterLock ============================================== + +class ConfigurationUpdaterLock +{ +public: + ConfigurationUpdaterLock (ConfigurationUpdater& rUpdater) + : mrUpdater(rUpdater) { mrUpdater.LockUpdates(); } + ~ConfigurationUpdaterLock(void) { mrUpdater.UnlockUpdates(); } +private: + ConfigurationUpdater& mrUpdater; +}; + + + + +//===== ConfigurationUpdater ================================================== + +ConfigurationUpdater::ConfigurationUpdater ( + const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster, + const ::boost::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager, + const Reference<XControllerManager>& rxControllerManager) + : mxControllerManager(), + mpBroadcaster(rpBroadcaster), + mxCurrentConfiguration(Reference<XConfiguration>(new Configuration(NULL, false))), + mxRequestedConfiguration(), + mbUpdatePending(false), + mbUpdateBeingProcessed(false), + mnLockCount(0), + maUpdateTimer(), + mnFailedUpdateCount(0), + mpResourceManager(rpResourceManager) +{ + // Prepare the timer that is started when after an update the current + // and the requested configuration differ. With the timer we try + // updates until the two configurations are the same. + maUpdateTimer.SetTimeout(snNormalTimeout); + maUpdateTimer.SetTimeoutHdl(LINK(this,ConfigurationUpdater,TimeoutHandler)); + SetControllerManager(rxControllerManager); +} + + + + +ConfigurationUpdater::~ConfigurationUpdater (void) +{ + maUpdateTimer.Stop(); +} + + + + +void ConfigurationUpdater::SetControllerManager( + const Reference<XControllerManager>& rxControllerManager) +{ + mxControllerManager = rxControllerManager; +} + + + + +void ConfigurationUpdater::RequestUpdate ( + const Reference<XConfiguration>& rxRequestedConfiguration) +{ + mxRequestedConfiguration = rxRequestedConfiguration; + + // Find out whether we really can update the configuration. + if (IsUpdatePossible()) + { +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("UpdateConfiguration start"); +#endif + + // Call UpdateConfiguration while that is possible and while someone + // set mbUpdatePending to true in the middle of it. + do + { + UpdateConfiguration(); + + if (mbUpdatePending && IsUpdatePossible()) + continue; + } + while (false); + } + else + { + mbUpdatePending = true; +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("scheduling update for later"); +#endif + } +} + + + + +Reference<XConfiguration> ConfigurationUpdater::GetCurrentConfiguration (void) const +{ + return mxCurrentConfiguration; +} + + + + +bool ConfigurationUpdater::IsUpdatePossible (void) +{ + return ! mbUpdateBeingProcessed + && mxControllerManager.is() + && mnLockCount==0 + && mxRequestedConfiguration.is() + && mxCurrentConfiguration.is(); +} + + + + +void ConfigurationUpdater::UpdateConfiguration (void) +{ +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("UpdateConfiguration update"); +#endif + SetUpdateBeingProcessed(true); + comphelper::ScopeGuard aScopeGuard ( + ::boost::bind(&ConfigurationUpdater::SetUpdateBeingProcessed, this, false)); + + try + { + mbUpdatePending = false; + + CleanRequestedConfiguration(); + ConfigurationClassifier aClassifier(mxRequestedConfiguration, mxCurrentConfiguration); + if (aClassifier.Partition()) + { +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationUpdater::UpdateConfiguration("); + ConfigurationTracer::TraceConfiguration( + mxRequestedConfiguration, "requested configuration"); + ConfigurationTracer::TraceConfiguration( + mxCurrentConfiguration, "current configuration"); +#endif + // Notify the begining of the update. + ConfigurationChangeEvent aEvent; + aEvent.Type = FrameworkHelper::msConfigurationUpdateStartEvent; + aEvent.Configuration = mxRequestedConfiguration; + mpBroadcaster->NotifyListeners(aEvent); + + // Do the actual update. All exceptions are caught and ignored, + // so that the the end of the update is notified always. + try + { + if (mnLockCount == 0) + UpdateCore(aClassifier); + } + catch(RuntimeException) + { + } + + // Notify the end of the update. + aEvent.Type = FrameworkHelper::msConfigurationUpdateEndEvent; + mpBroadcaster->NotifyListeners(aEvent); + + CheckUpdateSuccess(); + } + else + { +#if defined VERBOSE && VERBOSE>0 + OSL_TRACE("nothing to do"); +#if defined VERBOSE && VERBOSE>=2 + ConfigurationTracer::TraceConfiguration( + mxRequestedConfiguration, "requested configuration"); + ConfigurationTracer::TraceConfiguration( + mxCurrentConfiguration, "current configuration"); +#endif +#endif + } + } + catch (RuntimeException e) + { + DBG_UNHANDLED_EXCEPTION(); + } + +#if defined VERBOSE && VERBOSE>0 + OSL_TRACE("ConfigurationUpdater::UpdateConfiguration)"); + OSL_TRACE("UpdateConfiguration end"); +#endif +} + + + + +void ConfigurationUpdater::CleanRequestedConfiguration (void) +{ + if (mxControllerManager.is()) + { + // Request the deactivation of pure anchors that have no child. + vector<Reference<XResourceId> > aResourcesToDeactivate; + CheckPureAnchors(mxRequestedConfiguration, aResourcesToDeactivate); + if (aResourcesToDeactivate.size() > 0) + { + Reference<XConfigurationController> xCC ( + mxControllerManager->getConfigurationController()); + vector<Reference<XResourceId> >::iterator iId; + for (iId=aResourcesToDeactivate.begin(); iId!=aResourcesToDeactivate.end(); ++iId) + if (iId->is()) + xCC->requestResourceDeactivation(*iId); + } + } +} + + + + +void ConfigurationUpdater::CheckUpdateSuccess (void) +{ + // When the two configurations differ then start the timer to call + // another update later. + if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration)) + { + if (mnFailedUpdateCount <= snShortTimeoutCountThreshold) + maUpdateTimer.SetTimeout(snShortTimeout); + else if (mnFailedUpdateCount < snNormalTimeoutCountThreshold) + maUpdateTimer.SetTimeout(snNormalTimeout); + else + maUpdateTimer.SetTimeout(snLongTimeout); + ++mnFailedUpdateCount; + maUpdateTimer.Start(); + } + else + { + // Update was successfull. Reset the failed update count. + mnFailedUpdateCount = 0; + } +} + + + + +void ConfigurationUpdater::UpdateCore (const ConfigurationClassifier& rClassifier) +{ + try + { +#if defined VERBOSE && VERBOSE>=2 + rClassifier.TraceResourceIdVector( + "requested but not current resources:", rClassifier.GetC1minusC2()); + rClassifier.TraceResourceIdVector( + "current but not requested resources:", rClassifier.GetC2minusC1()); + rClassifier.TraceResourceIdVector( + "requested and current resources:", rClassifier.GetC1andC2()); +#endif + + // Updating of the sub controllers is done in two steps. In the + // first the sub controllers typically shut down resources that are + // not requested anymore. In the second the sub controllers + // typically set up resources that have been newly requested. + mpResourceManager->DeactivateResources(rClassifier.GetC2minusC1(), mxCurrentConfiguration); + mpResourceManager->ActivateResources(rClassifier.GetC1minusC2(), mxCurrentConfiguration); + +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("ConfigurationController::UpdateConfiguration)"); + ConfigurationTracer::TraceConfiguration( + mxRequestedConfiguration, "requested configuration"); + ConfigurationTracer::TraceConfiguration( + mxCurrentConfiguration, "current configuration"); +#endif + + // Deactivate pure anchors that have no child. + vector<Reference<XResourceId> > aResourcesToDeactivate; + CheckPureAnchors(mxCurrentConfiguration, aResourcesToDeactivate); + if (aResourcesToDeactivate.size() > 0) + mpResourceManager->DeactivateResources(aResourcesToDeactivate, mxCurrentConfiguration); + } + catch(RuntimeException) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + + + + +void ConfigurationUpdater::CheckPureAnchors ( + const Reference<XConfiguration>& rxConfiguration, + vector<Reference<XResourceId> >& rResourcesToDeactivate) +{ + if ( ! rxConfiguration.is()) + return; + + // Get a list of all resources in the configuration. + Sequence<Reference<XResourceId> > aResources( + rxConfiguration->getResources( + NULL, OUString(), AnchorBindingMode_INDIRECT)); + sal_Int32 nCount (aResources.getLength()); + + // Prepare the list of pure anchors that have to be deactivated. + rResourcesToDeactivate.clear(); + + // Iterate over the list in reverse order because when there is a chain + // of pure anchors with only the last one having no child then the whole + // list has to be deactivated. + sal_Int32 nIndex (nCount-1); + while (nIndex >= 0) + { + const Reference<XResourceId> xResourceId (aResources[nIndex]); + const Reference<XResource> xResource ( + mpResourceManager->GetResource(xResourceId).mxResource); + bool bDeactiveCurrentResource (false); + + // Skip all resources that are no pure anchors. + if (xResource.is() && xResource->isAnchorOnly()) + { + // When xResource is not an anchor of the the next resource in + // the list then it is the anchor of no resource at all. + if (nIndex == nCount-1) + { + // No following anchors, deactivate this one, then remove it + // from the list. + bDeactiveCurrentResource = true; + } + else + { + const Reference<XResourceId> xPrevResourceId (aResources[nIndex+1]); + if ( ! xPrevResourceId.is() + || ! xPrevResourceId->isBoundTo(xResourceId, AnchorBindingMode_DIRECT)) + { + // The previous resource (id) does not exist or is not bound to + // the current anchor. + bDeactiveCurrentResource = true; + } + } + } + + if (bDeactiveCurrentResource) + { +#if defined VERBOSE && VERBOSE>=2 + OSL_TRACE("deactiving pure anchor %s because it has no children", + OUStringToOString( + FrameworkHelper::ResourceIdToString(xResourceId), + RTL_TEXTENCODING_UTF8).getStr()); +#endif + // Erase element from current configuration. + for (sal_Int32 nI=nIndex; nI<nCount-2; ++nI) + aResources[nI] = aResources[nI+1]; + nCount -= 1; + + rResourcesToDeactivate.push_back(xResourceId); + } + nIndex -= 1; + } +} + + + + +void ConfigurationUpdater::LockUpdates (void) +{ + ++mnLockCount; +} + + + + +void ConfigurationUpdater::UnlockUpdates (void) +{ + --mnLockCount; + if (mnLockCount == 0 && mbUpdatePending) + { + RequestUpdate(mxRequestedConfiguration); + } +} + + + + +::boost::shared_ptr<ConfigurationUpdaterLock> ConfigurationUpdater::GetLock (void) +{ + return ::boost::shared_ptr<ConfigurationUpdaterLock>(new ConfigurationUpdaterLock(*this)); +} + + + + +void ConfigurationUpdater::SetUpdateBeingProcessed (bool bValue) +{ + mbUpdateBeingProcessed = bValue; +} + + + + +IMPL_LINK(ConfigurationUpdater, TimeoutHandler, Timer*, EMPTYARG) +{ + OSL_TRACE("configuration update timer"); + if ( ! mbUpdateBeingProcessed + && mxCurrentConfiguration.is() + && mxRequestedConfiguration.is()) + { + if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration)) + { + OSL_TRACE("configurations differ, requesting update"); + RequestUpdate(mxRequestedConfiguration); + } + } + return 0; +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ConfigurationUpdater.hxx b/sd/source/ui/framework/configuration/ConfigurationUpdater.hxx new file mode 100644 index 000000000000..509ebbd9b429 --- /dev/null +++ b/sd/source/ui/framework/configuration/ConfigurationUpdater.hxx @@ -0,0 +1,218 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CONFIGURATION_UPDATER_HXX +#define SD_FRAMEWORK_CONFIGURATION_UPDATER_HXX + +#include "ConfigurationControllerResourceManager.hxx" +#include <com/sun/star/drawing/framework/XResourceId.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <vcl/timer.hxx> +#include <vector> +#include <boost/shared_ptr.hpp> + +namespace css = ::com::sun::star; + +namespace sd { namespace framework { + +class ConfigurationClassifier; +class ConfigurationUpdaterLock; + +/** This is a helper class for the ConfigurationController. It handles the + update of the current configuration so that it looks like a requested + configuration. An update is made by activating or deactivating drawing + framework resources. + + When an update is not successfull, i.e. after the update the current + configuration is not equivalent to the requested configuration, then a + timer is started to repeat the update after a short time. +*/ +class ConfigurationUpdater +{ +public: + /** Create a new ConfigurationUpdater object that notifies configuration + changes and the start and end of updates via the given broadcaster. + */ + ConfigurationUpdater ( + const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster, + const ::boost::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager, + const css::uno::Reference< + css::drawing::framework::XControllerManager>& rxControllerManager); + ~ConfigurationUpdater (void); + + /** This method is typically called once, when the controller manager is + accessible to the caller. + */ + void SetControllerManager( + const css::uno::Reference< + css::drawing::framework::XControllerManager>& rxControllerManager); + + /** Request an update of the current configuration so that it looks like + the given requested configuration. It checks whether an update of + the current configuration can be done. Calls UpdateConfiguration() + if that is the case. Otherwise it schedules a later call to + UpdateConfiguration(). + */ + void RequestUpdate (const css::uno::Reference< + css::drawing::framework::XConfiguration>& rxRequestedConfiguration); + + css::uno::Reference< + css::drawing::framework::XConfiguration> GetCurrentConfiguration (void) const; + + friend class ConfigurationUpdaterLock; + /** Return a lock of the called ConfigurationUpdater. While the + returned object exists no update of the current configuration is + made. + */ + ::boost::shared_ptr<ConfigurationUpdaterLock> GetLock (void); + +private: + /** A reference to the XControllerManager is kept so that + UpdateConfiguration() has access to the other sub controllers. + */ + css::uno::Reference< + css::drawing::framework::XControllerManager> mxControllerManager; + + ::boost::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster; + + /** The current configuration holds the resources that are currently + active. It is modified during an update. + */ + css::uno::Reference< + css::drawing::framework::XConfiguration> mxCurrentConfiguration; + + /** The requested configuration holds the resources that have been + requested to activate or to deactivate since the last update. It is + (usually) not modified during an update. This configuration is + maintained by the ConfigurationController and given to the + ConfigurationUpdater in the RequestUpdate() method. + */ + css::uno::Reference< + css::drawing::framework::XConfiguration> mxRequestedConfiguration; + + /** This flag is set to </TRUE> when an update of the current + configurtion was requested (because the last request in the queue + was processed) but could not be exected because the + ConfigurationController was locked. A call to UpdateConfiguration() + resets the flag to </FALSE>. + */ + bool mbUpdatePending; + + /** This flag is set to </TRUE> while the UpdateConfiguration() method + is running. It is used to prevent reentrance problems with this + method. + */ + bool mbUpdateBeingProcessed; + + /** The ConfigurationController is locked when this count has a value + larger then zero. If the controller is locked then updates of the + current configuration are not made. + */ + sal_Int32 mnLockCount; + + /** This timer is used to check from time to time whether the requested + configuration and the current configuration are identcal and request + an update when they are not. + This is used to overcome problems with resources that become + available asynchronously. + */ + Timer maUpdateTimer; + + /** The number of failed updates (those after which the current + configuration is not equivalent to the requested configuration) is + used to determine how long to wait before another update is made. + */ + sal_Int32 mnFailedUpdateCount; + + ::boost::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager; + + /** This method does the main work of an update. It calls the sub + controllers that are responsible for the various types of resources + and tells them to update their active resources. It notifies + listeners about the start and end of the configuration update. + */ + void UpdateConfiguration (void); + + /** Basically calls UpdaterStart() andUpdateEnd() and makes some debug + output. + */ + void UpdateCore (const ConfigurationClassifier& rClassifier); + + /** Check for all pure anchors if they have at least one child. + Childless pure anchors are deactivated. + This affects only the current configuration. + */ + void CheckPureAnchors ( + const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration, + ::std::vector<css::uno::Reference<css::drawing::framework::XResourceId> >& + rResourcesToDeactivate); + + /** Remove from the requested configration all pure anchors that have no + child. Requested but not yet activated anchors can not be removed + because without the actual resource the 'pureness' of an anchor can + not be determined. + */ + void CleanRequestedConfiguration (void); + + /** Check the success of a recently executed configuration update. + When the update failed then start the timer. + */ + void CheckUpdateSuccess (void); + + /** This method sets the mbUpdateBeingProcessed member that is used to + prevent reentrance problems. This method allows function objects + easyly and safely to modify the variable. + */ + void SetUpdateBeingProcessed (bool bValue); + + /** Return whether it is possible to do an update of the configuration. + This takes into account whether another update is currently being + executed, the lock count, and whether the configuration controller + is still valid. + */ + bool IsUpdatePossible (void); + + /** Lock updates of the current configuration. For intermediate requests + for updates mbUpdatePending is set to <TRUE/>. + */ + void LockUpdates (void); + + /** When an update was requested since the last LockUpdates() call then + RequestUpdate() is called. + */ + void UnlockUpdates (void); + + DECL_LINK(TimeoutHandler, Timer*); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.cxx b/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.cxx new file mode 100644 index 000000000000..79ceb38324bc --- /dev/null +++ b/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.cxx @@ -0,0 +1,106 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "GenericConfigurationChangeRequest.hxx" + +#include "framework/FrameworkHelper.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; + +namespace sd { namespace framework { + +GenericConfigurationChangeRequest::GenericConfigurationChangeRequest ( + const Reference<XResourceId>& rxResourceId, + const Mode eMode) throw(::com::sun::star::lang::IllegalArgumentException) + : GenericConfigurationChangeRequestInterfaceBase(MutexOwner::maMutex), + mxResourceId(rxResourceId), + meMode(eMode) +{ + if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0) + throw ::com::sun::star::lang::IllegalArgumentException(); +} + + + + +GenericConfigurationChangeRequest::~GenericConfigurationChangeRequest (void) throw() +{ +} + + + + +void SAL_CALL GenericConfigurationChangeRequest::execute ( + const Reference<XConfiguration>& rxConfiguration) + throw (RuntimeException) +{ + if (rxConfiguration.is()) + { + switch (meMode) + { + case Activation: + rxConfiguration->addResource(mxResourceId); + break; + + case Deactivation: + rxConfiguration->removeResource(mxResourceId); + break; + } + } +} + + + + +OUString SAL_CALL GenericConfigurationChangeRequest::getName (void) + throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("GenericConfigurationChangeRequest ")) + + (meMode==Activation ? OUString(RTL_CONSTASCII_USTRINGPARAM("activate ")) : OUString(RTL_CONSTASCII_USTRINGPARAM("deactivate "))) + + FrameworkHelper::ResourceIdToString(mxResourceId); +} + + + + +void SAL_CALL GenericConfigurationChangeRequest::setName (const OUString& rsName) + throw (RuntimeException) +{ + (void)rsName; + // Ignored. +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.hxx b/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.hxx new file mode 100644 index 000000000000..119e49e5aa20 --- /dev/null +++ b/sd/source/ui/framework/configuration/GenericConfigurationChangeRequest.hxx @@ -0,0 +1,126 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_GENERIC_CONFIGURATTION_CHANGE_REQUEST_HXX +#define SD_FRAMEWORK_GENERIC_CONFIGURATTION_CHANGE_REQUEST_HXX + +#include "MutexOwner.hxx" +#include <com/sun/star/drawing/framework/XConfigurationChangeRequest.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/XResourceId.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <cppuhelper/compbase2.hxx> + +namespace css = ::com::sun::star; + +namespace { + +typedef ::cppu::WeakComponentImplHelper2 < + ::com::sun::star::drawing::framework::XConfigurationChangeRequest, + ::com::sun::star::container::XNamed + > GenericConfigurationChangeRequestInterfaceBase; + +} // end of anonymous namespace. + + +namespace sd { namespace framework { + +/** This implementation of the XConfigurationChangeRequest interface + represents a single explicit request for a configuration change. On its + execution it may result in other, implicit, configuration changes. For + example this is the case when the deactivation of a unique resource is + requested: the resources linked to it have to be deactivated as well. +*/ +class GenericConfigurationChangeRequest + : private MutexOwner, + public GenericConfigurationChangeRequestInterfaceBase +{ +public: + /** This enum specified whether the activation or deactivation of a + resource is requested. + */ + enum Mode { Activation, Deactivation }; + + /** Create a new object that represents the request for activation or + deactivation of the specified resource. + @param rxsResourceId + Id of the resource that is to be activated or deactivated. + @param eMode + The mode specifies whether to activate or to deactivate the + resource. + */ + GenericConfigurationChangeRequest ( + const ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XResourceId>& + rxResourceId, + const Mode eMode) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual ~GenericConfigurationChangeRequest (void) throw(); + + + // XConfigurationChangeOperation + + /** The requested configuration change is executed on the given + configuration. Additionally to the explicitly requested change + other changes have to be made as well. See class description for an + example. + @param rxConfiguration + The configuration to which the requested change is made. + */ + virtual void SAL_CALL execute ( + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XConfiguration>& rxConfiguration) + throw (::com::sun::star::uno::RuntimeException); + + + // XNamed + + /** Return a human readable string representation. This is used for + debugging purposes. + */ + virtual ::rtl::OUString SAL_CALL getName (void) + throw (::com::sun::star::uno::RuntimeException); + + /** This call is ignored because the XNamed interface is (mis)used to + give access to a human readable name for debugging purposes. + */ + virtual void SAL_CALL setName (const ::rtl::OUString& rName) + throw (::com::sun::star::uno::RuntimeException); + +private: + const css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId; + const Mode meMode; +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx b/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx new file mode 100644 index 000000000000..ef6b785e0495 --- /dev/null +++ b/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx @@ -0,0 +1,233 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ResourceFactoryManager.hxx" +#include <tools/wldcrd.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <comphelper/processfactory.hxx> +#include <boost/bind.hpp> +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +namespace sd { namespace framework { + +ResourceFactoryManager::ResourceFactoryManager (const Reference<XControllerManager>& rxManager) + : maMutex(), + maFactoryMap(), + maFactoryPatternList(), + mxControllerManager(rxManager), + mxURLTransformer() +{ + // Create the URL transformer. + Reference<lang::XMultiServiceFactory> xServiceManager ( + ::comphelper::getProcessServiceFactory()); + mxURLTransformer = Reference<util::XURLTransformer>( + xServiceManager->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), + UNO_QUERY); +} + + + + +ResourceFactoryManager::~ResourceFactoryManager (void) +{ + Reference<lang::XComponent> xComponent (mxURLTransformer, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); +} + + + + +void ResourceFactoryManager::AddFactory ( + const OUString& rsURL, + const Reference<XResourceFactory>& rxFactory) + throw (RuntimeException) +{ + if ( ! rxFactory.is()) + throw lang::IllegalArgumentException(); + if (rsURL.getLength() == 0) + throw lang::IllegalArgumentException(); + + ::osl::MutexGuard aGuard (maMutex); + + if (rsURL.indexOf('*') >= 0 || rsURL.indexOf('?') >= 0) + { + // The URL is a URL pattern not an single URL. + maFactoryPatternList.push_back(FactoryPatternList::value_type(rsURL, rxFactory)); + } + else + { + maFactoryMap[rsURL] = rxFactory; + } +} + + + + +void ResourceFactoryManager::RemoveFactoryForURL ( + const OUString& rsURL) + throw (RuntimeException) +{ + if (rsURL.getLength() == 0) + throw lang::IllegalArgumentException(); + + ::osl::MutexGuard aGuard (maMutex); + + FactoryMap::iterator iFactory (maFactoryMap.find(rsURL)); + if (iFactory != maFactoryMap.end()) + { + maFactoryMap.erase(iFactory); + } + else + { + // The URL may be a pattern. Look that up. + FactoryPatternList::iterator iPattern; + for (iPattern=maFactoryPatternList.begin(); + iPattern!=maFactoryPatternList.end(); + ++iPattern) + { + if (iPattern->first == rsURL) + { + // Found the pattern. Remove it. + maFactoryPatternList.erase(iPattern); + break; + } + } + } +} + + + + + +void ResourceFactoryManager::RemoveFactoryForReference( + const Reference<XResourceFactory>& rxFactory) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + + // Collect a list with all keys that map to the given factory. + ::std::vector<OUString> aKeys; + FactoryMap::const_iterator iFactory; + for (iFactory=maFactoryMap.begin(); iFactory!=maFactoryMap.end(); ++iFactory) + if (iFactory->second == rxFactory) + aKeys.push_back(iFactory->first); + + // Remove the entries whose keys we just have collected. + ::std::vector<OUString>::const_iterator iKey; + for (iKey=aKeys.begin(); iKey!=aKeys.end(); ++iKey) + maFactoryMap.erase(maFactoryMap.find(*iKey)); + + // Remove the pattern entries whose factories are identical to the given + // factory. + FactoryPatternList::iterator iNewEnd ( + std::remove_if( + maFactoryPatternList.begin(), + maFactoryPatternList.end(), + ::boost::bind( + std::equal_to<Reference<XResourceFactory> >(), + ::boost::bind(&FactoryPatternList::value_type::second, _1), + rxFactory))); + if (iNewEnd != maFactoryPatternList.end()) + maFactoryPatternList.erase(iNewEnd, maFactoryPatternList.end()); +} + + + + +Reference<XResourceFactory> ResourceFactoryManager::GetFactory ( + const OUString& rsCompleteURL) + throw (RuntimeException) +{ + OUString sURLBase (rsCompleteURL); + if (mxURLTransformer.is()) + { + util::URL aURL; + aURL.Complete = rsCompleteURL; + if (mxURLTransformer->parseStrict(aURL)) + sURLBase = aURL.Main; + } + + Reference<XResourceFactory> xFactory = FindFactory(sURLBase); + + if ( ! xFactory.is() && mxControllerManager.is()) + { + Reference<XModuleController> xModuleController(mxControllerManager->getModuleController()); + if (xModuleController.is()) + { + // Ask the module controller to provide a factory of the + // requested view type. Note that this can (and should) cause + // intermediate calls to AddFactory(). + xModuleController->requestResource(sURLBase); + + xFactory = FindFactory(sURLBase); + } + } + + return xFactory; +} + + + + +Reference<XResourceFactory> ResourceFactoryManager::FindFactory (const OUString& rsURLBase) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + FactoryMap::const_iterator iFactory (maFactoryMap.find(rsURLBase)); + if (iFactory != maFactoryMap.end()) + return iFactory->second; + else + { + // Check the URL patterns. + FactoryPatternList::const_iterator iPattern; + for (iPattern=maFactoryPatternList.begin(); + iPattern!=maFactoryPatternList.end(); + ++iPattern) + { + WildCard aWildCard (iPattern->first); + if (aWildCard.Matches(rsURLBase)) + return iPattern->second; + } + } + return NULL; +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ResourceFactoryManager.hxx b/sd/source/ui/framework/configuration/ResourceFactoryManager.hxx new file mode 100644 index 000000000000..f0b5d99094a6 --- /dev/null +++ b/sd/source/ui/framework/configuration/ResourceFactoryManager.hxx @@ -0,0 +1,131 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_RESOURCE_FACTORY_MANAGER_HXX +#define SD_FRAMEWORK_RESOURCE_FACTORY_MANAGER_HXX + +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XModuleController.hpp> +#include <com/sun/star/drawing/framework/XResourceFactoryManager.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <osl/mutex.hxx> +#include <comphelper/stl_types.hxx> +#include <hash_map> + +namespace css = ::com::sun::star; + +namespace sd { namespace framework { + +/** Container of resource factories of the drawing framework. +*/ +class ResourceFactoryManager +{ +public: + ResourceFactoryManager ( + const css::uno::Reference<css::drawing::framework::XControllerManager>& rxManager); + + ~ResourceFactoryManager (void); + + /** Register a resource factory for one type of resource. + @param rsURL + The type of the resource that will be created by the factory. + @param rxFactory + The factory that will create resource objects of the specfied type. + */ + void AddFactory ( + const ::rtl::OUString& rsURL, + const css::uno::Reference<css::drawing::framework::XResourceFactory>& rxFactory) + throw (css::uno::RuntimeException); + + /** Unregister the specifed factory. + @param rsURL + Unregister only the factory for this URL. When the same factory + is registered for other URLs then these remain registered. + */ + void RemoveFactoryForURL( + const ::rtl::OUString& rsURL) + throw (css::uno::RuntimeException); + + /** Unregister the specified factory. + @param rxFactory + Unregister the this factory for all URLs that it has been + registered for. + */ + void RemoveFactoryForReference( + const css::uno::Reference<css::drawing::framework::XResourceFactory>& rxFactory) + throw (css::uno::RuntimeException); + + /** Return a factory that can create resources specified by the given URL. + @param rsCompleteURL + This URL specifies the type of the resource. It may contain arguments. + @return + When a factory for the specified URL has been registered by a + previous call to AddFactory() then a reference to that factory + is returned. Otherwise an empty reference is returned. + */ + css::uno::Reference<css::drawing::framework::XResourceFactory> GetFactory ( + const ::rtl::OUString& rsURL) + throw (css::uno::RuntimeException); + +private: + ::osl::Mutex maMutex; + typedef ::std::hash_map< + ::rtl::OUString, + css::uno::Reference<css::drawing::framework::XResourceFactory>, + ::comphelper::UStringHash, + ::comphelper::UStringEqual> FactoryMap; + FactoryMap maFactoryMap; + + typedef ::std::vector< + ::std::pair< + rtl::OUString, + css::uno::Reference<css::drawing::framework::XResourceFactory> > > + FactoryPatternList; + FactoryPatternList maFactoryPatternList; + + css::uno::Reference<css::drawing::framework::XControllerManager> mxControllerManager; + css::uno::Reference<css::util::XURLTransformer> mxURLTransformer; + + /** Look up the factory for the given URL. + @param rsURLBase + The css::tools::URL.Main part of a URL. Arguments have to be + stripped off by the caller. + @return + When the factory has not yet been added then return NULL. + */ + css::uno::Reference<css::drawing::framework::XResourceFactory> FindFactory ( + const ::rtl::OUString& rsURLBase) + throw (css::uno::RuntimeException); +}; + + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/ResourceId.cxx b/sd/source/ui/framework/configuration/ResourceId.cxx new file mode 100644 index 000000000000..ce56cf0f0704 --- /dev/null +++ b/sd/source/ui/framework/configuration/ResourceId.cxx @@ -0,0 +1,629 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/ResourceId.hxx" +#include "framework/FrameworkHelper.hxx" +#include "tools/SdGlobalResourceContainer.hxx" +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <comphelper/processfactory.hxx> +#include <rtl/ref.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +/** When the USE_OPTIMIZATIONS symbol is defined then at some optimizations + are activated that work only together with XResourceId objects that are + implemented by the ResourceId class. For other implementations of when + the USE_OPTIMIZATIONS symbol is not defined then alternative code is + used instead. +*/ +#define USE_OPTIMIZATIONS + +namespace sd { namespace framework { + +Reference<XInterface> SAL_CALL ResourceId_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + (void)rxContext; + return Reference<XInterface>(static_cast<XWeak*>(new ::sd::framework::ResourceId())); +} + + + + +::rtl::OUString ResourceId_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.ResourceId")); +} + + + + +Sequence<rtl::OUString> SAL_CALL ResourceId_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.ResourceId"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== ResourceId ============================================================ + +WeakReference<util::XURLTransformer> ResourceId::mxURLTransformerWeak; + +ResourceId::ResourceId (void) + : ResourceIdInterfaceBase(), + maResourceURLs(0), + mpURL() +{ +} + + + + +ResourceId::ResourceId ( + const std::vector<OUString>& rResourceURLs) + : ResourceIdInterfaceBase(), + maResourceURLs(rResourceURLs), + mpURL() +{ + ParseResourceURL(); +} + + + + +ResourceId::ResourceId ( + const OUString& rsResourceURL) + : ResourceIdInterfaceBase(), + maResourceURLs(1, rsResourceURL), + mpURL() +{ + // Handle the special case of an empty resource URL. + if (rsResourceURL.getLength() == 0) + maResourceURLs.clear(); + ParseResourceURL(); +} + + + + +ResourceId::ResourceId ( + const OUString& rsResourceURL, + const OUString& rsAnchorURL) + : ResourceIdInterfaceBase(), + maResourceURLs(2), + mpURL() +{ + maResourceURLs[0] = rsResourceURL; + maResourceURLs[1] = rsAnchorURL; + ParseResourceURL(); +} + + + + +ResourceId::ResourceId ( + const OUString& rsResourceURL, + const ::std::vector<OUString>& rAnchorURLs) + : ResourceIdInterfaceBase(), + maResourceURLs(1+rAnchorURLs.size()), + mpURL() +{ + maResourceURLs[0] = rsResourceURL; + for (sal_uInt32 nIndex=0; nIndex<rAnchorURLs.size(); ++nIndex) + maResourceURLs[nIndex+1] = rAnchorURLs[nIndex]; + ParseResourceURL(); +} + + + + +ResourceId::ResourceId ( + const OUString& rsResourceURL, + const OUString& rsFirstAnchorURL, + const Sequence<OUString>& rAnchorURLs) + : ResourceIdInterfaceBase(), + maResourceURLs(2+rAnchorURLs.getLength()), + mpURL() +{ + maResourceURLs[0] = rsResourceURL; + maResourceURLs[1] = rsFirstAnchorURL; + for (sal_Int32 nIndex=0; nIndex<rAnchorURLs.getLength(); ++nIndex) + maResourceURLs[nIndex+2] = rAnchorURLs[nIndex]; + ParseResourceURL(); +} + + + + +ResourceId::~ResourceId (void) +{ + mpURL.reset(); +} + + + + +OUString SAL_CALL + ResourceId::getResourceURL (void) + throw(com::sun::star::uno::RuntimeException) +{ + if (maResourceURLs.size() > 0) + return maResourceURLs[0]; + else + return OUString(); +} + + + + +util::URL SAL_CALL + ResourceId::getFullResourceURL (void) + throw(com::sun::star::uno::RuntimeException) +{ + if (mpURL.get() != NULL) + return *mpURL; + + Reference<util::XURLTransformer> xURLTransformer (mxURLTransformerWeak); + if (xURLTransformer.is() && maResourceURLs.size() > 0) + { + mpURL.reset(new util::URL); + mpURL->Complete = maResourceURLs[0]; + xURLTransformer->parseStrict(*mpURL); + return *mpURL; + } + + util::URL aURL; + if (maResourceURLs.size() > 0) + aURL.Complete = maResourceURLs[0]; + return aURL; +} + + + + +sal_Bool SAL_CALL + ResourceId::hasAnchor (void) + throw (RuntimeException) +{ + return maResourceURLs.size()>1; +} + + + + +Reference<XResourceId> SAL_CALL + ResourceId::getAnchor (void) + throw (RuntimeException) +{ + ::rtl::Reference<ResourceId> rResourceId (new ResourceId()); + const sal_Int32 nAnchorCount (maResourceURLs.size()-1); + if (nAnchorCount > 0) + { + rResourceId->maResourceURLs.resize(nAnchorCount); + for (sal_Int32 nIndex=0; nIndex<nAnchorCount; ++nIndex) + rResourceId->maResourceURLs[nIndex] = maResourceURLs[nIndex+1]; + } + return Reference<XResourceId>(rResourceId.get()); +} + + + + +Sequence<OUString> SAL_CALL + ResourceId::getAnchorURLs (void) + throw (RuntimeException) +{ + const sal_Int32 nAnchorCount (maResourceURLs.size() - 1); + if (nAnchorCount > 0) + { + Sequence<OUString> aAnchorURLs (nAnchorCount); + for (sal_Int32 nIndex=0; nIndex<nAnchorCount; ++nIndex) + aAnchorURLs[nIndex] = maResourceURLs[nIndex+1]; + return aAnchorURLs; + } + else + return Sequence<OUString>(); +} + + + + +OUString SAL_CALL + ResourceId::getResourceTypePrefix (void) + throw (RuntimeException) +{ + if (maResourceURLs.size() > 0) + { + // Return the "private:resource/<type>/" prefix. + + // Get the the prefix that ends with the second "/". + const OUString& rsResourceURL (maResourceURLs[0]); + sal_Int32 nPrefixEnd (rsResourceURL.indexOf(sal_Unicode('/'), 0)); + if (nPrefixEnd >= 0) + nPrefixEnd = rsResourceURL.indexOf(sal_Unicode('/'), nPrefixEnd+1) + 1; + else + nPrefixEnd = 0; + + return rsResourceURL.copy(0,nPrefixEnd); + } + else + return OUString(); +} + + + + +sal_Int16 SAL_CALL + ResourceId::compareTo (const Reference<XResourceId>& rxResourceId) + throw (RuntimeException) +{ + sal_Int16 nResult (0); + + if ( ! rxResourceId.is()) + { + // The empty reference is interpreted as empty resource id object. + if (maResourceURLs.size() > 0) + nResult = +1; + else + nResult = 0; + } + else + { + ResourceId* pId = NULL; +#ifdef USE_OPTIMIZATIONS + pId = dynamic_cast<ResourceId*>(rxResourceId.get()); +#endif + if (pId != NULL) + { + // We have direct access to the implementation of the given + // resource id object. + nResult = CompareToLocalImplementation(*pId); + } + else + { + // We have to do the comparison via the UNO interface of the + // given resource id object. + nResult = CompareToExternalImplementation(rxResourceId); + } + } + + return nResult; +} + + + + +sal_Int16 ResourceId::CompareToLocalImplementation (const ResourceId& rId) const +{ + sal_Int16 nResult (0); + + const sal_uInt32 nLocalURLCount (maResourceURLs.size()); + const sal_uInt32 nURLCount(rId.maResourceURLs.size()); + + // Start comparison with the top most anchors. + for (sal_Int32 nIndex=nURLCount-1,nLocalIndex=nLocalURLCount-1; + nIndex>=0 && nLocalIndex>=0; + --nIndex,--nLocalIndex) + { + const OUString sLocalURL (maResourceURLs[nLocalIndex]); + const OUString sURL (rId.maResourceURLs[nIndex]); + const sal_Int32 nLocalResult (sURL.compareTo(sLocalURL)); + if (nLocalResult != 0) + { + if (nLocalResult < 0) + nResult = -1; + else + nResult = +1; + break; + } + } + + if (nResult == 0) + { + // No difference found yet. When the lengths are the same then the + // two resource ids are equivalent. Otherwise the shorter comes + // first. + if (nLocalURLCount != nURLCount) + { + if (nLocalURLCount < nURLCount) + nResult = -1; + else + nResult = +1; + } + } + + return nResult; +} + + + + +sal_Int16 ResourceId::CompareToExternalImplementation (const Reference<XResourceId>& rxId) const +{ + sal_Int16 nResult (0); + + const Sequence<OUString> aAnchorURLs (rxId->getAnchorURLs()); + const sal_uInt32 nLocalURLCount (maResourceURLs.size()); + const sal_uInt32 nURLCount(1+aAnchorURLs.getLength()); + + // Start comparison with the top most anchors. + sal_Int32 nLocalResult (0); + for (sal_Int32 nIndex=nURLCount-1,nLocalIndex=nLocalURLCount-1; + nIndex>=0&&nLocalIndex>=0; + --nIndex,--nLocalIndex) + { + if (nIndex == 0 ) + nLocalResult = maResourceURLs[nIndex].compareTo(rxId->getResourceURL()); + else + nLocalResult = maResourceURLs[nIndex].compareTo(aAnchorURLs[nIndex-1]); + if (nLocalResult != 0) + { + if (nLocalResult < 0) + nResult = -1; + else + nResult = +1; + break; + } + } + + if (nResult == 0) + { + // No difference found yet. When the lengths are the same then the + // two resource ids are equivalent. Otherwise the shorter comes + // first. + if (nLocalURLCount != nURLCount) + { + if (nLocalURLCount < nURLCount) + nResult = -1; + else + nResult = +1; + } + } + + return nResult; +} + + + + +sal_Bool SAL_CALL + ResourceId::isBoundTo ( + const Reference<XResourceId>& rxResourceId, + AnchorBindingMode eMode) + throw (RuntimeException) +{ + if ( ! rxResourceId.is()) + { + // An empty reference is interpreted as empty resource id. + return IsBoundToAnchor(NULL, NULL, eMode); + } + + ResourceId* pId = NULL; +#ifdef USE_OPTIMIZATIONS + pId = dynamic_cast<ResourceId*>(rxResourceId.get()); +#endif + if (pId != NULL) + { + return IsBoundToAnchor(pId->maResourceURLs, eMode); + } + else + { + const OUString sResourceURL (rxResourceId->getResourceURL()); + const Sequence<OUString> aAnchorURLs (rxResourceId->getAnchorURLs()); + return IsBoundToAnchor(&sResourceURL, &aAnchorURLs, eMode); + } +} + + + + +sal_Bool SAL_CALL + ResourceId::isBoundToURL ( + const OUString& rsAnchorURL, + AnchorBindingMode eMode) + throw (RuntimeException) +{ + return IsBoundToAnchor(&rsAnchorURL, NULL, eMode); +} + + + + +Reference<XResourceId> SAL_CALL + ResourceId::clone (void) + throw(RuntimeException) +{ + return new ResourceId(maResourceURLs); +} + + + + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL ResourceId::initialize (const Sequence<Any>& aArguments) + throw (RuntimeException) +{ + sal_uInt32 nCount (aArguments.getLength()); + for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex) + { + OUString sResourceURL; + if (aArguments[nIndex] >>= sResourceURL) + maResourceURLs.push_back(sResourceURL); + else + { + Reference<XResourceId> xAnchor; + if (aArguments[nIndex] >>= xAnchor) + { + if (xAnchor.is()) + { + maResourceURLs.push_back(xAnchor->getResourceURL()); + Sequence<OUString> aAnchorURLs (xAnchor->getAnchorURLs()); + for (sal_Int32 nURLIndex=0; nURLIndex<aAnchorURLs.getLength(); ++nURLIndex) + { + maResourceURLs.push_back(aAnchorURLs[nURLIndex]); + } + } + } + } + } + ParseResourceURL(); +} + + + + +//----------------------------------------------------------------------------- + +/** When eMode is DIRECTLY then the anchor of the called object and the + anchor represented by the given sequence of anchor URLs have to be + identical. When eMode is RECURSIVE then the anchor of the called + object has to start with the given anchor URLs. +*/ +bool ResourceId::IsBoundToAnchor ( + const OUString* psFirstAnchorURL, + const Sequence<OUString>* paAnchorURLs, + AnchorBindingMode eMode) const +{ + const sal_uInt32 nLocalAnchorURLCount (maResourceURLs.size() - 1); + const bool bHasFirstAnchorURL (psFirstAnchorURL!=NULL); + const sal_uInt32 nAnchorURLCount ((bHasFirstAnchorURL?1:0) + + (paAnchorURLs!=NULL ? paAnchorURLs->getLength() : 0)); + + // Check the lengths. + if (nLocalAnchorURLCount<nAnchorURLCount || + (eMode==AnchorBindingMode_DIRECT && nLocalAnchorURLCount!=nAnchorURLCount)) + { + return false; + } + + // Compare the nAnchorURLCount bottom-most anchor URLs of this resource + // id and the given anchor. + sal_uInt32 nOffset = 0; + if (paAnchorURLs != NULL) + { + sal_uInt32 nCount = paAnchorURLs->getLength(); + while (nOffset < nCount) + { + if ( ! maResourceURLs[nLocalAnchorURLCount - nOffset].equals( + (*paAnchorURLs)[nCount - 1 - nOffset])) + { + return false; + } + ++nOffset; + } + } + if (bHasFirstAnchorURL) + { + if ( ! psFirstAnchorURL->equals(maResourceURLs[nLocalAnchorURLCount - nOffset])) + return false; + } + + return true; +} + + + + +bool ResourceId::IsBoundToAnchor ( + const ::std::vector<OUString>& rAnchorURLs, + AnchorBindingMode eMode) const +{ + const sal_uInt32 nLocalAnchorURLCount (maResourceURLs.size() - 1); + const sal_uInt32 nAnchorURLCount (rAnchorURLs.size()); + + // Check the lengths. + if (nLocalAnchorURLCount<nAnchorURLCount || + (eMode==AnchorBindingMode_DIRECT && nLocalAnchorURLCount!=nAnchorURLCount)) + { + return false; + } + + // Compare the nAnchorURLCount bottom-most anchor URLs of this resource + // id and the given anchor. + for (sal_uInt32 nOffset=0; nOffset<nAnchorURLCount; ++nOffset) + { + if ( ! maResourceURLs[nLocalAnchorURLCount - nOffset].equals( + rAnchorURLs[nAnchorURLCount - 1 - nOffset])) + { + return false; + } + } + + return true; +} + + + + +void ResourceId::ParseResourceURL (void) +{ + ::osl::Guard< ::osl::Mutex > aGuard (::osl::Mutex::getGlobalMutex()); + Reference<util::XURLTransformer> xURLTransformer (mxURLTransformerWeak); + if ( ! xURLTransformer.is()) + { + // Create the URL transformer. + Reference<lang::XMultiServiceFactory> xServiceManager ( + ::comphelper::getProcessServiceFactory()); + xURLTransformer = Reference<util::XURLTransformer>( + xServiceManager->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), + UNO_QUERY); + mxURLTransformerWeak = xURLTransformer; + SdGlobalResourceContainer::Instance().AddResource( + Reference<XInterface>(xURLTransformer,UNO_QUERY)); + } + + if (xURLTransformer.is() && maResourceURLs.size() > 0) + { + mpURL.reset(new util::URL); + mpURL->Complete = maResourceURLs[0]; + xURLTransformer->parseStrict(*mpURL); + if (mpURL->Main == maResourceURLs[0]) + mpURL.reset(); + else + maResourceURLs[0] = mpURL->Main; + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/UpdateRequest.cxx b/sd/source/ui/framework/configuration/UpdateRequest.cxx new file mode 100644 index 000000000000..149e490dde20 --- /dev/null +++ b/sd/source/ui/framework/configuration/UpdateRequest.cxx @@ -0,0 +1,88 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "UpdateRequest.hxx" + +#include "framework/FrameworkHelper.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; + +namespace sd { namespace framework { + +UpdateRequest::UpdateRequest (void) + throw() + : UpdateRequestInterfaceBase(MutexOwner::maMutex) +{ +} + + + + +UpdateRequest::~UpdateRequest (void) throw() +{ +} + + + + +void SAL_CALL UpdateRequest::execute (const Reference<XConfiguration>& rxConfiguration) + throw (RuntimeException) +{ + (void)rxConfiguration; + // Do nothing here. The configuration is updated when the request queue + // becomes empty. +} + + + + +OUString SAL_CALL UpdateRequest::getName (void) + throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("UpdateRequest")); +} + + + + +void SAL_CALL UpdateRequest::setName (const OUString& rsName) + throw (RuntimeException) +{ + (void)rsName; + // Ignored. +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/UpdateRequest.hxx b/sd/source/ui/framework/configuration/UpdateRequest.hxx new file mode 100644 index 000000000000..f9b4cd32b82f --- /dev/null +++ b/sd/source/ui/framework/configuration/UpdateRequest.hxx @@ -0,0 +1,96 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_UPDATE_REQUEST_HXX +#define SD_FRAMEWORK_UPDATE_REQUEST_HXX + +#include "MutexOwner.hxx" +#include <com/sun/star/drawing/framework/XConfigurationChangeRequest.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <cppuhelper/compbase2.hxx> + + +namespace { + +typedef ::cppu::WeakComponentImplHelper2 < + ::com::sun::star::drawing::framework::XConfigurationChangeRequest, + ::com::sun::star::container::XNamed + > UpdateRequestInterfaceBase; + +} // end of anonymous namespace. + + + +namespace sd { namespace framework { + +/** This update request is used to request configuration updates + asynchronous when no other requests are being processed. When there are + other requests then we can simply wait until the last one is executed: + the configuration is updated when the request queue becomes empty. This + is use by this implementation as well. The execute() method does not + really do anything. This request just triggers the update of the + configuration when it is removed as last request from the queue. +*/ +class UpdateRequest + : private MutexOwner, + public UpdateRequestInterfaceBase +{ +public: + UpdateRequest (void) throw(); + virtual ~UpdateRequest (void) throw(); + + + // XConfigurationChangeOperation + + virtual void SAL_CALL execute ( + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XConfiguration>& rxConfiguration) + throw (::com::sun::star::uno::RuntimeException); + + + // XNamed + + /** Return a human readable string representation. This is used for + debugging purposes. + */ + virtual ::rtl::OUString SAL_CALL getName (void) + throw (::com::sun::star::uno::RuntimeException); + + /** This call is ignored because the XNamed interface is (mis)used to + give access to a human readable name for debugging purposes. + */ + virtual void SAL_CALL setName (const ::rtl::OUString& rName) + throw (::com::sun::star::uno::RuntimeException); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/configuration/makefile.mk b/sd/source/ui/framework/configuration/makefile.mk new file mode 100644 index 000000000000..cdc41491b307 --- /dev/null +++ b/sd/source/ui/framework/configuration/makefile.mk @@ -0,0 +1,63 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=framework_configuration +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true +PRJINC=..$/.. + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/ChangeRequestQueue.obj \ + $(SLO)$/ChangeRequestQueueProcessor.obj \ + $(SLO)$/Configuration.obj \ + $(SLO)$/ConfigurationClassifier.obj \ + $(SLO)$/ConfigurationController.obj \ + $(SLO)$/ConfigurationControllerBroadcaster.obj \ + $(SLO)$/ConfigurationControllerResourceManager.obj \ + $(SLO)$/ConfigurationTracer.obj \ + $(SLO)$/ConfigurationUpdater.obj \ + $(SLO)$/GenericConfigurationChangeRequest.obj \ + $(SLO)$/ResourceId.obj \ + $(SLO)$/ResourceFactoryManager.obj \ + $(SLO)$/UpdateRequest.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.cxx b/sd/source/ui/framework/factories/BasicPaneFactory.cxx new file mode 100644 index 000000000000..224280341995 --- /dev/null +++ b/sd/source/ui/framework/factories/BasicPaneFactory.cxx @@ -0,0 +1,564 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "BasicPaneFactory.hxx" + +#include "ChildWindowPane.hxx" +#include "FrameWindowPane.hxx" +#include "FullScreenPane.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "ViewShellBase.hxx" +#include "PaneChildWindows.hxx" +#include "DrawController.hxx" +#include "DrawDocShell.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <boost/bind.hpp> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +namespace { + enum PaneId { + CenterPaneId, + FullScreenPaneId, + LeftImpressPaneId, + LeftDrawPaneId, + RightPaneId + }; + + static const sal_Int32 gnConfigurationUpdateStartEvent(0); + static const sal_Int32 gnConfigurationUpdateEndEvent(1); +} + +namespace sd { namespace framework { + + +/** Store URL, XPane reference and (local) PaneId for every pane factory + that is registered at the PaneController. +*/ +class BasicPaneFactory::PaneDescriptor +{ +public: + OUString msPaneURL; + Reference<XResource> mxPane; + PaneId mePaneId; + /** The mbReleased flag is set when the pane has been released. Some + panes are just hidden and destroyed. When the pane is reused this + flag is reset. + */ + bool mbIsReleased; + bool mbIsChildWindow; + + bool CompareURL (const OUString& rsPaneURL) { return msPaneURL.equals(rsPaneURL); } + bool ComparePane (const Reference<XResource>& rxPane) { return mxPane==rxPane; } +}; + + +class BasicPaneFactory::PaneContainer + : public ::std::vector<PaneDescriptor> +{ +public: + PaneContainer (void) {} +}; + + + +Reference<XInterface> SAL_CALL BasicPaneFactory_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(static_cast<XWeak*>(new BasicPaneFactory(rxContext))); +} + + + + +::rtl::OUString BasicPaneFactory_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.BasicPaneFactory")); +} + + + + +Sequence<rtl::OUString> SAL_CALL BasicPaneFactory_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.BasicPaneFactory"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== PaneFactory =========================================================== + +BasicPaneFactory::BasicPaneFactory ( + const Reference<XComponentContext>& rxContext) + : BasicPaneFactoryInterfaceBase(m_aMutex), + mxComponentContext(rxContext), + mxConfigurationControllerWeak(), + mpViewShellBase(NULL), + mpPaneContainer(new PaneContainer), + mbFirstUpdateSeen(false), + mpUpdateLockManager() +{ +} + + + + + +BasicPaneFactory::~BasicPaneFactory (void) +{ +} + + + + +void SAL_CALL BasicPaneFactory::disposing (void) +{ + Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); + if (xCC.is()) + { + xCC->removeResourceFactoryForReference(this); + xCC->removeConfigurationChangeListener(this); + mxConfigurationControllerWeak = Reference<XConfigurationController>(); + } + + for (PaneContainer::const_iterator iDescriptor = mpPaneContainer->begin(); + iDescriptor != mpPaneContainer->end(); + ++iDescriptor) + { + if (iDescriptor->mbIsReleased) + { + Reference<XComponent> xComponent (iDescriptor->mxPane, UNO_QUERY); + if (xComponent.is()) + { + xComponent->removeEventListener(this); + xComponent->dispose(); + } + } + } +} + + + + +void SAL_CALL BasicPaneFactory::initialize (const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + if (aArguments.getLength() > 0) + { + try + { + // Get the XController from the first argument. + Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW); + mxControllerWeak = xController; + + // Tunnel through the controller to obtain access to the ViewShellBase. + try + { + Reference<lang::XUnoTunnel> xTunnel (xController, UNO_QUERY_THROW); + DrawController* pController + = reinterpret_cast<DrawController*>( + (sal::static_int_cast<sal_uIntPtr>( + xTunnel->getSomething(DrawController::getUnoTunnelId())))); + mpViewShellBase = pController->GetViewShellBase(); + mpUpdateLockManager = mpViewShellBase->GetUpdateLockManager(); + } + catch(RuntimeException&) + {} + + Reference<XControllerManager> xCM (xController, UNO_QUERY_THROW); + Reference<XConfigurationController> xCC (xCM->getConfigurationController()); + mxConfigurationControllerWeak = xCC; + + // Add pane factories for the two left panes (one for Impress and one for + // Draw), the center pane, and the right pane. + if (xController.is() && xCC.is()) + { + PaneDescriptor aDescriptor; + aDescriptor.msPaneURL = FrameworkHelper::msCenterPaneURL; + aDescriptor.mePaneId = CenterPaneId; + aDescriptor.mbIsReleased = false; + aDescriptor.mbIsChildWindow = false; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + + aDescriptor.msPaneURL = FrameworkHelper::msFullScreenPaneURL; + aDescriptor.mePaneId = FullScreenPaneId; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + + aDescriptor.msPaneURL = FrameworkHelper::msLeftImpressPaneURL; + aDescriptor.mePaneId = LeftImpressPaneId; + aDescriptor.mbIsChildWindow = true; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + + aDescriptor.msPaneURL = FrameworkHelper::msLeftDrawPaneURL; + aDescriptor.mePaneId = LeftDrawPaneId; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + + aDescriptor.msPaneURL = FrameworkHelper::msRightPaneURL; + aDescriptor.mePaneId = RightPaneId; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + } + + // Register as configuration change listener. + if (xCC.is()) + { + xCC->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateStartEvent, + makeAny(gnConfigurationUpdateStartEvent)); + xCC->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateEndEvent, + makeAny(gnConfigurationUpdateEndEvent)); + } + } + catch (RuntimeException&) + { + Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); + if (xCC.is()) + xCC->removeResourceFactoryForReference(this); + } + } +} + + + + +//===== XPaneFactory ========================================================== + +Reference<XResource> SAL_CALL BasicPaneFactory::createResource ( + const Reference<XResourceId>& rxPaneId) + throw (RuntimeException, IllegalArgumentException, WrappedTargetException) +{ + ThrowIfDisposed(); + + Reference<XResource> xPane; + + // Based on the ResourceURL of the given ResourceId look up the + // corresponding factory descriptor. + PaneContainer::iterator iDescriptor ( + ::std::find_if ( + mpPaneContainer->begin(), + mpPaneContainer->end(), + ::boost::bind(&PaneDescriptor::CompareURL, _1, rxPaneId->getResourceURL()))); + + if (iDescriptor != mpPaneContainer->end()) + { + if (iDescriptor->mxPane.is()) + { + // The pane has already been created and is still active (has + // not yet been released). This should not happen. + xPane = iDescriptor->mxPane; + } + else + { + // Create a new pane. + switch (iDescriptor->mePaneId) + { + case CenterPaneId: + xPane = CreateFrameWindowPane(rxPaneId); + break; + + case FullScreenPaneId: + xPane = CreateFullScreenPane(mxComponentContext, rxPaneId); + break; + + case LeftImpressPaneId: + case LeftDrawPaneId: + case RightPaneId: + xPane = CreateChildWindowPane( + rxPaneId, + *iDescriptor); + break; + } + iDescriptor->mxPane = xPane; + + // Listen for the pane being disposed. + Reference<lang::XComponent> xComponent (xPane, UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(this); + } + iDescriptor->mbIsReleased = false; + } + else + { + // The requested pane can not be created by any of the factories + // managed by the called BasicPaneFactory object. + throw lang::IllegalArgumentException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "BasicPaneFactory::createPane() called for unknown resource id")), + NULL, + 0); + } + + return xPane; +} + + + + + +void SAL_CALL BasicPaneFactory::releaseResource ( + const Reference<XResource>& rxPane) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + // Based on the given XPane reference look up the corresponding factory + // descriptor. + PaneContainer::iterator iDescriptor ( + ::std::find_if( + mpPaneContainer->begin(), + mpPaneContainer->end(), + ::boost::bind(&PaneDescriptor::ComparePane, _1, rxPane))); + + if (iDescriptor != mpPaneContainer->end()) + { + // The given pane was created by one of the factories. Child + // windows are just hidden and will be reused when requested later. + // Other windows are disposed and their reference is reset so that + // on the next createPane() call for the same pane type the pane is + // created anew. + ChildWindowPane* pChildWindowPane = dynamic_cast<ChildWindowPane*>(rxPane.get()); + if (pChildWindowPane != NULL) + { + iDescriptor->mbIsReleased = true; + pChildWindowPane->Hide(); + } + else + { + iDescriptor->mxPane = NULL; + Reference<XComponent> xComponent (rxPane, UNO_QUERY); + if (xComponent.is()) + { + // We are disposing the pane and do not have to be informed of + // that. + xComponent->removeEventListener(this); + xComponent->dispose(); + } + } + } + else + { + // The given XPane reference is either empty or the pane was not + // created by any of the factories managed by the called + // BasicPaneFactory object. + throw lang::IllegalArgumentException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "BasicPaneFactory::releasePane() called for pane that that was not created by same factory.")), + NULL, + 0); + } +} + + + + +//===== XConfigurationChangeListener ========================================== + +void SAL_CALL BasicPaneFactory::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + sal_Int32 nEventType = 0; + rEvent.UserData >>= nEventType; + switch (nEventType) + { + case gnConfigurationUpdateStartEvent: + // Lock UI updates while we are switching the views except for + // the first time after creation. Outherwise this leads to + // problems after reload (missing resizes for the side panes). + if (mbFirstUpdateSeen) + { + } + else + mbFirstUpdateSeen = true; + break; + + case gnConfigurationUpdateEndEvent: + // Unlock the update lock here when only the visibility of + // windows but not the view shells displayed in them have + // changed. Otherwise the UpdateLockManager takes care of + // unlocking at the right time. + if (mpUpdateLockManager.get() != NULL) + { + ::osl::Guard< ::osl::Mutex > aGuard (::osl::Mutex::getGlobalMutex()); + } + break; + } +} + + + + +//===== lang::XEventListener ================================================== + +void SAL_CALL BasicPaneFactory::disposing ( + const lang::EventObject& rEventObject) + throw (RuntimeException) +{ + if (mxConfigurationControllerWeak == rEventObject.Source) + { + mxConfigurationControllerWeak = Reference<XConfigurationController>(); + } + else + { + // Has one of the panes been disposed? If so, then release the + // reference to that pane, but not the pane descriptor. + Reference<XResource> xPane (rEventObject.Source, UNO_QUERY); + PaneContainer::iterator iDescriptor ( + ::std::find_if ( + mpPaneContainer->begin(), + mpPaneContainer->end(), + ::boost::bind(&PaneDescriptor::ComparePane, _1, xPane))); + if (iDescriptor != mpPaneContainer->end()) + { + iDescriptor->mxPane = NULL; + } + } +} + + + + +//----------------------------------------------------------------------------- + +Reference<XResource> BasicPaneFactory::CreateFrameWindowPane ( + const Reference<XResourceId>& rxPaneId) +{ + Reference<XResource> xPane; + + if (mpViewShellBase != NULL) + { + xPane = new FrameWindowPane(rxPaneId, mpViewShellBase->GetViewWindow()); + } + + return xPane; +} + + + + +Reference<XResource> BasicPaneFactory::CreateFullScreenPane ( + const Reference<XComponentContext>& rxComponentContext, + const Reference<XResourceId>& rxPaneId) +{ + Reference<XResource> xPane ( + new FullScreenPane( + rxComponentContext, + rxPaneId, + mpViewShellBase->GetViewWindow())); + + return xPane; +} + + + + +Reference<XResource> BasicPaneFactory::CreateChildWindowPane ( + const Reference<XResourceId>& rxPaneId, + const PaneDescriptor& rDescriptor) +{ + Reference<XResource> xPane; + + if (mpViewShellBase != NULL) + { + // Create the corresponding shell and determine the id of the child window. + USHORT nChildWindowId = 0; + ::std::auto_ptr<SfxShell> pShell; + switch (rDescriptor.mePaneId) + { + case LeftImpressPaneId: + pShell.reset(new LeftImpressPaneShell()); + nChildWindowId = ::sd::LeftPaneImpressChildWindow::GetChildWindowId(); + break; + + case LeftDrawPaneId: + pShell.reset(new LeftDrawPaneShell()); + nChildWindowId = ::sd::LeftPaneDrawChildWindow::GetChildWindowId(); + break; + + case RightPaneId: + pShell.reset(new ToolPanelPaneShell()); + nChildWindowId = ::sd::ToolPanelChildWindow::GetChildWindowId(); + break; + + default: + break; + } + + // With shell and child window id create the ChildWindowPane + // wrapper. + if (pShell.get() != NULL) + { + xPane = new ChildWindowPane( + rxPaneId, + nChildWindowId, + *mpViewShellBase, + pShell); + } + } + + return xPane; +} + +void BasicPaneFactory::ThrowIfDisposed (void) const + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "BasicPaneFactory object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.hxx b/sd/source/ui/framework/factories/BasicPaneFactory.hxx new file mode 100644 index 000000000000..bed0dc3b5e28 --- /dev/null +++ b/sd/source/ui/framework/factories/BasicPaneFactory.hxx @@ -0,0 +1,171 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_BASIC_PANE_FACTORY_HXX +#define SD_FRAMEWORK_BASIC_PANE_FACTORY_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/drawing/framework/XResourceFactory.hpp> +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase3.hxx> +#include "UpdateLockManager.hxx" + + +#include <boost/scoped_ptr.hpp> +#include <boost/shared_ptr.hpp> + +namespace css = ::com::sun::star; + + +namespace { + +typedef ::cppu::WeakComponentImplHelper3 < + css::lang::XInitialization, + css::drawing::framework::XResourceFactory, + css::drawing::framework::XConfigurationChangeListener + > BasicPaneFactoryInterfaceBase; + +} // end of anonymous namespace. + + +namespace sd { + +class ViewShellBase; +} + +namespace sd { namespace framework { + +/** This factory provides the frequently used standard panes + private:resource/pane/CenterPane + private:resource/pane/FullScreenPane + private:resource/pane/LeftImpressPane + private:resource/pane/LeftDrawPane + private:resource/pane/RightPane + There are two left panes because this is (seems to be) the only way to + show different titles for the left pane in Draw and Impress. +*/ +class BasicPaneFactory + : private ::cppu::BaseMutex, + public BasicPaneFactoryInterfaceBase +{ +public: + BasicPaneFactory ( + const css::uno::Reference<css::uno::XComponentContext>& rxContext); + virtual ~BasicPaneFactory (void); + + virtual void SAL_CALL disposing (void); + + + // XInitialization + + virtual void SAL_CALL initialize( + const css::uno::Sequence<css::uno::Any>& aArguments) + throw (css::uno::Exception, css::uno::RuntimeException); + + + // XResourceFactory + + virtual css::uno::Reference<css::drawing::framework::XResource> + SAL_CALL createResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId) + throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException); + + virtual void SAL_CALL + releaseResource ( + const css::uno::Reference<css::drawing::framework::XResource>& rxPane) + throw (css::uno::RuntimeException); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (css::uno::RuntimeException); + + + // lang::XEventListener + + virtual void SAL_CALL disposing ( + const css::lang::EventObject& rEventObject) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference<css::uno::XComponentContext> mxComponentContext; + css::uno::WeakReference<css::drawing::framework::XConfigurationController> + mxConfigurationControllerWeak; + css::uno::WeakReference<css::frame::XController> mxControllerWeak; + ViewShellBase* mpViewShellBase; + class PaneDescriptor; + class PaneContainer; + ::boost::scoped_ptr<PaneContainer> mpPaneContainer; + bool mbFirstUpdateSeen; + ::boost::shared_ptr<UpdateLockManager> mpUpdateLockManager; + + /** Create a new instance of FrameWindowPane. + @param rPaneId + There is only one frame window so this id is just checked to + have the correct value. + */ + css::uno::Reference<css::drawing::framework::XResource> + CreateFrameWindowPane ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId); + + /** Create a new pane that represents the center pane in full screen + mode. + */ + css::uno::Reference<css::drawing::framework::XResource> + CreateFullScreenPane ( + const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, + const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId); + + /** Create a new instance of ChildWindowPane. + @param rPaneId + The ResourceURL member defines which side pane to create. + */ + css::uno::Reference<css::drawing::framework::XResource> + CreateChildWindowPane ( + const css::uno::Reference< + css::drawing::framework::XResourceId>& rxPaneId, + const PaneDescriptor& rDescriptor); + + void ThrowIfDisposed (void) const + throw (css::lang::DisposedException); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/BasicToolBarFactory.cxx b/sd/source/ui/framework/factories/BasicToolBarFactory.cxx new file mode 100644 index 000000000000..6294b253841f --- /dev/null +++ b/sd/source/ui/framework/factories/BasicToolBarFactory.cxx @@ -0,0 +1,248 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "BasicToolBarFactory.hxx" + +#include "ViewTabBar.hxx" +#include "framework/FrameworkHelper.hxx" +#include <comphelper/mediadescriptor.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include "DrawController.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; + +namespace sd { namespace framework { + + +Reference<XInterface> SAL_CALL BasicToolBarFactory_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return static_cast<XWeak*>(new BasicToolBarFactory(rxContext)); +} + + + + +::rtl::OUString BasicToolBarFactory_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.BasicToolBarFactory")); +} + + + + +Sequence<rtl::OUString> SAL_CALL BasicToolBarFactory_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.BasicToolBarFactory"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + + +//===== BasicToolBarFactory =================================================== + +BasicToolBarFactory::BasicToolBarFactory ( + const Reference<XComponentContext>& rxContext) + : BasicToolBarFactoryInterfaceBase(m_aMutex), + mxConfigurationController(), + mxController(), + mpViewShellBase(NULL) +{ + (void)rxContext; +} + + + + +BasicToolBarFactory::~BasicToolBarFactory (void) +{ +} + + + + +void SAL_CALL BasicToolBarFactory::disposing (void) +{ + Shutdown(); +} + + + + +void BasicToolBarFactory::Shutdown (void) +{ + mpViewShellBase = NULL; + Reference<lang::XComponent> xComponent (mxConfigurationController, UNO_QUERY); + if (xComponent.is()) + xComponent->removeEventListener(static_cast<lang::XEventListener*>(this)); + if (mxConfigurationController.is()) + { + mxConfigurationController->removeResourceFactoryForReference(this); + mxConfigurationController = NULL; + } +} + + + + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL BasicToolBarFactory::initialize (const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + if (aArguments.getLength() > 0) + { + try + { + // Get the XController from the first argument. + mxController = Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW); + + // Tunnel through the controller to obtain a ViewShellBase. + Reference<lang::XUnoTunnel> xTunnel (mxController, UNO_QUERY_THROW); + ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>( + xTunnel->getSomething(sd::DrawController::getUnoTunnelId())); + if (pController != NULL) + mpViewShellBase = pController->GetViewShellBase(); + + ::comphelper::MediaDescriptor aDescriptor (mxController->getModel()->getArgs()); + if ( ! aDescriptor.getUnpackedValueOrDefault( + ::comphelper::MediaDescriptor::PROP_PREVIEW(), + sal_False)) + { + // Register the factory for its supported tool bars. + Reference<XControllerManager> xControllerManager(mxController, UNO_QUERY_THROW); + mxConfigurationController = xControllerManager->getConfigurationController(); + if (mxConfigurationController.is()) + { + mxConfigurationController->addResourceFactory( + FrameworkHelper::msViewTabBarURL, this); + } + + Reference<lang::XComponent> xComponent (mxConfigurationController, UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(static_cast<lang::XEventListener*>(this)); + } + else + { + // The view shell is in preview mode and thus does not need + // the view tab bar. + mxConfigurationController = NULL; + } + } + catch (RuntimeException&) + { + Shutdown(); + throw; + } + } +} + + + + +//----- lang::XEventListener -------------------------------------------------- + +void SAL_CALL BasicToolBarFactory::disposing ( + const lang::EventObject& rEventObject) + throw (RuntimeException) +{ + if (rEventObject.Source == mxConfigurationController) + mxConfigurationController = NULL; +} + + + + +//===== XPaneFactory ========================================================== + +Reference<XResource> SAL_CALL BasicToolBarFactory::createResource ( + const Reference<XResourceId>& rxToolBarId) + throw (RuntimeException, IllegalArgumentException, WrappedTargetException) +{ + ThrowIfDisposed(); + + Reference<XResource> xToolBar; + + if (rxToolBarId->getResourceURL().equals(FrameworkHelper::msViewTabBarURL)) + { + xToolBar = new ViewTabBar(rxToolBarId, mxController); + } + else + throw lang::IllegalArgumentException(); + + + return xToolBar; +} + + + + + +void SAL_CALL BasicToolBarFactory::releaseResource ( + const Reference<XResource>& rxToolBar) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + Reference<XComponent> xComponent (rxToolBar, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); +} + + + + +void BasicToolBarFactory::ThrowIfDisposed (void) const + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "BasicToolBarFactory object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/BasicToolBarFactory.hxx b/sd/source/ui/framework/factories/BasicToolBarFactory.hxx new file mode 100644 index 000000000000..edf4c9e4044a --- /dev/null +++ b/sd/source/ui/framework/factories/BasicToolBarFactory.hxx @@ -0,0 +1,121 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_BASIC_TOOL_BAR_FACTORY_HXX +#define SD_FRAMEWORK_BASIC_TOOL_BAR_FACTORY_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/drawing/framework/XResourceFactory.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XResourceId.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/basemutex.hxx> + + +namespace css = ::com::sun::star; + +namespace { + +typedef ::cppu::WeakComponentImplHelper3 < + css::drawing::framework::XResourceFactory, + css::lang::XInitialization, + css::lang::XEventListener + > BasicToolBarFactoryInterfaceBase; + +} // end of anonymous namespace. + +namespace sd { +class ViewShellBase; +} + +namespace sd { namespace framework { + +/** This factory provides some of the frequently used tool bars: + private:resource/toolbar/ViewTabBar +*/ +class BasicToolBarFactory + : protected ::cppu::BaseMutex, + public BasicToolBarFactoryInterfaceBase +{ +public: + BasicToolBarFactory ( + const css::uno::Reference<com::sun::star::uno::XComponentContext>& rxContext); + virtual ~BasicToolBarFactory (void); + + virtual void SAL_CALL disposing (void); + + + // ToolBarFactory + + virtual css::uno::Reference<com::sun::star::drawing::framework::XResource> SAL_CALL + createResource ( + const css::uno::Reference< + css::drawing::framework::XResourceId>& rxToolBarId) + throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException); + + virtual void SAL_CALL + releaseResource ( + const css::uno::Reference<com::sun::star::drawing::framework::XResource>& + rxToolBar) + throw (css::uno::RuntimeException); + + + // XInitialization + + virtual void SAL_CALL initialize( + const css::uno::Sequence<com::sun::star::uno::Any>& aArguments) + throw (css::uno::Exception, css::uno::RuntimeException); + + + // lang::XEventListener + + virtual void SAL_CALL disposing ( + const css::lang::EventObject& rEventObject) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference<css::drawing::framework::XConfigurationController> mxConfigurationController; + css::uno::Reference<css::frame::XController> mxController; + ViewShellBase* mpViewShellBase; + + void Shutdown (void); + + void ThrowIfDisposed (void) const + throw (css::lang::DisposedException); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx new file mode 100644 index 000000000000..6b577ba3009e --- /dev/null +++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx @@ -0,0 +1,618 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "BasicViewFactory.hxx" + +#include "framework/ViewShellWrapper.hxx" +#include "framework/FrameworkHelper.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include "framework/Pane.hxx" +#include "DrawController.hxx" +#include "DrawSubController.hxx" +#include "ViewShellBase.hxx" +#include "ViewShellManager.hxx" +#include "DrawDocShell.hxx" +#include "DrawViewShell.hxx" +#include "GraphicViewShell.hxx" +#include "OutlineViewShell.hxx" +#include "taskpane/ToolPanelViewShell.hxx" +#include "PresentationViewShell.hxx" +#include "SlideSorterViewShell.hxx" +#include "FrameView.hxx" + +#include <sfx2/viewfrm.hxx> +#include <vcl/wrkwin.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <boost/bind.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + + +Reference<XInterface> SAL_CALL BasicViewFactory_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(static_cast<XWeak*>(new BasicViewFactory(rxContext))); +} + + + + +::rtl::OUString BasicViewFactory_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.BasicViewFactory")); +} + + + + +Sequence<rtl::OUString> SAL_CALL BasicViewFactory_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.BasicViewFactory"))); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== ViewDescriptor ======================================================== + +class BasicViewFactory::ViewDescriptor +{ +public: + Reference<XResource> mxView; + ::boost::shared_ptr<sd::ViewShell> mpViewShell; + ViewShellWrapper* mpWrapper; + Reference<XResourceId> mxViewId; + static bool CompareView (const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor, + const Reference<XResource>& rxView) + { return rpDescriptor->mxView.get() == rxView.get(); } +}; + + + + + +//===== BasicViewFactory::ViewShellContainer ================================== + +class BasicViewFactory::ViewShellContainer + : public ::std::vector<boost::shared_ptr<ViewDescriptor> > +{ +public: + ViewShellContainer (void) {}; +}; + + +class BasicViewFactory::ViewCache + : public ::std::vector<boost::shared_ptr<ViewDescriptor> > +{ +public: + ViewCache (void) {}; +}; + + + + +//===== ViewFactory =========================================================== + +BasicViewFactory::BasicViewFactory ( + const Reference<XComponentContext>& rxContext) + : BasicViewFactoryInterfaceBase(MutexOwner::maMutex), + mxConfigurationController(), + mpViewShellContainer(new ViewShellContainer()), + mpBase(NULL), + mpFrameView(NULL), + mpWindow(new WorkWindow(NULL,WB_STDWORK)), + mpViewCache(new ViewCache()), + mxLocalPane(new Pane(Reference<XResourceId>(), mpWindow.get())) +{ + (void)rxContext; +} + + + + +BasicViewFactory::~BasicViewFactory (void) +{ +} + + + + +void SAL_CALL BasicViewFactory::disposing (void) +{ + // Disconnect from the frame view. + if (mpFrameView != NULL) + { + mpFrameView->Disconnect(); + mpFrameView = NULL; + } + + // Relase the view cache. + ViewShellContainer::const_iterator iView; + for (iView=mpViewCache->begin(); iView!=mpViewCache->end(); ++iView) + { + ReleaseView(*iView, true); + } + + // Release the view shell container. At this point no one other than us + // should hold references to the view shells (at the moment this is a + // trivial requirement, because no one other then us holds a shared + // pointer). + // ViewShellContainer::const_iterator iView; + for (iView=mpViewShellContainer->begin(); iView!=mpViewShellContainer->end(); ++iView) + { + OSL_ASSERT((*iView)->mpViewShell.unique()); + } + mpViewShellContainer.reset(); +} + + + + +Reference<XResource> SAL_CALL BasicViewFactory::createResource ( + const Reference<XResourceId>& rxViewId) + throw(RuntimeException, IllegalArgumentException, WrappedTargetException) +{ + Reference<XResource> xView; + const bool bIsCenterPane ( + rxViewId->isBoundToURL(FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)); + + // Get the pane for the anchor URL. + Reference<XPane> xPane; + if (mxConfigurationController.is()) + xPane = Reference<XPane>(mxConfigurationController->getResource(rxViewId->getAnchor()), + UNO_QUERY); + + // For main views use the frame view of the last main view. + ::sd::FrameView* pFrameView = NULL; + if (xPane.is() && bIsCenterPane) + { + pFrameView = mpFrameView; + } + + // Get Window pointer for XWindow of the pane. + ::Window* pWindow = NULL; + if (xPane.is()) + pWindow = VCLUnoHelper::GetWindow(xPane->getWindow()); + + // Get the view frame. + SfxViewFrame* pFrame = NULL; + if (mpBase != NULL) + pFrame = mpBase->GetViewFrame(); + + if (pFrame != NULL && mpBase!=NULL && pWindow!=NULL) + { + // Try to get the view from the cache. + ::boost::shared_ptr<ViewDescriptor> pDescriptor (GetViewFromCache(rxViewId, xPane)); + + // When the requested view is not in the cache then create a new view. + if (pDescriptor.get() == NULL) + { + pDescriptor = CreateView(rxViewId, *pFrame, *pWindow, xPane, pFrameView); + } + + if (pDescriptor.get() != NULL) + xView = pDescriptor->mxView; + + mpViewShellContainer->push_back(pDescriptor); + + if (bIsCenterPane) + ActivateCenterView(pDescriptor); + else + pWindow->Resize(); + } + + return xView; +} + + + + +void SAL_CALL BasicViewFactory::releaseResource (const Reference<XResource>& rxView) + throw(RuntimeException) +{ + if ( ! rxView.is()) + throw lang::IllegalArgumentException(); + + if (rxView.is() && mpBase!=NULL) + { + ViewShellContainer::iterator iViewShell ( + ::std::find_if( + mpViewShellContainer->begin(), + mpViewShellContainer->end(), + ::boost::bind(&ViewDescriptor::CompareView, _1, rxView))); + if (iViewShell != mpViewShellContainer->end()) + { + ::boost::shared_ptr<ViewShell> pViewShell ((*iViewShell)->mpViewShell); + + if ((*iViewShell)->mxViewId->isBoundToURL( + FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)) + { + // Obtain a pointer to and connect to the frame view of the + // view. The next view, that is created, will be + // initialized with this frame view. + if (mpFrameView == NULL) + { + mpFrameView = pViewShell->GetFrameView(); + if (mpFrameView) + mpFrameView->Connect(); + } + + // With the view in the center pane the sub controller is + // released, too. + mpBase->GetDrawController().SetSubController( + Reference<drawing::XDrawSubController>()); + + SfxViewShell* pSfxViewShell = pViewShell->GetViewShell(); + if (pSfxViewShell != NULL) + pSfxViewShell->DisconnectAllClients(); + } + + ReleaseView(*iViewShell); + + mpViewShellContainer->erase(iViewShell); + } + else + { + throw lang::IllegalArgumentException(); + } + } +} + + + + +void SAL_CALL BasicViewFactory::initialize (const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + if (aArguments.getLength() > 0) + { + Reference<XConfigurationController> xCC; + try + { + // Get the XController from the first argument. + Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW); + + // Tunnel through the controller to obtain a ViewShellBase. + Reference<lang::XUnoTunnel> xTunnel (xController, UNO_QUERY_THROW); + ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>( + xTunnel->getSomething(sd::DrawController::getUnoTunnelId())); + if (pController != NULL) + mpBase = pController->GetViewShellBase(); + + // Register the factory for its supported views. + Reference<XControllerManager> xCM (xController,UNO_QUERY_THROW); + mxConfigurationController = xCM->getConfigurationController(); + if ( ! mxConfigurationController.is()) + throw RuntimeException(); + mxConfigurationController->addResourceFactory(FrameworkHelper::msImpressViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msDrawViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msOutlineViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msNotesViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msHandoutViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msPresentationViewURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msTaskPaneURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msSlideSorterURL, this); + } + catch (RuntimeException&) + { + mpBase = NULL; + if (mxConfigurationController.is()) + mxConfigurationController->removeResourceFactoryForReference(this); + throw; + } + } +} + + + + +::boost::shared_ptr<BasicViewFactory::ViewDescriptor> BasicViewFactory::CreateView ( + const Reference<XResourceId>& rxViewId, + SfxViewFrame& rFrame, + ::Window& rWindow, + const Reference<XPane>& rxPane, + FrameView* pFrameView) +{ + ::boost::shared_ptr<ViewDescriptor> pDescriptor (new ViewDescriptor()); + + pDescriptor->mpViewShell = CreateViewShell( + rxViewId, + rFrame, + rWindow, + pFrameView); + pDescriptor->mxViewId = rxViewId; + + if (pDescriptor->mpViewShell.get() != NULL) + { + const bool bIsCenterPane ( + rxViewId->isBoundToURL(FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)); + pDescriptor->mpViewShell->Init(bIsCenterPane); + mpBase->GetViewShellManager()->ActivateViewShell(pDescriptor->mpViewShell.get()); + + pDescriptor->mpWrapper = new ViewShellWrapper( + pDescriptor->mpViewShell, + rxViewId, + rxPane->getWindow()); + pDescriptor->mxView.set( pDescriptor->mpWrapper->queryInterface( XResource::static_type() ), UNO_QUERY_THROW ); + } + + return pDescriptor; +} + + + + +::boost::shared_ptr<ViewShell> BasicViewFactory::CreateViewShell ( + const Reference<XResourceId>& rxViewId, + SfxViewFrame& rFrame, + ::Window& rWindow, + FrameView* pFrameView) +{ + ::boost::shared_ptr<ViewShell> pViewShell; + const OUString& rsViewURL (rxViewId->getResourceURL()); + if (rsViewURL.equals(FrameworkHelper::msImpressViewURL)) + { + pViewShell.reset( + new DrawViewShell( + &rFrame, + *mpBase, + &rWindow, + PK_STANDARD, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msDrawViewURL)) + { + pViewShell.reset( + new GraphicViewShell ( + &rFrame, + *mpBase, + &rWindow, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msOutlineViewURL)) + { + pViewShell.reset( + new OutlineViewShell ( + &rFrame, + *mpBase, + &rWindow, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msNotesViewURL)) + { + pViewShell.reset( + new DrawViewShell( + &rFrame, + *mpBase, + &rWindow, + PK_NOTES, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msHandoutViewURL)) + { + pViewShell.reset( + new DrawViewShell( + &rFrame, + *mpBase, + &rWindow, + PK_HANDOUT, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msPresentationViewURL)) + { + pViewShell.reset( + new PresentationViewShell( + &rFrame, + *mpBase, + &rWindow, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msTaskPaneURL)) + { + pViewShell.reset( + new ::sd::toolpanel::ToolPanelViewShell( + &rFrame, + *mpBase, + &rWindow, + pFrameView)); + } + else if (rsViewURL.equals(FrameworkHelper::msSlideSorterURL)) + { + pViewShell = ::sd::slidesorter::SlideSorterViewShell::Create ( + &rFrame, + *mpBase, + &rWindow, + pFrameView); + } + + return pViewShell; +} + + + + +void BasicViewFactory::ReleaseView ( + const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor, + bool bDoNotCache) +{ + bool bIsCacheable (!bDoNotCache && IsCacheable(rpDescriptor)); + + if (bIsCacheable) + { + Reference<XRelocatableResource> xResource (rpDescriptor->mxView, UNO_QUERY); + if (xResource.is()) + { + Reference<XResource> xNewAnchor (mxLocalPane, UNO_QUERY); + if (xNewAnchor.is()) + if (xResource->relocateToAnchor(xNewAnchor)) + mpViewCache->push_back(rpDescriptor); + else + bIsCacheable = false; + else + bIsCacheable = false; + } + else + { + bIsCacheable = false; + } + } + + if ( ! bIsCacheable) + { + // Shut down the current view shell. + rpDescriptor->mpViewShell->Shutdown (); + mpBase->GetDocShell()->Disconnect(rpDescriptor->mpViewShell.get()); + mpBase->GetViewShellManager()->DeactivateViewShell(rpDescriptor->mpViewShell.get()); + + Reference<XComponent> xComponent (rpDescriptor->mxView, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + } +} + + + + +bool BasicViewFactory::IsCacheable (const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor) +{ + bool bIsCacheable (false); + + Reference<XRelocatableResource> xResource (rpDescriptor->mxView, UNO_QUERY); + if (xResource.is()) + { + static ::std::vector<Reference<XResourceId> > maCacheableResources; + if (maCacheableResources.size() == 0) + { + ::boost::shared_ptr<FrameworkHelper> pHelper (FrameworkHelper::Instance(*mpBase)); + + // The slide sorter and the task panel are cacheable and relocatable. + maCacheableResources.push_back(pHelper->CreateResourceId( + FrameworkHelper::msSlideSorterURL, FrameworkHelper::msLeftDrawPaneURL)); + maCacheableResources.push_back(pHelper->CreateResourceId( + FrameworkHelper::msSlideSorterURL, FrameworkHelper::msLeftImpressPaneURL)); + maCacheableResources.push_back(pHelper->CreateResourceId( + FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL)); + } + + ::std::vector<Reference<XResourceId> >::const_iterator iId; + for (iId=maCacheableResources.begin(); iId!=maCacheableResources.end(); ++iId) + { + if ((*iId)->compareTo(rpDescriptor->mxViewId) == 0) + { + bIsCacheable = true; + break; + } + } + } + + return bIsCacheable; +} + + + + +::boost::shared_ptr<BasicViewFactory::ViewDescriptor> BasicViewFactory::GetViewFromCache ( + const Reference<XResourceId>& rxViewId, + const Reference<XPane>& rxPane) +{ + ::boost::shared_ptr<ViewDescriptor> pDescriptor; + + // Search for the requested view in the cache. + ViewCache::iterator iEntry; + for (iEntry=mpViewCache->begin(); iEntry!=mpViewCache->end(); ++iEntry) + { + if ((*iEntry)->mxViewId->compareTo(rxViewId) == 0) + { + pDescriptor = *iEntry; + mpViewCache->erase(iEntry); + break; + } + } + + // When the view has been found then relocate it to the given pane and + // remove it from the cache. + if (pDescriptor.get() != NULL) + { + bool bRelocationSuccessfull (false); + Reference<XRelocatableResource> xResource (pDescriptor->mxView, UNO_QUERY); + Reference<XResource> xNewAnchor (rxPane, UNO_QUERY); + if (xResource.is() && xNewAnchor.is()) + { + if (xResource->relocateToAnchor(xNewAnchor)) + bRelocationSuccessfull = true; + } + + if ( ! bRelocationSuccessfull) + { + ReleaseView(pDescriptor, true); + pDescriptor.reset(); + } + } + + return pDescriptor; +} + + + + +void BasicViewFactory::ActivateCenterView ( + const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor) +{ + mpBase->GetDocShell()->Connect(rpDescriptor->mpViewShell.get()); + + // During the creation of the new sub-shell, resize requests were not + // forwarded to it because it was not yet registered. Therefore, we + // have to request a resize now. + rpDescriptor->mpViewShell->UIFeatureChanged(); + if (mpBase->GetDocShell()->IsInPlaceActive()) + mpBase->GetViewFrame()->Resize(TRUE); + + mpBase->GetDrawController().SetSubController( + rpDescriptor->mpViewShell->CreateSubController()); +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/BasicViewFactory.hxx b/sd/source/ui/framework/factories/BasicViewFactory.hxx new file mode 100644 index 000000000000..f7ab37c5a4fb --- /dev/null +++ b/sd/source/ui/framework/factories/BasicViewFactory.hxx @@ -0,0 +1,160 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_BASIC_VIEW_FACTORY_HXX +#define SD_FRAMEWORK_BASIC_VIEW_FACTORY_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/drawing/framework/XResourceFactory.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XPane.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <cppuhelper/compbase2.hxx> +#include <osl/mutex.hxx> + +#include <boost/shared_ptr.hpp> +#include <boost/scoped_ptr.hpp> + +namespace css = ::com::sun::star; + +namespace sd { +class ViewShell; +class ViewShellBase; +class FrameView; +} +class SfxViewFrame; +class Window; + +namespace { + +typedef ::cppu::WeakComponentImplHelper2 < + css::drawing::framework::XResourceFactory, + css::lang::XInitialization + > BasicViewFactoryInterfaceBase; + +} // end of anonymous namespace. + + + + +namespace sd { namespace framework { + +/** Factory for the frequently used standard views of the drawing framework: + private:resource/view/ + private:resource/view/ImpressView + private:resource/view/GraphicView + private:resource/view/OutlineView + private:resource/view/NotesView + private:resource/view/HandoutView + private:resource/view/SlideSorter + private:resource/view/PresentationView + private:resource/view/TaskPane + For some views in some panes this class also acts as a cache. +*/ +class BasicViewFactory + : private sd::MutexOwner, + public BasicViewFactoryInterfaceBase +{ +public: + BasicViewFactory ( + const css::uno::Reference<css::uno::XComponentContext>& rxContext); + virtual ~BasicViewFactory (void); + + virtual void SAL_CALL disposing (void); + + + // XViewFactory + + virtual css::uno::Reference<css::drawing::framework::XResource> + SAL_CALL createResource ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) + throw(css::uno::RuntimeException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException); + + virtual void SAL_CALL releaseResource ( + const css::uno::Reference<css::drawing::framework::XResource>& xView) + throw(css::uno::RuntimeException); + + + // XInitialization + + virtual void SAL_CALL initialize( + const css::uno::Sequence<css::uno::Any>& aArguments) + throw (css::uno::Exception, css::uno::RuntimeException); + +private: + css::uno::Reference<css::drawing::framework::XConfigurationController> + mxConfigurationController; + class ViewDescriptor; + class ViewShellContainer; + ::boost::scoped_ptr<ViewShellContainer> mpViewShellContainer; + ViewShellBase* mpBase; + FrameView* mpFrameView; + + class ViewCache; + ::boost::shared_ptr<Window> mpWindow; + ::boost::shared_ptr<ViewCache> mpViewCache; + + css::uno::Reference<css::drawing::framework::XPane> mxLocalPane; + + ::boost::shared_ptr<ViewDescriptor> CreateView ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, + SfxViewFrame& rFrame, + ::Window& rWindow, + const css::uno::Reference<css::drawing::framework::XPane>& rxPane, + FrameView* pFrameView); + + ::boost::shared_ptr<ViewShell> CreateViewShell ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, + SfxViewFrame& rFrame, + ::Window& rWindow, + FrameView* pFrameView); + + void ActivateCenterView ( + const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor); + + void ReleaseView ( + const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor, + bool bDoNotCache = false); + + bool IsCacheable ( + const ::boost::shared_ptr<ViewDescriptor>& rpDescriptor); + + ::boost::shared_ptr<ViewDescriptor> GetViewFromCache ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, + const css::uno::Reference<css::drawing::framework::XPane>& rxPane); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/ChildWindowPane.cxx b/sd/source/ui/framework/factories/ChildWindowPane.cxx new file mode 100644 index 000000000000..fc0be98867e0 --- /dev/null +++ b/sd/source/ui/framework/factories/ChildWindowPane.cxx @@ -0,0 +1,254 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ChildWindowPane.hxx" + +#include "PaneDockingWindow.hxx" +#include "ViewShellBase.hxx" +#include "ViewShellManager.hxx" +#include "framework/FrameworkHelper.hxx" +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +namespace sd { namespace framework { + + +ChildWindowPane::ChildWindowPane ( + const Reference<XResourceId>& rxPaneId, + USHORT nChildWindowId, + ViewShellBase& rViewShellBase, + ::std::auto_ptr<SfxShell> pShell) + : ChildWindowPaneInterfaceBase(rxPaneId,(::Window*)NULL), + mnChildWindowId(nChildWindowId), + mrViewShellBase(rViewShellBase), + mpShell(pShell), + mbHasBeenActivated(false) +{ + mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get()); + + SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); + if (pViewFrame != NULL) + { + if (mrViewShellBase.IsActive()) + { + if (pViewFrame->KnowsChildWindow(mnChildWindowId)) + { + if (pViewFrame->HasChildWindow(mnChildWindowId)) + { + // The ViewShellBase has already been activated. Make + // the child window visible as soon as possible. + pViewFrame->SetChildWindow(mnChildWindowId, TRUE); + OSL_TRACE("ChildWindowPane:activating now"); + } + else + { + // The window is created asynchronously. Rely on the + // ConfigurationUpdater to try another update, and with + // that another request for this window, in a short + // time. + OSL_TRACE("ChildWindowPane:activated asynchronously"); + } + } + else + { + OSL_TRACE("ChildWindowPane:not known"); + } + } + else + { + // The ViewShellBase has not yet been activated. Hide the + // window and wait a little before it is made visible. See + // comments in the GetWindow() method for an explanation. + pViewFrame->SetChildWindow(mnChildWindowId, FALSE); + OSL_TRACE("ChildWindowPane:base not active"); + } + } +} + + + + +ChildWindowPane::~ChildWindowPane (void) throw() +{ +} + + + + +void ChildWindowPane::Hide (void) +{ + SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); + if (pViewFrame != NULL) + if (pViewFrame->KnowsChildWindow(mnChildWindowId)) + if (pViewFrame->HasChildWindow(mnChildWindowId)) + pViewFrame->SetChildWindow(mnChildWindowId, FALSE); + + // Release the window because when the child window is shown again it + // may use a different window. + mxWindow = NULL; +} + + + + +void SAL_CALL ChildWindowPane::disposing (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get()); + mpShell.reset(); + + if (mxWindow.is()) + { + mxWindow->removeEventListener(this); + } + + Pane::disposing(); +} + + + + +::Window* ChildWindowPane::GetWindow (void) +{ + do + { + if (mxWindow.is()) + // Window already exists => nothing to do. + break; + + // When the window is not yet present then obtain it only when the + // shell has already been activated. The activation is not + // necessary for the code to work properly but is used to optimize + // the layouting and displaying of the window. When it is made + // visible to early then some layouting seems to be made twice or at + // an inconvenient time and the overall process of initializing the + // Impress takes longer. + if ( ! mbHasBeenActivated && mpShell.get()!=NULL && ! mpShell->IsActive()) + break; + + mbHasBeenActivated = true; + SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); + if (pViewFrame == NULL) + break; + // The view frame has to know the child window. This can be the + // case, when for example the document is in read-only mode: the + // task pane is then not available. + if ( ! pViewFrame->KnowsChildWindow(mnChildWindowId)) + break; + + pViewFrame->SetChildWindow(mnChildWindowId, TRUE); + SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); + if (pChildWindow == NULL) + if (pViewFrame->HasChildWindow(mnChildWindowId)) + { + // The child window is not yet visible. Ask the view frame + // to show it and try again to get access to the child + // window. + pViewFrame->ShowChildWindow(mnChildWindowId, TRUE); + pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); + } + + // When the child window is still not visible then we have to try later. + if (pChildWindow == NULL) + break; + + // From the child window get the docking window and from that the + // content window that is the container for the actual content. + PaneDockingWindow* pDockingWindow = dynamic_cast<PaneDockingWindow*>( + pChildWindow->GetWindow()); + if (pDockingWindow == NULL) + break; + + // At last, we have access to the window and its UNO wrapper. + mpWindow = &pDockingWindow->GetContentWindow(); + mxWindow = VCLUnoHelper::GetInterface(mpWindow); + + // Register as window listener to be informed when the child window + // is hidden. + if (mxWindow.is()) + mxWindow->addEventListener(this); + } + while (false); + + return mpWindow; +} + + + + +Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow (void) + throw (RuntimeException) +{ + if (mpWindow == NULL || ! mxWindow.is()) + GetWindow(); + return Pane::getWindow(); +} + + + +IMPLEMENT_FORWARD_XINTERFACE2( + ChildWindowPane, + ChildWindowPaneInterfaceBase, + Pane); +IMPLEMENT_FORWARD_XTYPEPROVIDER2( + ChildWindowPane, + ChildWindowPaneInterfaceBase, + Pane); + + + + +//----- XEventListener -------------------------------------------------------- + +void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (rEvent.Source == mxWindow) + { + // The window is gone but the pane remains alive. The next call to + // GetWindow() may create the window anew. + mxWindow = NULL; + mpWindow = NULL; + } +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/ChildWindowPane.hxx b/sd/source/ui/framework/factories/ChildWindowPane.hxx new file mode 100644 index 000000000000..ecfcfd87e079 --- /dev/null +++ b/sd/source/ui/framework/factories/ChildWindowPane.hxx @@ -0,0 +1,125 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CHILD_WINDOW_PANE_HXX +#define SD_FRAMEWORK_CHILD_WINDOW_PANE_HXX + +#include "framework/Pane.hxx" +#include "PaneShells.hxx" + +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/drawing/framework/XResourceId.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <tools/link.hxx> +#include <memory> + +namespace { + +typedef ::cppu::ImplInheritanceHelper1 < + ::sd::framework::Pane, + ::com::sun::star::lang::XEventListener + > ChildWindowPaneInterfaceBase; + +} // end of anonymous namespace. + + +class SfxViewFrame; + +namespace sd { class ViewShellBase; } + +namespace sd { namespace framework { + +/** The ChildWindowPane listens to the child window and disposes itself when + the child window becomes inaccessible. This happens for instance when a + document is made read-only and the task pane is turned off. +*/ +class ChildWindowPane + : public ChildWindowPaneInterfaceBase +{ +public: + ChildWindowPane ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId>& rxPaneId, + USHORT nChildWindowId, + ViewShellBase& rViewShellBase, + ::std::auto_ptr<SfxShell> pShell); + virtual ~ChildWindowPane (void) throw(); + + /** Hide the pane. To make the pane visible again, call GetWindow(). + */ + void Hide (void); + + virtual void SAL_CALL disposing (void); + + /** This returns the content window when the child window is already + visible. Otherwise <NULL/> is returned. In that case a later call + may return the requested window (making a child window visible is an + asynchronous process.) + Note that GetWindow() may return different Window pointers when + Hide() is called in between. + */ + virtual ::Window* GetWindow (void); + + /** The local getWindow() first calls GetWindow() to provide a valid + window pointer before forwarding the call to the base class. + */ + virtual ::com::sun::star::uno::Reference<com::sun::star::awt::XWindow> + SAL_CALL getWindow (void) + throw (::com::sun::star::uno::RuntimeException); + + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + + + // XEventListener + + virtual void SAL_CALL disposing( + const com::sun::star::lang::EventObject& rEvent) + throw (com::sun::star::uno::RuntimeException); + +private: + ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XResourceId> mxPaneId; + USHORT mnChildWindowId; + ViewShellBase& mrViewShellBase; + ::std::auto_ptr<SfxShell> mpShell; + + /** This flag is set when the pane shell has been activated at least + once. It is used to optimize the start-up performance (by not + showing the window too early) and by not delaying its creation at + later times. + */ + bool mbHasBeenActivated; +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/FrameWindowPane.cxx b/sd/source/ui/framework/factories/FrameWindowPane.cxx new file mode 100644 index 000000000000..a3d8f1ee64d8 --- /dev/null +++ b/sd/source/ui/framework/factories/FrameWindowPane.cxx @@ -0,0 +1,65 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "FrameWindowPane.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +namespace sd { namespace framework { + +FrameWindowPane::FrameWindowPane ( + const Reference<XResourceId>& rxPaneId, + ::Window* pWindow) + : Pane(rxPaneId,pWindow) +{ +} + + + + +FrameWindowPane::~FrameWindowPane (void) throw() +{ +} + + + + +sal_Bool SAL_CALL FrameWindowPane::isAnchorOnly (void) + throw (RuntimeException) +{ + return false; +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/FrameWindowPane.hxx b/sd/source/ui/framework/factories/FrameWindowPane.hxx new file mode 100644 index 000000000000..5afcb4373d94 --- /dev/null +++ b/sd/source/ui/framework/factories/FrameWindowPane.hxx @@ -0,0 +1,64 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_FRAME_WINDOW_PANE_HXX +#define SD_FRAMEWORK_FRAME_WINDOW_PANE_HXX + +#include "framework/Pane.hxx" + +#include <com/sun/star/drawing/framework/XResourceId.hpp> + + +namespace sd { namespace framework { + +/** This subclass is not necessary anymore. We can remove it if that + remains so. +*/ +class FrameWindowPane + : public Pane +{ +public: + FrameWindowPane ( + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XResourceId>& rxPaneId, + ::Window* pWindow); + virtual ~FrameWindowPane (void) throw(); + + /** A frame window typically can (and should) exists on its own without + children, if only to visualize that something (a view) is missing. + Therefore this method always returns <FALSE/>. + */ + virtual sal_Bool SAL_CALL isAnchorOnly (void) + throw (com::sun::star::uno::RuntimeException); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/FullScreenPane.cxx b/sd/source/ui/framework/factories/FullScreenPane.cxx new file mode 100644 index 000000000000..fa7e3fbf7f9c --- /dev/null +++ b/sd/source/ui/framework/factories/FullScreenPane.cxx @@ -0,0 +1,297 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "FullScreenPane.hxx" +#include "ViewShellBase.hxx" +#include <cppcanvas/vclfactory.hxx> +#include <sfx2/dispatch.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/dialog.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/util/URL.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + +namespace sd { namespace framework { + +FullScreenPane::FullScreenPane ( + const Reference<XComponentContext>& rxComponentContext, + const Reference<XResourceId>& rxPaneId, + const ::Window* pViewShellWindow) + : FrameWindowPane(rxPaneId,NULL), + mxComponentContext(rxComponentContext), + mpWorkWindow(NULL) +{ + ::Window* pParent = NULL; + mpWorkWindow.reset(new WorkWindow( + pParent, + 0)); // For debugging (non-fullscreen) use WB_BORDER | WB_MOVEABLE | WB_SIZEABLE)); + + if ( ! rxPaneId.is()) + throw lang::IllegalArgumentException(); + + sal_Int32 nScreenNumber = 1; + ExtractArguments(rxPaneId, nScreenNumber); + + if (mpWorkWindow.get() == NULL) + return; + + // Create a new top-leve window that is displayed full screen. + mpWorkWindow->ShowFullScreenMode(TRUE, nScreenNumber); + // For debugging (non-fullscreen) use mpWorkWindow->SetScreenNumber(nScreenNumber); + mpWorkWindow->SetMenuBarMode(MENUBAR_MODE_HIDE); + mpWorkWindow->SetBorderStyle(WINDOW_BORDER_REMOVEBORDER); + mpWorkWindow->SetBackground(Wallpaper()); + // Don't show the window right now in order to allow the setting of an + // accessibility object: accessibility objects are typically + // requested by AT-tools when the window is shown. Chaning it + // afterwards may or may not work. + + // Add resize listener at the work window. + Link aWindowEventHandler (LINK(this, FullScreenPane, WindowEventHandler)); + mpWorkWindow->AddEventListener(aWindowEventHandler); + + // Set title and icon of the new window to those of the current window + // of the view shell. + if (pViewShellWindow != NULL) + { + const SystemWindow* pSystemWindow = pViewShellWindow->GetSystemWindow(); + mpWorkWindow->SetText(pSystemWindow->GetText()); + mpWorkWindow->SetIcon(pSystemWindow->GetIcon()); + } + + // For some reason the VCL canvas can not paint into a WorkWindow. + // Therefore a child window is created that covers the WorkWindow + // completely. + mpWindow = new ::Window(mpWorkWindow.get()); + mpWindow->SetPosSizePixel(Point(0,0), mpWorkWindow->GetSizePixel()); + mpWindow->SetBackground(Wallpaper()); + mxWindow = VCLUnoHelper::GetInterface(mpWindow); + + // Create the canvas. + mxCanvas = CreateCanvas(); + + mpWindow->GrabFocus(); +} + + + + +FullScreenPane::~FullScreenPane (void) throw() +{ +} + + + + +void SAL_CALL FullScreenPane::disposing (void) +{ + // We have created the window pointed to by mpWindow, we delete it. + if (mpWindow != NULL) + { + delete mpWindow; + } + + if (mpWorkWindow.get() != NULL) + { + Link aWindowEventHandler (LINK(this, FullScreenPane, WindowEventHandler)); + mpWorkWindow->RemoveEventListener(aWindowEventHandler); + mpWorkWindow.reset(); + } + + + FrameWindowPane::disposing(); +} + + + + +//----- XPane ----------------------------------------------------------------- + +sal_Bool SAL_CALL FullScreenPane::isVisible (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (mpWindow != NULL) + return mpWindow->IsReallyVisible(); + else + return false; +} + + + + +void SAL_CALL FullScreenPane::setVisible (const sal_Bool bIsVisible) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (mpWindow != NULL) + mpWindow->Show(bIsVisible); + if (mpWorkWindow != NULL) + mpWorkWindow->Show(bIsVisible); +} + + + + +Reference<accessibility::XAccessible> SAL_CALL FullScreenPane::getAccessible (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (mpWorkWindow != NULL) + return mpWorkWindow->GetAccessible(FALSE); + else + return NULL; +} + + + + +void SAL_CALL FullScreenPane::setAccessible ( + const Reference<accessibility::XAccessible>& rxAccessible) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (mpWindow != NULL) + { + Reference<lang::XInitialization> xInitializable (rxAccessible, UNO_QUERY); + if (xInitializable.is()) + { + ::Window* pParentWindow = mpWindow->GetParent(); + Reference<accessibility::XAccessible> xAccessibleParent; + if (pParentWindow != NULL) + xAccessibleParent = pParentWindow->GetAccessible(); + Sequence<Any> aArguments (1); + aArguments[0] = Any(xAccessibleParent); + xInitializable->initialize(aArguments); + } + GetWindow()->SetAccessible(rxAccessible); + } +} + + + + +//----------------------------------------------------------------------------- + +IMPL_LINK(FullScreenPane, WindowEventHandler, VclWindowEvent*, pEvent) +{ + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_RESIZE: + GetWindow()->SetPosPixel(Point(0,0)); + GetWindow()->SetSizePixel(Size( + mpWorkWindow->GetSizePixel().Width(), + mpWorkWindow->GetSizePixel().Height())); + break; + + case VCLEVENT_OBJECT_DYING: + mpWorkWindow.reset(); + break; + } + return 1; +} + + + + +Reference<rendering::XCanvas> FullScreenPane::CreateCanvas (void) + throw (RuntimeException) +{ + ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow); + if (pWindow != NULL) + { + Sequence<Any> aArg (5); + + // common: first any is VCL pointer to window (for VCL canvas) + aArg[0] = makeAny(reinterpret_cast<sal_Int64>(pWindow)); + aArg[1] = Any(); + aArg[2] = makeAny(::com::sun::star::awt::Rectangle()); + aArg[3] = makeAny(sal_False); + aArg[4] = makeAny(mxWindow); + + Reference<lang::XMultiServiceFactory> xFactory ( + mxComponentContext->getServiceManager(), UNO_QUERY_THROW); + return Reference<rendering::XCanvas>( + xFactory->createInstanceWithArguments( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.rendering.SpriteCanvas.VCL")), + aArg), + UNO_QUERY); + } + else + throw RuntimeException(); +} + + + + +void FullScreenPane::ExtractArguments ( + const Reference<XResourceId>& rxPaneId, + sal_Int32& rnScreenNumberReturnValue) +{ + // Extract arguments from the resource URL. + const util::URL aURL = rxPaneId->getFullResourceURL(); + sal_Int32 nIndex = 0; + while (nIndex >= 0) + { + const OUString aToken = aURL.Arguments.getToken(0, '&', nIndex); + if (aToken.getLength() > 0) + { + // Split at the first '='. + const sal_Int32 nAssign = aToken.indexOf('='); + const OUString sKey = aToken.copy(0, nAssign); + const OUString sValue = aToken.copy(nAssign+1); + + if (sKey.compareToAscii("ScreenNumber") == 0) + { + rnScreenNumberReturnValue = sValue.toInt32(); + } + } + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/FullScreenPane.hxx b/sd/source/ui/framework/factories/FullScreenPane.hxx new file mode 100644 index 000000000000..1d3d65d83764 --- /dev/null +++ b/sd/source/ui/framework/factories/FullScreenPane.hxx @@ -0,0 +1,108 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_FULL_SCREEN_PANE_HXX +#define SD_FRAMEWORK_FULL_SCREEN_PANE_HXX + +#include "FrameWindowPane.hxx" +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <vcl/vclevent.hxx> +#include <boost/scoped_ptr.hpp> + +namespace css = ::com::sun::star; + +class WorkWindow; + +namespace sd { class ViewShellBase; } + +namespace sd { namespace framework { + +/** The full screen pane creates a pane that covers the complete application + window, i.e. that hides menu bar, tool bars, status bars. +*/ +class FullScreenPane + : public FrameWindowPane +{ +public: + /** Create a new full screen pane. + @param rxComponentContext + Used for creating a new canvas. + @param rxPaneId + The resource id of the new pane. + @param pViewShellWindow + The top-level parent of this window is used to obtain title and + icon for the new top-level window. + */ + FullScreenPane ( + const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, + const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId, + const ::Window* pViewShellWindow); + virtual ~FullScreenPane (void) throw(); + + virtual void SAL_CALL disposing (void); + + //----- XPane ------------------------------------------------------------- + + virtual sal_Bool SAL_CALL isVisible (void) + throw (cssu::RuntimeException); + + virtual void SAL_CALL setVisible (sal_Bool bIsVisible) + throw (cssu::RuntimeException); + + virtual cssu::Reference<css::accessibility::XAccessible> SAL_CALL getAccessible (void) + throw (cssu::RuntimeException); + + virtual void SAL_CALL setAccessible ( + const cssu::Reference<css::accessibility::XAccessible>& rxAccessible) + throw (cssu::RuntimeException); + + + //------------------------------------------------------------------------- + + DECL_LINK(WindowEventHandler, VclWindowEvent*); + +protected: + virtual ::com::sun::star::uno::Reference<com::sun::star::rendering::XCanvas> + CreateCanvas (void) + throw (::com::sun::star::uno::RuntimeException); + +private: + css::uno::Reference<css::uno::XComponentContext> mxComponentContext; + ::boost::scoped_ptr<WorkWindow> mpWorkWindow; + + void ExtractArguments ( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId, + sal_Int32& rnScreenNumberReturnValue); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/Pane.cxx b/sd/source/ui/framework/factories/Pane.cxx new file mode 100644 index 000000000000..aef8527a0429 --- /dev/null +++ b/sd/source/ui/framework/factories/Pane.cxx @@ -0,0 +1,270 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/Pane.hxx" + +#include <rtl/uuid.h> +#include <vcl/svapp.hxx> +#include <osl/mutex.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/window.hxx> +#include <cppcanvas/vclfactory.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; + +namespace sd { namespace framework { + +Pane::Pane ( + const Reference<XResourceId>& rxPaneId, + ::Window* pWindow) + throw () + : PaneInterfaceBase(MutexOwner::maMutex), + mxPaneId(rxPaneId), + mpWindow(pWindow), + mxWindow(VCLUnoHelper::GetInterface(pWindow)) +{ +} + + + + +Pane::~Pane (void) throw() +{ +} + + + + +void Pane::disposing (void) +{ + mxWindow = NULL; + mpWindow = NULL; +} + + + + +::Window* Pane::GetWindow (void) +{ + if (mxWindow.is()) + return mpWindow; + else + return NULL; +} + + + + +//----- XPane ----------------------------------------------------------------- + +Reference<awt::XWindow> SAL_CALL Pane::getWindow (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + return mxWindow; +} + + + + +Reference<rendering::XCanvas> SAL_CALL Pane::getCanvas (void) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard (maMutex); + ThrowIfDisposed(); + + if ( ! mxCanvas.is()) + mxCanvas = CreateCanvas(); + + return mxCanvas; +} + + + + +//----- XPane2 ---------------------------------------------------------------- + +sal_Bool SAL_CALL Pane::isVisible (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + const ::Window* pWindow = GetWindow(); + if (pWindow != NULL) + return pWindow->IsVisible(); + else + return false; +} + + + + +void SAL_CALL Pane::setVisible (sal_Bool bIsVisible) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + ::Window* pWindow = GetWindow(); + if (pWindow != NULL) + pWindow->Show(bIsVisible); +} + + + + +Reference<accessibility::XAccessible> SAL_CALL Pane::getAccessible (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + ::Window* pWindow = GetWindow(); + if (pWindow != NULL) + return pWindow->GetAccessible(FALSE); + else + return NULL; +} + + + + +void SAL_CALL Pane::setAccessible ( + const Reference<accessibility::XAccessible>& rxAccessible) + throw (RuntimeException) +{ + ThrowIfDisposed(); + ::Window* pWindow = GetWindow(); + if (pWindow != NULL) + pWindow->SetAccessible(rxAccessible); +} + + + + +//----- XResource ------------------------------------------------------------- + +Reference<XResourceId> SAL_CALL Pane::getResourceId (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + return mxPaneId; +} + + + + +sal_Bool SAL_CALL Pane::isAnchorOnly (void) + throw (RuntimeException) +{ + return true; +} + + + + +//----- XUnoTunnel ------------------------------------------------------------ + +const Sequence<sal_Int8>& Pane::getUnoTunnelId (void) +{ + static Sequence<sal_Int8>* pSequence = NULL; + if (pSequence == NULL) + { + const SolarMutexGuard aSolarGuard; + if (pSequence == NULL) + { + static ::com::sun::star::uno::Sequence<sal_Int8> aSequence (16); + rtl_createUuid((sal_uInt8*)aSequence.getArray(), 0, sal_True); + pSequence = &aSequence; + } + } + return *pSequence; +} + + + + +sal_Int64 SAL_CALL Pane::getSomething (const Sequence<sal_Int8>& rId) + throw (RuntimeException) +{ + sal_Int64 nResult = 0; + + if (rId.getLength() == 16 + && rtl_compareMemory(getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0) + { + nResult = reinterpret_cast<sal_Int64>(this); + } + + return nResult; +} + + + + +//----------------------------------------------------------------------------- + +Reference<rendering::XCanvas> Pane::CreateCanvas (void) + throw (RuntimeException) +{ + Reference<rendering::XCanvas> xCanvas; + + if (mpWindow != NULL) + { + ::cppcanvas::SpriteCanvasSharedPtr pCanvas ( + ::cppcanvas::VCLFactory::getInstance().createSpriteCanvas(*mpWindow)); + if (pCanvas.get() != NULL) + xCanvas = Reference<rendering::XCanvas>(pCanvas->getUNOSpriteCanvas(), UNO_QUERY); + } + + return xCanvas; +} + + + + +void Pane::ThrowIfDisposed (void) const + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Pane object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/PresentationFactory.cxx b/sd/source/ui/framework/factories/PresentationFactory.cxx new file mode 100644 index 000000000000..998c51b413ce --- /dev/null +++ b/sd/source/ui/framework/factories/PresentationFactory.cxx @@ -0,0 +1,326 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/PresentationFactory.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "DrawController.hxx" +#include "ViewShellBase.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <cppuhelper/compbase1.hxx> +#include <tools/diagnose_ex.h> +#include "slideshow.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 <lang::XInitialization> PresentationFactoryProviderInterfaceBase; + +class PresentationFactoryProvider + : protected MutexOwner, + public PresentationFactoryProviderInterfaceBase +{ +public: + PresentationFactoryProvider (const Reference<XComponentContext>& rxContext); + virtual ~PresentationFactoryProvider (void); + + virtual void SAL_CALL disposing (void); + + // XInitialization + + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence<com::sun::star::uno::Any>& aArguments) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); +}; + + + + +typedef ::cppu::WeakComponentImplHelper1 <XView> PresentationViewInterfaceBase; + +/** The PresentationView is not an actual view, it is a marker whose + existence in a configuration indicates that a slideshow is running + (in another application window). +*/ +class PresentationView + : protected MutexOwner, + public PresentationViewInterfaceBase +{ +public: + PresentationView (const Reference<XResourceId>& rxViewId) + : PresentationViewInterfaceBase(maMutex),mxResourceId(rxViewId) {}; + virtual ~PresentationView (void) {}; + + // XView + + virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException) + { return mxResourceId; }; + + virtual sal_Bool SAL_CALL isAnchorOnly (void) throw (RuntimeException) + { return false; } + + +private: + Reference<XResourceId> mxResourceId; +}; + +} // end of anonymous namespace. + + + + +//===== PresentationFactoryProvider service =================================== + +Reference<XInterface> SAL_CALL PresentationFactoryProvider_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(static_cast<XWeak*>(new PresentationFactoryProvider(rxContext))); +} + + + + +::rtl::OUString PresentationFactoryProvider_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.comp.Draw.framework.PresentationFactoryProvider")); +} + + + + +Sequence<rtl::OUString> SAL_CALL PresentationFactoryProvider_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.drawing.framework.PresentationFactoryProvider")); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== PresentationFactory =================================================== + +const ::rtl::OUString PresentationFactory::msPresentationViewURL( + RTL_CONSTASCII_USTRINGPARAM("private:resource/view/Presentation")); + + +PresentationFactory::PresentationFactory ( + const Reference<frame::XController>& rxController) + : PresentationFactoryInterfaceBase(MutexOwner::maMutex), + mxConfigurationController(), + mxController(rxController) +{ + try + { + // Get the XController from the first argument. + Reference<XControllerManager> xControllerManager(rxController, UNO_QUERY_THROW); + mxConfigurationController = xControllerManager->getConfigurationController(); + } + catch (RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + + + + + +PresentationFactory::~PresentationFactory (void) +{ +} + + + + +void SAL_CALL PresentationFactory::disposing (void) +{ +} + + + + +//----- XViewFactory ---------------------------------------------------------- + +Reference<XResource> SAL_CALL PresentationFactory::createResource ( + const Reference<XResourceId>& rxViewId) + throw (RuntimeException, IllegalArgumentException, WrappedTargetException) +{ + ThrowIfDisposed(); + + if (rxViewId.is()) + if ( ! rxViewId->hasAnchor() && rxViewId->getResourceURL().equals(msPresentationViewURL)) + return new PresentationView(rxViewId); + + return Reference<XResource>(); +} + + + + +void SAL_CALL PresentationFactory::releaseResource ( + const Reference<XResource>& rxView) + throw (RuntimeException) +{ + ThrowIfDisposed(); + (void)rxView; + + Reference<lang::XUnoTunnel> xTunnel (mxController, 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) + SlideShow::Stop( *pBase ); + } + } +} + + + + +//===== XConfigurationChangeListener ========================================== + +void SAL_CALL PresentationFactory::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + (void)rEvent; +} + + + + +//===== lang::XEventListener ================================================== + +void SAL_CALL PresentationFactory::disposing ( + const lang::EventObject& rEventObject) + throw (RuntimeException) +{ + (void)rEventObject; +} + + + + + +//----------------------------------------------------------------------------- + +void PresentationFactory::ThrowIfDisposed (void) const + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "PresentationFactory object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + + +namespace { + +//===== PresentationFactoryProvider =========================================== + +PresentationFactoryProvider::PresentationFactoryProvider ( + const Reference<XComponentContext>& rxContext) + : PresentationFactoryProviderInterfaceBase(maMutex) +{ + (void)rxContext; +} + + + + +PresentationFactoryProvider::~PresentationFactoryProvider (void) +{ +} + + + + +void PresentationFactoryProvider::disposing (void) +{ +} + + + + +// XInitialization + +void SAL_CALL PresentationFactoryProvider::initialize( + const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + if (aArguments.getLength() > 0) + { + try + { + // Get the XController from the first argument. + Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW); + Reference<XControllerManager> xCM (xController, UNO_QUERY_THROW); + Reference<XConfigurationController> xCC (xCM->getConfigurationController()); + if (xCC.is()) + xCC->addResourceFactory( + PresentationFactory::msPresentationViewURL, + new PresentationFactory(xController)); + } + catch (RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } +} + + + +} // end of anonymous namespace. + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/TaskPanelFactory.cxx b/sd/source/ui/framework/factories/TaskPanelFactory.cxx new file mode 100644 index 000000000000..0cfbc942df87 --- /dev/null +++ b/sd/source/ui/framework/factories/TaskPanelFactory.cxx @@ -0,0 +1,326 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" +#include "TaskPanelFactory.hxx" +#include "taskpane/ToolPanelViewShell.hxx" +#include "DrawController.hxx" +#include "framework/FrameworkHelper.hxx" +#include <cppuhelper/compbase1.hxx> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +namespace sd { namespace framework { + +Reference<XInterface> SAL_CALL TaskPanelFactory_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(static_cast<XWeak*>(new TaskPanelFactory(rxContext))); +} + + + + +::rtl::OUString TaskPanelFactory_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.TaskPanelFactory")); +} + + + + +Sequence<rtl::OUString> SAL_CALL TaskPanelFactory_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const OUString sServiceName( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.TaskPanelFactory")); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== ToolPanelResource ===================================================== + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + css::drawing::framework::XResource + > TaskPanelResourceInterfaceBase; + +class TaskPanelResource + : private ::cppu::BaseMutex, + public TaskPanelResourceInterfaceBase +{ +public: + TaskPanelResource ( + const Reference<XResourceId>& rxResourceId ); + virtual ~TaskPanelResource (); + + virtual void SAL_CALL disposing (); + + // XResource + + virtual Reference<XResourceId> SAL_CALL getResourceId (void) + throw (css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isAnchorOnly () throw (RuntimeException) + { return false; } + +private: + const Reference<XResourceId> mxResourceId; +}; + +} // end of anonymous namespace. + + + + +//===== TaskPanelFactory ======================================================= + +TaskPanelFactory::TaskPanelFactory ( + const ::com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>& rxContext) + : TaskPanelFactoryInterfaceBase(m_aMutex), + mpViewShellBase(NULL) +{ + (void)rxContext; +} + + + + +TaskPanelFactory::~TaskPanelFactory (void) +{ +} + + + + +void SAL_CALL TaskPanelFactory::disposing (void) +{ +} + + + + +//===== XInitialization ======================================================= + +void SAL_CALL TaskPanelFactory::initialize( + const ::com::sun::star::uno::Sequence<com::sun::star::uno::Any>& aArguments) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if (aArguments.getLength() > 0) + { + try + { + // Get the XController from the first argument. + Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW); + + // Tunnel through the controller to obtain access to the ViewShellBase. + try + { + Reference<lang::XUnoTunnel> xTunnel (xController, UNO_QUERY_THROW); + DrawController* pController + = reinterpret_cast<DrawController*>( + sal::static_int_cast<sal_uIntPtr>( + xTunnel->getSomething(DrawController::getUnoTunnelId()))); + if (pController != NULL) + mpViewShellBase = pController->GetViewShellBase(); + + } + catch(RuntimeException&) + {} + + + Reference<XControllerManager> xCM (xController, UNO_QUERY_THROW); + Reference<XConfigurationController> xCC ( + xCM->getConfigurationController(), UNO_QUERY_THROW); + xCC->addResourceFactory(FrameworkHelper::msMasterPagesTaskPanelURL, this); + xCC->addResourceFactory(FrameworkHelper::msLayoutTaskPanelURL, this); + xCC->addResourceFactory(FrameworkHelper::msTableDesignPanelURL, this); + xCC->addResourceFactory(FrameworkHelper::msCustomAnimationTaskPanelURL, this); + xCC->addResourceFactory(FrameworkHelper::msSlideTransitionTaskPanelURL, this); + } + catch (RuntimeException&) + { + } + } +} + + +//===== XResourceController =================================================== + +namespace +{ + void lcl_collectResourceURLs( const Reference< XResourceId >& i_rResourceId, ::std::vector< ::rtl::OUString >& o_rResourceURLs ) + { + ENSURE_OR_RETURN_VOID( i_rResourceId.is(), "illegal resource ID" ); + o_rResourceURLs.resize(0); + + Reference< XResourceId > xResourceId( i_rResourceId ); + ::rtl::OUString sResourceURL = xResourceId->getResourceURL(); + while ( sResourceURL.getLength() > 0 ) + { + o_rResourceURLs.push_back( sResourceURL ); + xResourceId = xResourceId->getAnchor(); + sResourceURL = xResourceId->getResourceURL(); + } + } +} + +Reference<XResource> SAL_CALL TaskPanelFactory::createResource ( + const Reference<XResourceId>& rxResourceId) + throw (RuntimeException, IllegalArgumentException, WrappedTargetException) +{ + Reference<XResource> xResource; + + if ( ! rxResourceId.is()) + return NULL; + + OUString sResourceURL (rxResourceId->getResourceURL()); + + if ( sResourceURL.match( FrameworkHelper::msTaskPanelURLPrefix ) ) + { + toolpanel::PanelId ePanelId( toolpanel::GetStandardPanelId( sResourceURL ) ); + + if ( ( ePanelId != toolpanel::PID_UNKNOWN ) && ( mpViewShellBase != NULL ) ) + { + ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( *mpViewShellBase ) ); + + // assume that the top-level anchor is the URL of the pane + ::std::vector< ::rtl::OUString > aResourceURLs; + lcl_collectResourceURLs( rxResourceId, aResourceURLs ); + + const ::rtl::OUString sPaneURL = aResourceURLs[ aResourceURLs.size() - 1 ]; + const ::boost::shared_ptr< ViewShell > pPaneViewShell( pFrameworkHelper->GetViewShell( sPaneURL ) ); + + toolpanel::ToolPanelViewShell* pToolPanel = dynamic_cast< toolpanel::ToolPanelViewShell* >( pPaneViewShell.get() ); + if ( pToolPanel != NULL ) + xResource = new TaskPanelResource( rxResourceId ); + + OSL_POSTCOND( xResource.is(), "TaskPanelFactory::createResource: did not find the given resource!" ); + } + } + + return xResource; +} + + + + +void SAL_CALL TaskPanelFactory::releaseResource ( + const Reference<XResource>& rxResource) + throw (RuntimeException) +{ + ENSURE_OR_RETURN_VOID( rxResource.is(), "illegal resource" ); + const Reference< XResourceId > xResourceId( rxResource->getResourceId(), UNO_SET_THROW ); + + // assume that the top-level anchor is the URL of the pane + ::std::vector< ::rtl::OUString > aResourceURLs; + lcl_collectResourceURLs( xResourceId, aResourceURLs ); + + OSL_ENSURE( !aResourceURLs.empty(), "TaskPanelFactory::releaseResource: illegal resource/URL!" ); + if ( !aResourceURLs.empty() ) + { + const ::rtl::OUString sPaneURL = aResourceURLs[ aResourceURLs.size() - 1 ]; + ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( *mpViewShellBase ) ); + const ::boost::shared_ptr< ViewShell > pPaneViewShell( pFrameworkHelper->GetViewShell( sPaneURL ) ); + if ( pPaneViewShell != NULL ) + { + const ::rtl::OUString sPanelResourceURL( xResourceId->getResourceURL() ); + const toolpanel::PanelId ePanelId( toolpanel::GetStandardPanelId( sPanelResourceURL ) ); + toolpanel::ToolPanelViewShell* pToolPanel = dynamic_cast< toolpanel::ToolPanelViewShell* >( pPaneViewShell.get() ); + + if ( ( ePanelId != toolpanel::PID_UNKNOWN ) + && ( pToolPanel != NULL ) + ) + { + pToolPanel->DeactivatePanel( sPanelResourceURL ); + } + else + { + OSL_ENSURE( false, "TaskPanelFactory::releaseResource: don't know what to do with this resource!" ); + } + } + } + + Reference<XComponent> xComponent (rxResource, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); +} + + + + +//===== ToolPanelResource ===================================================== + +namespace { + +TaskPanelResource::TaskPanelResource ( + const Reference<XResourceId>& rxResourceId) + : TaskPanelResourceInterfaceBase(m_aMutex), + mxResourceId(rxResourceId) +{ +} + + + + +TaskPanelResource::~TaskPanelResource (void) +{ +} + + + + +void SAL_CALL TaskPanelResource::disposing () +{ +} + + + + +Reference<XResourceId> SAL_CALL TaskPanelResource::getResourceId () + throw (css::uno::RuntimeException) +{ + return mxResourceId; +} + +} // end of anonymous namespace + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/TaskPanelFactory.hxx b/sd/source/ui/framework/factories/TaskPanelFactory.hxx new file mode 100644 index 000000000000..d1eb0bb7a0ae --- /dev/null +++ b/sd/source/ui/framework/factories/TaskPanelFactory.hxx @@ -0,0 +1,99 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_TASK_PANEL_FACTORY_HXX +#define SD_FRAMEWORK_TASK_PANEL_FACTORY_HXX + +#include <com/sun/star/drawing/framework/XResourceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase2.hxx> + +#include <boost/scoped_ptr.hpp> + +namespace css = ::com::sun::star; + +namespace { + +typedef ::cppu::WeakComponentImplHelper2 < + css::lang::XInitialization, + css::drawing::framework::XResourceFactory + > TaskPanelFactoryInterfaceBase; + +} // end of anonymous namespace. + + +namespace sd { class ViewShellBase; } + +namespace sd { namespace framework { + +/** This class creates panels for the task pane. +*/ +class TaskPanelFactory + : private ::cppu::BaseMutex, + public TaskPanelFactoryInterfaceBase +{ +public: + TaskPanelFactory ( + const css::uno::Reference<css::uno::XComponentContext>& rxContext); + virtual ~TaskPanelFactory (void); + + virtual void SAL_CALL disposing (void); + + + // XInitialization + + virtual void SAL_CALL initialize( + const css::uno::Sequence<css::uno::Any>& aArguments) + throw (css::uno::Exception, css::uno::RuntimeException); + + + // XResourceFactory + + virtual css::uno::Reference<css::drawing::framework::XResource> + SAL_CALL createResource ( + const css::uno::Reference< + css::drawing::framework::XResourceId>& rxResourcesId) + throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException); + + virtual void SAL_CALL releaseResource ( + const css::uno::Reference< + css::drawing::framework::XResource>& rxResource) + throw (css::uno::RuntimeException); + +private: + ViewShellBase* mpViewShellBase; +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/ViewShellWrapper.cxx b/sd/source/ui/framework/factories/ViewShellWrapper.cxx new file mode 100644 index 000000000000..465e2b3640d8 --- /dev/null +++ b/sd/source/ui/framework/factories/ViewShellWrapper.cxx @@ -0,0 +1,272 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/ViewShellWrapper.hxx" +#include "framework/Pane.hxx" +#include "taskpane/ToolPanelViewShell.hxx" +#include "ViewShell.hxx" +#include "Window.hxx" + +#include <com/sun/star/drawing/framework/XPane.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +#include <rtl/uuid.h> +#include <toolkit/helper/vclunohelper.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <vcl/svapp.hxx> +#include <osl/mutex.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 ::com::sun::star::awt::XWindow; +using ::com::sun::star::rendering::XCanvas; +using ::com::sun::star::lang::DisposedException; + +using ::rtl::OUString; +using ::sd::toolpanel::ToolPanelViewShell; + +namespace sd { namespace framework { + +ViewShellWrapper::ViewShellWrapper ( + ::boost::shared_ptr<ViewShell> pViewShell, + const Reference<XResourceId>& rxViewId, + const Reference<awt::XWindow>& rxWindow) + : ViewShellWrapperInterfaceBase(MutexOwner::maMutex), + mpViewShell(pViewShell), + mxViewId(rxViewId), + mxWindow(rxWindow) +{ + if (rxWindow.is()) + { + rxWindow->addWindowListener(this); + if (pViewShell != NULL) + { + pViewShell->Resize(); + } + } +} + + + + +ViewShellWrapper::~ViewShellWrapper (void) +{ +} + + + + +void SAL_CALL ViewShellWrapper::disposing (void) +{ + ::osl::MutexGuard aGuard( maMutex ); + + OSL_TRACE("disposing ViewShellWrapper %x", this); + Reference<awt::XWindow> xWindow (mxWindow); + if (xWindow.is()) + { + OSL_TRACE("removing ViewShellWrapper %x from window listener at %x", this, mxWindow.get()); + xWindow->removeWindowListener(this); + } + + mpViewShell.reset(); +} + + + + +::boost::shared_ptr<ViewShell> ViewShellWrapper::GetViewShell (void) +{ + return mpViewShell; +} + + + + +//----- XResource ------------------------------------------------------------- + +Reference<XResourceId> SAL_CALL ViewShellWrapper::getResourceId (void) + throw (RuntimeException) +{ + return mxViewId; +} + + + + +sal_Bool SAL_CALL ViewShellWrapper::isAnchorOnly (void) + throw (RuntimeException) +{ + return false; +} + + + + +//----- XRelocatableResource -------------------------------------------------- + +sal_Bool SAL_CALL ViewShellWrapper::relocateToAnchor ( + const Reference<XResource>& xResource) + throw (RuntimeException) +{ + sal_Bool bResult (false); + + Reference<XPane> xPane (xResource, UNO_QUERY); + if (xPane.is()) + { + // Detach from the window of the old pane. + Reference<awt::XWindow> xWindow (mxWindow); + if (xWindow.is()) + xWindow->removeWindowListener(this); + mxWindow = NULL; + + if (mpViewShell.get() != NULL) + { + ::Window* pWindow = VCLUnoHelper::GetWindow(xPane->getWindow()); + if (pWindow != NULL && mpViewShell->RelocateToParentWindow(pWindow)) + { + bResult = sal_True; + + // Attach to the window of the new pane. + xWindow = Reference<awt::XWindow>(xPane->getWindow(), UNO_QUERY); + if (xWindow.is()) + { + xWindow->addWindowListener(this); + mpViewShell->Resize(); + } + } + } + } + + return bResult; +} + + + + +//----- XUnoTunnel ------------------------------------------------------------ + +const Sequence<sal_Int8>& ViewShellWrapper::getUnoTunnelId (void) +{ + static Sequence<sal_Int8>* pSequence = NULL; + if (pSequence == NULL) + { + const ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (pSequence == NULL) + { + static ::com::sun::star::uno::Sequence<sal_Int8> aSequence (16); + rtl_createUuid((sal_uInt8*)aSequence.getArray(), 0, sal_True); + pSequence = &aSequence; + } + } + return *pSequence; +} + + + + +sal_Int64 SAL_CALL ViewShellWrapper::getSomething (const Sequence<sal_Int8>& rId) + throw (RuntimeException) +{ + sal_Int64 nResult = 0; + + if (rId.getLength() == 16 + && rtl_compareMemory(getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0) + { + nResult = reinterpret_cast<sal_Int64>(this); + } + + return nResult; +} + + + + +//===== awt::XWindowListener ================================================== + +void SAL_CALL ViewShellWrapper::windowResized (const awt::WindowEvent& rEvent) + throw (RuntimeException) +{ + (void)rEvent; + ViewShell* pViewShell (mpViewShell.get()); + if (pViewShell != NULL) + pViewShell->Resize(); +} + + + + +void SAL_CALL ViewShellWrapper::windowMoved (const awt::WindowEvent& rEvent) + throw (RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL ViewShellWrapper::windowShown (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + (void)rEvent; + ViewShell* pViewShell (mpViewShell.get()); + if (pViewShell != NULL) + pViewShell->Resize(); +} + + + + +void SAL_CALL ViewShellWrapper::windowHidden (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + (void)rEvent; +} + + + + +//===== XEventListener ======================================================== + +void SAL_CALL ViewShellWrapper::disposing (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (rEvent.Source == mxWindow) + mxWindow = NULL; +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/factories/makefile.mk b/sd/source/ui/framework/factories/makefile.mk new file mode 100644 index 000000000000..23e780ba1eca --- /dev/null +++ b/sd/source/ui/framework/factories/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=framework_factories +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true +PRJINC=..$/.. + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/BasicPaneFactory.obj \ + $(SLO)$/BasicToolBarFactory.obj \ + $(SLO)$/BasicViewFactory.obj \ + $(SLO)$/ChildWindowPane.obj \ + $(SLO)$/FrameWindowPane.obj \ + $(SLO)$/FullScreenPane.obj \ + $(SLO)$/Pane.obj \ + $(SLO)$/PresentationFactory.obj \ + $(SLO)$/TaskPanelFactory.obj \ + $(SLO)$/ViewShellWrapper.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/ui/framework/module/CenterViewFocusModule.cxx b/sd/source/ui/framework/module/CenterViewFocusModule.cxx new file mode 100644 index 000000000000..3c740c929dd9 --- /dev/null +++ b/sd/source/ui/framework/module/CenterViewFocusModule.cxx @@ -0,0 +1,198 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "CenterViewFocusModule.hxx" + +#include "framework/ConfigurationController.hxx" +#include "framework/FrameworkHelper.hxx" +#include "framework/ViewShellWrapper.hxx" + +#include "DrawController.hxx" +#include "ViewShellBase.hxx" +#include "ViewShellManager.hxx" +#include "strings.hrc" +#include "sdresid.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> + +#include <toolkit/awt/vclxdevice.hxx> +#include <sfx2/viewfrm.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + +//===== CenterViewFocusModule ==================================================== + +CenterViewFocusModule::CenterViewFocusModule (Reference<frame::XController>& rxController) + : CenterViewFocusModuleInterfaceBase(MutexOwner::maMutex), + mbValid(false), + mxConfigurationController(), + mpBase(NULL), + mbNewViewCreated(false) +{ + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + + // 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) + mpBase = pController->GetViewShellBase(); + } + + // Check, if all required objects do exist. + if (mxConfigurationController.is() && mpBase!=NULL) + { + mbValid = true; + } + } + + if (mbValid) + { + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateEndEvent, + Any()); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationEvent, + Any()); + } +} + + + + +CenterViewFocusModule::~CenterViewFocusModule (void) +{ +} + + + + +void SAL_CALL CenterViewFocusModule::disposing (void) +{ + if (mxConfigurationController.is()) + mxConfigurationController->removeConfigurationChangeListener(this); + + mbValid = false; + mxConfigurationController = NULL; + mpBase = NULL; +} + + + + +void SAL_CALL CenterViewFocusModule::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (mbValid) + { + if (rEvent.Type.equals(FrameworkHelper::msConfigurationUpdateEndEvent)) + { + HandleNewView(rEvent.Configuration); + } + else if (rEvent.Type.equals(FrameworkHelper::msResourceActivationEvent)) + { + if (rEvent.ResourceId->getResourceURL().match(FrameworkHelper::msViewURLPrefix)) + mbNewViewCreated = true; + } + } +} + + + + +void CenterViewFocusModule::HandleNewView ( + const Reference<XConfiguration>& rxConfiguration) +{ + if (mbNewViewCreated) + { + mbNewViewCreated = false; + // Make the center pane the active one. Tunnel through the + // controller to obtain a ViewShell pointer. + + Sequence<Reference<XResourceId> > xViewIds (rxConfiguration->getResources( + FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL), + FrameworkHelper::msViewURLPrefix, + AnchorBindingMode_DIRECT)); + Reference<XView> xView; + if (xViewIds.getLength() > 0) + xView = Reference<XView>( + mxConfigurationController->getResource(xViewIds[0]),UNO_QUERY); + Reference<lang::XUnoTunnel> xTunnel (xView, UNO_QUERY); + if (xTunnel.is() && mpBase!=NULL) + { + ViewShellWrapper* pViewShellWrapper = reinterpret_cast<ViewShellWrapper*>( + xTunnel->getSomething(ViewShellWrapper::getUnoTunnelId())); + if (pViewShellWrapper != NULL) + { + ::boost::shared_ptr<ViewShell> pViewShell = pViewShellWrapper->GetViewShell(); + if (pViewShell.get() != NULL) + mpBase->GetViewShellManager()->MoveToTop(*pViewShell); + } + } + } +} + + + + +void SAL_CALL CenterViewFocusModule::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is()) + if (rEvent.Source == mxConfigurationController) + { + mbValid = false; + mxConfigurationController = NULL; + mpBase = NULL; + } +} + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/CenterViewFocusModule.hxx b/sd/source/ui/framework/module/CenterViewFocusModule.hxx new file mode 100644 index 000000000000..3631b161fa31 --- /dev/null +++ b/sd/source/ui/framework/module/CenterViewFocusModule.hxx @@ -0,0 +1,115 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_CENTER_VIEW_FOCUS_MODULE_HXX +#define SD_FRAMEWORK_CENTER_VIEW_FOCUS_MODULE_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/compbase1.hxx> + + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + ::com::sun::star::drawing::framework::XConfigurationChangeListener + > CenterViewFocusModuleInterfaceBase; + +} // end of anonymous namespace. + +namespace sd { + +class ViewShellBase; + +} + + + + +namespace sd { namespace framework { + +/** This module waits for new views to be created for the center pane and + then moves the center view to the top most place on the shell stack. As + we are moving away from the shell stack this module may become obsolete + or has to be modified. +*/ +class CenterViewFocusModule + : private sd::MutexOwner, + public CenterViewFocusModuleInterfaceBase +{ +public: + CenterViewFocusModule ( + ::com::sun::star::uno::Reference<com::sun::star::frame::XController>& rxController); + virtual ~CenterViewFocusModule (void); + + virtual void SAL_CALL disposing (void); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (com::sun::star::uno::RuntimeException); + + // XEventListener + + virtual void SAL_CALL disposing ( + const com::sun::star::lang::EventObject& rEvent) + throw (com::sun::star::uno::RuntimeException); + +private: + class ViewShellContainer; + + bool mbValid; + ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XConfigurationController> + mxConfigurationController; + ViewShellBase* mpBase; + /** This flag indicates whether in the last configuration change cycle a + new view has been created and thus the center view has to be moved + to the top of the shell stack. + */ + bool mbNewViewCreated; + + /** At the end of an update of the current configuration this method + handles a new view in the center pane by moving the associated view + shell to the top of the shell stack. + */ + void HandleNewView( + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XConfiguration>& rxConfiguration); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/DrawModule.cxx b/sd/source/ui/framework/module/DrawModule.cxx new file mode 100644 index 000000000000..0d1537161e0a --- /dev/null +++ b/sd/source/ui/framework/module/DrawModule.cxx @@ -0,0 +1,59 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/DrawModule.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "CenterViewFocusModule.hxx" +#include "SlideSorterModule.hxx" +#include "ToolBarModule.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + + +namespace sd { namespace framework { + + + +void DrawModule::Initialize (Reference<frame::XController>& rxController) +{ + new sd::framework::CenterViewFocusModule(rxController); + new sd::framework::SlideSorterModule( + rxController, + FrameworkHelper::msLeftDrawPaneURL); + new ToolBarModule(rxController); +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ImpressModule.cxx b/sd/source/ui/framework/module/ImpressModule.cxx new file mode 100644 index 000000000000..59f948a025e3 --- /dev/null +++ b/sd/source/ui/framework/module/ImpressModule.cxx @@ -0,0 +1,66 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/ImpressModule.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "ViewTabBarModule.hxx" +#include "CenterViewFocusModule.hxx" +#include "SlideSorterModule.hxx" +#include "ToolPanelModule.hxx" +#include "ToolBarModule.hxx" +#include "ShellStackGuard.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd { namespace framework { + + +void ImpressModule::Initialize (Reference<frame::XController>& rxController) +{ + new CenterViewFocusModule(rxController); + new ViewTabBarModule( + rxController, + FrameworkHelper::CreateResourceId( + FrameworkHelper::msViewTabBarURL, + FrameworkHelper::msCenterPaneURL)); + new SlideSorterModule( + rxController, + FrameworkHelper::msLeftImpressPaneURL); + ToolPanelModule::Initialize(rxController); + new ToolBarModule(rxController); + new ShellStackGuard(rxController); +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ModuleController.cxx b/sd/source/ui/framework/module/ModuleController.cxx new file mode 100644 index 000000000000..d244631eb403 --- /dev/null +++ b/sd/source/ui/framework/module/ModuleController.cxx @@ -0,0 +1,344 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/ModuleController.hxx" + +#include "tools/ConfigurationAccess.hxx" +#include <comphelper/processfactory.hxx> +#include <comphelper/stl_types.hxx> +#include <boost/bind.hpp> +#include <hash_map> + +#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; +using ::sd::tools::ConfigurationAccess; + +#undef VERBOSE +//#define VERBOSE 2 + +namespace sd { namespace framework { + +static const sal_uInt32 snFactoryPropertyCount (2); +static const sal_uInt32 snStartupPropertyCount (1); + + + + +class ModuleController::ResourceToFactoryMap + : public ::std::hash_map< + rtl::OUString, + rtl::OUString, + ::comphelper::UStringHash, + ::comphelper::UStringEqual> +{ +public: + ResourceToFactoryMap (void) {} +}; + + +class ModuleController::LoadedFactoryContainer + : public ::std::hash_map< + rtl::OUString, + WeakReference<XInterface>, + ::comphelper::UStringHash, + ::comphelper::UStringEqual> +{ +public: + LoadedFactoryContainer (void) {} +}; + + + + + +Reference<XInterface> SAL_CALL ModuleController_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(ModuleController::CreateInstance(rxContext), UNO_QUERY); +} + + + + +::rtl::OUString ModuleController_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.module.ModuleController")); +} + + + + +Sequence<rtl::OUString> SAL_CALL ModuleController_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.ModuleController")); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//===== ModuleController ====================================================== + +Reference<XModuleController> ModuleController::CreateInstance ( + const Reference<XComponentContext>& rxContext) +{ + return new ModuleController(rxContext); +} + + + + +ModuleController::ModuleController (const Reference<XComponentContext>& rxContext) throw() + : ModuleControllerInterfaceBase(MutexOwner::maMutex), + mxController(), + mpResourceToFactoryMap(new ResourceToFactoryMap()), + mpLoadedFactories(new LoadedFactoryContainer()) +{ + (void)rxContext; + LoadFactories(rxContext); +} + + + + +ModuleController::~ModuleController (void) throw() +{ +} + + + + +void SAL_CALL ModuleController::disposing (void) +{ +} + + + + +void ModuleController::LoadFactories (const Reference<XComponentContext>& rxContext) +{ + try + { + ConfigurationAccess aConfiguration ( + rxContext, + OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/")), + ConfigurationAccess::READ_ONLY); + Reference<container::XNameAccess> xFactories ( + aConfiguration.GetConfigurationNode( + OUString(RTL_CONSTASCII_USTRINGPARAM("MultiPaneGUI/Framework/ResourceFactories"))), + UNO_QUERY); + ::std::vector<rtl::OUString> aProperties (snFactoryPropertyCount); + aProperties[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceName")); + aProperties[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("ResourceList")); + ConfigurationAccess::ForAll( + xFactories, + aProperties, + ::boost::bind(&ModuleController::ProcessFactory, this, _2)); + } + catch (Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + + + + +void ModuleController::ProcessFactory (const ::std::vector<Any>& rValues) +{ + OSL_ASSERT(rValues.size() == snFactoryPropertyCount); + + // Get the service name of the factory. + rtl::OUString sServiceName; + rValues[0] >>= sServiceName; + + // Get all resource URLs that are created by the factory. + Reference<container::XNameAccess> xResources (rValues[1], UNO_QUERY); + ::std::vector<rtl::OUString> aURLs; + tools::ConfigurationAccess::FillList( + xResources, + OUString(RTL_CONSTASCII_USTRINGPARAM("URL")), + aURLs); + +#if defined VERBOSE && VERBOSE>0 + OSL_TRACE("ModuleController::adding factory %s", + OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); +#endif + + // Add the resource URLs to the map. + ::std::vector<rtl::OUString>::const_iterator iResource; + for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource) + { + (*mpResourceToFactoryMap)[*iResource] = sServiceName; +#if defined VERBOSE && VERBOSE>1 + OSL_TRACE(" %s", + OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr()); +#endif + } +} + + + + +void ModuleController::InstantiateStartupServices (void) +{ + try + { + tools::ConfigurationAccess aConfiguration ( + OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/")), + tools::ConfigurationAccess::READ_ONLY); + Reference<container::XNameAccess> xFactories ( + aConfiguration.GetConfigurationNode( + OUString(RTL_CONSTASCII_USTRINGPARAM("MultiPaneGUI/Framework/StartupServices"))), + UNO_QUERY); + ::std::vector<rtl::OUString> aProperties (snStartupPropertyCount); + aProperties[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceName")); + tools::ConfigurationAccess::ForAll( + xFactories, + aProperties, + ::boost::bind(&ModuleController::ProcessStartupService, this, _2)); + } + catch (Exception&) + { + OSL_TRACE("ERROR in ModuleController::InstantiateStartupServices"); + } +} + + + + +void ModuleController::ProcessStartupService (const ::std::vector<Any>& rValues) +{ + OSL_ASSERT(rValues.size() == snStartupPropertyCount); + + try + { + // Get the service name of the startup service. + rtl::OUString sServiceName; + rValues[0] >>= sServiceName; + + // Instantiate service. + Reference<lang::XMultiServiceFactory> xGlobalFactory ( + ::comphelper::getProcessServiceFactory(), UNO_QUERY); + if (xGlobalFactory.is()) + { + // Create the startup service. + Sequence<Any> aArguments(1); + aArguments[0] <<= mxController; + // Note that when the new object will be destroyed at the end of + // this scope when it does not register itself anywhere. + // Typically it will add itself as ConfigurationChangeListener + // at the configuration controller. + xGlobalFactory->createInstanceWithArguments(sServiceName, aArguments); + +#if defined VERBOSE && VERBOSE>0 + OSL_TRACE("ModuleController::created startup service %s", + OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); +#endif + } + } + catch (Exception&) + { + OSL_TRACE("ERROR in ModuleController::ProcessStartupServices"); + } +} + + + + +//----- XModuleController ----------------------------------------------------- + +void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL) + throw (RuntimeException) +{ + ResourceToFactoryMap::const_iterator iFactory (mpResourceToFactoryMap->find(rsResourceURL)); + if (iFactory != mpResourceToFactoryMap->end()) + { + // Check that the factory has already been loaded and not been + // destroyed in the meantime. + Reference<XInterface> xFactory; + LoadedFactoryContainer::const_iterator iLoadedFactory ( + mpLoadedFactories->find(iFactory->second)); + if (iLoadedFactory != mpLoadedFactories->end()) + xFactory = Reference<XInterface>(iLoadedFactory->second, UNO_QUERY); + if ( ! xFactory.is()) + { + // Create a new instance of the factory. + Reference<lang::XMultiServiceFactory> xGlobalFactory ( + ::comphelper::getProcessServiceFactory(), UNO_QUERY); + if (xGlobalFactory.is()) + { + // Create the factory service. + Sequence<Any> aArguments(1); + aArguments[0] <<= mxController; + xFactory = xGlobalFactory->createInstanceWithArguments( + iFactory->second, + aArguments); + + // Remember that this factory has been instanced. + (*mpLoadedFactories)[iFactory->second] = xFactory; + } + } + } +} + + + + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL ModuleController::initialize (const Sequence<Any>& aArguments) + throw (Exception, RuntimeException) +{ + if (aArguments.getLength() > 0) + { + try + { + // Get the XController from the first argument. + mxController = Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW); + + InstantiateStartupServices(); + } + catch (RuntimeException&) + {} + } +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/PresentationModule.cxx b/sd/source/ui/framework/module/PresentationModule.cxx new file mode 100644 index 000000000000..28f8521121b8 --- /dev/null +++ b/sd/source/ui/framework/module/PresentationModule.cxx @@ -0,0 +1,50 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "framework/PresentationModule.hxx" + +#include "CenterViewFocusModule.hxx" +#include "SlideSorterModule.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd { namespace framework { + + +void PresentationModule::Initialize (Reference<frame::XController>& rxController) +{ + new sd::framework::CenterViewFocusModule(rxController); +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ReadOnlyModeObserver.cxx b/sd/source/ui/framework/module/ReadOnlyModeObserver.cxx new file mode 100644 index 000000000000..1625b0c63f3f --- /dev/null +++ b/sd/source/ui/framework/module/ReadOnlyModeObserver.cxx @@ -0,0 +1,223 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ReadOnlyModeObserver.hxx" + +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <comphelper/processfactory.hxx> +#include <cppuhelper/interfacecontainer.hxx> + +#include "tools/SlotStateListener.hxx" +#include "framework/FrameworkHelper.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; + +namespace sd { namespace framework { + +class ReadOnlyModeObserver::ModifyBroadcaster + : public ::cppu::OBroadcastHelper +{ +public: + explicit ModifyBroadcaster (::osl::Mutex& rOslMutex) : ::cppu::OBroadcastHelper(rOslMutex) {} +}; + + + + +ReadOnlyModeObserver::ReadOnlyModeObserver ( + const Reference<frame::XController>& rxController) + : ReadOnlyModeObserverInterfaceBase(maMutex), + maSlotNameURL(), + mxController(rxController), + mxConfigurationController(NULL), + mxDispatch(NULL), + mpBroadcaster(new ModifyBroadcaster(maMutex)) +{ + // Create a URL object for the slot name. + maSlotNameURL.Complete = OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:EditDoc")); + uno::Reference<lang::XMultiServiceFactory> xServiceManager ( + ::comphelper::getProcessServiceFactory()); + if (xServiceManager.is()) + { + Reference<util::XURLTransformer> xTransformer(xServiceManager->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), + UNO_QUERY); + if (xTransformer.is()) + xTransformer->parseStrict(maSlotNameURL); + } + + if ( ! ConnectToDispatch()) + { + // The controller is not yet connected to a frame. This means that + // the dispatcher is not yet set up. We wait for this to happen by + // waiting for configuration updates and try again. + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + if (mxConfigurationController.is()) + { + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateStartEvent, + Any()); + } + } + } +} + + + + +ReadOnlyModeObserver::~ReadOnlyModeObserver (void) +{ +} + + + + +void SAL_CALL ReadOnlyModeObserver::disposing (void) +{ + if (mxController.is()) + { + mxController = NULL; + } + if (mxConfigurationController.is()) + { + mxConfigurationController->removeConfigurationChangeListener(this); + mxConfigurationController = NULL; + } + if (mxDispatch.is()) + { + mxDispatch->removeStatusListener(this, maSlotNameURL); + mxDispatch = NULL; + } + + lang::EventObject aEvent; + aEvent.Source = static_cast<XWeak*>(this); + ::cppu::OInterfaceContainerHelper* pIterator + = mpBroadcaster->getContainer(getCppuType((Reference<frame::XStatusListener>*)NULL)); + pIterator->disposeAndClear(aEvent); +} + + + + +void ReadOnlyModeObserver::AddStatusListener ( + const Reference<frame::XStatusListener>& rxListener) +{ + mpBroadcaster->addListener( + getCppuType((Reference<frame::XStatusListener>*)NULL), + rxListener); +} + + + + +bool ReadOnlyModeObserver::ConnectToDispatch (void) +{ + if ( ! mxDispatch.is()) + { + // Get the dispatch object. + Reference<frame::XDispatchProvider> xProvider (mxController->getFrame(), UNO_QUERY); + if (xProvider.is()) + { + mxDispatch = xProvider->queryDispatch(maSlotNameURL, OUString(), 0); + if (mxDispatch.is()) + { + mxDispatch->addStatusListener(this, maSlotNameURL); + } + } + } + + return mxDispatch.is(); +} + + + + +void ReadOnlyModeObserver::statusChanged (const frame::FeatureStateEvent& rEvent) + throw (RuntimeException) +{ + ::cppu::OInterfaceContainerHelper* pIterator + = mpBroadcaster->getContainer(getCppuType((Reference<frame::XStatusListener>*)NULL)); + if (pIterator != NULL) + { + pIterator->notifyEach(&frame::XStatusListener::statusChanged, rEvent); + } +} + + + + +//----- XEventListener -------------------------------------------------------- + +void SAL_CALL ReadOnlyModeObserver::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (rEvent.Source == mxConfigurationController) + mxConfigurationController = NULL; + else if (rEvent.Source == mxDispatch) + mxDispatch = NULL; + + dispose(); +} + + + + +void SAL_CALL ReadOnlyModeObserver::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (rEvent.Type.equals(FrameworkHelper::msConfigurationUpdateStartEvent)) + { + if (mxController.is() && mxController->getFrame().is()) + { + if (ConnectToDispatch()) + { + // We have connected successfully to the dispatcher and + // therefore can disconnect from the configuration controller. + mxConfigurationController->removeConfigurationChangeListener(this); + mxConfigurationController = NULL; + } + } + } +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ReadOnlyModeObserver.hxx b/sd/source/ui/framework/module/ReadOnlyModeObserver.hxx new file mode 100644 index 000000000000..e1172b2d1f20 --- /dev/null +++ b/sd/source/ui/framework/module/ReadOnlyModeObserver.hxx @@ -0,0 +1,142 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_READ_ONLY_MODE_OBSERVER_HXX +#define SD_FRAMEWORK_READ_ONLY_MODE_OBSERVER_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/util/XModifyListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/compbase2.hxx> +#include <tools/link.hxx> +#include <boost/function.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/shared_ptr.hpp> + +namespace { + +typedef ::cppu::WeakComponentImplHelper2 < + ::com::sun::star::drawing::framework::XConfigurationChangeListener, + ::com::sun::star::frame::XStatusListener + > ReadOnlyModeObserverInterfaceBase; + +} // end of anonymous namespace. + + + + +namespace sd { namespace framework { + +/** Wait for changes of the read-only mode. On switching between read-only + mode and read-write the registered listeners are called. + + This class handles the case that the given controller is not yet + connected to a frame and that the dispatcher is not yet set up. It + waits for this to happen and then registers at the .uno:EditDoc command + and waits for state changes. +*/ +class ReadOnlyModeObserver + : private sd::MutexOwner, + public ReadOnlyModeObserverInterfaceBase +{ +public: + /** Create a new read-only mode observer for the given controller. + */ + ReadOnlyModeObserver ( + const ::com::sun::star::uno::Reference<com::sun::star::frame::XController>& rxController); + virtual ~ReadOnlyModeObserver (void); + + virtual void SAL_CALL disposing (void); + + + /** Add a status listener that is called when the state of the + .uno:EditDoc command changes. Note that the listener has to take + into account both the IsEnabled and the State fields of the + FeatureStateEvent. Only when IsEnabled is true then the State field + is valid. + */ + void AddStatusListener ( + const ::com::sun::star::uno::Reference< + com::sun::star::frame::XStatusListener>& rxListener); + + // XEventListener + + virtual void SAL_CALL disposing ( + const com::sun::star::lang::EventObject& rEvent) + throw (com::sun::star::uno::RuntimeException); + + + // frame::XStatusListener + + /** Called by slot state change broadcasters. + @throws DisposedException + */ + virtual void SAL_CALL + statusChanged ( + const ::com::sun::star::frame::FeatureStateEvent& rState) + throw (::com::sun::star::uno::RuntimeException); + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const ::com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (::com::sun::star::uno::RuntimeException); + +private: + ::com::sun::star::util::URL maSlotNameURL; + /** The XController is stored to enable repeated calls to + ConnectToDispatch() (get access to the XDispatchProvider. + */ + ::com::sun::star::uno::Reference<com::sun::star::frame::XController> + mxController; + ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XConfigurationController> + mxConfigurationController; + ::com::sun::star::uno::Reference<com::sun::star::frame::XDispatch> + mxDispatch; + class ModifyBroadcaster; + ::boost::scoped_ptr<ModifyBroadcaster> mpBroadcaster; + + /** Listen for the .uno:EditMode command. Returns <TRUE/> when the connection + has been established. + */ + bool ConnectToDispatch (void); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ResourceManager.cxx b/sd/source/ui/framework/module/ResourceManager.cxx new file mode 100644 index 000000000000..08ee84c33e10 --- /dev/null +++ b/sd/source/ui/framework/module/ResourceManager.cxx @@ -0,0 +1,297 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ResourceManager.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "framework/ConfigurationController.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> + +#include <comphelper/stl_types.hxx> +#include <set> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +namespace { + static const sal_Int32 ResourceActivationRequestEvent = 0; + static const sal_Int32 ResourceDeactivationRequestEvent = 1; +} + + + + +namespace sd { namespace framework { + +class ResourceManager::MainViewContainer + : public ::std::set<OUString, ::comphelper::UStringLess> +{ +public: + MainViewContainer (void) {} +}; + + + + +//===== ResourceManager ======================================================= + +ResourceManager::ResourceManager ( + const Reference<frame::XController>& rxController, + const Reference<XResourceId>& rxResourceId) + : ResourceManagerInterfaceBase(MutexOwner::maMutex), + mxConfigurationController(), + mpActiveMainViewContainer(new MainViewContainer()), + mxResourceId(rxResourceId), + mxMainViewAnchorId(FrameworkHelper::Instance(rxController)->CreateResourceId( + FrameworkHelper::msCenterPaneURL)), + msCurrentMainViewURL(), + mbIsEnabled(true) +{ + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + + if (mxConfigurationController.is()) + { + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationRequestEvent, + makeAny(ResourceActivationRequestEvent)); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceDeactivationRequestEvent, + makeAny(ResourceDeactivationRequestEvent)); + } + } +} + + + + +ResourceManager::~ResourceManager (void) +{ +} + + + + +void ResourceManager::AddActiveMainView ( + const OUString& rsMainViewURL) +{ + mpActiveMainViewContainer->insert(rsMainViewURL); +} + + + + +void SAL_CALL ResourceManager::disposing (void) +{ + if (mxConfigurationController.is()) + { + mxConfigurationController->removeConfigurationChangeListener(this); + mxConfigurationController = NULL; + } +} + + + + +void ResourceManager::Enable (void) +{ + mbIsEnabled = true; + UpdateForMainViewShell(); +} + + + + +void ResourceManager::Disable (void) +{ + mbIsEnabled = false; + UpdateForMainViewShell(); +} + + + + +void SAL_CALL ResourceManager::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + OSL_ASSERT(rEvent.ResourceId.is()); + + sal_Int32 nEventType = 0; + rEvent.UserData >>= nEventType; + switch (nEventType) + { + case ResourceActivationRequestEvent: + if (rEvent.ResourceId->isBoundToURL( + FrameworkHelper::msCenterPaneURL, + AnchorBindingMode_DIRECT)) + { + // A resource directly bound to the center pane has been + // requested. + if (rEvent.ResourceId->getResourceTypePrefix().equals( + FrameworkHelper::msViewURLPrefix)) + { + // The requested resource is a view. Show or hide the + // resource managed by this ResourceManager accordingly. + HandleMainViewSwitch( + rEvent.ResourceId->getResourceURL(), + rEvent.Configuration, + true); + } + } + else if (rEvent.ResourceId->compareTo(mxResourceId) == 0) + { + // The resource managed by this ResourceManager has been + // explicitly been requested (maybe by us). Remember this + // setting. + HandleResourceRequest(true, rEvent.Configuration); + } + break; + + case ResourceDeactivationRequestEvent: + if (rEvent.ResourceId->compareTo(mxMainViewAnchorId) == 0) + { + HandleMainViewSwitch( + OUString(), + rEvent.Configuration, + false); + } + else if (rEvent.ResourceId->compareTo(mxResourceId) == 0) + { + // The resource managed by this ResourceManager has been + // explicitly been requested to be hidden (maybe by us). + // Remember this setting. + HandleResourceRequest(false, rEvent.Configuration); + } + break; + } +} + + + + +void ResourceManager::UpdateForMainViewShell (void) +{ + if (mxConfigurationController.is()) + { + ConfigurationController::Lock aLock (mxConfigurationController); + + if (mbIsEnabled + && mpActiveMainViewContainer->find(msCurrentMainViewURL) + != mpActiveMainViewContainer->end()) + { + // Activate resource. + mxConfigurationController->requestResourceActivation( + mxResourceId->getAnchor(), + ResourceActivationMode_ADD); + mxConfigurationController->requestResourceActivation( + mxResourceId, + ResourceActivationMode_REPLACE); + } + else + { + mxConfigurationController->requestResourceDeactivation(mxResourceId); + } + } +} + + + + +void ResourceManager::HandleMainViewSwitch ( + const OUString& rsViewURL, + const Reference<XConfiguration>& rxConfiguration, + const bool bIsActivated) +{ + (void)rxConfiguration; + if (bIsActivated) + msCurrentMainViewURL = rsViewURL; + else + msCurrentMainViewURL = OUString(); + UpdateForMainViewShell(); +} + + + + +void ResourceManager::HandleResourceRequest( + bool bActivation, + const Reference<XConfiguration>& rxConfiguration) +{ + if (mbIsEnabled) + { + Sequence<Reference<XResourceId> > aCenterViews = rxConfiguration->getResources( + FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL), + FrameworkHelper::msViewURLPrefix, + AnchorBindingMode_DIRECT); + if (aCenterViews.getLength() == 1) + { + if (bActivation) + { + mpActiveMainViewContainer->insert(aCenterViews[0]->getResourceURL()); + } + else + { + MainViewContainer::iterator iElement ( + mpActiveMainViewContainer->find(aCenterViews[0]->getResourceURL())); + if (iElement != mpActiveMainViewContainer->end()) + mpActiveMainViewContainer->erase(iElement); + } + } + } +} + + + + +void SAL_CALL ResourceManager::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is() + && rEvent.Source == mxConfigurationController) + { + // Without the configuration controller this class can do nothing. + mxConfigurationController = NULL; + dispose(); + } +} + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ResourceManager.hxx b/sd/source/ui/framework/module/ResourceManager.hxx new file mode 100644 index 000000000000..dc3215ae9e68 --- /dev/null +++ b/sd/source/ui/framework/module/ResourceManager.hxx @@ -0,0 +1,136 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_RESOURCE_MANAGER_HXX +#define SD_FRAMEWORK_RESOURCE_MANAGER_HXX + +#include "MutexOwner.hxx" +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <cppuhelper/compbase1.hxx> +#include <boost/scoped_ptr.hpp> + +namespace css = ::com::sun::star; + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + ::com::sun::star::drawing::framework::XConfigurationChangeListener + > ResourceManagerInterfaceBase; + +} // end of anonymous namespace. + + +namespace sd { namespace framework { + +/** Manage the activation state of one resource depending on the view in the + center pane. The ResourceManager remembers in which configuration to + activate and in which to deactivate the resource. When the resource is + deactivated or activated manually by the user then the ResourceManager + detects this and remembers it for the future. +*/ +class ResourceManager + : private sd::MutexOwner, + public ResourceManagerInterfaceBase +{ +public: + ResourceManager ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XController>& rxController, + const ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::framework::XResourceId>& rxResourceId); + virtual ~ResourceManager (void); + + /** Remember the given URL as one of a center pane view for which to + activate the resource managed by the called object. + */ + void AddActiveMainView (const ::rtl::OUString& rsMainViewURL); + + virtual void SAL_CALL disposing (void); + + /** Allow the ResourceManager to make resource activation or + deactivation requests. + */ + void Enable (void); + + /** Disable the resource management. When called, the ResourceManager + requests the resource to be deactivated. Until enabled again it + does not make any further requests for resource activation or + deactivation. + + Call this for example to hide resources in read-only mode. + */ + void Disable (void); + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (com::sun::star::uno::RuntimeException); + + // XEventListener + + virtual void SAL_CALL disposing ( + const com::sun::star::lang::EventObject& rEvent) + throw (com::sun::star::uno::RuntimeException); + +protected: + ::com::sun::star::uno::Reference<com::sun::star::drawing::framework::XConfigurationController> + mxConfigurationController; + +private: + class MainViewContainer; + ::boost::scoped_ptr<MainViewContainer> mpActiveMainViewContainer; + + /// The resource managed by this class. + css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId; + + /// The anchor of the main view. + css::uno::Reference<css::drawing::framework::XResourceId> mxMainViewAnchorId; + + ::rtl::OUString msCurrentMainViewURL; + bool mbIsEnabled; + + void HandleMainViewSwitch ( + const ::rtl::OUString& rsViewURL, + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XConfiguration>& rxConfiguration, + const bool bIsActivated); + void HandleResourceRequest( + bool bActivation, + const ::com::sun::star::uno::Reference< + com::sun::star::drawing::framework::XConfiguration>& rxConfiguration); + void UpdateForMainViewShell (void); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ShellStackGuard.cxx b/sd/source/ui/framework/module/ShellStackGuard.cxx new file mode 100644 index 000000000000..f13374ec673d --- /dev/null +++ b/sd/source/ui/framework/module/ShellStackGuard.cxx @@ -0,0 +1,195 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ShellStackGuard.hxx" + +#include "framework/ConfigurationController.hxx" +#include "framework/FrameworkHelper.hxx" + +#include "DrawController.hxx" +#include "ViewShellBase.hxx" +#include <sfx2/printer.hxx> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + +//===== CenterViewFocusModule ==================================================== + +ShellStackGuard::ShellStackGuard (Reference<frame::XController>& rxController) + : ShellStackGuardInterfaceBase(m_aMutex), + mxConfigurationController(), + mpBase(NULL), + mpUpdateLock(), + maPrinterPollingTimer() +{ + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + + // 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) + mpBase = pController->GetViewShellBase(); + } + } + + if (mxConfigurationController.is()) + { + // Listen for update starts so that the following update can be + // prevented in case of a printing printer. + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateStartEvent, + Any()); + + // Prepare the printer polling. + maPrinterPollingTimer.SetTimeoutHdl(LINK(this,ShellStackGuard,TimeoutHandler)); + maPrinterPollingTimer.SetTimeout(300); + } +} + + + + +ShellStackGuard::~ShellStackGuard (void) +{ +} + + + + +void SAL_CALL ShellStackGuard::disposing (void) +{ + if (mxConfigurationController.is()) + mxConfigurationController->removeConfigurationChangeListener(this); + + mxConfigurationController = NULL; + mpBase = NULL; +} + + + + +void SAL_CALL ShellStackGuard::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (rEvent.Type.equals(FrameworkHelper::msConfigurationUpdateStartEvent)) + { + if (mpUpdateLock.get() == NULL && IsPrinting()) + { + // Prevent configuration updates while the printer is printing. + mpUpdateLock.reset(new ConfigurationController::Lock(mxConfigurationController)); + + // Start polling for the printer having finished printing. + maPrinterPollingTimer.Start(); + } + } +} + + + + +void SAL_CALL ShellStackGuard::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is()) + if (rEvent.Source == mxConfigurationController) + { + mxConfigurationController = NULL; + mpBase = NULL; + } +} + + + + +IMPL_LINK(ShellStackGuard, TimeoutHandler, Timer*, pTimer) +{ +#ifdef DEBUG + OSL_ASSERT(pTimer==&maPrinterPollingTimer); +#else + (void)pTimer; +#endif + if (mpUpdateLock.get() != NULL) + { + if ( ! IsPrinting()) + { + // Printing finished. Release the update lock. + mpUpdateLock.reset(); + } + else + { + // Wait long for the printing to finish. + maPrinterPollingTimer.Start(); + } + } + + return 0; +} + + + + + +bool ShellStackGuard::IsPrinting (void) const +{ + if (mpBase != NULL) + { + SfxPrinter* pPrinter = mpBase->GetPrinter(); + if (pPrinter != NULL + && pPrinter->IsPrinting()) + { + return true; + } + } + + return false; +} + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ShellStackGuard.hxx b/sd/source/ui/framework/module/ShellStackGuard.hxx new file mode 100644 index 000000000000..7df5c499f216 --- /dev/null +++ b/sd/source/ui/framework/module/ShellStackGuard.hxx @@ -0,0 +1,119 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_SHELL_STACK_GUARD_HXX +#define SD_FRAMEWORK_SHELL_STACK_GUARD_HXX + +#include <cppuhelper/basemutex.hxx> + +#include "framework/ConfigurationController.hxx" + +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/frame/XController.hpp> + +#include <vcl/timer.hxx> +#include <cppuhelper/compbase1.hxx> +#include <boost/scoped_ptr.hpp> + + +namespace css = ::com::sun::star; + + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + css::drawing::framework::XConfigurationChangeListener + > ShellStackGuardInterfaceBase; + +} // end of anonymous namespace. + +namespace sd { + +class ViewShellBase; + +} + + + + +namespace sd { namespace framework { + +/** This module locks updates of the current configuration in situations + when the shell stack must not be modified. + + On every start of a configuration update the ShellStackGuard checks the + printer. If it is printing the configuration update is locked. It then + polls the printer and unlocks updates when printing finishes. + + When in the future there are no resources left that use shells then this + module can be removed. +*/ +class ShellStackGuard + : private ::cppu::BaseMutex, + public ShellStackGuardInterfaceBase +{ +public: + ShellStackGuard (css::uno::Reference<css::frame::XController>& rxController); + virtual ~ShellStackGuard (void); + + virtual void SAL_CALL disposing (void); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (css::uno::RuntimeException); + + // XEventListener + + virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference<css::drawing::framework::XConfigurationController> + mxConfigurationController; + ViewShellBase* mpBase; + ::boost::scoped_ptr<ConfigurationController::Lock> mpUpdateLock; + Timer maPrinterPollingTimer; + + DECL_LINK(TimeoutHandler, Timer*); + + /** Return <TRUE/> when the printer is printing. Return <FALSE/> when + the printer is not printing, or there is no printer, or someting + else went wrong. + */ + bool IsPrinting (void) const; +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/SlideSorterModule.cxx b/sd/source/ui/framework/module/SlideSorterModule.cxx new file mode 100644 index 000000000000..56594aa15774 --- /dev/null +++ b/sd/source/ui/framework/module/SlideSorterModule.cxx @@ -0,0 +1,158 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "SlideSorterModule.hxx" + +#include "framework/FrameworkHelper.hxx" +#include <com/sun/star/drawing/framework/XTabBar.hpp> +#include <com/sun/star/drawing/framework/TabBarButton.hpp> + +#include "strings.hrc" +#include "sdresid.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + + +//===== SlideSorterModule ================================================== + +SlideSorterModule::SlideSorterModule ( + const Reference<frame::XController>& rxController, + const OUString& rsLeftPaneURL) + : ResourceManager(rxController, + FrameworkHelper::CreateResourceId(FrameworkHelper::msSlideSorterURL, rsLeftPaneURL)), + mxViewTabBarId(FrameworkHelper::CreateResourceId( + FrameworkHelper::msViewTabBarURL, + FrameworkHelper::msCenterPaneURL)), + mxControllerManager(rxController,UNO_QUERY) +{ + if (mxConfigurationController.is()) + { + UpdateViewTabBar(NULL); + + AddActiveMainView(FrameworkHelper::msImpressViewURL); + AddActiveMainView(FrameworkHelper::msOutlineViewURL); + AddActiveMainView(FrameworkHelper::msNotesViewURL); + + AddActiveMainView(FrameworkHelper::msDrawViewURL); + + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationEvent, + Any()); + } +} + + + + +SlideSorterModule::~SlideSorterModule (void) +{ +} + + + + +void SAL_CALL SlideSorterModule::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (rEvent.Type.equals(FrameworkHelper::msResourceActivationEvent)) + { + if (rEvent.ResourceId->compareTo(mxViewTabBarId) == 0) + { + // Update the view tab bar because the view tab bar has just + // become active. + UpdateViewTabBar(Reference<XTabBar>(rEvent.ResourceObject,UNO_QUERY)); + } + else if (rEvent.ResourceId->getResourceTypePrefix().equals( + FrameworkHelper::msViewURLPrefix) + && rEvent.ResourceId->isBoundTo( + FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL), + AnchorBindingMode_DIRECT)) + { + // Update the view tab bar because the view in the center pane + // has changed. + UpdateViewTabBar(NULL); + } + } + else + { + ResourceManager::notifyConfigurationChange(rEvent); + } +} + + + + +void SlideSorterModule::UpdateViewTabBar (const Reference<XTabBar>& rxTabBar) +{ + if ( ! mxControllerManager.is()) + return; + + Reference<XTabBar> xBar (rxTabBar); + if ( ! xBar.is()) + { + Reference<XConfigurationController> xCC ( + mxControllerManager->getConfigurationController()); + if (xCC.is()) + xBar = Reference<XTabBar>(xCC->getResource(mxViewTabBarId), UNO_QUERY); + } + + if (xBar.is()) + { + TabBarButton aButtonA; + aButtonA.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msSlideSorterURL, + FrameworkHelper::msCenterPaneURL); + aButtonA.ButtonLabel = String(SdResId(STR_SLIDE_MODE)); + + TabBarButton aButtonB; + aButtonB.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msHandoutViewURL, + FrameworkHelper::msCenterPaneURL); + + if ( ! xBar->hasTabBarButton(aButtonA)) + xBar->addTabBarButtonAfter(aButtonA, aButtonB); + } +} + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/SlideSorterModule.hxx b/sd/source/ui/framework/module/SlideSorterModule.hxx new file mode 100644 index 000000000000..a89b359dbc7b --- /dev/null +++ b/sd/source/ui/framework/module/SlideSorterModule.hxx @@ -0,0 +1,72 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX +#define SD_FRAMEWORK_SLIDE_SORTER_MODULE_HXX + +#include "ResourceManager.hxx" + +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XTabBar.hpp> + +namespace css = ::com::sun::star; + +namespace sd { namespace framework { + +/** This module is responsible for showing the slide sorter bar and the the + slide sorter view in the center pane. +*/ +class SlideSorterModule + : public ResourceManager +{ +public: + SlideSorterModule ( + const css::uno::Reference<css::frame::XController>& rxController, + const ::rtl::OUString& rsLeftPaneURL); + virtual ~SlideSorterModule (void); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference<css::drawing::framework::XResourceId> mxViewTabBarId; + css::uno::Reference<css::drawing::framework::XControllerManager> mxControllerManager; + + void UpdateViewTabBar ( + const css::uno::Reference<css::drawing::framework::XTabBar>& rxViewTabBar); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolBarModule.cxx b/sd/source/ui/framework/module/ToolBarModule.cxx new file mode 100644 index 000000000000..58300805aae6 --- /dev/null +++ b/sd/source/ui/framework/module/ToolBarModule.cxx @@ -0,0 +1,237 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ToolBarModule.hxx" +#include "ViewShellBase.hxx" +#include "DrawController.hxx" +#include "framework/FrameworkHelper.hxx" +#include "framework/ConfigurationController.hxx" + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +namespace { + static const sal_Int32 gnConfigurationUpdateStartEvent(0); + static const sal_Int32 gnConfigurationUpdateEndEvent(1); + static const sal_Int32 gnResourceActivationRequestEvent(2); + static const sal_Int32 gnResourceDeactivationRequestEvent(3); +} + +namespace sd { namespace framework { + +//===== ToolBarModule ========================================================= + +ToolBarModule::ToolBarModule ( + const Reference<frame::XController>& rxController) + : ToolBarModuleInterfaceBase(m_aMutex), + mxConfigurationController(), + mpBase(NULL), + mpToolBarManagerLock(), + mbMainViewSwitchUpdatePending(false) +{ + // 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) + mpBase = pController->GetViewShellBase(); + } + + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + if (mxConfigurationController.is()) + { + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateStartEvent, + makeAny(gnConfigurationUpdateStartEvent)); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateEndEvent, + makeAny(gnConfigurationUpdateEndEvent)); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationRequestEvent, + makeAny(gnResourceActivationRequestEvent)); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceDeactivationRequestEvent, + makeAny(gnResourceDeactivationRequestEvent)); + } + } +} + + + + +ToolBarModule::~ToolBarModule (void) +{ +} + + + + +void SAL_CALL ToolBarModule::disposing (void) +{ + if (mxConfigurationController.is()) + mxConfigurationController->removeConfigurationChangeListener(this); + + mxConfigurationController = NULL; +} + + + + +void SAL_CALL ToolBarModule::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is()) + { + sal_Int32 nEventType = 0; + rEvent.UserData >>= nEventType; + switch (nEventType) + { + case gnConfigurationUpdateStartEvent: + HandleUpdateStart(); + break; + + case gnConfigurationUpdateEndEvent: + HandleUpdateEnd(); + break; + + case gnResourceActivationRequestEvent: + case gnResourceDeactivationRequestEvent: + // Remember the request for the activation or deactivation + // of the center pane view. When that happens then on end + // of the next configuration update the set of visible tool + // bars will be updated. + if ( ! mbMainViewSwitchUpdatePending) + if (rEvent.ResourceId->getResourceURL().match( + FrameworkHelper::msViewURLPrefix) + && rEvent.ResourceId->isBoundToURL( + FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)) + { + mbMainViewSwitchUpdatePending = true; + } + break; + } + } +} + + + + +//----------------------------------------------------------------------------- + + +void ToolBarModule::HandleUpdateStart (void) +{ + // Lock the ToolBarManager and tell it to lock the ViewShellManager as + // well. This way the ToolBarManager can optimize the releasing of + // locks and arranging of updates of both tool bars and the view shell + // stack. + if (mpBase != NULL) + { + ::boost::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); + mpToolBarManagerLock.reset(new ToolBarManager::UpdateLock(pToolBarManager)); + pToolBarManager->LockViewShellManager(); + } +} + + + + +void ToolBarModule::HandleUpdateEnd (void) +{ + if (mbMainViewSwitchUpdatePending) + { + mbMainViewSwitchUpdatePending = false; + // Update the set of visible tool bars and deactivate those that are + // no longer visible. This is done before the old view shell is + // destroyed in order to avoid unnecessary updates of those tool + // bars. + ::boost::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); + ::boost::shared_ptr<FrameworkHelper> pFrameworkHelper ( + FrameworkHelper::Instance(*mpBase)); + ViewShell* pViewShell + = pFrameworkHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get(); + if (pViewShell != NULL) + { + pToolBarManager->MainViewShellChanged(*pViewShell); + pToolBarManager->SelectionHasChanged( + *pViewShell, + *pViewShell->GetView()); + pToolBarManager->PreUpdate(); + } + else + { + pToolBarManager->MainViewShellChanged(ViewShell::ST_NONE); + pToolBarManager->PreUpdate(); + } + } + + // Releasing the update lock of the ToolBarManager will let the + // ToolBarManager with the help of the ViewShellManager take care of + // updating tool bars and view shell with the minimal amount of + // shell stack modifications and tool bar updates. + mpToolBarManagerLock.reset(); +} + + + + +void SAL_CALL ToolBarModule::disposing (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is() + && rEvent.Source == mxConfigurationController) + { + // Without the configuration controller this class can do nothing. + mxConfigurationController = NULL; + dispose(); + } +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolBarModule.hxx b/sd/source/ui/framework/module/ToolBarModule.hxx new file mode 100644 index 000000000000..0eab208908fb --- /dev/null +++ b/sd/source/ui/framework/module/ToolBarModule.hxx @@ -0,0 +1,105 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_TOOL_BAR_MODULE_HXX +#define SD_FRAMEWORK_TOOL_BAR_MODULE_HXX + +#include "ToolBarManager.hxx" +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XTabBar.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase1.hxx> +#include <boost/scoped_ptr.hpp> + +namespace css = ::com::sun::star; + +namespace sd { +class ViewShellBase; +} + + + +namespace sd { namespace framework { + +namespace { + typedef ::cppu::WeakComponentImplHelper1 < + ::css::drawing::framework::XConfigurationChangeListener + > ToolBarModuleInterfaceBase; +} + + +/** This module is responsible for locking the ToolBarManager during + configuration updates and for triggering ToolBarManager updates. +*/ +class ToolBarModule + : private ::cppu::BaseMutex, + public ToolBarModuleInterfaceBase +{ +public: + /** Create a new module. + @param rxController + This is the access point to the drawing framework. + */ + ToolBarModule ( + const css::uno::Reference<css::frame::XController>& rxController); + virtual ~ToolBarModule (void); + + virtual void SAL_CALL disposing (void); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (css::uno::RuntimeException); + + // XEventListener + + virtual void SAL_CALL disposing ( + const css::lang::EventObject& rEvent) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference< + css::drawing::framework::XConfigurationController> mxConfigurationController; + ViewShellBase* mpBase; + ::boost::scoped_ptr<ToolBarManager::UpdateLock> mpToolBarManagerLock; + bool mbMainViewSwitchUpdatePending; + + void HandleUpdateStart (void); + void HandleUpdateEnd (void); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolPanelModule.cxx b/sd/source/ui/framework/module/ToolPanelModule.cxx new file mode 100644 index 000000000000..28cab37951a5 --- /dev/null +++ b/sd/source/ui/framework/module/ToolPanelModule.cxx @@ -0,0 +1,165 @@ +/* -*- 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 2008 by Sun Microsystems, Inc. + * + * 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 "ToolPanelModule.hxx" +#include "ReadOnlyModeObserver.hxx" +#include "framework/FrameworkHelper.hxx" + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/compbase1.hxx> +#include <boost/enable_shared_from_this.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + + +namespace sd { namespace framework { + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + ::com::sun::star::frame::XStatusListener + > LocalReadOnlyModeObserverInterfaceBase; + +/** This local class enables or disables the ResourceManager of a + ToolPanelModule. It connects to a ReadOnlyModeObserver and is called + when the state of the .uno:EditDoc command changes. When either the + ResourceManager or the ReadOnlyModeObserver are disposed then the + LocalReadOnlyModeObserver disposes itself. The link + between the ResourceManager and the ReadOnlyModeObserver is removed and + the ReadOnlyModeObserver typically looses its last reference and is + destroyed. +*/ +class LocalReadOnlyModeObserver + : private MutexOwner, + public LocalReadOnlyModeObserverInterfaceBase +{ +public: + LocalReadOnlyModeObserver ( + const Reference<frame::XController>& rxController, + const ::rtl::Reference<ResourceManager>& rpResourceManager) + : MutexOwner(), + LocalReadOnlyModeObserverInterfaceBase(maMutex), + mpResourceManager(rpResourceManager), + mpObserver(new ReadOnlyModeObserver(rxController)) + { + mpObserver->AddStatusListener(this); + + Reference<lang::XComponent> xComponent ( + static_cast<XWeak*>(mpResourceManager.get()), UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(this); + } + + ~LocalReadOnlyModeObserver (void) + { + } + + virtual void SAL_CALL disposing (void) + { + Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpObserver.get()), UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + + xComponent = Reference<lang::XComponent>( + static_cast<XWeak*>(mpResourceManager.get()), UNO_QUERY); + if (xComponent.is()) + xComponent->removeEventListener(this); + + } + + virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& rEvent) + throw(RuntimeException) + { + if (rEvent.Source == Reference<XInterface>(static_cast<XWeak*>(mpObserver.get()))) + { + mpObserver = NULL; + } + else if (rEvent.Source == Reference<XInterface>( + static_cast<XWeak*>(mpResourceManager.get()))) + { + mpResourceManager = NULL; + } + dispose(); + } + + virtual void SAL_CALL statusChanged (const com::sun::star::frame::FeatureStateEvent& rEvent) + throw(RuntimeException) + { + bool bReadWrite (true); + if (rEvent.IsEnabled) + rEvent.State >>= bReadWrite; + + if (bReadWrite) + mpResourceManager->Enable(); + else + mpResourceManager->Disable(); + } + +private: + ::rtl::Reference<ResourceManager> mpResourceManager; + ::rtl::Reference<ReadOnlyModeObserver> mpObserver; + +}; +} + + + + +//===== ToolPanelModule ==================================================== + +void ToolPanelModule::Initialize (const Reference<frame::XController>& rxController) +{ + ::rtl::Reference<ResourceManager> pResourceManager ( + new ResourceManager( + rxController, + FrameworkHelper::CreateResourceId( + FrameworkHelper::msTaskPaneURL, + FrameworkHelper::msRightPaneURL))); + pResourceManager->AddActiveMainView(FrameworkHelper::msImpressViewURL); + pResourceManager->AddActiveMainView(FrameworkHelper::msNotesViewURL); + pResourceManager->AddActiveMainView(FrameworkHelper::msHandoutViewURL); + pResourceManager->AddActiveMainView(FrameworkHelper::msSlideSorterURL); + + new LocalReadOnlyModeObserver(rxController, pResourceManager); +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolPanelModule.hxx b/sd/source/ui/framework/module/ToolPanelModule.hxx new file mode 100644 index 000000000000..fbf902f6a49e --- /dev/null +++ b/sd/source/ui/framework/module/ToolPanelModule.hxx @@ -0,0 +1,52 @@ +/* -*- 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. + * +************************************************************************/ + +#ifndef SD_FRAMEWORK_TOOL_PANEL_MODULE_HXX +#define SD_FRAMEWORK_TOOL_PANEL_MODULE_HXX + +#include "ResourceManager.hxx" + +#include <rtl/ref.hxx> + +namespace sd { namespace framework { + +class ReadOnlyModeObserver; + +/** This module is responsible for showing the task pane. +*/ +class ToolPanelModule +{ +public: + static void Initialize ( + const ::com::sun::star::uno::Reference<com::sun::star::frame::XController>& rxController); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ViewTabBarModule.cxx b/sd/source/ui/framework/module/ViewTabBarModule.cxx new file mode 100644 index 000000000000..6c80afdeb1cc --- /dev/null +++ b/sd/source/ui/framework/module/ViewTabBarModule.cxx @@ -0,0 +1,223 @@ +/* -*- 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "ViewTabBarModule.hxx" + +#include "framework/FrameworkHelper.hxx" +#include "framework/ConfigurationController.hxx" +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XTabBar.hpp> + +#include "strings.hrc" +#include "sdresid.hxx" + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +namespace { + +static const sal_Int32 ResourceActivationRequestEvent = 0; +static const sal_Int32 ResourceDeactivationRequestEvent = 1; +static const sal_Int32 ResourceActivationEvent = 2; + +} + +namespace sd { namespace framework { + +//===== ViewTabBarModule ================================================== + +ViewTabBarModule::ViewTabBarModule ( + const Reference<frame::XController>& rxController, + const Reference<XResourceId>& rxViewTabBarId) + : ViewTabBarModuleInterfaceBase(MutexOwner::maMutex), + mxConfigurationController(), + mxViewTabBarId(rxViewTabBarId) +{ + Reference<XControllerManager> xControllerManager (rxController, UNO_QUERY); + + if (xControllerManager.is()) + { + mxConfigurationController = xControllerManager->getConfigurationController(); + if (mxConfigurationController.is()) + { + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationRequestEvent, + makeAny(ResourceActivationRequestEvent)); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceDeactivationRequestEvent, + makeAny(ResourceDeactivationRequestEvent)); + + UpdateViewTabBar(NULL); + mxConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationEvent, + makeAny(ResourceActivationEvent)); + } + } +} + + + + +ViewTabBarModule::~ViewTabBarModule (void) +{ +} + + + + +void SAL_CALL ViewTabBarModule::disposing (void) +{ + if (mxConfigurationController.is()) + mxConfigurationController->removeConfigurationChangeListener(this); + + mxConfigurationController = NULL; +} + + + + +void SAL_CALL ViewTabBarModule::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is()) + { + sal_Int32 nEventType = 0; + rEvent.UserData >>= nEventType; + switch (nEventType) + { + case ResourceActivationRequestEvent: + if (mxViewTabBarId->isBoundTo(rEvent.ResourceId, AnchorBindingMode_DIRECT)) + { + mxConfigurationController->requestResourceActivation( + mxViewTabBarId, + ResourceActivationMode_ADD); + } + break; + + case ResourceDeactivationRequestEvent: + if (mxViewTabBarId->isBoundTo(rEvent.ResourceId, AnchorBindingMode_DIRECT)) + { + mxConfigurationController->requestResourceDeactivation(mxViewTabBarId); + } + break; + + case ResourceActivationEvent: + if (rEvent.ResourceId->compareTo(mxViewTabBarId) == 0) + { + UpdateViewTabBar(Reference<XTabBar>(rEvent.ResourceObject,UNO_QUERY)); + } + } + } +} + + + + +void SAL_CALL ViewTabBarModule::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (mxConfigurationController.is() + && rEvent.Source == mxConfigurationController) + { + // Without the configuration controller this class can do nothing. + mxConfigurationController = NULL; + disposing(); + } +} + + + + +void ViewTabBarModule::UpdateViewTabBar (const Reference<XTabBar>& rxTabBar) +{ + if (mxConfigurationController.is()) + { + Reference<XTabBar> xBar (rxTabBar); + if ( ! xBar.is()) + xBar = Reference<XTabBar>( + mxConfigurationController->getResource(mxViewTabBarId), UNO_QUERY); + + if (xBar.is()) + { + TabBarButton aEmptyButton; + + Reference<XResourceId> xAnchor (mxViewTabBarId->getAnchor()); + + TabBarButton aImpressViewButton; + aImpressViewButton.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msImpressViewURL, + xAnchor); + aImpressViewButton.ButtonLabel = String(SdResId(STR_DRAW_MODE)); + if ( ! xBar->hasTabBarButton(aImpressViewButton)) + xBar->addTabBarButtonAfter(aImpressViewButton, aEmptyButton); + + TabBarButton aOutlineViewButton; + aOutlineViewButton.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msOutlineViewURL, + xAnchor); + aOutlineViewButton.ButtonLabel = String(SdResId(STR_OUTLINE_MODE)); + if ( ! xBar->hasTabBarButton(aOutlineViewButton)) + xBar->addTabBarButtonAfter(aOutlineViewButton, aImpressViewButton); + + TabBarButton aNotesViewButton; + aNotesViewButton.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msNotesViewURL, + xAnchor); + aNotesViewButton.ButtonLabel = String(SdResId(STR_NOTES_MODE)); + if ( ! xBar->hasTabBarButton(aNotesViewButton)) + xBar->addTabBarButtonAfter(aNotesViewButton, aOutlineViewButton); + + TabBarButton aHandoutViewButton; + aHandoutViewButton.ResourceId = FrameworkHelper::CreateResourceId( + FrameworkHelper::msHandoutViewURL, + xAnchor); + aHandoutViewButton.ButtonLabel = String(SdResId(STR_HANDOUT_MODE)); + if ( ! xBar->hasTabBarButton(aHandoutViewButton)) + xBar->addTabBarButtonAfter(aHandoutViewButton, aNotesViewButton); + } + } +} + + + + +} } // end of namespace sd::framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ViewTabBarModule.hxx b/sd/source/ui/framework/module/ViewTabBarModule.hxx new file mode 100644 index 000000000000..067375f07b9d --- /dev/null +++ b/sd/source/ui/framework/module/ViewTabBarModule.hxx @@ -0,0 +1,110 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef SD_FRAMEWORK_VIEW_TAB_BAR_MODULE_HXX +#define SD_FRAMEWORK_VIEW_TAB_BAR_MODULE_HXX + +#include "MutexOwner.hxx" + +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XTabBar.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/compbase1.hxx> + +namespace css = ::com::sun::star; + +namespace { + +typedef ::cppu::WeakComponentImplHelper1 < + ::css::drawing::framework::XConfigurationChangeListener + > ViewTabBarModuleInterfaceBase; + +} // end of anonymous namespace. + + + + +namespace sd { namespace framework { + +/** This module is responsible for showing the ViewTabBar above the view in + the center pane. +*/ +class ViewTabBarModule + : private sd::MutexOwner, + public ViewTabBarModuleInterfaceBase +{ +public: + /** Create a new module that controlls the view tab bar above the view + in the specified pane. + @param rxController + This is the access point to the drawing framework. + @param rxViewTabBarId + This ResourceId specifies which tab bar is to be managed by the + new module. + */ + ViewTabBarModule ( + const css::uno::Reference<css::frame::XController>& rxController, + const css::uno::Reference< + css::drawing::framework::XResourceId>& rxViewTabBarId); + virtual ~ViewTabBarModule (void); + + virtual void SAL_CALL disposing (void); + + + // XConfigurationChangeListener + + virtual void SAL_CALL notifyConfigurationChange ( + const css::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (css::uno::RuntimeException); + + // XEventListener + + virtual void SAL_CALL disposing ( + const css::lang::EventObject& rEvent) + throw (css::uno::RuntimeException); + +private: + css::uno::Reference< + css::drawing::framework::XConfigurationController> mxConfigurationController; + css::uno::Reference<css::drawing::framework::XResourceId> mxViewTabBarId; + + /** This is the place where the view tab bar is filled. Only missing + buttons are added, so it is safe to call this method multiple + times. + */ + void UpdateViewTabBar ( + const css::uno::Reference<css::drawing::framework::XTabBar>& rxTabBar); +}; + +} } // end of namespace sd::framework + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/makefile.mk b/sd/source/ui/framework/module/makefile.mk new file mode 100755 index 000000000000..bec9b1a04075 --- /dev/null +++ b/sd/source/ui/framework/module/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=framework_module +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true +PRJINC=..$/.. + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/CenterViewFocusModule.obj \ + $(SLO)$/DrawModule.obj \ + $(SLO)$/ImpressModule.obj \ + $(SLO)$/ModuleController.obj \ + $(SLO)$/PresentationModule.obj \ + $(SLO)$/ReadOnlyModeObserver.obj \ + $(SLO)$/ResourceManager.obj \ + $(SLO)$/ShellStackGuard.obj \ + $(SLO)$/SlideSorterModule.obj \ + $(SLO)$/ToolPanelModule.obj \ + $(SLO)$/ToolBarModule.obj \ + $(SLO)$/ViewTabBarModule.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx new file mode 100644 index 000000000000..47465f364398 --- /dev/null +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -0,0 +1,1222 @@ +/* -*- 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. + * + ************************************************************************/ + +#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( + RTL_CONSTASCII_USTRINGPARAM("private:resource/pane/")); +const OUString FrameworkHelper::msCenterPaneURL( + msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("CenterPane"))); +const OUString FrameworkHelper::msFullScreenPaneURL( + msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("FullScreenPane"))); +const OUString FrameworkHelper::msLeftImpressPaneURL( + msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("LeftImpressPane"))); +const OUString FrameworkHelper::msLeftDrawPaneURL( + msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("LeftDrawPane"))); +const OUString FrameworkHelper::msRightPaneURL( + msPaneURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("RightPane"))); + + +// View URLs. + +const OUString FrameworkHelper::msViewURLPrefix( + RTL_CONSTASCII_USTRINGPARAM("private:resource/view/")); +const OUString FrameworkHelper::msImpressViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("ImpressView"))); +const OUString FrameworkHelper::msDrawViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicView"))); +const OUString FrameworkHelper::msOutlineViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("OutlineView"))); +const OUString FrameworkHelper::msNotesViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("NotesView"))); +const OUString FrameworkHelper::msHandoutViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("HandoutView"))); +const OUString FrameworkHelper::msSlideSorterURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("SlideSorter"))); +const OUString FrameworkHelper::msPresentationViewURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("PresentationView"))); +const OUString FrameworkHelper::msTaskPaneURL( + msViewURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("TaskPane"))); + + +// Tool bar URLs. + +const OUString FrameworkHelper::msToolBarURLPrefix( + RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/")); +const OUString FrameworkHelper::msViewTabBarURL( + msToolBarURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("ViewTabBar"))); + + +// Task panel URLs. +const ::rtl::OUString FrameworkHelper::msTaskPanelURLPrefix( + RTL_CONSTASCII_USTRINGPARAM("private:resource/toolpanel/DrawingFramework/")); +const ::rtl::OUString FrameworkHelper::msMasterPagesTaskPanelURL( + msTaskPanelURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("MasterPages"))); +const ::rtl::OUString FrameworkHelper::msLayoutTaskPanelURL( + msTaskPanelURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("Layouts"))); +const ::rtl::OUString FrameworkHelper::msTableDesignPanelURL( + msTaskPanelURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("TableDesign"))); +const ::rtl::OUString FrameworkHelper::msCustomAnimationTaskPanelURL( + msTaskPanelURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("CustomAnimations"))); +const ::rtl::OUString FrameworkHelper::msSlideTransitionTaskPanelURL( + msTaskPanelURLPrefix + OUString(RTL_CONSTASCII_USTRINGPARAM("SlideTransitions"))); + + +// Event URLs. +const OUString FrameworkHelper::msResourceActivationRequestEvent( + RTL_CONSTASCII_USTRINGPARAM("ResourceActivationRequested")); +const OUString FrameworkHelper::msResourceDeactivationRequestEvent( + RTL_CONSTASCII_USTRINGPARAM("ResourceDeactivationRequest")); +const OUString FrameworkHelper::msResourceActivationEvent( + RTL_CONSTASCII_USTRINGPARAM("ResourceActivation")); +const OUString FrameworkHelper::msResourceDeactivationEvent( + RTL_CONSTASCII_USTRINGPARAM("ResourceDeactivation")); +const OUString FrameworkHelper::msConfigurationUpdateStartEvent( + RTL_CONSTASCII_USTRINGPARAM("ConfigurationUpdateStart")); +const OUString FrameworkHelper::msConfigurationUpdateEndEvent( + RTL_CONSTASCII_USTRINGPARAM("ConfigurationUpdateEnd")); + + +// Service names of controllers. +const OUString FrameworkHelper::msModuleControllerService( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.framework.ModuleController")); +const OUString FrameworkHelper::msConfigurationControllerService( + RTL_CONSTASCII_USTRINGPARAM("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) const {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(RTL_CONSTASCII_USTRINGPARAM(" | ")); + 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. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/tools/makefile.mk b/sd/source/ui/framework/tools/makefile.mk new file mode 100644 index 000000000000..b09d0fa19b25 --- /dev/null +++ b/sd/source/ui/framework/tools/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=framework_tools +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true +PRJINC=..$/.. + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/FrameworkHelper.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + |