Update ooo320-m1
[ooovba.git] / sdext / source / presenter / PresenterController.cxx
blobb8dff941458840cd778852628d1363b17cf110ca
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterController.cxx,v $
11 * $Revision: 1.5 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterController.hxx"
37 #include "PresenterAccessibility.hxx"
38 #include "PresenterAnimator.hxx"
39 #include "PresenterCanvasHelper.hxx"
40 #include "PresenterCurrentSlideObserver.hxx"
41 #include "PresenterFrameworkObserver.hxx"
42 #include "PresenterHelper.hxx"
43 #include "PresenterNotesView.hxx"
44 #include "PresenterPaintManager.hxx"
45 #include "PresenterPaneAnimator.hxx"
46 #include "PresenterPaneBase.hxx"
47 #include "PresenterPaneContainer.hxx"
48 #include "PresenterPaneBorderPainter.hxx"
49 #include "PresenterTheme.hxx"
50 #include "PresenterViewFactory.hxx"
51 #include "PresenterWindowManager.hxx"
53 #include <com/sun/star/accessibility/AccessibleRole.hpp>
54 #include <com/sun/star/accessibility/XAccessible.hpp>
55 #include <com/sun/star/awt/Key.hpp>
56 #include <com/sun/star/awt/KeyModifier.hpp>
57 #include <com/sun/star/awt/MouseButton.hpp>
58 #include <com/sun/star/awt/XWindowPeer.hpp>
59 #include <com/sun/star/container/XNamed.hpp>
60 #include <com/sun/star/drawing/XDrawView.hpp>
61 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
62 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
63 #include <com/sun/star/drawing/framework/ResourceId.hpp>
64 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
65 #include <com/sun/star/frame/FrameSearchFlag.hpp>
66 #include <com/sun/star/frame/XDispatchProvider.hpp>
67 #include <com/sun/star/presentation/XPresentation.hpp>
68 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
69 #include <com/sun/star/rendering/CompositeOperation.hpp>
70 #include <com/sun/star/rendering/TextDirection.hpp>
72 #include <rtl/ustrbuf.hxx>
73 #include <boost/bind.hpp>
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::presentation;
78 using namespace ::com::sun::star::drawing::framework;
79 using ::rtl::OUString;
80 using ::rtl::OUStringBuffer;
82 namespace {
83 const sal_Int32 ResourceActivationEventType = 0;
84 const sal_Int32 ResourceDeactivationEventType = 1;
85 const sal_Int32 ConfigurationUpdateEndEventType = 2;
89 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
92 namespace sdext { namespace presenter {
94 PresenterController::InstanceContainer PresenterController::maInstances;
96 ::rtl::Reference<PresenterController> PresenterController::Instance (
97 const css::uno::Reference<css::frame::XFrame>& rxFrame)
99 InstanceContainer::const_iterator iInstance (maInstances.find(rxFrame));
100 if (iInstance != maInstances.end())
101 return iInstance->second;
102 else
103 return ::rtl::Reference<PresenterController>();
109 PresenterController::PresenterController (
110 const Reference<XComponentContext>& rxContext,
111 const Reference<frame::XController>& rxController,
112 const Reference<presentation::XSlideShowController>& rxSlideShowController,
113 const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
114 const Reference<XResourceId>& rxMainPaneId)
115 : PresenterControllerInterfaceBase(m_aMutex),
116 mxComponentContext(rxContext),
117 mxController(rxController),
118 mxConfigurationController(),
119 mxSlideShowController(rxSlideShowController),
120 mxMainPaneId(rxMainPaneId),
121 mpPaneContainer(rpPaneContainer),
122 mnCurrentSlideIndex(-1),
123 mxCurrentSlide(),
124 mxNextSlide(),
125 mpWindowManager(new PresenterWindowManager(rxContext,mpPaneContainer,this)),
126 mpCurrentPaneAnimation(),
127 mnWindowBackgroundColor(0x00ffffff),
128 mpTheme(),
129 mxMainWindow(),
130 mpPaneBorderPainter(),
131 mpAnimator(new PresenterAnimator()),
132 mpCanvasHelper(new PresenterCanvasHelper()),
133 mxPresenterHelper(),
134 mpPaintManager(),
135 mnPendingSlideNumber(-1),
136 mxUrlTransformer(),
137 mpAccessibleObject(),
138 mbIsAccessibilityActive(false)
140 OSL_ASSERT(mxController.is());
142 if ( ! mxSlideShowController.is())
143 throw new lang::IllegalArgumentException(
144 A2S("missing slide show controller"),
145 static_cast<XWeak*>(this),
148 new PresenterCurrentSlideObserver(this,rxSlideShowController);
150 // Listen for configuration changes.
151 Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
152 mxConfigurationController = xCM->getConfigurationController();
153 if (mxConfigurationController.is())
155 mxConfigurationController->addConfigurationChangeListener(
156 this,
157 A2S("ResourceActivation"),
158 Any(ResourceActivationEventType));
159 mxConfigurationController->addConfigurationChangeListener(
160 this,
161 A2S("ResourceDeactivation"),
162 Any(ResourceDeactivationEventType));
163 mxConfigurationController->addConfigurationChangeListener(
164 this,
165 A2S("ConfigurationUpdateEnd"),
166 Any(ConfigurationUpdateEndEventType));
169 // Listen for the frame being activated.
170 Reference<frame::XFrame> xFrame (mxController->getFrame());
171 if (xFrame.is())
172 xFrame->addFrameActionListener(this);
174 // Create the border painter.
175 mpPaneBorderPainter = new PresenterPaneBorderPainter(rxContext);
176 mpWindowManager->SetPaneBorderPainter(mpPaneBorderPainter);
178 // Create an object that is able to load the bitmaps in a format that is
179 // supported by the canvas.
180 Reference<lang::XMultiComponentFactory> xFactory (
181 rxContext->getServiceManager(), UNO_QUERY);
182 if ( ! xFactory.is())
183 return;
184 mxPresenterHelper = Reference<drawing::XPresenterHelper>(
185 xFactory->createInstanceWithContext(
186 A2S("com.sun.star.drawing.PresenterHelper"),
187 rxContext),
188 UNO_QUERY_THROW);
190 if (mxSlideShowController.is())
192 mxSlideShowController->activate();
193 Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY);
194 if (xProperties.is())
196 Reference<awt::XWindow> xWindow (
197 xProperties->getPropertyValue(A2S("ParentWindow")), UNO_QUERY);
198 if (xWindow.is())
199 xWindow->addKeyListener(this);
203 UpdateCurrentSlide(0);
205 maInstances[mxController->getFrame()] = this;
207 // Create a URLTransformer.
208 if (xFactory.is())
210 mxUrlTransformer = Reference<util::XURLTransformer>(
211 xFactory->createInstanceWithContext(
212 A2S("com.sun.star.util.URLTransformer"),
213 mxComponentContext),
214 UNO_QUERY);
221 PresenterController::~PresenterController (void)
228 void PresenterController::disposing (void)
230 maInstances.erase(mxController->getFrame());
232 if (mxMainWindow.is())
234 mxMainWindow->removeKeyListener(this);
235 mxMainWindow->removeFocusListener(this);
236 mxMainWindow->removeMouseListener(this);
237 mxMainWindow->removeMouseMotionListener(this);
238 mxMainWindow = NULL;
240 if (mxConfigurationController.is())
241 mxConfigurationController->removeConfigurationChangeListener(this);
243 Reference<XComponent> xWindowManagerComponent (
244 static_cast<XWeak*>(mpWindowManager.get()), UNO_QUERY);
245 mpWindowManager = NULL;
246 if (xWindowManagerComponent.is())
247 xWindowManagerComponent->dispose();
249 if (mxController.is())
251 Reference<frame::XFrame> xFrame (mxController->getFrame());
252 if (xFrame.is())
253 xFrame->removeFrameActionListener(this);
254 mxController = NULL;
257 mxComponentContext = NULL;
258 mxConfigurationController = NULL;
259 mxSlideShowController = NULL;
260 mxMainPaneId = NULL;
261 mpPaneContainer = NULL;
262 mnCurrentSlideIndex = -1;
263 mxCurrentSlide = NULL;
264 mxNextSlide = NULL;
265 mpCurrentPaneAnimation.reset();
266 mpTheme.reset();
268 Reference<lang::XComponent> xComponent (
269 static_cast<XWeak*>(mpPaneBorderPainter.get()), UNO_QUERY);
270 mpPaneBorderPainter = NULL;
271 if (xComponent.is())
272 xComponent->dispose();
274 mpAnimator.reset();
275 mpCanvasHelper.reset();
277 Reference<lang::XComponent> xComponent (mxPresenterHelper, UNO_QUERY);
278 mxPresenterHelper = NULL;
279 if (xComponent.is())
280 xComponent->dispose();
282 mpPaintManager.reset();
283 mnPendingSlideNumber = -1;
285 Reference<lang::XComponent> xComponent (mxUrlTransformer, UNO_QUERY);
286 mxUrlTransformer = NULL;
287 if (xComponent.is())
288 xComponent->dispose();
295 void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset)
297 GetSlides(nOffset);
298 UpdatePaneTitles();
299 UpdateViews();
301 // Update the accessibility object.
302 if (IsAccessibilityActive())
304 sal_Int32 nSlideCount (0);
305 Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
306 if (xIndexAccess.is())
307 nSlideCount = xIndexAccess->getCount();
308 mpAccessibleObject->NotifyCurrentSlideChange(mnCurrentSlideIndex, nSlideCount);
315 void PresenterController::GetSlides (const sal_Int32 nOffset)
317 if ( ! mxSlideShowController.is())
318 return;
320 // Get the current slide from the slide show controller.
321 mxCurrentSlide = NULL;
322 Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
323 sal_Int32 nSlideIndex = -1;
326 nSlideIndex = mxSlideShowController->getCurrentSlideIndex() + nOffset;
327 if (mxSlideShowController->isPaused())
328 nSlideIndex = -1;
330 if (xIndexAccess.is() && nSlideIndex>=0)
332 if (nSlideIndex < xIndexAccess->getCount())
334 mnCurrentSlideIndex = nSlideIndex;
335 mxCurrentSlide = Reference<drawing::XDrawPage>(
336 xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY);
340 catch (RuntimeException&)
344 // Get the next slide.
345 mxNextSlide = NULL;
348 const sal_Int32 nNextSlideIndex (mxSlideShowController->getNextSlideIndex()+nOffset);
349 if (nNextSlideIndex >= 0)
351 if (xIndexAccess.is())
353 if (nNextSlideIndex < xIndexAccess->getCount())
354 mxNextSlide = Reference<drawing::XDrawPage>(
355 xIndexAccess->getByIndex(nNextSlideIndex), UNO_QUERY);
359 catch (RuntimeException&)
367 void PresenterController::UpdatePaneTitles (void)
369 if ( ! mxSlideShowController.is())
370 return;
372 // Get placeholders and their values.
373 const OUString sCurrentSlideNumberPlaceholder (A2S("CURRENT_SLIDE_NUMBER"));
374 const OUString sCurrentSlideNamePlaceholder (A2S("CURRENT_SLIDE_NAME"));
375 const OUString sSlideCountPlaceholder (A2S("SLIDE_COUNT"));
377 // Get string for slide count.
378 OUString sSlideCount (A2S("---"));
379 Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
380 if (xIndexAccess.is())
381 sSlideCount = OUString::valueOf(xIndexAccess->getCount());
383 // Get string for current slide index.
384 OUString sCurrentSlideNumber (OUString::valueOf(mnCurrentSlideIndex + 1));
386 // Get name of the current slide.
387 OUString sCurrentSlideName;
388 Reference<container::XNamed> xNamedSlide (mxCurrentSlide, UNO_QUERY);
389 if (xNamedSlide.is())
390 sCurrentSlideName = xNamedSlide->getName();
391 Reference<beans::XPropertySet> xSlideProperties (mxCurrentSlide, UNO_QUERY);
392 if (xSlideProperties.is())
396 OUString sName;
397 if (xSlideProperties->getPropertyValue(A2S("LinkDisplayName")) >>= sName)
399 // Find out whether the name of the current slide has been
400 // automatically created or has been set by the user.
401 if (sName != sCurrentSlideName)
402 sCurrentSlideName = sName;
405 catch (beans::UnknownPropertyException&)
410 // Replace the placeholders with their current values.
411 PresenterPaneContainer::PaneList::const_iterator iPane;
412 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
414 OSL_ASSERT((*iPane).get() != NULL);
416 OUString sTemplate (IsAccessibilityActive()
417 ? (*iPane)->msAccessibleTitleTemplate
418 : (*iPane)->msTitleTemplate);
419 if (sTemplate.getLength() <= 0)
420 continue;
422 OUStringBuffer sResult;
423 sResult.ensureCapacity(sTemplate.getLength());
425 sal_Int32 nIndex (0);
426 while (true)
428 sal_Int32 nStartIndex = sTemplate.indexOf('%', nIndex);
429 if (nStartIndex < 0)
431 // Add the remaining part of the string.
432 sResult.append(sTemplate.copy(nIndex, sTemplate.getLength()-nIndex));
433 break;
435 else
437 // Add the part preceding the next %.
438 sResult.append(sTemplate.copy(nIndex, nStartIndex-nIndex));
440 // Get the placeholder
441 ++nIndex;
442 ++nStartIndex;
443 const sal_Int32 nEndIndex (sTemplate.indexOf('%', nStartIndex+1));
444 const OUString sPlaceholder (sTemplate.copy(nStartIndex, nEndIndex-nStartIndex));
445 nIndex = nEndIndex+1;
447 // Replace the placeholder with its current value.
448 if (sPlaceholder == sCurrentSlideNumberPlaceholder)
449 sResult.append(sCurrentSlideNumber);
450 else if (sPlaceholder == sCurrentSlideNamePlaceholder)
451 sResult.append(sCurrentSlideName);
452 else if (sPlaceholder == sSlideCountPlaceholder)
453 sResult.append(sSlideCount);
457 (*iPane)->msTitle = sResult.makeStringAndClear();
458 if ((*iPane)->mxPane.is())
459 (*iPane)->mxPane->SetTitle((*iPane)->msTitle);
466 void PresenterController::UpdateViews (void)
468 // Tell all views about the slides they should display.
469 PresenterPaneContainer::PaneList::const_iterator iPane;
470 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
472 Reference<drawing::XDrawView> xDrawView ((*iPane)->mxView, UNO_QUERY);
473 if (xDrawView.is())
474 xDrawView->setCurrentPage(mxCurrentSlide);
481 SharedBitmapDescriptor
482 PresenterController::GetViewBackground (const ::rtl::OUString& rsViewURL) const
484 if (mpTheme.get() != NULL)
486 const OUString sStyleName (mpTheme->GetStyleName(rsViewURL));
487 return mpTheme->GetBitmap(sStyleName, A2S("Background"));
489 return SharedBitmapDescriptor();
495 PresenterTheme::SharedFontDescriptor
496 PresenterController::GetViewFont (const ::rtl::OUString& rsViewURL) const
498 if (mpTheme.get() != NULL)
500 const OUString sStyleName (mpTheme->GetStyleName(rsViewURL));
501 return mpTheme->GetFont(sStyleName);
503 return PresenterTheme::SharedFontDescriptor();
509 ::boost::shared_ptr<PresenterTheme> PresenterController::GetTheme (void) const
511 return mpTheme;
517 ::rtl::Reference<PresenterWindowManager> PresenterController::GetWindowManager (void) const
519 return mpWindowManager;
525 Reference<presentation::XSlideShowController>
526 PresenterController::GetSlideShowController(void) const
528 return mxSlideShowController;
534 rtl::Reference<PresenterPaneContainer> PresenterController::GetPaneContainer (void) const
536 return mpPaneContainer;
542 ::rtl::Reference<PresenterPaneBorderPainter> PresenterController::GetPaneBorderPainter (void) const
544 return mpPaneBorderPainter;
550 ::boost::shared_ptr<PresenterAnimator> PresenterController::GetAnimator (void) const
552 return mpAnimator;
558 ::boost::shared_ptr<PresenterCanvasHelper> PresenterController::GetCanvasHelper (void) const
560 return mpCanvasHelper;
566 Reference<drawing::XPresenterHelper> PresenterController::GetPresenterHelper (void) const
568 return mxPresenterHelper;
574 ::boost::shared_ptr<PresenterPaintManager> PresenterController::GetPaintManager (void) const
576 return mpPaintManager;
582 void PresenterController::HideSlideSorter (void)
584 if (mpCurrentPaneAnimation.get() != NULL)
586 mpCurrentPaneAnimation->HidePane();
587 mpCurrentPaneAnimation.reset();
594 void PresenterController::ShowView (const OUString& rsViewURL)
596 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
597 mpPaneContainer->FindViewURL(rsViewURL));
598 if (pDescriptor.get() != NULL)
600 pDescriptor->mbIsActive = true;
601 mxConfigurationController->requestResourceActivation(
602 pDescriptor->mxPaneId,
603 ResourceActivationMode_ADD);
604 mxConfigurationController->requestResourceActivation(
605 ResourceId::createWithAnchor(
606 mxComponentContext,
607 rsViewURL,
608 pDescriptor->mxPaneId),
609 ResourceActivationMode_REPLACE);
616 void PresenterController::HideView (const OUString& rsViewURL)
618 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
619 mpPaneContainer->FindViewURL(rsViewURL));
620 if (pDescriptor.get() != NULL)
622 mxConfigurationController->requestResourceDeactivation(
623 ResourceId::createWithAnchor(
624 mxComponentContext,
625 rsViewURL,
626 pDescriptor->mxPaneId));
633 bool PresenterController::IsViewVisible (const OUString& rsViewURL) const
635 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
636 mpPaneContainer->FindViewURL(rsViewURL));
637 if (pDescriptor.get() != NULL)
639 return mxConfigurationController->getResource(
640 ResourceId::createWithAnchor(
641 mxComponentContext,
642 rsViewURL,
643 pDescriptor->mxPaneId)).is();
645 return false;
651 void PresenterController::DispatchUnoCommand (const OUString& rsCommand) const
653 if ( ! mxUrlTransformer.is())
654 return;
656 util::URL aURL;
657 aURL.Complete = rsCommand;
658 mxUrlTransformer->parseStrict(aURL);
660 Reference<frame::XDispatch> xDispatch (GetDispatch(aURL));
661 if ( ! xDispatch.is())
662 return;
664 xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>());
670 Reference<css::frame::XDispatch> PresenterController::GetDispatch (const util::URL& rURL) const
672 if ( ! mxController.is())
673 return NULL;
675 Reference<frame::XDispatchProvider> xDispatchProvider (mxController->getFrame(), UNO_QUERY);
676 if ( ! xDispatchProvider.is())
677 return NULL;
679 return xDispatchProvider->queryDispatch(
680 rURL,
681 OUString(),
682 frame::FrameSearchFlag::SELF);
688 util::URL PresenterController::CreateURLFromString (const ::rtl::OUString& rsURL) const
690 util::URL aURL;
692 if (mxUrlTransformer.is())
694 aURL.Complete = rsURL;
695 mxUrlTransformer->parseStrict(aURL);
698 return aURL;
704 Reference<drawing::framework::XConfigurationController>
705 PresenterController::GetConfigurationController (void) const
707 return mxConfigurationController;
713 Reference<drawing::XDrawPage> PresenterController::GetCurrentSlide (void) const
715 return mxCurrentSlide;
721 ::rtl::Reference<PresenterAccessible> PresenterController::GetAccessible (void) const
723 return mpAccessibleObject;
729 void PresenterController::SetAccessibilityActiveState (const bool bIsActive)
731 if ( mbIsAccessibilityActive != bIsActive)
733 mbIsAccessibilityActive = bIsActive;
734 UpdatePaneTitles();
741 bool PresenterController::IsAccessibilityActive (void) const
743 return mbIsAccessibilityActive;
749 void PresenterController::HandleMouseClick (const awt::MouseEvent& rEvent)
751 if (mxSlideShowController.is())
753 switch (rEvent.Buttons)
755 case awt::MouseButton::LEFT:
756 if (rEvent.Modifiers == awt::KeyModifier::MOD2)
757 mxSlideShowController->gotoNextSlide();
758 else
759 mxSlideShowController->gotoNextEffect();
760 break;
762 case awt::MouseButton::RIGHT:
763 mxSlideShowController->gotoPreviousSlide();
764 break;
766 default:
767 // Other or multiple buttons.
768 break;
776 void PresenterController::RequestViews (
777 const bool bIsSlideSorterActive,
778 const bool bIsNotesViewActive,
779 const bool bIsHelpViewActive)
781 PresenterPaneContainer::PaneList::const_iterator iPane;
782 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
783 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
785 bool bActivate (true);
786 const OUString sViewURL ((*iPane)->msViewURL);
787 if (sViewURL == PresenterViewFactory::msNotesViewURL)
789 bActivate = bIsNotesViewActive && !bIsSlideSorterActive && !bIsHelpViewActive;
791 else if (sViewURL == PresenterViewFactory::msSlideSorterURL)
793 bActivate = bIsSlideSorterActive;
795 else if (sViewURL == PresenterViewFactory::msCurrentSlidePreviewViewURL
796 || sViewURL == PresenterViewFactory::msNextSlidePreviewViewURL)
798 bActivate = !bIsSlideSorterActive && ! bIsHelpViewActive;
800 else if (sViewURL == PresenterViewFactory::msToolBarViewURL)
802 bActivate = true;
804 else if (sViewURL == PresenterViewFactory::msHelpViewURL)
806 bActivate = bIsHelpViewActive;
809 if (bActivate)
810 ShowView(sViewURL);
811 else
812 HideView(sViewURL);
819 //----- XConfigurationChangeListener ------------------------------------------
821 void SAL_CALL PresenterController::notifyConfigurationChange (
822 const ConfigurationChangeEvent& rEvent)
823 throw (RuntimeException)
825 ThrowIfDisposed();
827 sal_Int32 nType (0);
828 if ( ! (rEvent.UserData >>= nType))
829 return;
831 switch (nType)
833 case ResourceActivationEventType:
834 if (rEvent.ResourceId->compareTo(mxMainPaneId) == 0)
836 InitializeMainPane(Reference<XPane>(rEvent.ResourceObject,UNO_QUERY));
838 else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_DIRECT))
840 // A pane bound to the main pane has been created and is
841 // stored in the pane container.
842 Reference<XPane> xPane (rEvent.ResourceObject,UNO_QUERY);
843 if (xPane.is())
845 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
846 mpPaneContainer->FindPaneId(xPane->getResourceId()));
848 // When there is a call out anchor location set then tell the
849 // window about it.
850 if (pDescriptor->mbHasCalloutAnchor)
851 pDescriptor->mxPane->SetCalloutAnchor(
852 pDescriptor->maCalloutAnchorLocation);
855 else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT))
857 // A view bound to one of the panes has been created and is
858 // stored in the pane container along with its pane.
859 Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY);
860 if (xView.is())
862 SharedBitmapDescriptor pViewBackground(
863 GetViewBackground(xView->getResourceId()->getResourceURL()));
864 mpPaneContainer->StoreView(xView, pViewBackground);
865 UpdateViews();
866 mpWindowManager->NotifyViewCreation(xView);
869 break;
871 case ResourceDeactivationEventType:
872 if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT))
874 // If this is a view then remove it from the pane container.
875 Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY);
876 if (xView.is())
878 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
879 mpPaneContainer->RemoveView(xView));
881 // A possibly opaque view has been removed. Update()
882 // updates the clip polygon.
883 mpWindowManager->Update();
884 // Request the repainting of the area previously
885 // occupied by the view.
886 if (pDescriptor.get() != NULL)
887 GetPaintManager()->Invalidate(pDescriptor->mxBorderWindow);
890 break;
892 case ConfigurationUpdateEndEventType:
893 if (IsAccessibilityActive())
895 mpAccessibleObject->UpdateAccessibilityHierarchy();
896 UpdateCurrentSlide(0);
898 break;
905 //----- XEventListener --------------------------------------------------------
907 void SAL_CALL PresenterController::disposing (
908 const lang::EventObject& rEvent)
909 throw (RuntimeException)
911 if (rEvent.Source == mxController)
912 mxController = NULL;
913 else if (rEvent.Source == mxConfigurationController)
914 mxConfigurationController = NULL;
915 else if (rEvent.Source == mxSlideShowController)
916 mxSlideShowController = NULL;
917 else if (rEvent.Source == mxMainWindow)
918 mxMainWindow = NULL;
924 //----- XFrameActionListener --------------------------------------------------
926 void SAL_CALL PresenterController::frameAction (
927 const frame::FrameActionEvent& rEvent)
928 throw (RuntimeException)
930 if (rEvent.Action == frame::FrameAction_FRAME_ACTIVATED)
932 if (mxSlideShowController.is())
933 mxSlideShowController->activate();
940 //----- XKeyListener ----------------------------------------------------------
942 void SAL_CALL PresenterController::keyPressed (const awt::KeyEvent& rEvent)
943 throw (RuntimeException)
945 // Tell all views about the unhandled key event.
946 PresenterPaneContainer::PaneList::const_iterator iPane;
947 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
949 if ( ! (*iPane)->mbIsActive)
950 continue;
952 Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY);
953 if (xKeyListener.is())
954 xKeyListener->keyPressed(rEvent);
961 void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent)
962 throw (RuntimeException)
964 if (rEvent.Source != mxMainWindow)
965 return;
967 switch (rEvent.KeyCode)
969 case awt::Key::ESCAPE:
970 case awt::Key::SUBTRACT:
972 if( mxController.is() )
974 Reference< XPresentationSupplier > xPS( mxController->getModel(), UNO_QUERY );
975 if( xPS.is() )
977 Reference< XPresentation > xP( xPS->getPresentation() );
978 if( xP.is() )
979 xP->end();
983 break;
985 case awt::Key::PAGEDOWN:
986 if (mxSlideShowController.is())
988 if (rEvent.Modifiers == awt::KeyModifier::MOD2)
989 mxSlideShowController->gotoNextSlide();
990 else
991 mxSlideShowController->gotoNextEffect();
993 break;
995 case awt::Key::RIGHT:
996 case awt::Key::SPACE:
997 case awt::Key::DOWN:
998 case awt::Key::N:
999 if (mxSlideShowController.is())
1001 mxSlideShowController->gotoNextEffect();
1003 break;
1005 case awt::Key::PAGEUP:
1006 if (mxSlideShowController.is())
1008 if (rEvent.Modifiers == awt::KeyModifier::MOD2)
1009 mxSlideShowController->gotoPreviousSlide();
1010 else
1011 mxSlideShowController->gotoPreviousEffect();
1013 break;
1015 case awt::Key::LEFT:
1016 case awt::Key::UP:
1017 case awt::Key::P:
1018 case awt::Key::BACKSPACE:
1019 if (mxSlideShowController.is())
1021 mxSlideShowController->gotoPreviousEffect();
1023 break;
1025 case awt::Key::HOME:
1026 if (mxSlideShowController.is())
1028 mxSlideShowController->gotoFirstSlide();
1030 break;
1032 case awt::Key::END:
1033 if (mxSlideShowController.is())
1035 mxSlideShowController->gotoLastSlide();
1037 break;
1039 case awt::Key::W:
1040 case awt::Key::COMMA:
1041 if (mxSlideShowController.is())
1043 if (mxSlideShowController->isPaused())
1044 mxSlideShowController->resume();
1045 else
1046 mxSlideShowController->blankScreen(0x00ffffff);
1048 break;
1050 case awt::Key::B:
1051 case awt::Key::POINT:
1052 if (mxSlideShowController.is())
1054 if (mxSlideShowController->isPaused())
1055 mxSlideShowController->resume();
1056 else
1057 mxSlideShowController->blankScreen(0x00000000);
1059 break;
1061 case awt::Key::NUM0:
1062 case awt::Key::NUM1:
1063 case awt::Key::NUM2:
1064 case awt::Key::NUM3:
1065 case awt::Key::NUM4:
1066 case awt::Key::NUM5:
1067 case awt::Key::NUM6:
1068 case awt::Key::NUM7:
1069 case awt::Key::NUM8:
1070 case awt::Key::NUM9:
1071 HandleNumericKeyPress(rEvent.KeyCode-awt::Key::NUM0, rEvent.Modifiers);
1072 break;
1074 case awt::Key::RETURN:
1075 if (mnPendingSlideNumber > 0)
1077 if (mxSlideShowController.is())
1078 mxSlideShowController->gotoSlideIndex(mnPendingSlideNumber - 1);
1079 mnPendingSlideNumber = -1;
1081 else
1083 if (mxSlideShowController.is())
1084 mxSlideShowController->gotoNextEffect();
1087 break;
1089 case awt::Key::F1:
1090 // Toggle the help view.
1091 if (mpWindowManager.get() != NULL)
1092 if (mpWindowManager->GetViewMode() != PresenterWindowManager::VM_Help)
1093 mpWindowManager->SetViewMode(PresenterWindowManager::VM_Help);
1094 else
1095 mpWindowManager->SetHelpViewState(false);
1097 break;
1099 default:
1100 // Tell all views about the unhandled key event.
1101 PresenterPaneContainer::PaneList::const_iterator iPane;
1102 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=mpPaneContainer->maPanes.end(); ++iPane)
1104 if ( ! (*iPane)->mbIsActive)
1105 continue;
1107 Reference<awt::XKeyListener> xKeyListener ((*iPane)->mxView, UNO_QUERY);
1108 if (xKeyListener.is())
1109 xKeyListener->keyReleased(rEvent);
1111 break;
1118 void PresenterController::HandleNumericKeyPress (
1119 const sal_Int32 nKey,
1120 const sal_Int32 nModifiers)
1122 switch (nModifiers)
1124 case 0:
1125 if (mnPendingSlideNumber == -1)
1126 mnPendingSlideNumber = 0;
1127 UpdatePendingSlideNumber(mnPendingSlideNumber * 10 + nKey);
1128 break;
1130 case awt::KeyModifier::MOD1:
1131 // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
1132 // (slide view, notes view, normal)
1133 mnPendingSlideNumber = -1;
1134 if (mpWindowManager.get() == NULL)
1135 return;
1136 switch(nKey)
1138 case 1:
1139 mpWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
1140 break;
1141 case 2:
1142 mpWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
1143 break;
1144 case 3:
1145 mpWindowManager->SetViewMode(PresenterWindowManager::VM_SlideOverview);
1146 break;
1147 default:
1148 // Ignore unsupported key.
1149 break;
1152 default:
1153 // Ignore unsupported modifiers.
1154 break;
1161 //----- XFocusListener --------------------------------------------------------
1163 void SAL_CALL PresenterController::focusGained (const css::awt::FocusEvent& rEvent)
1164 throw (css::uno::RuntimeException)
1166 (void)rEvent;
1172 void SAL_CALL PresenterController::focusLost (const css::awt::FocusEvent& rEvent)
1173 throw (css::uno::RuntimeException)
1175 (void)rEvent;
1181 //----- XMouseListener --------------------------------------------------------
1183 void SAL_CALL PresenterController::mousePressed (const css::awt::MouseEvent& rEvent)
1184 throw (css::uno::RuntimeException)
1186 (void)rEvent;
1187 if (mxMainWindow.is())
1188 mxMainWindow->setFocus();
1194 void SAL_CALL PresenterController::mouseReleased (const css::awt::MouseEvent& rEvent)
1195 throw (css::uno::RuntimeException)
1197 (void)rEvent;
1203 void SAL_CALL PresenterController::mouseEntered (const css::awt::MouseEvent& rEvent)
1204 throw (css::uno::RuntimeException)
1206 (void)rEvent;
1212 void SAL_CALL PresenterController::mouseExited (const css::awt::MouseEvent& rEvent)
1213 throw (css::uno::RuntimeException)
1215 (void)rEvent;
1221 //----- XMouseMotionListener --------------------------------------------------
1223 void SAL_CALL PresenterController::mouseMoved (const css::awt::MouseEvent& rEvent)
1224 throw (css::uno::RuntimeException)
1226 (void)rEvent;
1232 void SAL_CALL PresenterController::mouseDragged (const css::awt::MouseEvent& rEvent)
1233 throw (css::uno::RuntimeException)
1235 (void)rEvent;
1241 //-----------------------------------------------------------------------------
1243 void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane)
1245 if ( ! rxPane.is())
1246 return;
1248 mpAccessibleObject = new PresenterAccessible(
1249 mxComponentContext,
1250 this,
1251 rxPane);
1253 LoadTheme(rxPane);
1255 // Main pane has been created and is now observed by the window
1256 // manager.
1257 mpWindowManager->SetParentPane(rxPane);
1258 mpWindowManager->SetTheme(mpTheme);
1260 if (mpPaneBorderPainter.get() != NULL)
1261 mpPaneBorderPainter->SetTheme(mpTheme);
1263 // Add key listener
1264 mxMainWindow = rxPane->getWindow();
1265 if (mxMainWindow.is())
1267 mxMainWindow->addKeyListener(this);
1268 mxMainWindow->addFocusListener(this);
1269 mxMainWindow->addMouseListener(this);
1270 mxMainWindow->addMouseMotionListener(this);
1272 Reference<XPane2> xPane2 (rxPane, UNO_QUERY);
1273 if (xPane2.is())
1274 xPane2->setVisible(sal_True);
1276 mpPaintManager.reset(new PresenterPaintManager(mxMainWindow, mxPresenterHelper, mpPaneContainer));
1278 mxCanvas = Reference<rendering::XSpriteCanvas>(rxPane->getCanvas(), UNO_QUERY);
1280 if (mxSlideShowController.is())
1281 mxSlideShowController->activate();
1283 UpdateCurrentSlide(0);
1289 void PresenterController::LoadTheme (const Reference<XPane>& rxPane)
1291 // Create (load) the current theme.
1292 if (rxPane.is())
1293 mpTheme.reset(new PresenterTheme(mxComponentContext, OUString(), rxPane->getCanvas()));
1299 double PresenterController::GetSlideAspectRatio (void) const
1301 double nSlideAspectRatio (28.0/21.0);
1305 if (mxController.is())
1307 Reference<drawing::XDrawPagesSupplier> xSlideSupplier (
1308 mxController->getModel(), UNO_QUERY_THROW);
1309 Reference<drawing::XDrawPages> xSlides (xSlideSupplier->getDrawPages());
1310 if (xSlides.is() && xSlides->getCount()>0)
1312 Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW);
1313 sal_Int32 nWidth (28000);
1314 sal_Int32 nHeight (21000);
1315 if ((xProperties->getPropertyValue(OUString::createFromAscii("Width")) >>= nWidth)
1316 && (xProperties->getPropertyValue(OUString::createFromAscii("Height")) >>= nHeight)
1317 && nHeight > 0)
1319 nSlideAspectRatio = double(nWidth) / double(nHeight);
1324 catch (RuntimeException&)
1326 OSL_ASSERT(false);
1329 return nSlideAspectRatio;
1335 void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber)
1337 mnPendingSlideNumber = nPendingSlideNumber;
1339 if (mpTheme.get() == NULL)
1340 return;
1342 if ( ! mxMainWindow.is())
1343 return;
1345 PresenterTheme::SharedFontDescriptor pFont (
1346 mpTheme->GetFont(A2S("PendingSlideNumberFont")));
1347 if (pFont.get() == NULL)
1348 return;
1350 pFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY));
1351 if ( ! pFont->mxFont.is())
1352 return;
1354 const OUString sText (OUString::valueOf(mnPendingSlideNumber));
1355 rendering::StringContext aContext (sText, 0, sText.getLength());
1356 Reference<rendering::XTextLayout> xLayout (
1357 pFont->mxFont->createTextLayout(
1358 aContext,
1359 rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1360 0));
1366 void PresenterController::ThrowIfDisposed (void) const
1367 throw (::com::sun::star::lang::DisposedException)
1369 if (rBHelper.bDisposed || rBHelper.bInDispose)
1371 throw lang::DisposedException (
1372 OUString(RTL_CONSTASCII_USTRINGPARAM(
1373 "PresenterController object has already been disposed")),
1374 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1379 } } // end of namespace ::sdext::presenter