1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "PresenterController.hxx"
22 #include "PresenterAccessibility.hxx"
23 #include "PresenterCanvasHelper.hxx"
24 #include "PresenterCurrentSlideObserver.hxx"
25 #include "PresenterFrameworkObserver.hxx"
26 #include "PresenterHelper.hxx"
27 #include "PresenterScreen.hxx"
28 #include "PresenterNotesView.hxx"
29 #include "PresenterPaintManager.hxx"
30 #include "PresenterPaneBase.hxx"
31 #include "PresenterPaneContainer.hxx"
32 #include "PresenterPaneBorderPainter.hxx"
33 #include "PresenterTheme.hxx"
34 #include "PresenterViewFactory.hxx"
35 #include "PresenterWindowManager.hxx"
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/XAccessible.hpp>
39 #include <com/sun/star/awt/Key.hpp>
40 #include <com/sun/star/awt/KeyModifier.hpp>
41 #include <com/sun/star/awt/MouseButton.hpp>
42 #include <com/sun/star/awt/XWindowPeer.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/drawing/XDrawView.hpp>
45 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
46 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
47 #include <com/sun/star/drawing/framework/ResourceId.hpp>
48 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
49 #include <com/sun/star/frame/FrameSearchFlag.hpp>
50 #include <com/sun/star/frame/XDispatchProvider.hpp>
51 #include <com/sun/star/presentation/AnimationEffect.hpp>
52 #include <com/sun/star/presentation/XPresentation.hpp>
53 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
54 #include <com/sun/star/rendering/CompositeOperation.hpp>
55 #include <com/sun/star/rendering/TextDirection.hpp>
56 #include <com/sun/star/util/URLTransformer.hpp>
58 #include <rtl/ustrbuf.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::presentation
;
63 using namespace ::com::sun::star::drawing::framework
;
66 const sal_Int32 ResourceActivationEventType
= 0;
67 const sal_Int32 ResourceDeactivationEventType
= 1;
68 const sal_Int32 ConfigurationUpdateEndEventType
= 2;
71 namespace sdext
{ namespace presenter
{
73 PresenterController::InstanceContainer
PresenterController::maInstances
;
75 ::rtl::Reference
<PresenterController
> PresenterController::Instance (
76 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
)
78 InstanceContainer::const_iterator
iInstance (maInstances
.find(rxFrame
));
79 if (iInstance
!= maInstances
.end())
80 return iInstance
->second
;
82 return ::rtl::Reference
<PresenterController
>();
85 PresenterController::PresenterController (
86 const css::uno::WeakReference
<css::lang::XEventListener
> &rxScreen
,
87 const Reference
<XComponentContext
>& rxContext
,
88 const Reference
<frame::XController
>& rxController
,
89 const Reference
<presentation::XSlideShowController
>& rxSlideShowController
,
90 const rtl::Reference
<PresenterPaneContainer
>& rpPaneContainer
,
91 const Reference
<XResourceId
>& rxMainPaneId
)
92 : PresenterControllerInterfaceBase(m_aMutex
),
94 mxComponentContext(rxContext
),
95 mxController(rxController
),
96 mxConfigurationController(),
97 mxSlideShowController(rxSlideShowController
),
98 mxMainPaneId(rxMainPaneId
),
99 mpPaneContainer(rpPaneContainer
),
100 mnCurrentSlideIndex(-1),
103 mpWindowManager(new PresenterWindowManager(rxContext
,mpPaneContainer
,this)),
104 mnWindowBackgroundColor(0x00ffffff),
107 mpPaneBorderPainter(),
108 mpCanvasHelper(new PresenterCanvasHelper()),
111 mnPendingSlideNumber(-1),
113 mpAccessibleObject(),
114 mbIsAccessibilityActive(false)
116 OSL_ASSERT(mxController
.is());
118 if ( ! mxSlideShowController
.is())
119 throw lang::IllegalArgumentException(
120 "missing slide show controller",
121 static_cast<XWeak
*>(this),
124 new PresenterCurrentSlideObserver(this,rxSlideShowController
);
126 // Listen for configuration changes.
127 Reference
<XControllerManager
> xCM (mxController
, UNO_QUERY_THROW
);
128 mxConfigurationController
= xCM
->getConfigurationController();
129 if (mxConfigurationController
.is())
131 mxConfigurationController
->addConfigurationChangeListener(
133 "ResourceActivation",
134 Any(ResourceActivationEventType
));
135 mxConfigurationController
->addConfigurationChangeListener(
137 "ResourceDeactivation",
138 Any(ResourceDeactivationEventType
));
139 mxConfigurationController
->addConfigurationChangeListener(
141 "ConfigurationUpdateEnd",
142 Any(ConfigurationUpdateEndEventType
));
145 // Listen for the frame being activated.
146 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
148 xFrame
->addFrameActionListener(this);
150 // Create the border painter.
151 mpPaneBorderPainter
= new PresenterPaneBorderPainter(rxContext
);
152 mpWindowManager
->SetPaneBorderPainter(mpPaneBorderPainter
);
154 // Create an object that is able to load the bitmaps in a format that is
155 // supported by the canvas.
156 Reference
<lang::XMultiComponentFactory
> xFactory (
157 rxContext
->getServiceManager(), UNO_QUERY
);
158 if ( ! xFactory
.is())
160 mxPresenterHelper
= Reference
<drawing::XPresenterHelper
>(
161 xFactory
->createInstanceWithContext(
162 "com.sun.star.drawing.PresenterHelper",
166 if (mxSlideShowController
.is())
168 mxSlideShowController
->activate();
169 Reference
<beans::XPropertySet
> xProperties (mxSlideShowController
, UNO_QUERY
);
170 if (xProperties
.is())
172 Reference
<awt::XWindow
> xWindow (
173 xProperties
->getPropertyValue("ParentWindow"), UNO_QUERY
);
175 xWindow
->addKeyListener(this);
179 UpdateCurrentSlide(0);
181 maInstances
[mxController
->getFrame()] = this;
183 // Create a URLTransformer.
186 mxUrlTransformer
= Reference
<util::XURLTransformer
>(util::URLTransformer::create(mxComponentContext
));
190 PresenterController::~PresenterController()
194 void PresenterController::disposing()
196 maInstances
.erase(mxController
->getFrame());
198 if (mxMainWindow
.is())
200 mxMainWindow
->removeKeyListener(this);
201 mxMainWindow
->removeFocusListener(this);
202 mxMainWindow
->removeMouseListener(this);
203 mxMainWindow
->removeMouseMotionListener(this);
206 if (mxConfigurationController
.is())
207 mxConfigurationController
->removeConfigurationChangeListener(this);
209 Reference
<XComponent
> xWindowManagerComponent (
210 static_cast<XWeak
*>(mpWindowManager
.get()), UNO_QUERY
);
211 mpWindowManager
= NULL
;
212 if (xWindowManagerComponent
.is())
213 xWindowManagerComponent
->dispose();
215 if (mxController
.is())
217 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
219 xFrame
->removeFrameActionListener(this);
223 mxComponentContext
= NULL
;
224 mxConfigurationController
= NULL
;
225 mxSlideShowController
= NULL
;
227 mpPaneContainer
= NULL
;
228 mnCurrentSlideIndex
= -1;
229 mxCurrentSlide
= NULL
;
233 Reference
<lang::XComponent
> xComponent (
234 static_cast<XWeak
*>(mpPaneBorderPainter
.get()), UNO_QUERY
);
235 mpPaneBorderPainter
= NULL
;
237 xComponent
->dispose();
239 mpCanvasHelper
.reset();
241 Reference
<lang::XComponent
> xComponent (mxPresenterHelper
, UNO_QUERY
);
242 mxPresenterHelper
= NULL
;
244 xComponent
->dispose();
246 mpPaintManager
.reset();
247 mnPendingSlideNumber
= -1;
249 Reference
<lang::XComponent
> xComponent (mxUrlTransformer
, UNO_QUERY
);
250 mxUrlTransformer
= NULL
;
252 xComponent
->dispose();
256 void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset
)
258 // std::cerr << "Updating current Slide to " << nOffset << std::endl;
263 // Update the accessibility object.
264 if (IsAccessibilityActive())
266 sal_Int32
nSlideCount (0);
267 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
268 if (xIndexAccess
.is())
269 nSlideCount
= xIndexAccess
->getCount();
270 mpAccessibleObject
->NotifyCurrentSlideChange(mnCurrentSlideIndex
, nSlideCount
);
274 void PresenterController::GetSlides (const sal_Int32 nOffset
)
276 if ( ! mxSlideShowController
.is())
279 // Get the current slide from the slide show controller.
280 mxCurrentSlide
= NULL
;
281 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
282 sal_Int32 nSlideIndex
= -1;
285 nSlideIndex
= mxSlideShowController
->getCurrentSlideIndex() + nOffset
;
286 if (mxSlideShowController
->isPaused())
289 if (xIndexAccess
.is() && nSlideIndex
>=0)
291 if (nSlideIndex
< xIndexAccess
->getCount())
293 mnCurrentSlideIndex
= nSlideIndex
;
294 mxCurrentSlide
= Reference
<drawing::XDrawPage
>(
295 xIndexAccess
->getByIndex(nSlideIndex
), UNO_QUERY
);
299 catch (RuntimeException
&)
303 // Get the next slide.
307 const sal_Int32
nNextSlideIndex (mxSlideShowController
->getNextSlideIndex()+nOffset
);
308 if (nNextSlideIndex
>= 0)
310 if (xIndexAccess
.is())
312 if (nNextSlideIndex
< xIndexAccess
->getCount())
313 mxNextSlide
= Reference
<drawing::XDrawPage
>(
314 xIndexAccess
->getByIndex(nNextSlideIndex
), UNO_QUERY
);
318 catch (RuntimeException
&)
323 void PresenterController::UpdatePaneTitles()
325 if ( ! mxSlideShowController
.is())
328 // Get placeholders and their values.
329 const OUString
sCurrentSlideNumberPlaceholder ("CURRENT_SLIDE_NUMBER");
330 const OUString
sCurrentSlideNamePlaceholder ("CURRENT_SLIDE_NAME");
331 const OUString
sSlideCountPlaceholder ("SLIDE_COUNT");
333 // Get string for slide count.
334 OUString
sSlideCount ("---");
335 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
336 if (xIndexAccess
.is())
337 sSlideCount
= OUString::number(xIndexAccess
->getCount());
339 // Get string for current slide index.
340 OUString
sCurrentSlideNumber (OUString::number(mnCurrentSlideIndex
+ 1));
342 // Get name of the current slide.
343 OUString sCurrentSlideName
;
344 Reference
<container::XNamed
> xNamedSlide (mxCurrentSlide
, UNO_QUERY
);
345 if (xNamedSlide
.is())
346 sCurrentSlideName
= xNamedSlide
->getName();
347 Reference
<beans::XPropertySet
> xSlideProperties (mxCurrentSlide
, UNO_QUERY
);
348 if (xSlideProperties
.is())
353 if (xSlideProperties
->getPropertyValue("LinkDisplayName") >>= sName
)
355 // Find out whether the name of the current slide has been
356 // automatically created or has been set by the user.
357 if (sName
!= sCurrentSlideName
)
358 sCurrentSlideName
= sName
;
361 catch (const beans::UnknownPropertyException
&)
366 // Replace the placeholders with their current values.
367 PresenterPaneContainer::PaneList::const_iterator iPane
;
368 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=mpPaneContainer
->maPanes
.end(); ++iPane
)
370 OSL_ASSERT((*iPane
).get() != NULL
);
372 OUString
sTemplate (IsAccessibilityActive()
373 ? (*iPane
)->msAccessibleTitleTemplate
374 : (*iPane
)->msTitleTemplate
);
375 if (sTemplate
.isEmpty())
378 OUStringBuffer sResult
;
379 sResult
.ensureCapacity(sTemplate
.getLength());
381 sal_Int32
nIndex (0);
384 sal_Int32 nStartIndex
= sTemplate
.indexOf('%', nIndex
);
387 // Add the remaining part of the string.
388 sResult
.append(sTemplate
.copy(nIndex
, sTemplate
.getLength()-nIndex
));
393 // Add the part preceding the next %.
394 sResult
.append(sTemplate
.copy(nIndex
, nStartIndex
-nIndex
));
396 // Get the placeholder
398 const sal_Int32
nEndIndex (sTemplate
.indexOf('%', nStartIndex
+1));
399 const OUString
sPlaceholder (sTemplate
.copy(nStartIndex
, nEndIndex
-nStartIndex
));
400 nIndex
= nEndIndex
+1;
402 // Replace the placeholder with its current value.
403 if (sPlaceholder
== sCurrentSlideNumberPlaceholder
)
404 sResult
.append(sCurrentSlideNumber
);
405 else if (sPlaceholder
== sCurrentSlideNamePlaceholder
)
406 sResult
.append(sCurrentSlideName
);
407 else if (sPlaceholder
== sSlideCountPlaceholder
)
408 sResult
.append(sSlideCount
);
412 (*iPane
)->msTitle
= sResult
.makeStringAndClear();
413 if ((*iPane
)->mxPane
.is())
414 (*iPane
)->mxPane
->SetTitle((*iPane
)->msTitle
);
418 void PresenterController::UpdateViews()
420 // Tell all views about the slides they should display.
421 PresenterPaneContainer::PaneList::const_iterator iPane
;
422 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=mpPaneContainer
->maPanes
.end(); ++iPane
)
424 Reference
<drawing::XDrawView
> xDrawView ((*iPane
)->mxView
, UNO_QUERY
);
426 xDrawView
->setCurrentPage(mxCurrentSlide
);
430 SharedBitmapDescriptor
431 PresenterController::GetViewBackground (const OUString
& rsViewURL
) const
433 if (mpTheme
.get() != NULL
)
435 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
436 return mpTheme
->GetBitmap(sStyleName
, "Background");
438 return SharedBitmapDescriptor();
441 PresenterTheme::SharedFontDescriptor
442 PresenterController::GetViewFont (const OUString
& rsViewURL
) const
444 if (mpTheme
.get() != NULL
)
446 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
447 return mpTheme
->GetFont(sStyleName
);
449 return PresenterTheme::SharedFontDescriptor();
452 ::boost::shared_ptr
<PresenterTheme
> PresenterController::GetTheme() const
457 ::rtl::Reference
<PresenterWindowManager
> PresenterController::GetWindowManager() const
459 return mpWindowManager
;
462 Reference
<presentation::XSlideShowController
>
463 PresenterController::GetSlideShowController() const
465 return mxSlideShowController
;
468 rtl::Reference
<PresenterPaneContainer
> PresenterController::GetPaneContainer() const
470 return mpPaneContainer
;
473 ::rtl::Reference
<PresenterPaneBorderPainter
> PresenterController::GetPaneBorderPainter() const
475 return mpPaneBorderPainter
;
478 ::boost::shared_ptr
<PresenterCanvasHelper
> PresenterController::GetCanvasHelper() const
480 return mpCanvasHelper
;
483 Reference
<drawing::XPresenterHelper
> PresenterController::GetPresenterHelper() const
485 return mxPresenterHelper
;
488 ::boost::shared_ptr
<PresenterPaintManager
> PresenterController::GetPaintManager() const
490 return mpPaintManager
;
493 void PresenterController::ShowView (const OUString
& rsViewURL
)
495 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
496 mpPaneContainer
->FindViewURL(rsViewURL
));
497 if (pDescriptor
.get() != NULL
)
499 pDescriptor
->mbIsActive
= true;
500 mxConfigurationController
->requestResourceActivation(
501 pDescriptor
->mxPaneId
,
502 ResourceActivationMode_ADD
);
503 mxConfigurationController
->requestResourceActivation(
504 ResourceId::createWithAnchor(
507 pDescriptor
->mxPaneId
),
508 ResourceActivationMode_REPLACE
);
512 void PresenterController::HideView (const OUString
& rsViewURL
)
514 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
515 mpPaneContainer
->FindViewURL(rsViewURL
));
516 if (pDescriptor
.get() != NULL
)
518 mxConfigurationController
->requestResourceDeactivation(
519 ResourceId::createWithAnchor(
522 pDescriptor
->mxPaneId
));
526 void PresenterController::DispatchUnoCommand (const OUString
& rsCommand
) const
528 if ( ! mxUrlTransformer
.is())
532 aURL
.Complete
= rsCommand
;
533 mxUrlTransformer
->parseStrict(aURL
);
535 Reference
<frame::XDispatch
> xDispatch (GetDispatch(aURL
));
536 if ( ! xDispatch
.is())
539 xDispatch
->dispatch(aURL
, Sequence
<beans::PropertyValue
>());
542 Reference
<css::frame::XDispatch
> PresenterController::GetDispatch (const util::URL
& rURL
) const
544 if ( ! mxController
.is())
547 Reference
<frame::XDispatchProvider
> xDispatchProvider (mxController
->getFrame(), UNO_QUERY
);
548 if ( ! xDispatchProvider
.is())
551 return xDispatchProvider
->queryDispatch(
554 frame::FrameSearchFlag::SELF
);
557 util::URL
PresenterController::CreateURLFromString (const OUString
& rsURL
) const
561 if (mxUrlTransformer
.is())
563 aURL
.Complete
= rsURL
;
564 mxUrlTransformer
->parseStrict(aURL
);
570 Reference
<drawing::framework::XConfigurationController
>
571 PresenterController::GetConfigurationController() const
573 return mxConfigurationController
;
576 Reference
<drawing::XDrawPage
> PresenterController::GetCurrentSlide() const
578 return mxCurrentSlide
;
581 bool PresenterController::HasTransition (Reference
<drawing::XDrawPage
>& rxPage
)
583 bool bTransition
= false;
584 sal_uInt16 aTransitionType
= 0;
587 Reference
<beans::XPropertySet
> xSlidePropertySet (rxPage
, UNO_QUERY
);
590 xSlidePropertySet
->getPropertyValue("TransitionType") >>= aTransitionType
;
591 if (aTransitionType
> 0)
596 catch (const beans::UnknownPropertyException
&)
603 bool PresenterController::HasCustomAnimation (Reference
<drawing::XDrawPage
>& rxPage
)
605 bool bCustomAnimation
= false;
608 sal_uInt32 i
, nCount
= rxPage
->getCount();
609 for ( i
= 0; i
< nCount
; i
++ )
611 Reference
<drawing::XShape
> xShape(rxPage
->getByIndex(i
), UNO_QUERY
);
612 Reference
<beans::XPropertySet
> xShapePropertySet(xShape
, UNO_QUERY
);
613 presentation::AnimationEffect aEffect
= presentation::AnimationEffect_NONE
;
614 presentation::AnimationEffect aTextEffect
= presentation::AnimationEffect_NONE
;
617 xShapePropertySet
->getPropertyValue("Effect") >>= aEffect
;
618 xShapePropertySet
->getPropertyValue("TextEffect") >>= aTextEffect
;
620 catch (const beans::UnknownPropertyException
&)
623 if( aEffect
!= presentation::AnimationEffect_NONE
||
624 aTextEffect
!= presentation::AnimationEffect_NONE
)
626 bCustomAnimation
= true;
631 return bCustomAnimation
;
634 void PresenterController::SetAccessibilityActiveState (const bool bIsActive
)
636 if ( mbIsAccessibilityActive
!= bIsActive
)
638 mbIsAccessibilityActive
= bIsActive
;
644 void PresenterController::HandleMouseClick (const awt::MouseEvent
& rEvent
)
646 if (mxSlideShowController
.is())
648 switch (rEvent
.Buttons
)
650 case awt::MouseButton::LEFT
:
651 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
652 mxSlideShowController
->gotoNextSlide();
654 mxSlideShowController
->gotoNextEffect();
657 case awt::MouseButton::RIGHT
:
658 mxSlideShowController
->gotoPreviousSlide();
662 // Other or multiple buttons.
668 void PresenterController::RequestViews (
669 const bool bIsSlideSorterActive
,
670 const bool bIsNotesViewActive
,
671 const bool bIsHelpViewActive
)
673 PresenterPaneContainer::PaneList::const_iterator iPane
;
674 PresenterPaneContainer::PaneList::const_iterator
iEnd (mpPaneContainer
->maPanes
.end());
675 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=iEnd
; ++iPane
)
677 bool bActivate (true);
678 const OUString
sViewURL ((*iPane
)->msViewURL
);
679 if (sViewURL
== PresenterViewFactory::msNotesViewURL
)
681 bActivate
= bIsNotesViewActive
&& !bIsSlideSorterActive
&& !bIsHelpViewActive
;
683 else if (sViewURL
== PresenterViewFactory::msSlideSorterURL
)
685 bActivate
= bIsSlideSorterActive
;
687 else if (sViewURL
== PresenterViewFactory::msCurrentSlidePreviewViewURL
688 || sViewURL
== PresenterViewFactory::msNextSlidePreviewViewURL
)
690 bActivate
= !bIsSlideSorterActive
&& ! bIsHelpViewActive
;
692 else if (sViewURL
== PresenterViewFactory::msToolBarViewURL
)
696 else if (sViewURL
== PresenterViewFactory::msHelpViewURL
)
698 bActivate
= bIsHelpViewActive
;
708 //----- XConfigurationChangeListener ------------------------------------------
710 void SAL_CALL
PresenterController::notifyConfigurationChange (
711 const ConfigurationChangeEvent
& rEvent
)
712 throw (RuntimeException
, std::exception
)
717 if ( ! (rEvent
.UserData
>>= nType
))
722 case ResourceActivationEventType
:
723 if (rEvent
.ResourceId
->compareTo(mxMainPaneId
) == 0)
725 InitializeMainPane(Reference
<XPane
>(rEvent
.ResourceObject
,UNO_QUERY
));
727 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_DIRECT
))
729 // A pane bound to the main pane has been created and is
730 // stored in the pane container.
731 Reference
<XPane
> xPane (rEvent
.ResourceObject
,UNO_QUERY
);
734 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
735 mpPaneContainer
->FindPaneId(xPane
->getResourceId()));
737 // When there is a call out anchor location set then tell the
739 if (pDescriptor
->mbHasCalloutAnchor
)
740 pDescriptor
->mxPane
->SetCalloutAnchor(
741 pDescriptor
->maCalloutAnchorLocation
);
744 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
746 // A view bound to one of the panes has been created and is
747 // stored in the pane container along with its pane.
748 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
751 SharedBitmapDescriptor
pViewBackground(
752 GetViewBackground(xView
->getResourceId()->getResourceURL()));
753 mpPaneContainer
->StoreView(xView
, pViewBackground
);
755 mpWindowManager
->NotifyViewCreation(xView
);
760 case ResourceDeactivationEventType
:
761 if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
763 // If this is a view then remove it from the pane container.
764 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
767 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
768 mpPaneContainer
->RemoveView(xView
));
770 // A possibly opaque view has been removed. Update()
771 // updates the clip polygon.
772 mpWindowManager
->Update();
773 // Request the repainting of the area previously
774 // occupied by the view.
775 if (pDescriptor
.get() != NULL
)
776 GetPaintManager()->Invalidate(pDescriptor
->mxBorderWindow
);
781 case ConfigurationUpdateEndEventType
:
782 if (IsAccessibilityActive())
784 mpAccessibleObject
->UpdateAccessibilityHierarchy();
785 UpdateCurrentSlide(0);
791 //----- XEventListener --------------------------------------------------------
793 void SAL_CALL
PresenterController::disposing (
794 const lang::EventObject
& rEvent
)
795 throw (RuntimeException
, std::exception
)
797 if (rEvent
.Source
== mxController
)
799 else if (rEvent
.Source
== mxConfigurationController
)
800 mxConfigurationController
= NULL
;
801 else if (rEvent
.Source
== mxSlideShowController
)
802 mxSlideShowController
= NULL
;
803 else if (rEvent
.Source
== mxMainWindow
)
807 //----- XFrameActionListener --------------------------------------------------
809 void SAL_CALL
PresenterController::frameAction (
810 const frame::FrameActionEvent
& rEvent
)
811 throw (RuntimeException
, std::exception
)
813 if (rEvent
.Action
== frame::FrameAction_FRAME_ACTIVATED
)
815 if (mxSlideShowController
.is())
816 mxSlideShowController
->activate();
820 //----- XKeyListener ----------------------------------------------------------
822 void SAL_CALL
PresenterController::keyPressed (const awt::KeyEvent
& rEvent
)
823 throw (RuntimeException
, std::exception
)
825 // Tell all views about the unhandled key event.
826 PresenterPaneContainer::PaneList::const_iterator iPane
;
827 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=mpPaneContainer
->maPanes
.end(); ++iPane
)
829 if ( ! (*iPane
)->mbIsActive
)
832 Reference
<awt::XKeyListener
> xKeyListener ((*iPane
)->mxView
, UNO_QUERY
);
833 if (xKeyListener
.is())
834 xKeyListener
->keyPressed(rEvent
);
838 void SAL_CALL
PresenterController::keyReleased (const awt::KeyEvent
& rEvent
)
839 throw (RuntimeException
, std::exception
)
841 if (rEvent
.Source
!= mxMainWindow
)
844 switch (rEvent
.KeyCode
)
846 case awt::Key::ESCAPE
:
847 case awt::Key::SUBTRACT
:
849 if( mxController
.is() )
851 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
854 Reference
< XPresentation
> xP( xPS
->getPresentation() );
862 case awt::Key::PAGEDOWN
:
863 if (mxSlideShowController
.is())
865 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
866 mxSlideShowController
->gotoNextSlide();
868 mxSlideShowController
->gotoNextEffect();
872 case awt::Key::RIGHT
:
873 case awt::Key::SPACE
:
876 if (mxSlideShowController
.is())
878 mxSlideShowController
->gotoNextEffect();
882 case awt::Key::PAGEUP
:
883 if (mxSlideShowController
.is())
885 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
886 mxSlideShowController
->gotoPreviousSlide();
888 mxSlideShowController
->gotoPreviousEffect();
895 case awt::Key::BACKSPACE
:
896 if (mxSlideShowController
.is())
898 mxSlideShowController
->gotoPreviousEffect();
903 if (mxSlideShowController
.is())
905 mxSlideShowController
->gotoFirstSlide();
910 if (mxSlideShowController
.is())
912 mxSlideShowController
->gotoLastSlide();
917 case awt::Key::COMMA
:
918 if (mxSlideShowController
.is())
920 if (mxSlideShowController
->isPaused())
921 mxSlideShowController
->resume();
923 mxSlideShowController
->blankScreen(0x00ffffff);
928 case awt::Key::POINT
:
929 if (mxSlideShowController
.is())
931 if (mxSlideShowController
->isPaused())
932 mxSlideShowController
->resume();
934 mxSlideShowController
->blankScreen(0x00000000);
948 HandleNumericKeyPress(rEvent
.KeyCode
-awt::Key::NUM0
, rEvent
.Modifiers
);
951 case awt::Key::RETURN
:
952 if (mnPendingSlideNumber
> 0)
954 if (mxSlideShowController
.is())
955 mxSlideShowController
->gotoSlideIndex(mnPendingSlideNumber
- 1);
956 mnPendingSlideNumber
= -1;
960 if (mxSlideShowController
.is())
961 mxSlideShowController
->gotoNextEffect();
967 // Toggle the help view.
968 if (mpWindowManager
.get() != NULL
)
970 if (mpWindowManager
->GetViewMode() != PresenterWindowManager::VM_Help
)
971 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Help
);
973 mpWindowManager
->SetHelpViewState(false);
979 // Tell all views about the unhandled key event.
980 PresenterPaneContainer::PaneList::const_iterator iPane
;
981 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=mpPaneContainer
->maPanes
.end(); ++iPane
)
983 if ( ! (*iPane
)->mbIsActive
)
986 Reference
<awt::XKeyListener
> xKeyListener ((*iPane
)->mxView
, UNO_QUERY
);
987 if (xKeyListener
.is())
988 xKeyListener
->keyReleased(rEvent
);
994 void PresenterController::HandleNumericKeyPress (
995 const sal_Int32 nKey
,
996 const sal_Int32 nModifiers
)
1001 if (mnPendingSlideNumber
== -1)
1002 mnPendingSlideNumber
= 0;
1003 UpdatePendingSlideNumber(mnPendingSlideNumber
* 10 + nKey
);
1006 case awt::KeyModifier::MOD1
:
1007 // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
1008 // (slide view, notes view, normal). Ctrl-4 switches monitors
1009 mnPendingSlideNumber
= -1;
1010 if (mpWindowManager
.get() == NULL
)
1015 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
1018 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
1021 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_SlideOverview
);
1027 // Ignore unsupported key.
1032 // Ignore unsupported modifiers.
1037 //----- XFocusListener --------------------------------------------------------
1039 void SAL_CALL
PresenterController::focusGained (const css::awt::FocusEvent
& rEvent
)
1040 throw (css::uno::RuntimeException
, std::exception
)
1045 void SAL_CALL
PresenterController::focusLost (const css::awt::FocusEvent
& rEvent
)
1046 throw (css::uno::RuntimeException
, std::exception
)
1051 //----- XMouseListener --------------------------------------------------------
1053 void SAL_CALL
PresenterController::mousePressed (const css::awt::MouseEvent
& rEvent
)
1054 throw (css::uno::RuntimeException
, std::exception
)
1057 if (mxMainWindow
.is())
1058 mxMainWindow
->setFocus();
1061 void SAL_CALL
PresenterController::mouseReleased (const css::awt::MouseEvent
& rEvent
)
1062 throw (css::uno::RuntimeException
, std::exception
)
1067 void SAL_CALL
PresenterController::mouseEntered (const css::awt::MouseEvent
& rEvent
)
1068 throw (css::uno::RuntimeException
, std::exception
)
1073 void SAL_CALL
PresenterController::mouseExited (const css::awt::MouseEvent
& rEvent
)
1074 throw (css::uno::RuntimeException
, std::exception
)
1079 //----- XMouseMotionListener --------------------------------------------------
1081 void SAL_CALL
PresenterController::mouseMoved (const css::awt::MouseEvent
& rEvent
)
1082 throw (css::uno::RuntimeException
, std::exception
)
1087 void SAL_CALL
PresenterController::mouseDragged (const css::awt::MouseEvent
& rEvent
)
1088 throw (css::uno::RuntimeException
, std::exception
)
1095 void PresenterController::InitializeMainPane (const Reference
<XPane
>& rxPane
)
1100 mpAccessibleObject
= new PresenterAccessible(
1107 // Main pane has been created and is now observed by the window
1109 mpWindowManager
->SetParentPane(rxPane
);
1110 mpWindowManager
->SetTheme(mpTheme
);
1112 if (mpPaneBorderPainter
.get() != NULL
)
1113 mpPaneBorderPainter
->SetTheme(mpTheme
);
1116 mxMainWindow
= rxPane
->getWindow();
1117 if (mxMainWindow
.is())
1119 mxMainWindow
->addKeyListener(this);
1120 mxMainWindow
->addFocusListener(this);
1121 mxMainWindow
->addMouseListener(this);
1122 mxMainWindow
->addMouseMotionListener(this);
1124 Reference
<XPane2
> xPane2 (rxPane
, UNO_QUERY
);
1126 xPane2
->setVisible(sal_True
);
1128 mpPaintManager
.reset(new PresenterPaintManager(mxMainWindow
, mxPresenterHelper
, mpPaneContainer
));
1130 mxCanvas
= Reference
<rendering::XSpriteCanvas
>(rxPane
->getCanvas(), UNO_QUERY
);
1132 if (mxSlideShowController
.is())
1133 mxSlideShowController
->activate();
1135 UpdateCurrentSlide(0);
1138 void PresenterController::LoadTheme (const Reference
<XPane
>& rxPane
)
1140 // Create (load) the current theme.
1142 mpTheme
.reset(new PresenterTheme(mxComponentContext
, OUString(), rxPane
->getCanvas()));
1145 double PresenterController::GetSlideAspectRatio() const
1147 double nSlideAspectRatio (28.0/21.0);
1151 if (mxController
.is())
1153 Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (
1154 mxController
->getModel(), UNO_QUERY_THROW
);
1155 Reference
<drawing::XDrawPages
> xSlides (xSlideSupplier
->getDrawPages());
1156 if (xSlides
.is() && xSlides
->getCount()>0)
1158 Reference
<beans::XPropertySet
> xProperties(xSlides
->getByIndex(0),UNO_QUERY_THROW
);
1159 sal_Int32
nWidth (28000);
1160 sal_Int32
nHeight (21000);
1161 if ((xProperties
->getPropertyValue("Width") >>= nWidth
)
1162 && (xProperties
->getPropertyValue("Height") >>= nHeight
)
1165 nSlideAspectRatio
= double(nWidth
) / double(nHeight
);
1170 catch (RuntimeException
&)
1175 return nSlideAspectRatio
;
1178 void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber
)
1180 mnPendingSlideNumber
= nPendingSlideNumber
;
1182 if (mpTheme
.get() == NULL
)
1185 if ( ! mxMainWindow
.is())
1188 PresenterTheme::SharedFontDescriptor
pFont (
1189 mpTheme
->GetFont("PendingSlideNumberFont"));
1190 if (pFont
.get() == NULL
)
1193 pFont
->PrepareFont(Reference
<rendering::XCanvas
>(mxCanvas
, UNO_QUERY
));
1194 if ( ! pFont
->mxFont
.is())
1197 const OUString
sText (OUString::number(mnPendingSlideNumber
));
1198 rendering::StringContext
aContext (sText
, 0, sText
.getLength());
1199 Reference
<rendering::XTextLayout
> xLayout (
1200 pFont
->mxFont
->createTextLayout(
1202 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1206 void PresenterController::ThrowIfDisposed() const
1207 throw (::com::sun::star::lang::DisposedException
)
1209 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1211 throw lang::DisposedException (
1212 OUString( "PresenterController object has already been disposed"),
1213 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1217 void PresenterController::SwitchMonitors()
1219 Reference
<lang::XEventListener
> xScreen( mxScreen
);
1223 PresenterScreen
*pScreen
= dynamic_cast<PresenterScreen
*>(xScreen
.get());
1227 pScreen
->SwitchMonitors();
1230 } } // end of namespace ::sdext::presenter
1232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */