diff options
Diffstat (limited to 'sdext/source/presenter/PresenterController.cxx')
-rw-r--r-- | sdext/source/presenter/PresenterController.cxx | 1376 |
1 files changed, 1376 insertions, 0 deletions
diff --git a/sdext/source/presenter/PresenterController.cxx b/sdext/source/presenter/PresenterController.cxx new file mode 100644 index 000000000000..42208f670f56 --- /dev/null +++ b/sdext/source/presenter/PresenterController.cxx @@ -0,0 +1,1376 @@ +/************************************************************************* + * + * 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_sdext.hxx" + +#include "PresenterController.hxx" + +#include "PresenterAccessibility.hxx" +#include "PresenterAnimator.hxx" +#include "PresenterCanvasHelper.hxx" +#include "PresenterCurrentSlideObserver.hxx" +#include "PresenterFrameworkObserver.hxx" +#include "PresenterHelper.hxx" +#include "PresenterNotesView.hxx" +#include "PresenterPaintManager.hxx" +#include "PresenterPaneAnimator.hxx" +#include "PresenterPaneBase.hxx" +#include "PresenterPaneContainer.hxx" +#include "PresenterPaneBorderPainter.hxx" +#include "PresenterTheme.hxx" +#include "PresenterViewFactory.hxx" +#include "PresenterWindowManager.hxx" + +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/awt/Key.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp> +#include <com/sun/star/drawing/framework/ResourceId.hpp> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/presentation/XPresentation.hpp> +#include <com/sun/star/presentation/XPresentationSupplier.hpp> +#include <com/sun/star/rendering/CompositeOperation.hpp> +#include <com/sun/star/rendering/TextDirection.hpp> + +#include <rtl/ustrbuf.hxx> +#include <boost/bind.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::presentation; +using namespace ::com::sun::star::drawing::framework; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +namespace { + const sal_Int32 ResourceActivationEventType = 0; + const sal_Int32 ResourceDeactivationEventType = 1; + const sal_Int32 ConfigurationUpdateEndEventType = 2; +} + + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + + +namespace sdext { namespace presenter { + +PresenterController::InstanceContainer PresenterController::maInstances; + +::rtl::Reference<PresenterController> PresenterController::Instance ( + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + InstanceContainer::const_iterator iInstance (maInstances.find(rxFrame)); + if (iInstance != maInstances.end()) + return iInstance->second; + else + return ::rtl::Reference<PresenterController>(); +} + + + + +PresenterController::PresenterController ( + const Reference<XComponentContext>& rxContext, + const Reference<frame::XController>& rxController, + const Reference<presentation::XSlideShowController>& rxSlideShowController, + const rtl::Reference<PresenterPaneContainer>& rpPaneContainer, + const Reference<XResourceId>& rxMainPaneId) + : PresenterControllerInterfaceBase(m_aMutex), + mxComponentContext(rxContext), + mxController(rxController), + mxConfigurationController(), + mxSlideShowController(rxSlideShowController), + mxMainPaneId(rxMainPaneId), + mpPaneContainer(rpPaneContainer), + mnCurrentSlideIndex(-1), + mxCurrentSlide(), + mxNextSlide(), + mpWindowManager(new PresenterWindowManager(rxContext,mpPaneContainer,this)), + mpCurrentPaneAnimation(), + mnWindowBackgroundColor(0x00ffffff), + mpTheme(), + mxMainWindow(), + mpPaneBorderPainter(), + mpAnimator(new PresenterAnimator()), + mpCanvasHelper(new PresenterCanvasHelper()), + mxPresenterHelper(), + mpPaintManager(), + mnPendingSlideNumber(-1), + mxUrlTransformer(), + mpAccessibleObject(), + mbIsAccessibilityActive(false) +{ + OSL_ASSERT(mxController.is()); + + if ( ! mxSlideShowController.is()) + throw new lang::IllegalArgumentException( + A2S("missing slide show controller"), + static_cast<XWeak*>(this), + 2); + + new PresenterCurrentSlideObserver(this,rxSlideShowController); + + // Listen for configuration changes. + Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW); + mxConfigurationController = xCM->getConfigurationController(); + if (mxConfigurationController.is()) + { + mxConfigurationController->addConfigurationChangeListener( + this, + A2S("ResourceActivation"), + Any(ResourceActivationEventType)); + mxConfigurationController->addConfigurationChangeListener( + this, + A2S("ResourceDeactivation"), + Any(ResourceDeactivationEventType)); + mxConfigurationController->addConfigurationChangeListener( + this, + A2S("ConfigurationUpdateEnd"), + Any(ConfigurationUpdateEndEventType)); + } + + // Listen for the frame being activated. + Reference<frame::XFrame> xFrame (mxController->getFrame()); + if (xFrame.is()) + xFrame->addFrameActionListener(this); + + // Create the border painter. + mpPaneBorderPainter = new PresenterPaneBorderPainter(rxContext); + mpWindowManager->SetPaneBorderPainter(mpPaneBorderPainter); + + // Create an object that is able to load the bitmaps in a format that is + // supported by the canvas. + Reference<lang::XMultiComponentFactory> xFactory ( + rxContext->getServiceManager(), UNO_QUERY); + if ( ! xFactory.is()) + return; + mxPresenterHelper = Reference<drawing::XPresenterHelper>( + xFactory->createInstanceWithContext( + A2S("com.sun.star.drawing.PresenterHelper"), + rxContext), + UNO_QUERY_THROW); + + if (mxSlideShowController.is()) + { + mxSlideShowController->activate(); + Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY); + if (xProperties.is()) + { + Reference<awt::XWindow> xWindow ( + xProperties->getPropertyValue(A2S("ParentWindow")), UNO_QUERY); + if (xWindow.is()) + xWindow->addKeyListener(this); + } + } + + UpdateCurrentSlide(0); + + maInstances[mxController->getFrame()] = this; + + // Create a URLTransformer. + if (xFactory.is()) + { + mxUrlTransformer = Reference<util::XURLTransformer>( + xFactory->createInstanceWithContext( + A2S("com.sun.star.util.URLTransformer"), + mxComponentContext), + UNO_QUERY); + } +} + + + + +PresenterController::~PresenterController (void) +{ +} + + + + +void PresenterController::disposing (void) +{ + maInstances.erase(mxController->getFrame()); + + if (mxMainWindow.is()) + { + mxMainWindow->removeKeyListener(this); + mxMainWindow->removeFocusListener(this); + mxMainWindow->removeMouseListener(this); + mxMainWindow->removeMouseMotionListener(this); + mxMainWindow = NULL; + } + if (mxConfigurationController.is()) + mxConfigurationController->removeConfigurationChangeListener(this); + + Reference<XComponent> xWindowManagerComponent ( + static_cast<XWeak*>(mpWindowManager.get()), UNO_QUERY); + mpWindowManager = NULL; + if (xWindowManagerComponent.is()) + xWindowManagerComponent->dispose(); + + if (mxController.is()) + { + Reference<frame::XFrame> xFrame (mxController->getFrame()); + if (xFrame.is()) + xFrame->removeFrameActionListener(this); + mxController = NULL; + } + + mxComponentContext = NULL; + mxConfigurationController = NULL; + mxSlideShowController = NULL; + mxMainPaneId = NULL; + mpPaneContainer = NULL; + mnCurrentSlideIndex = -1; + mxCurrentSlide = NULL; + mxNextSlide = NULL; + mpCurrentPaneAnimation.reset(); + mpTheme.reset(); + { + Reference<lang::XComponent> xComponent ( + static_cast<XWeak*>(mpPaneBorderPainter.get()), UNO_QUERY); + mpPaneBorderPainter = NULL; + if (xComponent.is()) + xComponent->dispose(); + } + mpAnimator.reset(); + mpCanvasHelper.reset(); + { + Reference<lang::XComponent> xComponent (mxPresenterHelper, UNO_QUERY); + mxPresenterHelper = NULL; + if (xComponent.is()) + xComponent->dispose(); + } + mpPaintManager.reset(); + mnPendingSlideNumber = -1; + { + Reference<lang::XComponent> xComponent (mxUrlTransformer, UNO_QUERY); + mxUrlTransformer = NULL; + if (xComponent.is()) + xComponent->dispose(); + } +} + + + + +void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset) +{ + GetSlides(nOffset); + UpdatePaneTitles(); + UpdateViews(); + + // Update the accessibility object. + if (IsAccessibilityActive()) + { + sal_Int32 nSlideCount (0); + Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); + if (xIndexAccess.is()) + nSlideCount = xIndexAccess->getCount(); + mpAccessibleObject->NotifyCurrentSlideChange(mnCurrentSlideIndex, nSlideCount); + } +} + + + + +void PresenterController::GetSlides (const sal_Int32 nOffset) +{ + if ( ! mxSlideShowController.is()) + return; + + // Get the current slide from the slide show controller. + mxCurrentSlide = NULL; + Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); + sal_Int32 nSlideIndex = -1; + try + { + nSlideIndex = mxSlideShowController->getCurrentSlideIndex() + nOffset; + if (mxSlideShowController->isPaused()) + nSlideIndex = -1; + + if (xIndexAccess.is() && nSlideIndex>=0) + { + if (nSlideIndex < xIndexAccess->getCount()) + { + mnCurrentSlideIndex = nSlideIndex; + mxCurrentSlide = Reference<drawing::XDrawPage>( + xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY); + } + } + } + catch (RuntimeException&) + { + } + + // Get the next slide. + mxNextSlide = NULL; + try + { + const sal_Int32 nNextSlideIndex (mxSlideShowController->getNextSlideIndex()+nOffset); + if (nNextSlideIndex >= 0) + { + if (xIndexAccess.is()) + { + if (nNextSlideIndex < xIndexAccess->getCount()) + mxNextSlide = Reference<drawing::XDrawPage>( + xIndexAccess->getByIndex(nNextSlideIndex), UNO_QUERY); + } + } + } + catch (RuntimeException&) + { + } +} + + + + +void PresenterController::UpdatePaneTitles (void) +{ + if ( ! mxSlideShowController.is()) + return; + + // Get placeholders and their values. + const OUString sCurrentSlideNumberPlaceholder (A2S("CURRENT_SLIDE_NUMBER")); + const OUString sCurrentSlideNamePlaceholder (A2S("CURRENT_SLIDE_NAME")); + const OUString sSlideCountPlaceholder (A2S("SLIDE_COUNT")); + + // Get string for slide count. + OUString sSlideCount (A2S("---")); + Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); + if (xIndexAccess.is()) + sSlideCount = OUString::valueOf(xIndexAccess->getCount()); + + // Get string for current slide index. + OUString sCurrentSlideNumber (OUString::valueOf(mnCurrentSlideIndex + 1)); + + // Get name of the current slide. + OUString sCurrentSlideName; + Reference<container::XNamed> xNamedSlide (mxCurrentSlide, UNO_QUERY); + if (xNamedSlide.is()) + sCurrentSlideName = xNamedSlide->getName(); + Reference<beans::XPropertySet> xSlideProperties (mxCurrentSlide, UNO_QUERY); + if (xSlideProperties.is()) + { + try + { + OUString sName; + if (xSlideProperties->getPropertyValue(A2S("LinkDisplayName")) >>= sName) + { + // Find out whether the name of the current slide has been + // automatically created or has been set by the user. + if (sName != sCurrentSlideName) + sCurrentSlideName = sName; + } + } + catch (beans::UnknownPropertyException&) + { + } + } + + // Replace the placeholders with their current values. + PresenterPaneContainer::PaneList::const_iterator iPane; + for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane) + { + OSL_ASSERT((*iPane).get() != NULL); + + OUString sTemplate (IsAccessibilityActive() + ? (*iPane)->msAccessibleTitleTemplate + : (*iPane)->msTitleTemplate); + if (sTemplate.getLength() <= 0) + continue; + + OUStringBuffer sResult; + sResult.ensureCapacity(sTemplate.getLength()); + + sal_Int32 nIndex (0); + while (true) + { + sal_Int32 nStartIndex = sTemplate.indexOf('%', nIndex); + if (nStartIndex < 0) + { + // Add the remaining part of the string. + sResult.append(sTemplate.copy(nIndex, sTemplate.getLength()-nIndex)); + break; + } + else + { + // Add the part preceding the next %. + sResult.append(sTemplate.copy(nIndex, nStartIndex-nIndex)); + + // Get the placeholder + ++nIndex; + ++nStartIndex; + const sal_Int32 nEndIndex (sTemplate.indexOf('%', nStartIndex+1)); + const OUString sPlaceholder (sTemplate.copy(nStartIndex, nEndIndex-nStartIndex)); + nIndex = nEndIndex+1; + + // Replace the placeholder with its current value. + if (sPlaceholder == sCurrentSlideNumberPlaceholder) + sResult.append(sCurrentSlideNumber); + else if (sPlaceholder == sCurrentSlideNamePlaceholder) + sResult.append(sCurrentSlideName); + else if (sPlaceholder == sSlideCountPlaceholder) + sResult.append(sSlideCount); + } + } + + (*iPane)->msTitle = sResult.makeStringAndClear(); + if ((*iPane)->mxPane.is()) + (*iPane)->mxPane->SetTitle((*iPane)->msTitle); + } +} + + + + +void PresenterController::UpdateViews (void) +{ + // Tell all views about the slides they should display. + PresenterPaneContainer::PaneList::const_iterator iPane; + for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane) + { + Reference<drawing::XDrawView> xDrawView ((*iPane)->mxView, UNO_QUERY); + if (xDrawView.is()) + xDrawView->setCurrentPage(mxCurrentSlide); + } +} + + + + +SharedBitmapDescriptor + PresenterController::GetViewBackground (const ::rtl::OUString& rsViewURL) const +{ + if (mpTheme.get() != NULL) + { + const OUString sStyleName (mpTheme->GetStyleName(rsViewURL)); + return mpTheme->GetBitmap(sStyleName, A2S("Background")); + } + return SharedBitmapDescriptor(); +} + + + + +PresenterTheme::SharedFontDescriptor + PresenterController::GetViewFont (const ::rtl::OUString& rsViewURL) const +{ + if (mpTheme.get() != NULL) + { + const OUString sStyleName (mpTheme->GetStyleName(rsViewURL)); + return mpTheme->GetFont(sStyleName); + } + return PresenterTheme::SharedFontDescriptor(); +} + + + + +::boost::shared_ptr<PresenterTheme> PresenterController::GetTheme (void) const +{ + return mpTheme; +} + + + + +::rtl::Reference<PresenterWindowManager> PresenterController::GetWindowManager (void) const +{ + return mpWindowManager; +} + + + + +Reference<presentation::XSlideShowController> + PresenterController::GetSlideShowController(void) const +{ + return mxSlideShowController; +} + + + + +rtl::Reference<PresenterPaneContainer> PresenterController::GetPaneContainer (void) const +{ + return mpPaneContainer; +} + + + + +::rtl::Reference<PresenterPaneBorderPainter> PresenterController::GetPaneBorderPainter (void) const +{ + return mpPaneBorderPainter; +} + + + + +::boost::shared_ptr<PresenterAnimator> PresenterController::GetAnimator (void) const +{ + return mpAnimator; +} + + + + +::boost::shared_ptr<PresenterCanvasHelper> PresenterController::GetCanvasHelper (void) const +{ + return mpCanvasHelper; +} + + + + +Reference<drawing::XPresenterHelper> PresenterController::GetPresenterHelper (void) const +{ + return mxPresenterHelper; +} + + + + +::boost::shared_ptr<PresenterPaintManager> PresenterController::GetPaintManager (void) const +{ + return mpPaintManager; +} + + + + +void PresenterController::HideSlideSorter (void) +{ + if (mpCurrentPaneAnimation.get() != NULL) + { + mpCurrentPaneAnimation->HidePane(); + mpCurrentPaneAnimation.reset(); + } +} + + + + +void PresenterController::ShowView (const OUString& rsViewURL) +{ + PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( + mpPaneContainer->FindViewURL(rsViewURL)); + if (pDescriptor.get() != NULL) + { + pDescriptor->mbIsActive = true; + mxConfigurationController->requestResourceActivation( + pDescriptor->mxPaneId, + ResourceActivationMode_ADD); + mxConfigurationController->requestResourceActivation( + ResourceId::createWithAnchor( + mxComponentContext, + rsViewURL, + pDescriptor->mxPaneId), + ResourceActivationMode_REPLACE); + } +} + + + + +void PresenterController::HideView (const OUString& rsViewURL) +{ + PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( + mpPaneContainer->FindViewURL(rsViewURL)); + if (pDescriptor.get() != NULL) + { + mxConfigurationController->requestResourceDeactivation( + ResourceId::createWithAnchor( + mxComponentContext, + rsViewURL, + pDescriptor->mxPaneId)); + } +} + + + + +bool PresenterController::IsViewVisible (const OUString& rsViewURL) const +{ + PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( + mpPaneContainer->FindViewURL(rsViewURL)); + if (pDescriptor.get() != NULL) + { + return mxConfigurationController->getResource( + ResourceId::createWithAnchor( + mxComponentContext, + rsViewURL, + pDescriptor->mxPaneId)).is(); + } + return false; +} + + + + +void PresenterController::DispatchUnoCommand (const OUString& rsCommand) const +{ + if ( ! mxUrlTransformer.is()) + return; + + util::URL aURL; + aURL.Complete = rsCommand; + mxUrlTransformer->parseStrict(aURL); + + Reference<frame::XDispatch> xDispatch (GetDispatch(aURL)); + if ( ! xDispatch.is()) + return; + + xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>()); +} + + + + +Reference<css::frame::XDispatch> PresenterController::GetDispatch (const util::URL& rURL) const +{ + if ( ! mxController.is()) + return NULL; + + Reference<frame::XDispatchProvider> xDispatchProvider (mxController->getFrame(), UNO_QUERY); + if ( ! xDispatchProvider.is()) + return NULL; + + return xDispatchProvider->queryDispatch( + rURL, + OUString(), + frame::FrameSearchFlag::SELF); +} + + + + +util::URL PresenterController::CreateURLFromString (const ::rtl::OUString& rsURL) const +{ + util::URL aURL; + + if (mxUrlTransformer.is()) + { + aURL.Complete = rsURL; + mxUrlTransformer->parseStrict(aURL); + } + + return aURL; +} + + + + +Reference<drawing::framework::XConfigurationController> + PresenterController::GetConfigurationController (void) const +{ + return mxConfigurationController; +} + + + + +Reference<drawing::XDrawPage> PresenterController::GetCurrentSlide (void) const +{ + return mxCurrentSlide; +} + + + + +::rtl::Reference<PresenterAccessible> PresenterController::GetAccessible (void) const +{ + return mpAccessibleObject; +} + + + + +void PresenterController::SetAccessibilityActiveState (const bool bIsActive) +{ + if ( mbIsAccessibilityActive != bIsActive) + { + mbIsAccessibilityActive = bIsActive; + UpdatePaneTitles(); + } +} + + + + +bool PresenterController::IsAccessibilityActive (void) const +{ + return mbIsAccessibilityActive; +} + + + + +void PresenterController::HandleMouseClick (const awt::MouseEvent& rEvent) +{ + if (mxSlideShowController.is()) + { + switch (rEvent.Buttons) + { + case awt::MouseButton::LEFT: + if (rEvent.Modifiers == awt::KeyModifier::MOD2) + mxSlideShowController->gotoNextSlide(); + else + mxSlideShowController->gotoNextEffect(); + break; + + case awt::MouseButton::RIGHT: + mxSlideShowController->gotoPreviousSlide(); + break; + + default: + // Other or multiple buttons. + break; + } + } +} + + + + +void PresenterController::RequestViews ( + const bool bIsSlideSorterActive, + const bool bIsNotesViewActive, + const bool bIsHelpViewActive) +{ + PresenterPaneContainer::PaneList::const_iterator iPane; + PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end()); + for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane) + { + bool bActivate (true); + const OUString sViewURL ((*iPane)->msViewURL); + if (sViewURL == PresenterViewFactory::msNotesViewURL) + { + bActivate = bIsNotesViewActive && !bIsSlideSorterActive && !bIsHelpViewActive; + } + else if (sViewURL == PresenterViewFactory::msSlideSorterURL) + { + bActivate = bIsSlideSorterActive; + } + else if (sViewURL == PresenterViewFactory::msCurrentSlidePreviewViewURL + || sViewURL == PresenterViewFactory::msNextSlidePreviewViewURL) + { + bActivate = !bIsSlideSorterActive && ! bIsHelpViewActive; + } + else if (sViewURL == PresenterViewFactory::msToolBarViewURL) + { + bActivate = true; + } + else if (sViewURL == PresenterViewFactory::msHelpViewURL) + { + bActivate = bIsHelpViewActive; + } + + if (bActivate) + ShowView(sViewURL); + else + HideView(sViewURL); + } +} + + + + +//----- XConfigurationChangeListener ------------------------------------------ + +void SAL_CALL PresenterController::notifyConfigurationChange ( + const ConfigurationChangeEvent& rEvent) + throw (RuntimeException) +{ + ThrowIfDisposed(); + + sal_Int32 nType (0); + if ( ! (rEvent.UserData >>= nType)) + return; + + switch (nType) + { + case ResourceActivationEventType: + if (rEvent.ResourceId->compareTo(mxMainPaneId) == 0) + { + InitializeMainPane(Reference<XPane>(rEvent.ResourceObject,UNO_QUERY)); + } + else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_DIRECT)) + { + // A pane bound to the main pane has been created and is + // stored in the pane container. + Reference<XPane> xPane (rEvent.ResourceObject,UNO_QUERY); + if (xPane.is()) + { + PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( + mpPaneContainer->FindPaneId(xPane->getResourceId())); + + // When there is a call out anchor location set then tell the + // window about it. + if (pDescriptor->mbHasCalloutAnchor) + pDescriptor->mxPane->SetCalloutAnchor( + pDescriptor->maCalloutAnchorLocation); + } + } + else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT)) + { + // A view bound to one of the panes has been created and is + // stored in the pane container along with its pane. + Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY); + if (xView.is()) + { + SharedBitmapDescriptor pViewBackground( + GetViewBackground(xView->getResourceId()->getResourceURL())); + mpPaneContainer->StoreView(xView, pViewBackground); + UpdateViews(); + mpWindowManager->NotifyViewCreation(xView); + } + } + break; + + case ResourceDeactivationEventType: + if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT)) + { + // If this is a view then remove it from the pane container. + Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY); + if (xView.is()) + { + PresenterPaneContainer::SharedPaneDescriptor pDescriptor( + mpPaneContainer->RemoveView(xView)); + + // A possibly opaque view has been removed. Update() + // updates the clip polygon. + mpWindowManager->Update(); + // Request the repainting of the area previously + // occupied by the view. + if (pDescriptor.get() != NULL) + GetPaintManager()->Invalidate(pDescriptor->mxBorderWindow); + } + } + break; + + case ConfigurationUpdateEndEventType: + if (IsAccessibilityActive()) + { + mpAccessibleObject->UpdateAccessibilityHierarchy(); + UpdateCurrentSlide(0); + } + break; + } +} + + + + +//----- XEventListener -------------------------------------------------------- + +void SAL_CALL PresenterController::disposing ( + const lang::EventObject& rEvent) + throw (RuntimeException) +{ + if (rEvent.Source == mxController) + mxController = NULL; + else if (rEvent.Source == mxConfigurationController) + mxConfigurationController = NULL; + else if (rEvent.Source == mxSlideShowController) + mxSlideShowController = NULL; + else if (rEvent.Source == mxMainWindow) + mxMainWindow = NULL; +} + + + + +//----- XFrameActionListener -------------------------------------------------- + +void SAL_CALL PresenterController::frameAction ( + const frame::FrameActionEvent& rEvent) + throw (RuntimeException) +{ + if (rEvent.Action == frame::FrameAction_FRAME_ACTIVATED) + { + if (mxSlideShowController.is()) + mxSlideShowController->activate(); + } +} + + + + +//----- XKeyListener ---------------------------------------------------------- + +void SAL_CALL PresenterController::keyPressed (const awt::KeyEvent& rEvent) + throw (RuntimeException) +{ + // Tell all views about the unhandled key event. + PresenterPaneContainer::PaneList::const_iterator iPane; + for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane) + { + if ( ! (*iPane)->mbIsActive) + continue; + + Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY); + if (xKeyListener.is()) + xKeyListener->keyPressed(rEvent); + } +} + + + + +void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent) + throw (RuntimeException) +{ + if (rEvent.Source != mxMainWindow) + return; + + switch (rEvent.KeyCode) + { + case awt::Key::ESCAPE: + case awt::Key::SUBTRACT: + { + if( mxController.is() ) + { + Reference< XPresentationSupplier > xPS( mxController->getModel(), UNO_QUERY ); + if( xPS.is() ) + { + Reference< XPresentation > xP( xPS->getPresentation() ); + if( xP.is() ) + xP->end(); + } + } + } + break; + + case awt::Key::PAGEDOWN: + if (mxSlideShowController.is()) + { + if (rEvent.Modifiers == awt::KeyModifier::MOD2) + mxSlideShowController->gotoNextSlide(); + else + mxSlideShowController->gotoNextEffect(); + } + break; + + case awt::Key::RIGHT: + case awt::Key::SPACE: + case awt::Key::DOWN: + case awt::Key::N: + if (mxSlideShowController.is()) + { + mxSlideShowController->gotoNextEffect(); + } + break; + + case awt::Key::LEFT: + case awt::Key::PAGEUP: + if (mxSlideShowController.is()) + { + if (rEvent.Modifiers == awt::KeyModifier::MOD2) + mxSlideShowController->gotoPreviousSlide(); + else + mxSlideShowController->gotoPreviousEffect(); + } + break; + + case awt::Key::UP: + case awt::Key::P: + case awt::Key::BACKSPACE: + if (mxSlideShowController.is()) + { + mxSlideShowController->gotoPreviousEffect(); + } + break; + + case awt::Key::HOME: + if (mxSlideShowController.is()) + { + mxSlideShowController->gotoFirstSlide(); + } + break; + + case awt::Key::END: + if (mxSlideShowController.is()) + { + mxSlideShowController->gotoLastSlide(); + } + break; + + case awt::Key::W: + case awt::Key::COMMA: + if (mxSlideShowController.is()) + { + if (mxSlideShowController->isPaused()) + mxSlideShowController->resume(); + else + mxSlideShowController->blankScreen(0x00ffffff); + } + break; + + case awt::Key::B: + case awt::Key::POINT: + if (mxSlideShowController.is()) + { + if (mxSlideShowController->isPaused()) + mxSlideShowController->resume(); + else + mxSlideShowController->blankScreen(0x00000000); + } + break; + + case awt::Key::NUM0: + case awt::Key::NUM1: + case awt::Key::NUM2: + case awt::Key::NUM3: + case awt::Key::NUM4: + case awt::Key::NUM5: + case awt::Key::NUM6: + case awt::Key::NUM7: + case awt::Key::NUM8: + case awt::Key::NUM9: + HandleNumericKeyPress(rEvent.KeyCode-awt::Key::NUM0, rEvent.Modifiers); + break; + + case awt::Key::RETURN: + if (mnPendingSlideNumber > 0) + { + if (mxSlideShowController.is()) + mxSlideShowController->gotoSlideIndex(mnPendingSlideNumber - 1); + mnPendingSlideNumber = -1; + } + else + { + if (mxSlideShowController.is()) + mxSlideShowController->gotoNextEffect(); + } + + break; + + case awt::Key::F1: + // Toggle the help view. + if (mpWindowManager.get() != NULL) + if (mpWindowManager->GetViewMode() != PresenterWindowManager::VM_Help) + mpWindowManager->SetViewMode(PresenterWindowManager::VM_Help); + else + mpWindowManager->SetHelpViewState(false); + + break; + + default: + // Tell all views about the unhandled key event. + PresenterPaneContainer::PaneList::const_iterator iPane; + for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane) + { + if ( ! (*iPane)->mbIsActive) + continue; + + Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY); + if (xKeyListener.is()) + xKeyListener->keyReleased(rEvent); + } + break; + } +} + + + + +void PresenterController::HandleNumericKeyPress ( + const sal_Int32 nKey, + const sal_Int32 nModifiers) +{ + switch (nModifiers) + { + case 0: + if (mnPendingSlideNumber == -1) + mnPendingSlideNumber = 0; + UpdatePendingSlideNumber(mnPendingSlideNumber * 10 + nKey); + break; + + case awt::KeyModifier::MOD1: + // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views + // (slide view, notes view, normal) + mnPendingSlideNumber = -1; + if (mpWindowManager.get() == NULL) + return; + switch(nKey) + { + case 1: + mpWindowManager->SetViewMode(PresenterWindowManager::VM_Standard); + break; + case 2: + mpWindowManager->SetViewMode(PresenterWindowManager::VM_Notes); + break; + case 3: + mpWindowManager->SetViewMode(PresenterWindowManager::VM_SlideOverview); + break; + default: + // Ignore unsupported key. + break; + } + + default: + // Ignore unsupported modifiers. + break; + } +} + + + + +//----- XFocusListener -------------------------------------------------------- + +void SAL_CALL PresenterController::focusGained (const css::awt::FocusEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterController::focusLost (const css::awt::FocusEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +//----- XMouseListener -------------------------------------------------------- + +void SAL_CALL PresenterController::mousePressed (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; + if (mxMainWindow.is()) + mxMainWindow->setFocus(); +} + + + + +void SAL_CALL PresenterController::mouseReleased (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterController::mouseEntered (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterController::mouseExited (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +//----- XMouseMotionListener -------------------------------------------------- + +void SAL_CALL PresenterController::mouseMoved (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterController::mouseDragged (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +//----------------------------------------------------------------------------- + +void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane) +{ + if ( ! rxPane.is()) + return; + + mpAccessibleObject = new PresenterAccessible( + mxComponentContext, + this, + rxPane); + + LoadTheme(rxPane); + + // Main pane has been created and is now observed by the window + // manager. + mpWindowManager->SetParentPane(rxPane); + mpWindowManager->SetTheme(mpTheme); + + if (mpPaneBorderPainter.get() != NULL) + mpPaneBorderPainter->SetTheme(mpTheme); + + // Add key listener + mxMainWindow = rxPane->getWindow(); + if (mxMainWindow.is()) + { + mxMainWindow->addKeyListener(this); + mxMainWindow->addFocusListener(this); + mxMainWindow->addMouseListener(this); + mxMainWindow->addMouseMotionListener(this); + } + Reference<XPane2> xPane2 (rxPane, UNO_QUERY); + if (xPane2.is()) + xPane2->setVisible(sal_True); + + mpPaintManager.reset(new PresenterPaintManager(mxMainWindow, mxPresenterHelper, mpPaneContainer)); + + mxCanvas = Reference<rendering::XSpriteCanvas>(rxPane->getCanvas(), UNO_QUERY); + + if (mxSlideShowController.is()) + mxSlideShowController->activate(); + + UpdateCurrentSlide(0); +} + + + + +void PresenterController::LoadTheme (const Reference<XPane>& rxPane) +{ + // Create (load) the current theme. + if (rxPane.is()) + mpTheme.reset(new PresenterTheme(mxComponentContext, OUString(), rxPane->getCanvas())); +} + + + + +double PresenterController::GetSlideAspectRatio (void) const +{ + double nSlideAspectRatio (28.0/21.0); + + try + { + if (mxController.is()) + { + Reference<drawing::XDrawPagesSupplier> xSlideSupplier ( + mxController->getModel(), UNO_QUERY_THROW); + Reference<drawing::XDrawPages> xSlides (xSlideSupplier->getDrawPages()); + if (xSlides.is() && xSlides->getCount()>0) + { + Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW); + sal_Int32 nWidth (28000); + sal_Int32 nHeight (21000); + if ((xProperties->getPropertyValue(OUString::createFromAscii("Width")) >>= nWidth) + && (xProperties->getPropertyValue(OUString::createFromAscii("Height")) >>= nHeight) + && nHeight > 0) + { + nSlideAspectRatio = double(nWidth) / double(nHeight); + } + } + } + } + catch (RuntimeException&) + { + OSL_ASSERT(false); + } + + return nSlideAspectRatio; +} + + + + +void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber) +{ + mnPendingSlideNumber = nPendingSlideNumber; + + if (mpTheme.get() == NULL) + return; + + if ( ! mxMainWindow.is()) + return; + + PresenterTheme::SharedFontDescriptor pFont ( + mpTheme->GetFont(A2S("PendingSlideNumberFont"))); + if (pFont.get() == NULL) + return; + + pFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY)); + if ( ! pFont->mxFont.is()) + return; + + const OUString sText (OUString::valueOf(mnPendingSlideNumber)); + rendering::StringContext aContext (sText, 0, sText.getLength()); + Reference<rendering::XTextLayout> xLayout ( + pFont->mxFont->createTextLayout( + aContext, + rendering::TextDirection::WEAK_LEFT_TO_RIGHT, + 0)); +} + + + + +void PresenterController::ThrowIfDisposed (void) const + throw (::com::sun::star::lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "PresenterController object has already been disposed")), + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + + +} } // end of namespace ::sdext::presenter + |