/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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::Instance ( const css::uno::Reference& rxFrame) { InstanceContainer::const_iterator iInstance (maInstances.find(rxFrame)); if (iInstance != maInstances.end()) return iInstance->second; else return ::rtl::Reference(); } PresenterController::PresenterController ( const Reference& rxContext, const Reference& rxController, const Reference& rxSlideShowController, const rtl::Reference& rpPaneContainer, const Reference& 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(this), 2); new PresenterCurrentSlideObserver(this,rxSlideShowController); // Listen for configuration changes. Reference 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 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 xFactory ( rxContext->getServiceManager(), UNO_QUERY); if ( ! xFactory.is()) return; mxPresenterHelper = Reference( xFactory->createInstanceWithContext( A2S("com.sun.star.drawing.PresenterHelper"), rxContext), UNO_QUERY_THROW); if (mxSlideShowController.is()) { mxSlideShowController->activate(); Reference xProperties (mxSlideShowController, UNO_QUERY); if (xProperties.is()) { Reference 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( 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 xWindowManagerComponent ( static_cast(mpWindowManager.get()), UNO_QUERY); mpWindowManager = NULL; if (xWindowManagerComponent.is()) xWindowManagerComponent->dispose(); if (mxController.is()) { Reference 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 xComponent ( static_cast(mpPaneBorderPainter.get()), UNO_QUERY); mpPaneBorderPainter = NULL; if (xComponent.is()) xComponent->dispose(); } mpAnimator.reset(); mpCanvasHelper.reset(); { Reference xComponent (mxPresenterHelper, UNO_QUERY); mxPresenterHelper = NULL; if (xComponent.is()) xComponent->dispose(); } mpPaintManager.reset(); mnPendingSlideNumber = -1; { Reference 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 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 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( 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( 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 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 xNamedSlide (mxCurrentSlide, UNO_QUERY); if (xNamedSlide.is()) sCurrentSlideName = xNamedSlide->getName(); Reference 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 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 PresenterController::GetTheme (void) const { return mpTheme; } ::rtl::Reference PresenterController::GetWindowManager (void) const { return mpWindowManager; } Reference PresenterController::GetSlideShowController(void) const { return mxSlideShowController; } rtl::Reference PresenterController::GetPaneContainer (void) const { return mpPaneContainer; } ::rtl::Reference PresenterController::GetPaneBorderPainter (void) const { return mpPaneBorderPainter; } ::boost::shared_ptr PresenterController::GetAnimator (void) const { return mpAnimator; } ::boost::shared_ptr PresenterController::GetCanvasHelper (void) const { return mpCanvasHelper; } Reference PresenterController::GetPresenterHelper (void) const { return mxPresenterHelper; } ::boost::shared_ptr 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 xDispatch (GetDispatch(aURL)); if ( ! xDispatch.is()) return; xDispatch->dispatch(aURL, Sequence()); } Reference PresenterController::GetDispatch (const util::URL& rURL) const { if ( ! mxController.is()) return NULL; Reference 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 PresenterController::GetConfigurationController (void) const { return mxConfigurationController; } Reference PresenterController::GetCurrentSlide (void) const { return mxCurrentSlide; } ::rtl::Reference 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(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 (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 (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 (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 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::PAGEUP: if (mxSlideShowController.is()) { if (rEvent.Modifiers == awt::KeyModifier::MOD2) mxSlideShowController->gotoPreviousSlide(); else mxSlideShowController->gotoPreviousEffect(); } break; case awt::Key::LEFT: 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 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& 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 (rxPane, UNO_QUERY); if (xPane2.is()) xPane2->setVisible(sal_True); mpPaintManager.reset(new PresenterPaintManager(mxMainWindow, mxPresenterHelper, mpPaneContainer)); mxCanvas = Reference(rxPane->getCanvas(), UNO_QUERY); if (mxSlideShowController.is()) mxSlideShowController->activate(); UpdateCurrentSlide(0); } void PresenterController::LoadTheme (const Reference& 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 xSlideSupplier ( mxController->getModel(), UNO_QUERY_THROW); Reference xSlides (xSlideSupplier->getDrawPages()); if (xSlides.is() && xSlides->getCount()>0) { Reference 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(mxCanvas, UNO_QUERY)); if ( ! pFont->mxFont.is()) return; const OUString sText (OUString::valueOf(mnPendingSlideNumber)); rendering::StringContext aContext (sText, 0, sText.getLength()); Reference 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(static_cast(this))); } } } } // end of namespace ::sdext::presenter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */