| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 |
| |