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 <sal/config.h>
22 #include <string_view>
24 #include "PresenterController.hxx"
26 #include "PresenterAccessibility.hxx"
27 #include "PresenterCanvasHelper.hxx"
28 #include "PresenterCurrentSlideObserver.hxx"
29 #include "PresenterScreen.hxx"
30 #include "PresenterPaintManager.hxx"
31 #include "PresenterPaneBase.hxx"
32 #include "PresenterPaneContainer.hxx"
33 #include "PresenterPaneBorderPainter.hxx"
34 #include "PresenterTheme.hxx"
35 #include "PresenterViewFactory.hxx"
36 #include "PresenterWindowManager.hxx"
38 #include <com/sun/star/awt/Key.hpp>
39 #include <com/sun/star/awt/KeyModifier.hpp>
40 #include <com/sun/star/awt/MouseButton.hpp>
41 #include <com/sun/star/container/XNamed.hpp>
42 #include <com/sun/star/drawing/XDrawView.hpp>
43 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
44 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
45 #include <com/sun/star/drawing/framework/ResourceId.hpp>
46 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
47 #include <com/sun/star/frame/FrameSearchFlag.hpp>
48 #include <com/sun/star/frame/XDispatchProvider.hpp>
49 #include <com/sun/star/presentation/AnimationEffect.hpp>
50 #include <com/sun/star/presentation/XPresentation.hpp>
51 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
52 #include <com/sun/star/rendering/TextDirection.hpp>
53 #include <com/sun/star/util/URLTransformer.hpp>
55 #include <rtl/ustrbuf.hxx>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::uno
;
59 using namespace ::com::sun::star::presentation
;
60 using namespace ::com::sun::star::drawing::framework
;
63 const sal_Int32 ResourceActivationEventType
= 0;
64 const sal_Int32 ResourceDeactivationEventType
= 1;
65 const sal_Int32 ConfigurationUpdateEndEventType
= 2;
68 namespace sdext
{ namespace presenter
{
70 IPresentationTime::~IPresentationTime()
74 PresenterController::InstanceContainer
PresenterController::maInstances
;
76 ::rtl::Reference
<PresenterController
> PresenterController::Instance (
77 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
)
79 InstanceContainer::const_iterator
iInstance (maInstances
.find(rxFrame
));
80 if (iInstance
!= maInstances
.end())
81 return iInstance
->second
;
83 return ::rtl::Reference
<PresenterController
>();
86 PresenterController::PresenterController (
87 const css::uno::WeakReference
<css::lang::XEventListener
> &rxScreen
,
88 const Reference
<XComponentContext
>& rxContext
,
89 const Reference
<frame::XController
>& rxController
,
90 const Reference
<presentation::XSlideShowController
>& rxSlideShowController
,
91 const rtl::Reference
<PresenterPaneContainer
>& rpPaneContainer
,
92 const Reference
<XResourceId
>& rxMainPaneId
)
93 : PresenterControllerInterfaceBase(m_aMutex
),
95 mxComponentContext(rxContext
),
96 mxController(rxController
),
97 mxConfigurationController(),
98 mxSlideShowController(rxSlideShowController
),
99 mxMainPaneId(rxMainPaneId
),
100 mpPaneContainer(rpPaneContainer
),
101 mnCurrentSlideIndex(-1),
104 mpWindowManager(new PresenterWindowManager(rxContext
,mpPaneContainer
,this)),
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();
158 if ( ! xFactory
.is())
160 mxPresenterHelper
.set(
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
.set(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
->removeMouseListener(this);
202 mxMainWindow
= nullptr;
204 if (mxConfigurationController
.is())
205 mxConfigurationController
->removeConfigurationChangeListener(this);
207 Reference
<XComponent
> xWindowManagerComponent (
208 static_cast<XWeak
*>(mpWindowManager
.get()), UNO_QUERY
);
209 mpWindowManager
= nullptr;
210 if (xWindowManagerComponent
.is())
211 xWindowManagerComponent
->dispose();
213 if (mxController
.is())
215 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
217 xFrame
->removeFrameActionListener(this);
218 mxController
= nullptr;
221 mxComponentContext
= nullptr;
222 mxConfigurationController
= nullptr;
223 mxSlideShowController
= nullptr;
224 mxMainPaneId
= nullptr;
225 mpPaneContainer
= nullptr;
226 mnCurrentSlideIndex
= -1;
227 mxCurrentSlide
= nullptr;
228 mxNextSlide
= nullptr;
231 Reference
<lang::XComponent
> xComponent (
232 static_cast<XWeak
*>(mpPaneBorderPainter
.get()), UNO_QUERY
);
233 mpPaneBorderPainter
= nullptr;
235 xComponent
->dispose();
237 mpCanvasHelper
.reset();
239 Reference
<lang::XComponent
> xComponent (mxPresenterHelper
, UNO_QUERY
);
240 mxPresenterHelper
= nullptr;
242 xComponent
->dispose();
244 mpPaintManager
.reset();
245 mnPendingSlideNumber
= -1;
247 Reference
<lang::XComponent
> xComponent (mxUrlTransformer
, UNO_QUERY
);
248 mxUrlTransformer
= nullptr;
250 xComponent
->dispose();
254 void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset
)
256 // std::cerr << "Updating current Slide to " << nOffset << std::endl;
261 // Update the accessibility object.
262 if (IsAccessibilityActive())
264 mpAccessibleObject
->NotifyCurrentSlideChange();
268 void PresenterController::GetSlides (const sal_Int32 nOffset
)
270 if ( ! mxSlideShowController
.is())
273 // Get the current slide from the slide show controller.
274 mxCurrentSlide
= nullptr;
275 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
276 sal_Int32 nSlideIndex
= -1;
279 nSlideIndex
= mxSlideShowController
->getCurrentSlideIndex() + nOffset
;
280 if (mxSlideShowController
->isPaused())
283 if (xIndexAccess
.is() && nSlideIndex
>=0)
285 if (nSlideIndex
< xIndexAccess
->getCount())
287 mnCurrentSlideIndex
= nSlideIndex
;
288 mxCurrentSlide
.set( xIndexAccess
->getByIndex(nSlideIndex
), UNO_QUERY
);
292 catch (RuntimeException
&)
296 // Get the next slide.
297 mxNextSlide
= nullptr;
300 const sal_Int32
nNextSlideIndex (mxSlideShowController
->getNextSlideIndex()+nOffset
);
301 if (nNextSlideIndex
>= 0)
303 if (xIndexAccess
.is())
305 if (nNextSlideIndex
< xIndexAccess
->getCount())
306 mxNextSlide
.set( xIndexAccess
->getByIndex(nNextSlideIndex
), UNO_QUERY
);
310 catch (RuntimeException
&)
315 void PresenterController::UpdatePaneTitles()
317 if ( ! mxSlideShowController
.is())
320 // Get placeholders and their values.
321 const OUString
sCurrentSlideNumberPlaceholder ("CURRENT_SLIDE_NUMBER");
322 const OUString
sCurrentSlideNamePlaceholder ("CURRENT_SLIDE_NAME");
323 const OUString
sSlideCountPlaceholder ("SLIDE_COUNT");
325 // Get string for slide count.
326 OUString
sSlideCount ("---");
327 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
328 if (xIndexAccess
.is())
329 sSlideCount
= OUString::number(xIndexAccess
->getCount());
331 // Get string for current slide index.
332 OUString
sCurrentSlideNumber (OUString::number(mnCurrentSlideIndex
+ 1));
334 // Get name of the current slide.
335 OUString sCurrentSlideName
;
336 Reference
<container::XNamed
> xNamedSlide (mxCurrentSlide
, UNO_QUERY
);
337 if (xNamedSlide
.is())
338 sCurrentSlideName
= xNamedSlide
->getName();
339 Reference
<beans::XPropertySet
> xSlideProperties (mxCurrentSlide
, UNO_QUERY
);
340 if (xSlideProperties
.is())
345 if (xSlideProperties
->getPropertyValue("LinkDisplayName") >>= sName
)
347 // Find out whether the name of the current slide has been
348 // automatically created or has been set by the user.
349 if (sName
!= sCurrentSlideName
)
350 sCurrentSlideName
= sName
;
353 catch (const beans::UnknownPropertyException
&)
358 // Replace the placeholders with their current values.
359 for (auto& rxPane
: mpPaneContainer
->maPanes
)
361 OSL_ASSERT(rxPane
!= nullptr);
363 OUString
sTemplate (IsAccessibilityActive()
364 ? rxPane
->msAccessibleTitleTemplate
365 : rxPane
->msTitleTemplate
);
366 if (sTemplate
.isEmpty())
369 OUStringBuffer sResult
;
370 sResult
.ensureCapacity(sTemplate
.getLength());
372 sal_Int32
nIndex (0);
375 sal_Int32 nStartIndex
= sTemplate
.indexOf('%', nIndex
);
378 // Add the remaining part of the string.
379 sResult
.append(std::u16string_view(sTemplate
).substr(nIndex
));
384 // Add the part preceding the next %.
385 sResult
.append(std::u16string_view(sTemplate
).substr(nIndex
, nStartIndex
-nIndex
));
387 // Get the placeholder
389 const sal_Int32
nEndIndex (sTemplate
.indexOf('%', nStartIndex
+1));
390 const OUString
sPlaceholder (sTemplate
.copy(nStartIndex
, nEndIndex
-nStartIndex
));
391 nIndex
= nEndIndex
+1;
393 // Replace the placeholder with its current value.
394 if (sPlaceholder
== sCurrentSlideNumberPlaceholder
)
395 sResult
.append(sCurrentSlideNumber
);
396 else if (sPlaceholder
== sCurrentSlideNamePlaceholder
)
397 sResult
.append(sCurrentSlideName
);
398 else if (sPlaceholder
== sSlideCountPlaceholder
)
399 sResult
.append(sSlideCount
);
403 rxPane
->msTitle
= sResult
.makeStringAndClear();
404 if (rxPane
->mxPane
.is())
405 rxPane
->mxPane
->SetTitle(rxPane
->msTitle
);
409 void PresenterController::UpdateViews()
411 // Tell all views about the slides they should display.
412 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
414 Reference
<drawing::XDrawView
> xDrawView (rxPane
->mxView
, UNO_QUERY
);
416 xDrawView
->setCurrentPage(mxCurrentSlide
);
420 SharedBitmapDescriptor
421 PresenterController::GetViewBackground (const OUString
& rsViewURL
) const
423 if (mpTheme
!= nullptr)
425 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
426 return mpTheme
->GetBitmap(sStyleName
, "Background");
428 return SharedBitmapDescriptor();
431 PresenterTheme::SharedFontDescriptor
432 PresenterController::GetViewFont (const OUString
& rsViewURL
) const
434 if (mpTheme
!= nullptr)
436 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
437 return mpTheme
->GetFont(sStyleName
);
439 return PresenterTheme::SharedFontDescriptor();
442 const std::shared_ptr
<PresenterTheme
>& PresenterController::GetTheme() const
447 const ::rtl::Reference
<PresenterWindowManager
>& PresenterController::GetWindowManager() const
449 return mpWindowManager
;
452 const Reference
<presentation::XSlideShowController
>&
453 PresenterController::GetSlideShowController() const
455 return mxSlideShowController
;
458 const rtl::Reference
<PresenterPaneContainer
>& PresenterController::GetPaneContainer() const
460 return mpPaneContainer
;
463 const ::rtl::Reference
<PresenterPaneBorderPainter
>& PresenterController::GetPaneBorderPainter() const
465 return mpPaneBorderPainter
;
468 const std::shared_ptr
<PresenterCanvasHelper
>& PresenterController::GetCanvasHelper() const
470 return mpCanvasHelper
;
473 const Reference
<drawing::XPresenterHelper
>& PresenterController::GetPresenterHelper() const
475 return mxPresenterHelper
;
478 const std::shared_ptr
<PresenterPaintManager
>& PresenterController::GetPaintManager() const
480 return mpPaintManager
;
483 void PresenterController::ShowView (const OUString
& rsViewURL
)
485 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
486 mpPaneContainer
->FindViewURL(rsViewURL
));
487 if (pDescriptor
.get() == nullptr)
490 pDescriptor
->mbIsActive
= true;
491 mxConfigurationController
->requestResourceActivation(
492 pDescriptor
->mxPaneId
,
493 ResourceActivationMode_ADD
);
494 mxConfigurationController
->requestResourceActivation(
495 ResourceId::createWithAnchor(
498 pDescriptor
->mxPaneId
),
499 ResourceActivationMode_REPLACE
);
502 void PresenterController::HideView (const OUString
& rsViewURL
)
504 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
505 mpPaneContainer
->FindViewURL(rsViewURL
));
506 if (pDescriptor
.get() != nullptr)
508 mxConfigurationController
->requestResourceDeactivation(
509 ResourceId::createWithAnchor(
512 pDescriptor
->mxPaneId
));
516 void PresenterController::DispatchUnoCommand (const OUString
& rsCommand
) const
518 if ( ! mxUrlTransformer
.is())
522 aURL
.Complete
= rsCommand
;
523 mxUrlTransformer
->parseStrict(aURL
);
525 Reference
<frame::XDispatch
> xDispatch (GetDispatch(aURL
));
526 if ( ! xDispatch
.is())
529 xDispatch
->dispatch(aURL
, Sequence
<beans::PropertyValue
>());
532 Reference
<css::frame::XDispatch
> PresenterController::GetDispatch (const util::URL
& rURL
) const
534 if ( ! mxController
.is())
537 Reference
<frame::XDispatchProvider
> xDispatchProvider (mxController
->getFrame(), UNO_QUERY
);
538 if ( ! xDispatchProvider
.is())
541 return xDispatchProvider
->queryDispatch(
544 frame::FrameSearchFlag::SELF
);
547 util::URL
PresenterController::CreateURLFromString (const OUString
& rsURL
) const
551 if (mxUrlTransformer
.is())
553 aURL
.Complete
= rsURL
;
554 mxUrlTransformer
->parseStrict(aURL
);
560 const Reference
<drawing::framework::XConfigurationController
>&
561 PresenterController::GetConfigurationController() const
563 return mxConfigurationController
;
566 const Reference
<drawing::XDrawPage
>& PresenterController::GetCurrentSlide() const
568 return mxCurrentSlide
;
571 bool PresenterController::HasTransition (Reference
<drawing::XDrawPage
> const & rxPage
)
573 bool bTransition
= false;
574 sal_uInt16 aTransitionType
= 0;
577 Reference
<beans::XPropertySet
> xSlidePropertySet (rxPage
, UNO_QUERY
);
580 xSlidePropertySet
->getPropertyValue("TransitionType") >>= aTransitionType
;
581 if (aTransitionType
> 0)
586 catch (const beans::UnknownPropertyException
&)
593 bool PresenterController::HasCustomAnimation (Reference
<drawing::XDrawPage
> const & rxPage
)
595 bool bCustomAnimation
= false;
598 sal_uInt32 i
, nCount
= rxPage
->getCount();
599 for ( i
= 0; i
< nCount
; i
++ )
601 Reference
<drawing::XShape
> xShape(rxPage
->getByIndex(i
), UNO_QUERY
);
602 Reference
<beans::XPropertySet
> xShapePropertySet(xShape
, UNO_QUERY
);
603 presentation::AnimationEffect aEffect
= presentation::AnimationEffect_NONE
;
604 presentation::AnimationEffect aTextEffect
= presentation::AnimationEffect_NONE
;
607 xShapePropertySet
->getPropertyValue("Effect") >>= aEffect
;
608 xShapePropertySet
->getPropertyValue("TextEffect") >>= aTextEffect
;
610 catch (const beans::UnknownPropertyException
&)
613 if( aEffect
!= presentation::AnimationEffect_NONE
||
614 aTextEffect
!= presentation::AnimationEffect_NONE
)
616 bCustomAnimation
= true;
621 return bCustomAnimation
;
624 void PresenterController::SetAccessibilityActiveState (const bool bIsActive
)
626 if ( mbIsAccessibilityActive
!= bIsActive
)
628 mbIsAccessibilityActive
= bIsActive
;
634 void PresenterController::HandleMouseClick (const awt::MouseEvent
& rEvent
)
636 if (!mxSlideShowController
.is())
639 switch (rEvent
.Buttons
)
641 case awt::MouseButton::LEFT
:
642 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
643 mxSlideShowController
->gotoNextSlide();
645 mxSlideShowController
->gotoNextEffect();
648 case awt::MouseButton::RIGHT
:
649 mxSlideShowController
->gotoPreviousSlide();
653 // Other or multiple buttons.
658 void PresenterController::RequestViews (
659 const bool bIsSlideSorterActive
,
660 const bool bIsNotesViewActive
,
661 const bool bIsHelpViewActive
)
663 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
665 bool bActivate (true);
666 const OUString
sViewURL (rxPane
->msViewURL
);
667 if (sViewURL
== PresenterViewFactory::msNotesViewURL
)
669 bActivate
= bIsNotesViewActive
&& !bIsSlideSorterActive
&& !bIsHelpViewActive
;
671 else if (sViewURL
== PresenterViewFactory::msSlideSorterURL
)
673 bActivate
= bIsSlideSorterActive
;
675 else if (sViewURL
== PresenterViewFactory::msCurrentSlidePreviewViewURL
676 || sViewURL
== PresenterViewFactory::msNextSlidePreviewViewURL
)
678 bActivate
= !bIsSlideSorterActive
&& ! bIsHelpViewActive
;
680 else if (sViewURL
== PresenterViewFactory::msToolBarViewURL
)
684 else if (sViewURL
== PresenterViewFactory::msHelpViewURL
)
686 bActivate
= bIsHelpViewActive
;
696 void PresenterController::SetPresentationTime(IPresentationTime
* pPresentationTime
)
698 mpPresentationTime
= pPresentationTime
;
701 IPresentationTime
* PresenterController::GetPresentationTime()
703 return mpPresentationTime
;
706 //----- XConfigurationChangeListener ------------------------------------------
708 void SAL_CALL
PresenterController::notifyConfigurationChange (
709 const ConfigurationChangeEvent
& rEvent
)
711 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
713 throw lang::DisposedException (
714 "PresenterController object has already been disposed",
715 static_cast<uno::XWeak
*>(this));
719 if ( ! (rEvent
.UserData
>>= nType
))
724 case ResourceActivationEventType
:
725 if (rEvent
.ResourceId
->compareTo(mxMainPaneId
) == 0)
727 InitializeMainPane(Reference
<XPane
>(rEvent
.ResourceObject
,UNO_QUERY
));
729 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_DIRECT
))
731 // A pane bound to the main pane has been created and is
732 // stored in the pane container.
733 Reference
<XPane
> xPane (rEvent
.ResourceObject
,UNO_QUERY
);
736 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
737 mpPaneContainer
->FindPaneId(xPane
->getResourceId()));
740 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
742 // A view bound to one of the panes has been created and is
743 // stored in the pane container along with its pane.
744 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
747 mpPaneContainer
->StoreView(xView
);
749 mpWindowManager
->NotifyViewCreation(xView
);
754 case ResourceDeactivationEventType
:
755 if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
757 // If this is a view then remove it from the pane container.
758 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
761 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
762 mpPaneContainer
->RemoveView(xView
));
764 // A possibly opaque view has been removed. Update()
765 // updates the clip polygon.
766 mpWindowManager
->Update();
767 // Request the repainting of the area previously
768 // occupied by the view.
769 if (pDescriptor
.get() != nullptr)
770 GetPaintManager()->Invalidate(pDescriptor
->mxBorderWindow
);
775 case ConfigurationUpdateEndEventType
:
776 if (IsAccessibilityActive())
778 mpAccessibleObject
->UpdateAccessibilityHierarchy();
779 UpdateCurrentSlide(0);
785 //----- XEventListener --------------------------------------------------------
787 void SAL_CALL
PresenterController::disposing (
788 const lang::EventObject
& rEvent
)
790 if (rEvent
.Source
== mxController
)
791 mxController
= nullptr;
792 else if (rEvent
.Source
== mxConfigurationController
)
793 mxConfigurationController
= nullptr;
794 else if (rEvent
.Source
== mxSlideShowController
)
795 mxSlideShowController
= nullptr;
796 else if (rEvent
.Source
== mxMainWindow
)
797 mxMainWindow
= nullptr;
800 //----- XFrameActionListener --------------------------------------------------
802 void SAL_CALL
PresenterController::frameAction (
803 const frame::FrameActionEvent
& rEvent
)
805 if (rEvent
.Action
== frame::FrameAction_FRAME_ACTIVATED
)
807 if (mxSlideShowController
.is())
808 mxSlideShowController
->activate();
812 //----- XKeyListener ----------------------------------------------------------
814 void SAL_CALL
PresenterController::keyPressed (const awt::KeyEvent
& rEvent
)
816 // Tell all views about the unhandled key event.
817 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
819 if ( ! rxPane
->mbIsActive
)
822 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
823 if (xKeyListener
.is())
824 xKeyListener
->keyPressed(rEvent
);
828 void SAL_CALL
PresenterController::keyReleased (const awt::KeyEvent
& rEvent
)
830 if (rEvent
.Source
!= mxMainWindow
)
833 switch (rEvent
.KeyCode
)
835 case awt::Key::ESCAPE
:
836 case awt::Key::SUBTRACT
:
838 if( mxController
.is() )
840 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
843 Reference
< XPresentation
> xP( xPS
->getPresentation() );
851 case awt::Key::PAGEDOWN
:
852 if (mxSlideShowController
.is())
854 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
855 mxSlideShowController
->gotoNextSlide();
857 mxSlideShowController
->gotoNextEffect();
861 case awt::Key::RIGHT
:
862 case awt::Key::SPACE
:
865 if (mxSlideShowController
.is())
867 mxSlideShowController
->gotoNextEffect();
871 case awt::Key::PAGEUP
:
872 if (mxSlideShowController
.is())
874 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
875 mxSlideShowController
->gotoPreviousSlide();
877 mxSlideShowController
->gotoPreviousEffect();
884 case awt::Key::BACKSPACE
:
885 if (mxSlideShowController
.is())
887 mxSlideShowController
->gotoPreviousEffect();
892 if (mxSlideShowController
.is())
894 mxSlideShowController
->gotoFirstSlide();
899 if (mxSlideShowController
.is())
901 mxSlideShowController
->gotoLastSlide();
906 case awt::Key::COMMA
:
907 if (mxSlideShowController
.is())
909 if (mxSlideShowController
->isPaused())
910 mxSlideShowController
->resume();
912 mxSlideShowController
->blankScreen(0x00ffffff);
917 case awt::Key::POINT
:
918 if (mxSlideShowController
.is())
920 if (mxSlideShowController
->isPaused())
921 mxSlideShowController
->resume();
923 mxSlideShowController
->blankScreen(0x00000000);
937 HandleNumericKeyPress(rEvent
.KeyCode
-awt::Key::NUM0
, rEvent
.Modifiers
);
940 case awt::Key::RETURN
:
941 if (mnPendingSlideNumber
> 0)
943 if (mxSlideShowController
.is())
944 mxSlideShowController
->gotoSlideIndex(mnPendingSlideNumber
- 1);
945 mnPendingSlideNumber
= -1;
949 if (mxSlideShowController
.is())
950 mxSlideShowController
->gotoNextEffect();
956 // Toggle the help view.
957 if (mpWindowManager
.get() != nullptr)
959 if (mpWindowManager
->GetViewMode() != PresenterWindowManager::VM_Help
)
960 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Help
);
962 mpWindowManager
->SetHelpViewState(false);
968 // Tell all views about the unhandled key event.
969 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
971 if ( ! rxPane
->mbIsActive
)
974 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
975 if (xKeyListener
.is())
976 xKeyListener
->keyReleased(rEvent
);
982 void PresenterController::HandleNumericKeyPress (
983 const sal_Int32 nKey
,
984 const sal_Int32 nModifiers
)
989 if (mnPendingSlideNumber
== -1)
990 mnPendingSlideNumber
= 0;
991 UpdatePendingSlideNumber(mnPendingSlideNumber
* 10 + nKey
);
994 case awt::KeyModifier::MOD1
:
995 // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
996 // (slide view, notes view, normal). Ctrl-4 switches monitors
997 mnPendingSlideNumber
= -1;
998 if (mpWindowManager
.get() == nullptr)
1003 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
1006 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
1009 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_SlideOverview
);
1015 // Ignore unsupported key.
1021 // Ignore unsupported modifiers.
1026 //----- XMouseListener --------------------------------------------------------
1028 void SAL_CALL
PresenterController::mousePressed (const css::awt::MouseEvent
&)
1030 if (mxMainWindow
.is())
1031 mxMainWindow
->setFocus();
1034 void SAL_CALL
PresenterController::mouseReleased (const css::awt::MouseEvent
&) {}
1036 void SAL_CALL
PresenterController::mouseEntered (const css::awt::MouseEvent
&) {}
1038 void SAL_CALL
PresenterController::mouseExited (const css::awt::MouseEvent
&) {}
1040 void PresenterController::InitializeMainPane (const Reference
<XPane
>& rxPane
)
1045 mpAccessibleObject
= new PresenterAccessible(
1052 // Main pane has been created and is now observed by the window
1054 mpWindowManager
->SetParentPane(rxPane
);
1055 mpWindowManager
->SetTheme(mpTheme
);
1057 if (mpPaneBorderPainter
.get() != nullptr)
1058 mpPaneBorderPainter
->SetTheme(mpTheme
);
1061 mxMainWindow
= rxPane
->getWindow();
1062 if (mxMainWindow
.is())
1064 mxMainWindow
->addKeyListener(this);
1065 mxMainWindow
->addMouseListener(this);
1067 Reference
<XPane2
> xPane2 (rxPane
, UNO_QUERY
);
1069 xPane2
->setVisible(true);
1071 mpPaintManager
.reset(new PresenterPaintManager(mxMainWindow
, mxPresenterHelper
, mpPaneContainer
));
1073 mxCanvas
.set(rxPane
->getCanvas(), UNO_QUERY
);
1075 if (mxSlideShowController
.is())
1076 mxSlideShowController
->activate();
1078 UpdateCurrentSlide(0);
1081 void PresenterController::LoadTheme (const Reference
<XPane
>& rxPane
)
1083 // Create (load) the current theme.
1085 mpTheme
.reset(new PresenterTheme(mxComponentContext
, rxPane
->getCanvas()));
1088 double PresenterController::GetSlideAspectRatio() const
1090 double nSlideAspectRatio (28.0/21.0);
1094 if (mxController
.is())
1096 Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (
1097 mxController
->getModel(), UNO_QUERY_THROW
);
1098 Reference
<drawing::XDrawPages
> xSlides (xSlideSupplier
->getDrawPages());
1099 if (xSlides
.is() && xSlides
->getCount()>0)
1101 Reference
<beans::XPropertySet
> xProperties(xSlides
->getByIndex(0),UNO_QUERY_THROW
);
1102 sal_Int32
nWidth (28000);
1103 sal_Int32
nHeight (21000);
1104 if ((xProperties
->getPropertyValue("Width") >>= nWidth
)
1105 && (xProperties
->getPropertyValue("Height") >>= nHeight
)
1108 nSlideAspectRatio
= double(nWidth
) / double(nHeight
);
1113 catch (RuntimeException
&)
1118 return nSlideAspectRatio
;
1121 void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber
)
1123 mnPendingSlideNumber
= nPendingSlideNumber
;
1125 if (mpTheme
== nullptr)
1128 if ( ! mxMainWindow
.is())
1131 PresenterTheme::SharedFontDescriptor
pFont (
1132 mpTheme
->GetFont("PendingSlideNumberFont"));
1133 if (pFont
.get() == nullptr)
1136 pFont
->PrepareFont(mxCanvas
);
1137 if ( ! pFont
->mxFont
.is())
1140 const OUString
sText (OUString::number(mnPendingSlideNumber
));
1141 rendering::StringContext
aContext (sText
, 0, sText
.getLength());
1142 pFont
->mxFont
->createTextLayout(
1144 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1148 void PresenterController::SwitchMonitors()
1150 Reference
<lang::XEventListener
> xScreen( mxScreen
);
1154 PresenterScreen
*pScreen
= dynamic_cast<PresenterScreen
*>(xScreen
.get());
1158 pScreen
->SwitchMonitors();
1161 } } // end of namespace ::sdext::presenter
1163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */