diff options
Diffstat (limited to 'sd/source/ui/tools')
-rw-r--r-- | sd/source/ui/tools/AsynchronousCall.cxx | 82 | ||||
-rw-r--r-- | sd/source/ui/tools/ConfigurationAccess.cxx | 231 | ||||
-rw-r--r-- | sd/source/ui/tools/EventMultiplexer.cxx | 823 | ||||
-rw-r--r-- | sd/source/ui/tools/IconCache.cxx | 133 | ||||
-rw-r--r-- | sd/source/ui/tools/IdleDetection.cxx | 130 | ||||
-rw-r--r-- | sd/source/ui/tools/PreviewRenderer.cxx | 501 | ||||
-rw-r--r-- | sd/source/ui/tools/PropertySet.cxx | 248 | ||||
-rw-r--r-- | sd/source/ui/tools/SdGlobalResourceContainer.cxx | 240 | ||||
-rw-r--r-- | sd/source/ui/tools/SlotStateListener.cxx | 243 | ||||
-rw-r--r-- | sd/source/ui/tools/TimerBasedTaskExecution.cxx | 180 | ||||
-rw-r--r-- | sd/source/ui/tools/makefile.mk | 61 |
11 files changed, 2872 insertions, 0 deletions
diff --git a/sd/source/ui/tools/AsynchronousCall.cxx b/sd/source/ui/tools/AsynchronousCall.cxx new file mode 100644 index 000000000000..3527b74fbeda --- /dev/null +++ b/sd/source/ui/tools/AsynchronousCall.cxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/AsynchronousCall.hxx" + +#include <boost/bind.hpp> +#include "DrawViewShell.hxx" + +namespace sd { namespace tools { + +AsynchronousCall::AsynchronousCall (void) + : maTimer(), + mpFunction() +{ + Link aCallback (LINK(this,AsynchronousCall,TimerCallback)); + maTimer.SetTimeoutHdl(aCallback); +} + + + + +AsynchronousCall::~AsynchronousCall (void) +{ + mpFunction.reset(); + maTimer.Stop(); +} + + + + +void AsynchronousCall::Post ( + const AsynchronousFunction& rFunction, + sal_uInt32 nTimeoutInMilliseconds) +{ + mpFunction.reset(new AsynchronousFunction(rFunction)); + maTimer.SetTimeout(nTimeoutInMilliseconds); + maTimer.Start(); +} + + + + +IMPL_LINK(AsynchronousCall,TimerCallback,Timer*,pTimer) +{ + if (pTimer == &maTimer) + { + ::std::auto_ptr<AsynchronousFunction> pFunction (mpFunction); + mpFunction.reset(); + (*pFunction)(); + } + return 0; +} + + +} } // end of namespace ::sd::tools diff --git a/sd/source/ui/tools/ConfigurationAccess.cxx b/sd/source/ui/tools/ConfigurationAccess.cxx new file mode 100644 index 000000000000..94ada78461ec --- /dev/null +++ b/sd/source/ui/tools/ConfigurationAccess.cxx @@ -0,0 +1,231 @@ +/************************************************************************* + * + * 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 "tools/ConfigurationAccess.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <comphelper/processfactory.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::rtl::OUString; + +namespace sd { namespace tools { + +ConfigurationAccess::ConfigurationAccess ( + const Reference<XComponentContext>& rxContext, + const OUString& rsRootName, + const WriteMode eMode) + : mxRoot() +{ + Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); + if (xFactory.is()) + { + Reference<lang::XMultiServiceFactory> xProvider ( + xFactory->createInstanceWithContext( + OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"), + rxContext), + UNO_QUERY); + if (xProvider.is()) + Initialize(xProvider, rsRootName, eMode); + } +} + + + + +ConfigurationAccess::ConfigurationAccess ( + const OUString& rsRootName, + const WriteMode eMode) + : mxRoot() +{ + Reference<lang::XMultiServiceFactory> xProvider ( + ::comphelper::getProcessServiceFactory()->createInstance( + OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), + UNO_QUERY); + if (xProvider.is()) + Initialize(xProvider, rsRootName, eMode); +} + + + + +void ConfigurationAccess::Initialize ( + const Reference<lang::XMultiServiceFactory>& rxProvider, + const OUString& rsRootName, + const WriteMode eMode) +{ + try + { + Sequence<Any> aCreationArguments(3); + aCreationArguments[0] = makeAny(beans::PropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")), + 0, + makeAny(rsRootName), + beans::PropertyState_DIRECT_VALUE)); + aCreationArguments[1] = makeAny(beans::PropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("depth")), + 0, + makeAny((sal_Int32)-1), + beans::PropertyState_DIRECT_VALUE)); + aCreationArguments[2] = makeAny(beans::PropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("lazywrite")), + 0, + makeAny(true), + beans::PropertyState_DIRECT_VALUE)); + OUString sAccessService; + if (eMode == READ_ONLY) + sAccessService = OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess")); + else + sAccessService = OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationUpdateAccess")); + + mxRoot = rxProvider->createInstanceWithArguments( + sAccessService, + aCreationArguments); + } + catch (Exception& rException) + { + OSL_TRACE ("caught exception while opening configuration: %s", + ::rtl::OUStringToOString(rException.Message, + RTL_TEXTENCODING_UTF8).getStr()); + } +} + + + + +Any ConfigurationAccess::GetConfigurationNode ( + const OUString& sPathToNode) +{ + return GetConfigurationNode( + Reference<container::XHierarchicalNameAccess>(mxRoot, UNO_QUERY), + sPathToNode); +} + + + + +Any ConfigurationAccess::GetConfigurationNode ( + const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, + const OUString& sPathToNode) +{ + if (sPathToNode.getLength() == 0) + return Any(rxNode); + + try + { + if (rxNode.is()) + { + return rxNode->getByHierarchicalName(sPathToNode); + } + } + catch (Exception& rException) + { + OSL_TRACE ("caught exception while getting configuration node %s: %s", + ::rtl::OUStringToOString(sPathToNode, RTL_TEXTENCODING_UTF8).getStr(), + ::rtl::OUStringToOString(rException.Message, RTL_TEXTENCODING_UTF8).getStr()); + } + + return Any(); +} + + + + +void ConfigurationAccess::CommitChanges (void) +{ + Reference<util::XChangesBatch> xConfiguration (mxRoot, UNO_QUERY); + if (xConfiguration.is()) + xConfiguration->commitChanges(); +} + + + + +void ConfigurationAccess::ForAll ( + const Reference<container::XNameAccess>& rxContainer, + const ::std::vector<OUString>& rArguments, + const Functor& rFunctor) +{ + if (rxContainer.is()) + { + ::std::vector<Any> aValues(rArguments.size()); + Sequence<OUString> aKeys (rxContainer->getElementNames()); + for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex) + { + const OUString& rsKey (aKeys[nItemIndex]); + Reference<container::XNameAccess> xSetItem (rxContainer->getByName(rsKey), UNO_QUERY); + if (xSetItem.is()) + { + // Get from the current item of the container the children + // that match the names in the rArguments list. + for (sal_uInt32 nValueIndex=0; nValueIndex<aValues.size(); ++nValueIndex) + aValues[nValueIndex] = xSetItem->getByName(rArguments[nValueIndex]); + } + rFunctor(rsKey, aValues); + } + } +} + + + + +void ConfigurationAccess::FillList( + const Reference<container::XNameAccess>& rxContainer, + const ::rtl::OUString& rsArgument, + ::std::vector<OUString>& rList) +{ + try + { + if (rxContainer.is()) + { + Sequence<OUString> aKeys (rxContainer->getElementNames()); + rList.resize(aKeys.getLength()); + for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex) + { + Reference<container::XNameAccess> xSetItem ( + rxContainer->getByName(aKeys[nItemIndex]), UNO_QUERY); + if (xSetItem.is()) + { + xSetItem->getByName(rsArgument) >>= rList[nItemIndex]; + } + } + } + } + catch (RuntimeException&) + {} +} + + +} } // end of namespace sd::tools + diff --git a/sd/source/ui/tools/EventMultiplexer.cxx b/sd/source/ui/tools/EventMultiplexer.cxx new file mode 100644 index 000000000000..8d6bd5f6b4bc --- /dev/null +++ b/sd/source/ui/tools/EventMultiplexer.cxx @@ -0,0 +1,823 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "EventMultiplexer.hxx" + +#include "MutexOwner.hxx" +#include "ViewShellBase.hxx" +#include "drawdoc.hxx" +#include "DrawController.hxx" +#include "SlideSorterViewShell.hxx" +#include "framework/FrameworkHelper.hxx" + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/compbase4.hxx> +#include <sfx2/viewfrm.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::rtl::OUString; +using ::sd::framework::FrameworkHelper; + +class SdDrawDocument; + +namespace { +static const sal_Int32 ResourceActivationEvent = 0; +static const sal_Int32 ResourceDeactivationEvent = 1; +static const sal_Int32 ConfigurationUpdateEvent = 2; +} + +namespace sd { namespace tools { + +typedef cppu::WeakComponentImplHelper4< + ::com::sun::star::beans::XPropertyChangeListener, + ::com::sun::star::frame::XFrameActionListener, + ::com::sun::star::view::XSelectionChangeListener, + ::com::sun::star::drawing::framework::XConfigurationChangeListener + > EventMultiplexerImplementationInterfaceBase; + +class EventMultiplexer::Implementation + : protected MutexOwner, + public EventMultiplexerImplementationInterfaceBase, + public SfxListener +{ +public: + Implementation (ViewShellBase& rBase); + ~Implementation (void); + + void AddEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes); + + void RemoveEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes); + + void CallListeners (EventMultiplexerEvent& rEvent); + + ViewShellBase& GetViewShellBase() const { return mrBase; } + + //===== lang::XEventListener ============================================== + virtual void SAL_CALL + disposing (const ::com::sun::star::lang::EventObject& rEventObject) + throw (::com::sun::star::uno::RuntimeException); + + + //===== beans::XPropertySetListener ======================================= + virtual void SAL_CALL + propertyChange ( + const com::sun::star::beans::PropertyChangeEvent& rEvent) + throw (::com::sun::star::uno::RuntimeException); + + //===== view::XSelectionChangeListener ==================================== + virtual void SAL_CALL + selectionChanged ( + const com::sun::star::lang::EventObject& rEvent) + throw (::com::sun::star::uno::RuntimeException); + + //===== frame::XFrameActionListener ====================================== + /** For certain actions the listener connects to a new controller of the + frame it is listening to. This usually happens when the view shell + in the center pane is replaced by another view shell. + */ + virtual void SAL_CALL + frameAction (const ::com::sun::star::frame::FrameActionEvent& rEvent) + throw (::com::sun::star::uno::RuntimeException); + + //===== drawing::framework::XConfigurationChangeListener ================== + virtual void SAL_CALL + notifyConfigurationChange ( + const ::com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent) + throw (::com::sun::star::uno::RuntimeException); + + + virtual void SAL_CALL disposing (void); + +protected: + virtual void Notify ( + SfxBroadcaster& rBroadcaster, + const SfxHint& rHint); + +private: + ViewShellBase& mrBase; + typedef ::std::pair<Link,EventMultiplexerEvent::EventId> ListenerDescriptor; + typedef ::std::vector<ListenerDescriptor> ListenerList; + ListenerList maListeners; + + /// Remember whether we are listening to the UNO controller. + bool mbListeningToController; + /// Remember whether we are listening to the frame. + bool mbListeningToFrame; + + ::com::sun::star::uno::WeakReference< + ::com::sun::star::frame::XController> mxControllerWeak; + ::com::sun::star::uno::WeakReference< + ::com::sun::star::frame::XFrame> mxFrameWeak; + ::com::sun::star::uno::WeakReference< + ::com::sun::star::view::XSelectionSupplier> mxSlideSorterSelectionWeak; + SdDrawDocument* mpDocument; + ::com::sun::star::uno::WeakReference< + ::com::sun::star::drawing::framework::XConfigurationController> + mxConfigurationControllerWeak; + + static const ::rtl::OUString msCurrentPagePropertyName; + static const ::rtl::OUString msEditModePropertyName; + + void ReleaseListeners (void); + + void ConnectToController (void); + void DisconnectFromController (void); + + void CallListeners ( + EventMultiplexerEvent::EventId eId, + void* pUserData = NULL); + + /** This method throws a DisposedException when the object has already been + disposed. + */ + void ThrowIfDisposed (void) + throw (::com::sun::star::lang::DisposedException); + + DECL_LINK(SlideSorterSelectionChangeListener, void*); +}; + + +const ::rtl::OUString EventMultiplexer::Implementation::msCurrentPagePropertyName ( + RTL_CONSTASCII_USTRINGPARAM("CurrentPage")); +const ::rtl::OUString EventMultiplexer::Implementation::msEditModePropertyName ( + RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode")); + + +//===== EventMultiplexer ====================================================== + +EventMultiplexer::EventMultiplexer (ViewShellBase& rBase) + : mpImpl (new EventMultiplexer::Implementation(rBase)) +{ + mpImpl->acquire(); +} + + + + +EventMultiplexer::~EventMultiplexer (void) +{ + try + { + mpImpl->dispose(); + // Now we call release twice. One decreases the use count of the + // implementation object (if all goes well to zero and thus deletes + // it.) The other releases the auto_ptr and prevents the + // implementation object from being deleted a second time. + mpImpl->release(); + mpImpl.release(); + } + catch (RuntimeException aException) + { + } + catch (Exception aException) + { + } +} + + + + +void EventMultiplexer::AddEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes) +{ + mpImpl->AddEventListener (rCallback, aEventTypes); +} + + + + +void EventMultiplexer::RemoveEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes) +{ + mpImpl->RemoveEventListener (rCallback, aEventTypes); +} + + + + +void EventMultiplexer::MultiplexEvent( + EventMultiplexerEvent::EventId eEventId, + void* pUserData ) +{ + EventMultiplexerEvent aEvent (mpImpl->GetViewShellBase(), eEventId, pUserData); + mpImpl->CallListeners(aEvent); +} + + + + +//===== EventMultiplexer::Implementation ====================================== + +EventMultiplexer::Implementation::Implementation (ViewShellBase& rBase) + : MutexOwner(), + EventMultiplexerImplementationInterfaceBase(maMutex), + SfxListener(), + mrBase (rBase), + mbListeningToController (false), + mbListeningToFrame (false), + mxControllerWeak(NULL), + mxFrameWeak(NULL), + mxSlideSorterSelectionWeak(NULL), + mpDocument(NULL), + mxConfigurationControllerWeak() +{ + // Connect to the frame to listen for controllers being exchanged. + // Listen to changes of certain properties. + Reference<frame::XFrame> xFrame ( + mrBase.GetFrame()->GetTopFrame()->GetFrameInterface(), + uno::UNO_QUERY); + mxFrameWeak = xFrame; + if (xFrame.is()) + { + xFrame->addFrameActionListener ( + Reference<frame::XFrameActionListener>( + static_cast<XWeak*>(this), UNO_QUERY)); + mbListeningToFrame = true; + } + + // Connect to the current controller. + ConnectToController (); + + // Listen for document changes. + mpDocument = mrBase.GetDocument(); + if (mpDocument != NULL) + StartListening (*mpDocument); + + // Listen for configuration changes. + Reference<XControllerManager> xControllerManager ( + Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY); + if (xControllerManager.is()) + { + Reference<XConfigurationController> xConfigurationController ( + xControllerManager->getConfigurationController()); + mxConfigurationControllerWeak = xConfigurationController; + if (xConfigurationController.is()) + { + Reference<XComponent> xComponent (xConfigurationController, UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(static_cast<beans::XPropertyChangeListener*>(this)); + + xConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceActivationEvent, + makeAny(ResourceActivationEvent)); + xConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msResourceDeactivationEvent, + makeAny(ResourceDeactivationEvent)); + xConfigurationController->addConfigurationChangeListener( + this, + FrameworkHelper::msConfigurationUpdateEndEvent, + makeAny(ConfigurationUpdateEvent)); + } + } +} + + + + +EventMultiplexer::Implementation::~Implementation (void) +{ + DBG_ASSERT( !mbListeningToFrame, + "sd::EventMultiplexer::Implementation::~Implementation(), disposing was not called!" ); +} + + + + +void EventMultiplexer::Implementation::ReleaseListeners (void) +{ + if (mbListeningToFrame) + { + mbListeningToFrame = false; + + // Stop listening for changes of certain properties. + Reference<frame::XFrame> xFrame (mxFrameWeak); + if (xFrame.is()) + { + xFrame->removeFrameActionListener ( + Reference<frame::XFrameActionListener>( + static_cast<XWeak*>(this), UNO_QUERY)); + } + } + + DisconnectFromController (); + + if (mpDocument != NULL) + { + EndListening (*mpDocument); + mpDocument = NULL; + } + + // Stop listening for configuration changes. + Reference<XConfigurationController> xConfigurationController (mxConfigurationControllerWeak); + if (xConfigurationController.is()) + { + Reference<XComponent> xComponent (xConfigurationController, UNO_QUERY); + if (xComponent.is()) + xComponent->removeEventListener(static_cast<beans::XPropertyChangeListener*>(this)); + + xConfigurationController->removeConfigurationChangeListener(this); + } +} + + + + +void EventMultiplexer::Implementation::AddEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes) +{ + ListenerList::iterator iListener (maListeners.begin()); + ListenerList::const_iterator iEnd (maListeners.end()); + for (;iListener!=iEnd; ++iListener) + if (iListener->first == rCallback) + break; + if (iListener != maListeners.end()) + { + // Listener exists. Update its event type set. + iListener->second |= aEventTypes; + } + else + { + maListeners.push_back (ListenerDescriptor(rCallback,aEventTypes)); + } +} + + + + +void EventMultiplexer::Implementation::RemoveEventListener ( + Link& rCallback, + EventMultiplexerEvent::EventId aEventTypes) +{ + ListenerList::iterator iListener (maListeners.begin()); + ListenerList::const_iterator iEnd (maListeners.end()); + for (;iListener!=iEnd; ++iListener) + if (iListener->first == rCallback) + break; + if (iListener != maListeners.end()) + { + // Update the event type set. + iListener->second &= ~aEventTypes; + // When no events remain in the set then remove the listener. + if (iListener->second == EID_EMPTY_SET) + maListeners.erase (iListener); + } +} + + + + +void EventMultiplexer::Implementation::ConnectToController (void) +{ + // Just in case that we missed some event we now disconnect from the old + // controller. + DisconnectFromController (); + + // Register at the controller of the main view shell. + + // We have to store a (weak) reference to the controller so that we can + // unregister without having to ask the mrBase member (which at that + // time may be destroyed.) + Reference<frame::XController> xController = mrBase.GetController(); + mxControllerWeak = mrBase.GetController(); + + try + { + // Listen for disposing events. + Reference<lang::XComponent> xComponent (xController, UNO_QUERY); + if (xComponent.is()) + { + xComponent->addEventListener ( + Reference<lang::XEventListener>( + static_cast<XWeak*>(this), UNO_QUERY)); + mbListeningToController = true; + } + + // Listen to changes of certain properties. + Reference<beans::XPropertySet> xSet (xController, UNO_QUERY); + if (xSet.is()) + { + try + { + xSet->addPropertyChangeListener(msCurrentPagePropertyName, this); + } + catch (beans::UnknownPropertyException) + { + OSL_TRACE("EventMultiplexer::ConnectToController: CurrentPage unknown"); + } + + try + { + xSet->addPropertyChangeListener(msEditModePropertyName, this); + } + catch (beans::UnknownPropertyException) + { + OSL_TRACE("EventMultiplexer::ConnectToController: IsMasterPageMode unknown"); + } + } + + // Listen for selection change events. + Reference<view::XSelectionSupplier> xSelection (xController, UNO_QUERY); + if (xSelection.is()) + { + xSelection->addSelectionChangeListener(this); + } + } + catch (const lang::DisposedException aException) + { + mbListeningToController = false; + } +} + + + + +void EventMultiplexer::Implementation::DisconnectFromController (void) +{ + if (mbListeningToController) + { + mbListeningToController = false; + + Reference<frame::XController> xController = mxControllerWeak; + + Reference<beans::XPropertySet> xSet (xController, UNO_QUERY); + // Remove the property listener. + if (xSet.is()) + { + try + { + xSet->removePropertyChangeListener(msCurrentPagePropertyName, this); + } + catch (beans::UnknownPropertyException aEvent) + { + OSL_TRACE ("DisconnectFromController: CurrentPage unknown"); + } + + try + { + xSet->removePropertyChangeListener(msEditModePropertyName, this); + } + catch (beans::UnknownPropertyException aEvent) + { + OSL_TRACE ("DisconnectFromController: IsMasterPageMode unknown"); + } + } + + // Remove selection change listener. + Reference<view::XSelectionSupplier> xSelection (xController, UNO_QUERY); + if (xSelection.is()) + { + xSelection->removeSelectionChangeListener(this); + } + + // Remove listener for disposing events. + Reference<lang::XComponent> xComponent (xController, UNO_QUERY); + if (xComponent.is()) + { + xComponent->removeEventListener ( + Reference<lang::XEventListener>(static_cast<XWeak*>(this), UNO_QUERY)); + } + } +} + + + + +//===== lang::XEventListener ================================================ + +void SAL_CALL EventMultiplexer::Implementation::disposing ( + const lang::EventObject& rEventObject) + throw (RuntimeException) +{ + if (mbListeningToController) + { + Reference<frame::XController> xController (mxControllerWeak); + if (rEventObject.Source == xController) + { + mbListeningToController = false; + } + } + + Reference<XConfigurationController> xConfigurationController ( + mxConfigurationControllerWeak); + if (xConfigurationController.is() + && rEventObject.Source == xConfigurationController) + { + mxConfigurationControllerWeak = Reference<XConfigurationController>(); + } +} + + + + +//===== beans::XPropertySetListener ========================================= + +void SAL_CALL EventMultiplexer::Implementation::propertyChange ( + const beans::PropertyChangeEvent& rEvent) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + if (rEvent.PropertyName.equals(msCurrentPagePropertyName)) + { + CallListeners(EventMultiplexerEvent::EID_CURRENT_PAGE); + } + else if (rEvent.PropertyName.equals(msEditModePropertyName)) + { + bool bIsMasterPageMode (false); + rEvent.NewValue >>= bIsMasterPageMode; + if (bIsMasterPageMode) + CallListeners(EventMultiplexerEvent::EID_EDIT_MODE_MASTER); + else + CallListeners(EventMultiplexerEvent::EID_EDIT_MODE_NORMAL); + } +} + + + + +//===== frame::XFrameActionListener ========================================== + +void SAL_CALL EventMultiplexer::Implementation::frameAction ( + const frame::FrameActionEvent& rEvent) + throw (::com::sun::star::uno::RuntimeException) +{ + Reference<frame::XFrame> xFrame (mxFrameWeak); + if (rEvent.Frame == xFrame) + switch (rEvent.Action) + { + case frame::FrameAction_COMPONENT_DETACHING: + DisconnectFromController(); + CallListeners (EventMultiplexerEvent::EID_CONTROLLER_DETACHED); + break; + + case frame::FrameAction_COMPONENT_REATTACHED: + CallListeners (EventMultiplexerEvent::EID_CONTROLLER_DETACHED); + DisconnectFromController(); + ConnectToController(); + CallListeners (EventMultiplexerEvent::EID_CONTROLLER_ATTACHED); + break; + + case frame::FrameAction_COMPONENT_ATTACHED: + ConnectToController(); + CallListeners (EventMultiplexerEvent::EID_CONTROLLER_ATTACHED); + break; + + default: + break; + } +} + + + + +//===== view::XSelectionChangeListener ======================================== + +void SAL_CALL EventMultiplexer::Implementation::selectionChanged ( + const lang::EventObject& ) + throw (::com::sun::star::uno::RuntimeException) +{ + CallListeners (EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION); +} + + + + +//===== drawing::framework::XConfigurationChangeListener ================== + +void SAL_CALL EventMultiplexer::Implementation::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + sal_Int32 nEventType = 0; + rEvent.UserData >>= nEventType; + switch (nEventType) + { + case ResourceActivationEvent: + if (rEvent.ResourceId->getResourceURL().match(FrameworkHelper::msViewURLPrefix)) + { + CallListeners (EventMultiplexerEvent::EID_VIEW_ADDED); + + if (rEvent.ResourceId->isBoundToURL( + FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)) + { + CallListeners (EventMultiplexerEvent::EID_MAIN_VIEW_ADDED); + } + + // Add selection change listener at slide sorter. + if (rEvent.ResourceId->getResourceURL().equals(FrameworkHelper::msSlideSorterURL)) + { + slidesorter::SlideSorterViewShell* pViewShell + = dynamic_cast<slidesorter::SlideSorterViewShell*>( + FrameworkHelper::GetViewShell( + Reference<XView>(rEvent.ResourceObject,UNO_QUERY)).get()); + if (pViewShell != NULL) + pViewShell->AddSelectionChangeListener ( + LINK(this, + EventMultiplexer::Implementation, + SlideSorterSelectionChangeListener)); + } + } + break; + + case ResourceDeactivationEvent: + if (rEvent.ResourceId->getResourceURL().match(FrameworkHelper::msViewURLPrefix)) + { + CallListeners (EventMultiplexerEvent::EID_VIEW_REMOVED); + + if (rEvent.ResourceId->isBoundToURL( + FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)) + { + CallListeners (EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED); + } + + // Remove selection change listener from slide sorter. Add + // selection change listener at slide sorter. + if (rEvent.ResourceId->getResourceURL().equals(FrameworkHelper::msSlideSorterURL)) + { + slidesorter::SlideSorterViewShell* pViewShell + = dynamic_cast<slidesorter::SlideSorterViewShell*>( + FrameworkHelper::GetViewShell( + Reference<XView>(rEvent.ResourceObject, UNO_QUERY)).get()); + if (pViewShell != NULL) + pViewShell->RemoveSelectionChangeListener ( + LINK(this, + EventMultiplexer::Implementation, + SlideSorterSelectionChangeListener)); + } + } + break; + + case ConfigurationUpdateEvent: + CallListeners (EventMultiplexerEvent::EID_CONFIGURATION_UPDATED); + break; + } + +} + + + + +void SAL_CALL EventMultiplexer::Implementation::disposing (void) +{ + CallListeners (EventMultiplexerEvent::EID_DISPOSING); + ReleaseListeners(); +} + + + + +void EventMultiplexer::Implementation::ThrowIfDisposed (void) + throw (::com::sun::star::lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "SlideSorterController object has already been disposed")), + static_cast<uno::XWeak*>(this)); + } +} + + + + +void EventMultiplexer::Implementation::Notify ( + SfxBroadcaster&, + const SfxHint& rHint) +{ + if (rHint.ISA(SdrHint)) + { + SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint)); + switch (rSdrHint.GetKind()) + { + case HINT_MODELCLEARED: + case HINT_PAGEORDERCHG: + CallListeners (EventMultiplexerEvent::EID_PAGE_ORDER); + break; + + case HINT_SWITCHTOPAGE: + CallListeners (EventMultiplexerEvent::EID_CURRENT_PAGE); + break; + + case HINT_OBJCHG: + CallListeners(EventMultiplexerEvent::EID_SHAPE_CHANGED, + const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage()))); + break; + + case HINT_OBJINSERTED: + CallListeners(EventMultiplexerEvent::EID_SHAPE_INSERTED, + const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage()))); + break; + + case HINT_OBJREMOVED: + CallListeners(EventMultiplexerEvent::EID_SHAPE_REMOVED, + const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage()))); + break; + default: + break; + } + } + else if (rHint.ISA(SfxSimpleHint)) + { + SfxSimpleHint& rSimpleHint (*PTR_CAST(SfxSimpleHint, &rHint)); + if (rSimpleHint.GetId() == SFX_HINT_DYING) + mpDocument = NULL; + } +} + + + + +void EventMultiplexer::Implementation::CallListeners ( + EventMultiplexerEvent::EventId eId, + void* pUserData) +{ + EventMultiplexerEvent aEvent (mrBase, eId, pUserData); + CallListeners(aEvent); +} + + + + +void EventMultiplexer::Implementation::CallListeners (EventMultiplexerEvent& rEvent) +{ + ListenerList aCopyListeners( maListeners ); + ListenerList::iterator iListener (aCopyListeners.begin()); + ListenerList::const_iterator iListenerEnd (aCopyListeners.end()); + for (; iListener!=iListenerEnd; ++iListener) + { + if ((iListener->second && rEvent.meEventId) != 0) + iListener->first.Call(&rEvent); + } +} + + + + +IMPL_LINK(EventMultiplexer::Implementation, SlideSorterSelectionChangeListener, void*, EMPTYARG) +{ + CallListeners (EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION); + return 0; +} + + + + +//===== EventMultiplexerEvent ================================================= + +EventMultiplexerEvent::EventMultiplexerEvent ( + const ViewShellBase& rBase, + EventId eEventId, + const void* pUserData) + : mrBase(rBase), + meEventId(eEventId), + mpUserData(pUserData) + +{ +} + +} } // end of namespace ::sd::tools diff --git a/sd/source/ui/tools/IconCache.cxx b/sd/source/ui/tools/IconCache.cxx new file mode 100644 index 000000000000..12e7b6b52e95 --- /dev/null +++ b/sd/source/ui/tools/IconCache.cxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/IconCache.hxx" + +#include "sdresid.hxx" +#include <hash_map> +#include <osl/doublecheckedlocking.h> +#include <osl/getglobalmutex.hxx> + +namespace sd { + +//===== IconCache::Implementation ============================================= + +class IconCache::Implementation +{ +private: + friend class IconCache; + + /** This pointer holds a valid reference from first time that + IconCache::Instance() is called to the end of the sd module when the + cache is destroyed from SdGlobalResourceContainer. + */ + static IconCache* mpInstance; + + typedef ::std::hash_map<USHORT,Image> ImageContainer; + ImageContainer maContainer; + + Image GetIcon (USHORT nResourceId); +}; + +IconCache* IconCache::Implementation::mpInstance = NULL; + + + +Image IconCache::Implementation::GetIcon (USHORT nResourceId) +{ + Image aResult; + ImageContainer::iterator iImage; + iImage = maContainer.find (nResourceId); + if (iImage == maContainer.end()) + { + aResult = Image(BitmapEx(SdResId(nResourceId))); + maContainer[nResourceId] = aResult; + } + else + aResult = iImage->second; + return aResult; +} + + + + +//===== IconCache ============================================================= + +//static +IconCache& IconCache::Instance (void) +{ + if (Implementation::mpInstance == NULL) + { + ::osl::GetGlobalMutex aMutexFunctor; + ::osl::MutexGuard aGuard (aMutexFunctor()); + if (Implementation::mpInstance == NULL) + { + IconCache* pCache = new IconCache (); + SdGlobalResourceContainer::Instance().AddResource ( + ::std::auto_ptr<SdGlobalResource>(pCache)); + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + Implementation::mpInstance = pCache; + } + } + else + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } + + DBG_ASSERT(Implementation::mpInstance!=NULL, + "IconCache::Instance(): instance is NULL"); + return *Implementation::mpInstance; +} + + + + +Image IconCache::GetIcon (USHORT nResourceId) +{ + return mpImpl->GetIcon (nResourceId); +} + + + + +IconCache::IconCache (void) + : mpImpl (new Implementation()) +{ +} + + + + +IconCache::~IconCache (void) +{ + // empty +} + +} // end of namespace sd diff --git a/sd/source/ui/tools/IdleDetection.cxx b/sd/source/ui/tools/IdleDetection.cxx new file mode 100644 index 000000000000..ae36f8954e56 --- /dev/null +++ b/sd/source/ui/tools/IdleDetection.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/IdleDetection.hxx" + +#include "ViewShell.hxx" +#include "slideshow.hxx" +#include "ViewShellBase.hxx" + +#include <vcl/window.hxx> +#include <sfx2/viewfrm.hxx> + +#include <com/sun/star/frame/XFrame.hdl> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; + +namespace sd { namespace tools { + + +sal_Int32 IdleDetection::GetIdleState (const ::Window* pWindow) +{ + sal_Int32 nResult (CheckInputPending() | CheckSlideShowRunning()); + if (pWindow != NULL) + nResult |= CheckWindowPainting(*pWindow); + return nResult; +} + + + + +sal_Int32 IdleDetection::CheckInputPending (void) +{ + if (GetpApp()->AnyInput(INPUT_MOUSE | INPUT_KEYBOARD | INPUT_PAINT)) + return IDET_SYSTEM_EVENT_PENDING; + else + return IDET_IDLE; +} + + + + +sal_Int32 IdleDetection::CheckSlideShowRunning (void) +{ + sal_Int32 eResult (IDET_IDLE); + + bool bIsSlideShowShowing = false; + + // Iterate over all view frames. + SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(); + for (pViewFrame = SfxViewFrame::GetFirst(); + pViewFrame!=NULL && !bIsSlideShowShowing; + pViewFrame = SfxViewFrame::GetNext(*pViewFrame)) + { + // Ignore the current frame when it does not exist, is not valid, or + // is not active. + bool bIgnoreFrame (true); + if (pViewFrame->GetFrame() != NULL) + { + uno::Reference<frame::XFrame> xFrame (pViewFrame->GetFrame()->GetFrameInterface()); + try + { + if (xFrame.is() && xFrame->isActive()) + bIgnoreFrame = false; + } + catch (uno::RuntimeException e) + { + (void) e; + } + } + if (bIgnoreFrame) + continue; + + // Get sd::ViewShell from active frame. + ViewShellBase* pBase = ViewShellBase::GetViewShellBase(pViewFrame); + if (pBase != NULL) + { + rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( *pBase ) ); + if( xSlideShow.is() && xSlideShow->isRunning() ) + { + if (xSlideShow->isFullScreen()) + eResult |= IDET_FULL_SCREEN_SHOW_ACTIVE; + else + eResult |= IDET_WINDOW_SHOW_ACTIVE; + } + } + } + + return eResult; +} + + + + +sal_Int32 IdleDetection::CheckWindowPainting (const ::Window& rWindow) +{ + if (rWindow.IsInPaint()) + return IDET_WINDOW_PAINTING; + else + return IDET_IDLE; +} + +} } // end of namespace ::sd::tools diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx new file mode 100644 index 000000000000..b791454bd10a --- /dev/null +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -0,0 +1,501 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "PreviewRenderer.hxx" + +#include "DrawDocShell.hxx" +#include "drawdoc.hxx" +#include "drawview.hxx" +#include "sdpage.hxx" +#include "ViewShell.hxx" +#include <vcl/virdev.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdoutl.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/editstat.hxx> +#include <tools/link.hxx> +#include <vcl/svapp.hxx> + + +namespace sd { + +const int PreviewRenderer::snSubstitutionTextSize = 11; +const int PreviewRenderer::snFrameWidth = 1; + +PreviewRenderer::PreviewRenderer ( + OutputDevice* pTemplate, + const bool bHasFrame) + : mpPreviewDevice (new VirtualDevice()), + mpView(NULL), + mpDocShellOfView(NULL), + mnWidthOfView(0), + maFrameColor (svtools::ColorConfig().GetColorValue(svtools::DOCBOUNDARIES).nColor), + mbHasFrame(bHasFrame) +{ + if (pTemplate != NULL) + { + mpPreviewDevice->SetDigitLanguage (pTemplate->GetDigitLanguage()); + mpPreviewDevice->SetBackground(pTemplate->GetBackground()); + } + else + mpPreviewDevice->SetBackground(Wallpaper(COL_WHITE)); +} + + + + +PreviewRenderer::~PreviewRenderer (void) +{ + if (mpDocShellOfView != NULL) + EndListening (*mpDocShellOfView); +} + + + + +Image PreviewRenderer::RenderPage ( + const SdPage* pPage, + const sal_Int32 nWidth, + const String& rSubstitutionText, + const bool bObeyHighContrastMode) +{ + if (pPage != NULL) + { + const Size aPageModelSize (pPage->GetSize()); + const double nAspectRatio ( + double(aPageModelSize.Width()) / double(aPageModelSize.Height())); + const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); + const sal_Int32 nHeight (sal::static_int_cast<sal_Int32>( + (nWidth - 2*nFrameWidth) / nAspectRatio + 2*nFrameWidth + 0.5)); + return RenderPage (pPage, Size(nWidth,nHeight), rSubstitutionText, bObeyHighContrastMode); + } + else + return Image(); +} + + + + +Image PreviewRenderer::RenderPage ( + const SdPage* pPage, + Size aPixelSize, + const String& rSubstitutionText, + const bool bObeyHighContrastMode) +{ + Image aPreview; + + if (pPage != NULL) + { + try + { + if (Initialize (pPage, aPixelSize, bObeyHighContrastMode)) + { + PaintPage (pPage); + PaintSubstitutionText (rSubstitutionText); + PaintFrame(); + + Size aSize (mpPreviewDevice->GetOutputSizePixel()); + aPreview = mpPreviewDevice->GetBitmap ( + mpPreviewDevice->PixelToLogic(Point(0,0)), + mpPreviewDevice->PixelToLogic(aSize)); + + Cleanup(); + } + } + catch (const com::sun::star::uno::Exception&) + { + OSL_TRACE("PreviewRenderer::RenderPage: caught exception"); + } + } + + return aPreview; +} + + + + +Image PreviewRenderer::RenderSubstitution ( + const Size& rPreviewPixelSize, + const String& rSubstitutionText) +{ + Image aPreview; + + try + { + // Set size. + mpPreviewDevice->SetOutputSizePixel(rPreviewPixelSize); + + // Adjust contrast mode. + bool bUseContrast = Application::GetSettings().GetStyleSettings(). + GetHighContrastMode(); + mpPreviewDevice->SetDrawMode (bUseContrast + ? ViewShell::OUTPUT_DRAWMODE_CONTRAST + : ViewShell::OUTPUT_DRAWMODE_COLOR); + + // Set a map mode makes a typical substitution text completely + // visible. + MapMode aMapMode (mpPreviewDevice->GetMapMode()); + aMapMode.SetMapUnit(MAP_100TH_MM); + double nFinalScale (25.0 * rPreviewPixelSize.Width() / 28000.0); + aMapMode.SetScaleX(nFinalScale); + aMapMode.SetScaleY(nFinalScale); + const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); + aMapMode.SetOrigin(mpPreviewDevice->PixelToLogic( + Point(nFrameWidth,nFrameWidth),aMapMode)); + mpPreviewDevice->SetMapMode (aMapMode); + + // Clear the background. + Rectangle aPaintRectangle ( + Point(0,0), + mpPreviewDevice->GetOutputSizePixel()); + mpPreviewDevice->EnableMapMode(FALSE); + mpPreviewDevice->SetLineColor(); + svtools::ColorConfig aColorConfig; + mpPreviewDevice->SetFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + mpPreviewDevice->DrawRect (aPaintRectangle); + mpPreviewDevice->EnableMapMode(TRUE); + + // Paint substitution text and a frame around it. + PaintSubstitutionText (rSubstitutionText); + PaintFrame(); + + Size aSize (mpPreviewDevice->GetOutputSizePixel()); + aPreview = mpPreviewDevice->GetBitmap ( + mpPreviewDevice->PixelToLogic(Point(0,0)), + mpPreviewDevice->PixelToLogic(aSize)); + } + catch (const com::sun::star::uno::Exception&) + { + OSL_TRACE("PreviewRenderer::RenderPage: caught exception"); + } + + return aPreview; +} + + + + +bool PreviewRenderer::Initialize ( + const SdPage* pPage, + const Size& rPixelSize, + const bool bObeyHighContrastMode) +{ + bool bSuccess = false; + do + { + if (pPage == NULL) + break; + + SdrModel* pModel = pPage->GetModel(); + if (pModel == NULL) + break; + + SetupOutputSize(*pPage, rPixelSize); + + SdDrawDocument* pDocument + = static_cast<SdDrawDocument*>(pPage->GetModel()); + DrawDocShell* pDocShell = pDocument->GetDocSh(); + + // Create view + ProvideView (pDocShell); + if (mpView.get() == NULL) + break; + + // Adjust contrast mode. + bool bUseContrast (bObeyHighContrastMode + && Application::GetSettings().GetStyleSettings().GetHighContrastMode()); + mpPreviewDevice->SetDrawMode (bUseContrast + ? ViewShell::OUTPUT_DRAWMODE_CONTRAST + : ViewShell::OUTPUT_DRAWMODE_COLOR); + mpPreviewDevice->SetSettings(Application::GetSettings()); + + // Tell the view to show the given page. + SdPage* pNonConstPage = const_cast<SdPage*>(pPage); + if (pPage->IsMasterPage()) + { + mpView->ShowSdrPage(mpView->GetModel()->GetMasterPage(pPage->GetPageNum())); + } + else + { + mpView->ShowSdrPage(pNonConstPage); + } + + // Make sure that a page view exists. + SdrPageView* pPageView = mpView->GetSdrPageView(); + if (pPageView == NULL) + break; + // Set background color of page view and outliner. + svtools::ColorConfig aColorConfig; + const Color aPageBackgroundColor(pPage->GetPageBackgroundColor(pPageView)); + pPageView->SetApplicationBackgroundColor(aPageBackgroundColor); + SdrOutliner& rOutliner (pDocument->GetDrawOutliner(NULL)); + rOutliner.SetBackgroundColor(aPageBackgroundColor); + rOutliner.SetDefaultLanguage(pDocument->GetLanguage(EE_CHAR_LANGUAGE)); + mpView->SetApplicationBackgroundColor( + Color(aColorConfig.GetColorValue(svtools::APPBACKGROUND).nColor)); + + bSuccess = true; + } + while (false); + + return bSuccess; +} + + + + +void PreviewRenderer::Cleanup (void) +{ + mpView->HideSdrPage(); +} + + + + +void PreviewRenderer::PaintPage (const SdPage* pPage) +{ + // Paint the page. + Rectangle aPaintRectangle (Point(0,0), pPage->GetSize()); + Region aRegion (aPaintRectangle); + + // Turn off online spelling and redlining. + SdrOutliner* pOutliner = NULL; + ULONG nOriginalControlWord = 0; + if (mpDocShellOfView!=NULL && mpDocShellOfView->GetDoc()!=NULL) + { + pOutliner = &mpDocShellOfView->GetDoc()->GetDrawOutliner(); + nOriginalControlWord = pOutliner->GetControlWord(); + pOutliner->SetControlWord( + (nOriginalControlWord & ~EE_CNTRL_ONLINESPELLING)); + } + + try + { + mpView->CompleteRedraw (mpPreviewDevice.get(), aRegion); + } + catch (const ::com::sun::star::uno::Exception&) + { + OSL_TRACE("PreviewRenderer::PaintPage: caught exception"); + } + + // Restore the previous online spelling and redlining states. + if (pOutliner != NULL) + pOutliner->SetControlWord(nOriginalControlWord); +} + + + + +void PreviewRenderer::PaintSubstitutionText (const String& rSubstitutionText) +{ + if (rSubstitutionText.Len() > 0) + { + // Set the font size. + const Font& rOriginalFont (mpPreviewDevice->GetFont()); + Font aFont (mpPreviewDevice->GetSettings().GetStyleSettings().GetAppFont()); + sal_Int32 nHeight (mpPreviewDevice->PixelToLogic(Size(0,snSubstitutionTextSize)).Height()); + aFont.SetHeight(nHeight); + mpPreviewDevice->SetFont (aFont); + + // Paint the substitution text. + Rectangle aTextBox ( + Point(0,0), + mpPreviewDevice->PixelToLogic( + mpPreviewDevice->GetOutputSizePixel())); + USHORT nTextStyle = + TEXT_DRAW_CENTER + | TEXT_DRAW_VCENTER + | TEXT_DRAW_MULTILINE + | TEXT_DRAW_WORDBREAK; + mpPreviewDevice->DrawText (aTextBox, rSubstitutionText, nTextStyle); + + // Restore the font. + mpPreviewDevice->SetFont (rOriginalFont); + } +} + + + + +void PreviewRenderer::PaintFrame (void) +{ + if (mbHasFrame) + { + // Paint a frame arround the preview. + Rectangle aPaintRectangle ( + Point(0,0), + mpPreviewDevice->GetOutputSizePixel()); + mpPreviewDevice->EnableMapMode(FALSE); + mpPreviewDevice->SetLineColor(maFrameColor); + mpPreviewDevice->SetFillColor(); + mpPreviewDevice->DrawRect(aPaintRectangle); + mpPreviewDevice->EnableMapMode(TRUE); + } +} + + + + +void PreviewRenderer::SetupOutputSize ( + const SdPage& rPage, + const Size& rFramePixelSize) +{ + // First set the map mode to some arbitrary scale that is numerically + // stable. + MapMode aMapMode (mpPreviewDevice->GetMapMode()); + aMapMode.SetMapUnit(MAP_100TH_MM); + double nInitialScale = 1; + aMapMode.SetScaleX (Fraction(nInitialScale)); + aMapMode.SetScaleY (Fraction(nInitialScale)); + aMapMode.SetOrigin (Point(0,0)); + + // Adapt it to the desired width. + const Size aPageModelSize (rPage.GetSize()); + const Size aOutputSize = mpPreviewDevice->LogicToPixel(rPage.GetSize(), aMapMode); + const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); + const double nFinalScale (nInitialScale * (rFramePixelSize.Width()-2*nFrameWidth) + / aOutputSize.Width()); + aMapMode.SetScaleX (nFinalScale); + aMapMode.SetScaleY (nFinalScale); + aMapMode.SetOrigin (mpPreviewDevice->PixelToLogic( + Point(nFrameWidth,nFrameWidth),aMapMode)); + + mpPreviewDevice->SetMapMode (aMapMode); + mpPreviewDevice->SetOutputSizePixel(rFramePixelSize); +} + + + + +void PreviewRenderer::ProvideView (DrawDocShell* pDocShell) +{ + if (pDocShell != mpDocShellOfView) + { + // Destroy the view that is connected to the current doc shell. + mpView.reset (NULL); + + // Switch our attention, i.e. listening for DYING events, to + // the new doc shell. + if (mpDocShellOfView != NULL) + EndListening (*mpDocShellOfView); + mpDocShellOfView = pDocShell; + if (mpDocShellOfView != NULL) + StartListening (*mpDocShellOfView); + } + if (mpView.get() == NULL) + { + mpView.reset (new DrawView (pDocShell, mpPreviewDevice.get(), NULL)); + } + mpView->SetPreviewRenderer( sal_True ); + mpView->SetBordVisible(FALSE); + mpView->SetPageBorderVisible(FALSE); + mpView->SetPageVisible(TRUE); +} + + + + +Image PreviewRenderer::ScaleBitmap ( + const BitmapEx& rBitmapEx, + int nWidth) +{ + Image aPreview; + + do + { + // Adjust contrast mode. + bool bUseContrast = Application::GetSettings().GetStyleSettings(). + GetHighContrastMode(); + mpPreviewDevice->SetDrawMode (bUseContrast + ? ViewShell::OUTPUT_DRAWMODE_CONTRAST + : ViewShell::OUTPUT_DRAWMODE_COLOR); + + // Set output size. + Size aSize (rBitmapEx.GetSizePixel()); + if (aSize.Width() <= 0) + break; + Size aFrameSize ( + nWidth, + (long)((nWidth*1.0 * aSize.Height()) / aSize.Width() + 0.5)); + Size aPreviewSize (aFrameSize.Width()-2,aFrameSize.Height()-2); + MapMode aMapMode (mpPreviewDevice->GetMapMode()); + aMapMode.SetMapUnit(MAP_PIXEL); + aMapMode.SetOrigin (Point()); + aMapMode.SetScaleX (1.0); + aMapMode.SetScaleY (1.0); + mpPreviewDevice->SetMapMode (aMapMode); + mpPreviewDevice->SetOutputSize (aFrameSize); + + // Paint a frame arround the preview. + mpPreviewDevice->SetLineColor (maFrameColor); + mpPreviewDevice->SetFillColor (); + mpPreviewDevice->DrawRect (Rectangle(Point(0,0), aFrameSize)); + + // Paint the bitmap scaled to the desired width. + BitmapEx aScaledBitmap (rBitmapEx.GetBitmap()); + aScaledBitmap.Scale (aPreviewSize, BMP_SCALE_INTERPOLATE); + mpPreviewDevice->DrawBitmap ( + Point(1,1), + aPreviewSize, + aScaledBitmap.GetBitmap()); + + // Get the resulting bitmap. + aPreview = mpPreviewDevice->GetBitmap (Point(0,0), aFrameSize); + } + while (false); + + return aPreview; +} + + + + +void PreviewRenderer::Notify(SfxBroadcaster&, const SfxHint& rHint) +{ + if (rHint.IsA(TYPE(SfxSimpleHint)) + && mpDocShellOfView != NULL) + { + const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, &rHint); + if (pSimpleHint != NULL + && pSimpleHint->GetId() == SFX_HINT_DYING) + { + // The doc shell is dying. Our view uses its item pool and + // has to be destroyed as well. The next call to + // ProvideView will create a new one (for another + // doc shell, of course.) + mpView.reset (NULL); + mpDocShellOfView = NULL; + } + } +} + + + +} // end of namespace ::sd diff --git a/sd/source/ui/tools/PropertySet.cxx b/sd/source/ui/tools/PropertySet.cxx new file mode 100644 index 000000000000..010571b10927 --- /dev/null +++ b/sd/source/ui/tools/PropertySet.cxx @@ -0,0 +1,248 @@ +/************************************************************************* + * + * 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 "tools/PropertySet.hxx" +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::rtl::OUString; + +namespace sd { namespace tools { + +PropertySet::PropertySet (void) + : PropertySetInterfaceBase(m_aMutex), + mpChangeListeners(new ChangeListenerContainer()) +{ +} + + + + +PropertySet::~PropertySet (void) +{ +} + + + + +void SAL_CALL PropertySet::disposing (void) +{ +} + + + + +beans::UnknownPropertyException PropertySet::CreateUnknownPropertyException ( + const rtl::OUString& rsPropertyName) +{ + return beans::UnknownPropertyException( + OUString::createFromAscii("property ") + + rsPropertyName + + OUString::createFromAscii(" is not known"), + static_cast<XWeak*>(this)); +} + + + + +//----- XPropertySet ---------------------------------------------------------- + +Reference<beans::XPropertySetInfo> SAL_CALL PropertySet::getPropertySetInfo (void) + throw(RuntimeException) +{ + return NULL; +} + + + + +void SAL_CALL PropertySet::setPropertyValue ( + const rtl::OUString& rsPropertyName, + const css::uno::Any& rsPropertyValue) + throw(css::beans::UnknownPropertyException, + css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + ThrowIfDisposed(); + + Any aOldValue (SetPropertyValue(rsPropertyName,rsPropertyValue)); + if (aOldValue != rsPropertyValue) + { + // Inform listeners that are registered specifically for the + // property and those registered for any property. + beans::PropertyChangeEvent aEvent( + static_cast<XWeak*>(this), + rsPropertyName, + sal_False, + -1, + aOldValue, + rsPropertyValue); + CallListeners(rsPropertyName, aEvent); + CallListeners(OUString(), aEvent); + } +} + + + + +Any SAL_CALL PropertySet::getPropertyValue (const OUString& rsPropertyName) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + ThrowIfDisposed(); + + return GetPropertyValue(rsPropertyName); +} + + + + +void SAL_CALL PropertySet::addPropertyChangeListener ( + const rtl::OUString& rsPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + if ( ! rxListener.is()) + throw lang::IllegalArgumentException(); + + if (rBHelper.bDisposed || rBHelper.bInDispose) + return; + + mpChangeListeners->insert( + ChangeListenerContainer::value_type( + rsPropertyName, + rxListener)); +} + + + + +void SAL_CALL PropertySet::removePropertyChangeListener ( + const rtl::OUString& rsPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener) + throw(beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + ::std::pair<ChangeListenerContainer::iterator,ChangeListenerContainer::iterator> + aRange (mpChangeListeners->equal_range(rsPropertyName)); + + ChangeListenerContainer::iterator iListener ( + ::std::find_if( + aRange.first, + aRange.second, + std::compose1( + std::bind1st(std::equal_to<Reference<beans::XPropertyChangeListener> >(), + rxListener), + std::select2nd<ChangeListenerContainer::value_type>()))); + if (iListener != mpChangeListeners->end()) + { + mpChangeListeners->erase(iListener); + } + else + { + throw lang::IllegalArgumentException(); + } +} + + + + +void SAL_CALL PropertySet::addVetoableChangeListener ( + const rtl::OUString& rsPropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + // Constraint properties are not supported and thus no vetoable + // listeners. + (void)rsPropertyName; + (void)rxListener; +} + + + + +void SAL_CALL PropertySet::removeVetoableChangeListener ( + const rtl::OUString& rsPropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + // Constraint properties are not supported and thus no vetoable + // listeners. + (void)rsPropertyName; + (void)rxListener; +} + + + + +//----------------------------------------------------------------------------- + +void PropertySet::CallListeners ( + const rtl::OUString& rsPropertyName, + const beans::PropertyChangeEvent& rEvent) +{ + ::std::pair<ChangeListenerContainer::iterator,ChangeListenerContainer::iterator> + aRange (mpChangeListeners->equal_range(rsPropertyName)); + ChangeListenerContainer::const_iterator iListener; + for (iListener=aRange.first; iListener!=aRange.second; ++iListener) + { + if (iListener->second.is()) + iListener->second->propertyChange(rEvent); + } +} + + + + +void PropertySet::ThrowIfDisposed (void) + throw (::com::sun::star::lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "PropertySet object has already been disposed")), + static_cast<uno::XWeak*>(this)); + } +} + +} } // end of namespace ::sd::tools diff --git a/sd/source/ui/tools/SdGlobalResourceContainer.cxx b/sd/source/ui/tools/SdGlobalResourceContainer.cxx new file mode 100644 index 000000000000..878ef16a52f4 --- /dev/null +++ b/sd/source/ui/tools/SdGlobalResourceContainer.cxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/SdGlobalResourceContainer.hxx" + +#include <algorithm> +#include <vector> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + +namespace sd { + + +//===== SdGlobalResourceContainer::Implementation ============================= + +class SdGlobalResourceContainer::Implementation +{ +private: + friend class SdGlobalResourceContainer; + static SdGlobalResourceContainer* mpInstance; + + ::osl::Mutex maMutex; + + /** All instances of SdGlobalResource in this vector are owned by the + container and will be destroyed when the container is destroyed. + */ + typedef ::std::vector<SdGlobalResource*> ResourceList; + ResourceList maResources; + + typedef ::std::vector<boost::shared_ptr<SdGlobalResource> > SharedResourceList; + SharedResourceList maSharedResources; + + typedef ::std::vector<Reference<XInterface> > XInterfaceResourceList; + XInterfaceResourceList maXInterfaceResources; +}; + + + + +// static +SdGlobalResourceContainer& SdGlobalResourceContainer::Instance (void) +{ + DBG_ASSERT(Implementation::mpInstance!=NULL, + "SdGlobalResourceContainer::Instance(): instance has been deleted"); + // Maybe we should throw an exception when the instance has been deleted. + return *Implementation::mpInstance; +} + +SdGlobalResourceContainer* + SdGlobalResourceContainer::Implementation::mpInstance = NULL; + + + + +//===== SdGlobalResourceContainer ============================================= + +void SdGlobalResourceContainer::AddResource ( + ::std::auto_ptr<SdGlobalResource> pResource) +{ + ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Implementation::ResourceList::iterator iResource; + iResource = ::std::find ( + mpImpl->maResources.begin(), + mpImpl->maResources.end(), + pResource.get()); + if (iResource == mpImpl->maResources.end()) + mpImpl->maResources.push_back(pResource.get()); + else + { + // Because the given resource is an auto_ptr it is highly unlikely + // that we come here. But who knows? + DBG_ASSERT (false, + "SdGlobalResourceContainer:AddResource(): Resource added twice."); + } + // We can not put the auto_ptr into the vector so we release the + // auto_ptr and document that we take ownership explicitly. + pResource.release(); +} + + + + +void SdGlobalResourceContainer::AddResource ( + ::boost::shared_ptr<SdGlobalResource> pResource) +{ + ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Implementation::SharedResourceList::iterator iResource; + iResource = ::std::find ( + mpImpl->maSharedResources.begin(), + mpImpl->maSharedResources.end(), + pResource); + if (iResource == mpImpl->maSharedResources.end()) + mpImpl->maSharedResources.push_back(pResource); + else + { + DBG_ASSERT (false, + "SdGlobalResourceContainer:AddResource(): Resource added twice."); + } +} + + + + +void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxResource) +{ + ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Implementation::XInterfaceResourceList::iterator iResource; + iResource = ::std::find ( + mpImpl->maXInterfaceResources.begin(), + mpImpl->maXInterfaceResources.end(), + rxResource); + if (iResource == mpImpl->maXInterfaceResources.end()) + mpImpl->maXInterfaceResources.push_back(rxResource); + else + { + DBG_ASSERT (false, + "SdGlobalResourceContainer:AddResource(): Resource added twice."); + } +} + + + + +::std::auto_ptr<SdGlobalResource> SdGlobalResourceContainer::ReleaseResource ( + SdGlobalResource* pResource) +{ + ::std::auto_ptr<SdGlobalResource> pResult (NULL); + + ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Implementation::ResourceList::iterator iResource; + iResource = ::std::find ( + mpImpl->maResources.begin(), + mpImpl->maResources.end(), + pResource); + if (iResource != mpImpl->maResources.end()) + { + pResult.reset (*iResource); + mpImpl->maResources.erase(iResource); + } + + return pResult; +} + + + + +SdGlobalResourceContainer::SdGlobalResourceContainer (void) + : mpImpl (new SdGlobalResourceContainer::Implementation()) +{ + Implementation::mpInstance = this; +} + + + + +SdGlobalResourceContainer::~SdGlobalResourceContainer (void) +{ + ::osl::MutexGuard aGuard (mpImpl->maMutex); + + // Release the resources in reversed order of their addition to the + // container. This is because a resource A added before resource B + // may have been created due to a request of B. Thus B depends on A and + // should be destroyed first. + Implementation::ResourceList::reverse_iterator iResource; + for (iResource = mpImpl->maResources.rbegin(); + iResource != mpImpl->maResources.rend(); + ++iResource) + { + delete *iResource; + } + + // The SharedResourceList has not to be released manually. We just + // assert resources that are still held by someone other than us. + Implementation::SharedResourceList::reverse_iterator iSharedResource; + for (iSharedResource = mpImpl->maSharedResources.rbegin(); + iSharedResource != mpImpl->maSharedResources.rend(); + ++iSharedResource) + { + if ( ! iSharedResource->unique()) + { + SdGlobalResource* pResource = iSharedResource->get(); + OSL_TRACE(" %p %d", pResource, iSharedResource->use_count()); + DBG_ASSERT(iSharedResource->unique(), + "SdGlobalResource still held in ~SdGlobalResourceContainer"); + } + } + + Implementation::XInterfaceResourceList::reverse_iterator iXInterfaceResource; + for (iXInterfaceResource = mpImpl->maXInterfaceResources.rbegin(); + iXInterfaceResource != mpImpl->maXInterfaceResources.rend(); + ++iXInterfaceResource) + { + Reference<lang::XComponent> xComponent (*iXInterfaceResource, UNO_QUERY); + *iXInterfaceResource = NULL; + if (xComponent.is()) + xComponent->dispose(); + } + + DBG_ASSERT(Implementation::mpInstance == this, + "~SdGlobalResourceContainer(): more than one instance of singleton"); + Implementation::mpInstance = NULL; +} + + + + +} // end of namespace sd diff --git a/sd/source/ui/tools/SlotStateListener.cxx b/sd/source/ui/tools/SlotStateListener.cxx new file mode 100644 index 000000000000..e8e2ffb24f2b --- /dev/null +++ b/sd/source/ui/tools/SlotStateListener.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/SlotStateListener.hxx" +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#ifndef _COM_SUN_STAR_FRAME_XDISPATCHP_HPP_ +#include <com/sun/star/frame/XDispatch.hpp> +#endif +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> + +#include <comphelper/processfactory.hxx> + +using namespace ::com::sun::star; +using namespace ::rtl; + +namespace sd { namespace tools { + + +SlotStateListener::SlotStateListener (void) + : SlotStateListenerInterfaceBase(maMutex), + maCallback(), + mxDispatchProviderWeak(NULL) +{ +} + + + + +SlotStateListener::SlotStateListener ( + Link& rCallback, + const uno::Reference<frame::XDispatchProvider>& rxDispatchProvider, + const ::rtl::OUString& rSlotName) + : SlotStateListenerInterfaceBase(maMutex), + maCallback(), + mxDispatchProviderWeak(NULL) +{ + SetCallback(rCallback); + ConnectToDispatchProvider(rxDispatchProvider); + ObserveSlot(rSlotName); +} + + + + +SlotStateListener::~SlotStateListener (void) +{ + ReleaseListeners(); +} + + + + +void SlotStateListener::SetCallback (const Link& rCallback) +{ + ThrowIfDisposed(); + + maCallback = rCallback; +} + + + + +void SlotStateListener::ConnectToDispatchProvider ( + const uno::Reference<frame::XDispatchProvider>& rxDispatchProvider) +{ + ThrowIfDisposed(); + + // When we are listening to state changes of slots of another frame then + // release these listeners first. + if ( ! maRegisteredURLList.empty()) + ReleaseListeners(); + + mxDispatchProviderWeak = rxDispatchProvider; +} + + + + +void SlotStateListener::ObserveSlot (const ::rtl::OUString& rSlotName) +{ + ThrowIfDisposed(); + + if (maCallback.IsSet()) + { + // Connect the state change listener. + util::URL aURL (MakeURL(rSlotName)); + uno::Reference<frame::XDispatch> xDispatch (GetDispatch(aURL)); + if (xDispatch.is()) + { + maRegisteredURLList.push_back(aURL); + xDispatch->addStatusListener(this,aURL); + } + } +} + + + + +bool SlotStateListener::IsValid (void) const +{ + return maRegisteredURLList.size() > 0; +} + + + + +void SlotStateListener::disposing (void) +{ + ReleaseListeners(); + mxDispatchProviderWeak = uno::WeakReference<frame::XDispatchProvider>(NULL); + maCallback = Link(); +} + + + + +util::URL SlotStateListener::MakeURL (const OUString& rSlotName) const +{ + util::URL aURL; + + aURL.Complete = rSlotName; + + uno::Reference<lang::XMultiServiceFactory> xServiceManager ( + ::comphelper::getProcessServiceFactory()); + if (xServiceManager.is()) + { + uno::Reference<util::XURLTransformer> xTransformer(xServiceManager->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), + uno::UNO_QUERY); + if (xTransformer.is()) + xTransformer->parseStrict(aURL); + } + + return aURL; +} + + + + +uno::Reference<frame::XDispatch> + SlotStateListener::GetDispatch (const util::URL& rURL) const +{ + uno::Reference<frame::XDispatch> xDispatch; + + uno::Reference<frame::XDispatchProvider> xDispatchProvider (mxDispatchProviderWeak); + if (xDispatchProvider.is()) + xDispatch = xDispatchProvider->queryDispatch(rURL, OUString(), 0); + + return xDispatch; +} + + + + +void SlotStateListener::statusChanged ( + const frame::FeatureStateEvent& rState) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + OUString sSlotName (rState.FeatureURL.Complete); + if (maCallback.IsSet()) + maCallback.Call(&sSlotName); +} + + + + +void SlotStateListener::ReleaseListeners (void) +{ + if ( ! maRegisteredURLList.empty()) + { + RegisteredURLList::iterator iURL (maRegisteredURLList.begin()); + RegisteredURLList::iterator iEnd (maRegisteredURLList.end()); + for (; iURL!=iEnd; ++iURL) + { + uno::Reference<frame::XDispatch> xDispatch (GetDispatch(*iURL)); + if (xDispatch.is()) + { + xDispatch->removeStatusListener(this,*iURL); + } + } + } +} + + + + +//===== lang::XEventListener ================================================ + +void SAL_CALL SlotStateListener::disposing ( + const lang::EventObject& ) + throw (uno::RuntimeException) +{ +} + + + + +void SlotStateListener::ThrowIfDisposed (void) + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "SlideSorterController object has already been disposed")), + static_cast<uno::XWeak*>(this)); + } +} + + + + +} } // end of namespace ::sd::tools diff --git a/sd/source/ui/tools/TimerBasedTaskExecution.cxx b/sd/source/ui/tools/TimerBasedTaskExecution.cxx new file mode 100644 index 000000000000..87ff4d318132 --- /dev/null +++ b/sd/source/ui/tools/TimerBasedTaskExecution.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "tools/TimerBasedTaskExecution.hxx" +#include "tools/AsynchronousTask.hxx" +#include <tools/time.hxx> +#include <osl/diagnose.h> +#include <boost/weak_ptr.hpp> + +#undef VERBOSE + +namespace sd { namespace tools { + +/** Used by the shared_ptr instead of the private destructor. +*/ +class TimerBasedTaskExecution::Deleter +{ +public: + void operator() (TimerBasedTaskExecution* pObject) + { + delete pObject; + } +}; + + + + +::boost::shared_ptr<TimerBasedTaskExecution> TimerBasedTaskExecution::Create ( + const ::boost::shared_ptr<AsynchronousTask>& rpTask, + sal_uInt32 nMillisecondsBetweenSteps, + sal_uInt32 nMaxTimePerStep) +{ + ::boost::shared_ptr<TimerBasedTaskExecution> pExecution( + new TimerBasedTaskExecution(rpTask,nMillisecondsBetweenSteps,nMaxTimePerStep), + Deleter()); + // Let the new object have a shared_ptr to itself, so that it can + // release itself when the AsynchronousTask has been executed + // completely. + pExecution->SetSelf(pExecution); + return pExecution; +} + + + + +void TimerBasedTaskExecution::Release (void) +{ + maTimer.Stop(); + mpSelf.reset(); +} + + + + +//static +void TimerBasedTaskExecution::ReleaseTask ( + const ::boost::weak_ptr<TimerBasedTaskExecution>& rpExecution) +{ + if ( ! rpExecution.expired()) + { + try + { + ::boost::shared_ptr<tools::TimerBasedTaskExecution> pExecution (rpExecution); + pExecution->Release(); + } + catch (::boost::bad_weak_ptr) + { + // When a bad_weak_ptr has been thrown then the object pointed + // to by rpTask has been released right after we checked that it + // still existed. Too bad, but that means, that we have nothing + // more do. + } + } +} + + + + +TimerBasedTaskExecution::TimerBasedTaskExecution ( + const ::boost::shared_ptr<AsynchronousTask>& rpTask, + sal_uInt32 nMillisecondsBetweenSteps, + sal_uInt32 nMaxTimePerStep) + : mpTask(rpTask), + maTimer(), + mpSelf(), + mnMaxTimePerStep(nMaxTimePerStep) +{ + Link aLink(LINK(this,TimerBasedTaskExecution,TimerCallback)); + maTimer.SetTimeoutHdl(aLink); + maTimer.SetTimeout(nMillisecondsBetweenSteps); + maTimer.Start(); +} + + + + +TimerBasedTaskExecution::~TimerBasedTaskExecution (void) +{ + maTimer.Stop(); +} + + + + +void TimerBasedTaskExecution::SetSelf ( + const ::boost::shared_ptr<TimerBasedTaskExecution>& rpSelf) +{ + if (mpTask.get() != NULL) + mpSelf = rpSelf; +} + + + + +IMPL_LINK(TimerBasedTaskExecution,TimerCallback, Timer*,EMPTYARG) +{ + if (mpTask.get() != NULL) + { + if (mpTask->HasNextStep()) + { + // Execute as many steps as fit into the time span of length + // mnMaxTimePerStep. Note that the last step may take longer + // than allowed. + sal_uInt32 nStartTime (Time().GetMSFromTime()); +#ifdef VERBOSE + OSL_TRACE("starting TimerBasedTaskExecution at %d", nStartTime); +#endif + do + { + mpTask->RunNextStep(); + sal_uInt32 nDuration (Time().GetMSFromTime()-nStartTime); +#ifdef VERBOSE + OSL_TRACE("executed step in %d", nDuration); +#endif + if (nDuration > mnMaxTimePerStep) + break; + } + while (mpTask->HasNextStep()); +#ifdef VERBOSE + OSL_TRACE("TimerBasedTaskExecution sleeping"); +#endif + maTimer.Start(); + } + else + mpSelf.reset(); + } + + return 0; +} + + +} } // end of namespace ::sd::tools + diff --git a/sd/source/ui/tools/makefile.mk b/sd/source/ui/tools/makefile.mk new file mode 100644 index 000000000000..67ea9e718b91 --- /dev/null +++ b/sd/source/ui/tools/makefile.mk @@ -0,0 +1,61 @@ +#************************************************************************* +# +# 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=uitools +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/AsynchronousCall.obj \ + $(SLO)$/ConfigurationAccess.obj \ + $(SLO)$/IconCache.obj \ + $(SLO)$/IdleDetection.obj \ + $(SLO)$/EventMultiplexer.obj \ + $(SLO)$/PreviewRenderer.obj \ + $(SLO)$/PropertySet.obj \ + $(SLO)$/SdGlobalResourceContainer.obj \ + $(SLO)$/SlotStateListener.obj \ + $(SLO)$/TimerBasedTaskExecution.obj + +EXCEPTIONSFILES= + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + |