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::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(std::make_shared
<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 if (mxController
.is())
209 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
211 xFrame
->removeFrameActionListener(this);
212 mxController
= nullptr;
215 Reference
<XComponent
> xWindowManagerComponent (
216 static_cast<XWeak
*>(mpWindowManager
.get()), UNO_QUERY
);
217 mpWindowManager
= nullptr;
218 if (xWindowManagerComponent
.is())
219 xWindowManagerComponent
->dispose();
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
);
278 sal_Int32 nSlideIndex
= mxSlideShowController
->getCurrentSlideIndex() + nOffset
;
279 if (mxSlideShowController
->isPaused())
282 if (xIndexAccess
.is() && nSlideIndex
>=0)
284 if (nSlideIndex
< xIndexAccess
->getCount())
286 mnCurrentSlideIndex
= nSlideIndex
;
287 mxCurrentSlide
.set( xIndexAccess
->getByIndex(nSlideIndex
), UNO_QUERY
);
291 catch (RuntimeException
&)
295 // Get the next slide.
296 mxNextSlide
= nullptr;
299 const sal_Int32
nNextSlideIndex (mxSlideShowController
->getNextSlideIndex()+nOffset
);
300 if (nNextSlideIndex
>= 0)
302 if (xIndexAccess
.is())
304 if (nNextSlideIndex
< xIndexAccess
->getCount())
305 mxNextSlide
.set( xIndexAccess
->getByIndex(nNextSlideIndex
), UNO_QUERY
);
309 catch (RuntimeException
&)
314 void PresenterController::UpdatePaneTitles()
316 if ( ! mxSlideShowController
.is())
319 // Get placeholders and their values.
320 static const OUStringLiteral
sCurrentSlideNumberPlaceholder (u
"CURRENT_SLIDE_NUMBER");
321 static const OUStringLiteral
sCurrentSlideNamePlaceholder (u
"CURRENT_SLIDE_NAME");
322 static const OUStringLiteral
sSlideCountPlaceholder (u
"SLIDE_COUNT");
324 // Get string for slide count.
325 OUString
sSlideCount ("---");
326 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
327 if (xIndexAccess
.is())
328 sSlideCount
= OUString::number(xIndexAccess
->getCount());
330 // Get string for current slide index.
331 OUString
sCurrentSlideNumber (OUString::number(mnCurrentSlideIndex
+ 1));
333 // Get name of the current slide.
334 OUString sCurrentSlideName
;
335 Reference
<container::XNamed
> xNamedSlide (mxCurrentSlide
, UNO_QUERY
);
336 if (xNamedSlide
.is())
337 sCurrentSlideName
= xNamedSlide
->getName();
338 Reference
<beans::XPropertySet
> xSlideProperties (mxCurrentSlide
, UNO_QUERY
);
339 if (xSlideProperties
.is())
344 if (xSlideProperties
->getPropertyValue("LinkDisplayName") >>= sName
)
346 // Find out whether the name of the current slide has been
347 // automatically created or has been set by the user.
348 if (sName
!= sCurrentSlideName
)
349 sCurrentSlideName
= sName
;
352 catch (const beans::UnknownPropertyException
&)
357 // Replace the placeholders with their current values.
358 for (auto& rxPane
: mpPaneContainer
->maPanes
)
360 OSL_ASSERT(rxPane
!= nullptr);
362 OUString
sTemplate (IsAccessibilityActive()
363 ? rxPane
->msAccessibleTitleTemplate
364 : rxPane
->msTitleTemplate
);
365 if (sTemplate
.isEmpty())
368 OUStringBuffer sResult
;
369 sResult
.ensureCapacity(sTemplate
.getLength());
371 sal_Int32
nIndex (0);
374 sal_Int32 nStartIndex
= sTemplate
.indexOf('%', nIndex
);
377 // Add the remaining part of the string.
378 sResult
.append(sTemplate
.subView(nIndex
));
383 // Add the part preceding the next %.
384 sResult
.append(sTemplate
.subView(nIndex
, nStartIndex
-nIndex
));
386 // Get the placeholder
388 const sal_Int32
nEndIndex (sTemplate
.indexOf('%', nStartIndex
+1));
389 const OUString
sPlaceholder (sTemplate
.copy(nStartIndex
, nEndIndex
-nStartIndex
));
390 nIndex
= nEndIndex
+1;
392 // Replace the placeholder with its current value.
393 if (sPlaceholder
== sCurrentSlideNumberPlaceholder
)
394 sResult
.append(sCurrentSlideNumber
);
395 else if (sPlaceholder
== sCurrentSlideNamePlaceholder
)
396 sResult
.append(sCurrentSlideName
);
397 else if (sPlaceholder
== sSlideCountPlaceholder
)
398 sResult
.append(sSlideCount
);
402 rxPane
->msTitle
= sResult
.makeStringAndClear();
403 if (rxPane
->mxPane
.is())
404 rxPane
->mxPane
->SetTitle(rxPane
->msTitle
);
408 void PresenterController::UpdateViews()
410 // Tell all views about the slides they should display.
411 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
413 Reference
<drawing::XDrawView
> xDrawView (rxPane
->mxView
, UNO_QUERY
);
415 xDrawView
->setCurrentPage(mxCurrentSlide
);
419 SharedBitmapDescriptor
420 PresenterController::GetViewBackground (const OUString
& rsViewURL
) const
422 if (mpTheme
!= nullptr)
424 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
425 return mpTheme
->GetBitmap(sStyleName
, "Background");
427 return SharedBitmapDescriptor();
430 PresenterTheme::SharedFontDescriptor
431 PresenterController::GetViewFont (const OUString
& rsViewURL
) const
433 if (mpTheme
!= nullptr)
435 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
436 return mpTheme
->GetFont(sStyleName
);
438 return PresenterTheme::SharedFontDescriptor();
441 const std::shared_ptr
<PresenterTheme
>& PresenterController::GetTheme() const
446 const ::rtl::Reference
<PresenterWindowManager
>& PresenterController::GetWindowManager() const
448 return mpWindowManager
;
451 const Reference
<presentation::XSlideShowController
>&
452 PresenterController::GetSlideShowController() const
454 return mxSlideShowController
;
457 const rtl::Reference
<PresenterPaneContainer
>& PresenterController::GetPaneContainer() const
459 return mpPaneContainer
;
462 const ::rtl::Reference
<PresenterPaneBorderPainter
>& PresenterController::GetPaneBorderPainter() const
464 return mpPaneBorderPainter
;
467 const std::shared_ptr
<PresenterCanvasHelper
>& PresenterController::GetCanvasHelper() const
469 return mpCanvasHelper
;
472 const Reference
<drawing::XPresenterHelper
>& PresenterController::GetPresenterHelper() const
474 return mxPresenterHelper
;
477 const std::shared_ptr
<PresenterPaintManager
>& PresenterController::GetPaintManager() const
479 return mpPaintManager
;
482 void PresenterController::ShowView (const OUString
& rsViewURL
)
484 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
485 mpPaneContainer
->FindViewURL(rsViewURL
));
489 pDescriptor
->mbIsActive
= true;
490 mxConfigurationController
->requestResourceActivation(
491 pDescriptor
->mxPaneId
,
492 ResourceActivationMode_ADD
);
493 mxConfigurationController
->requestResourceActivation(
494 ResourceId::createWithAnchor(
497 pDescriptor
->mxPaneId
),
498 ResourceActivationMode_REPLACE
);
501 void PresenterController::HideView (const OUString
& rsViewURL
)
503 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
504 mpPaneContainer
->FindViewURL(rsViewURL
));
507 mxConfigurationController
->requestResourceDeactivation(
508 ResourceId::createWithAnchor(
511 pDescriptor
->mxPaneId
));
515 void PresenterController::DispatchUnoCommand (const OUString
& rsCommand
) const
517 if ( ! mxUrlTransformer
.is())
521 aURL
.Complete
= rsCommand
;
522 mxUrlTransformer
->parseStrict(aURL
);
524 Reference
<frame::XDispatch
> xDispatch (GetDispatch(aURL
));
525 if ( ! xDispatch
.is())
528 xDispatch
->dispatch(aURL
, Sequence
<beans::PropertyValue
>());
531 Reference
<css::frame::XDispatch
> PresenterController::GetDispatch (const util::URL
& rURL
) const
533 if ( ! mxController
.is())
536 Reference
<frame::XDispatchProvider
> xDispatchProvider (mxController
->getFrame(), UNO_QUERY
);
537 if ( ! xDispatchProvider
.is())
540 return xDispatchProvider
->queryDispatch(
543 frame::FrameSearchFlag::SELF
);
546 util::URL
PresenterController::CreateURLFromString (const OUString
& rsURL
) const
550 if (mxUrlTransformer
.is())
552 aURL
.Complete
= rsURL
;
553 mxUrlTransformer
->parseStrict(aURL
);
559 const Reference
<drawing::framework::XConfigurationController
>&
560 PresenterController::GetConfigurationController() const
562 return mxConfigurationController
;
565 const Reference
<drawing::XDrawPage
>& PresenterController::GetCurrentSlide() const
567 return mxCurrentSlide
;
570 bool PresenterController::HasTransition (Reference
<drawing::XDrawPage
> const & rxPage
)
572 bool bTransition
= false;
575 Reference
<beans::XPropertySet
> xSlidePropertySet (rxPage
, UNO_QUERY
);
578 sal_uInt16 aTransitionType
= 0;
579 xSlidePropertySet
->getPropertyValue("TransitionType") >>= aTransitionType
;
580 if (aTransitionType
> 0)
585 catch (const beans::UnknownPropertyException
&)
592 bool PresenterController::HasCustomAnimation (Reference
<drawing::XDrawPage
> const & rxPage
)
594 bool bCustomAnimation
= false;
597 sal_uInt32 i
, nCount
= rxPage
->getCount();
598 for ( i
= 0; i
< nCount
; i
++ )
600 Reference
<drawing::XShape
> xShape(rxPage
->getByIndex(i
), UNO_QUERY
);
601 Reference
<beans::XPropertySet
> xShapePropertySet(xShape
, UNO_QUERY
);
602 presentation::AnimationEffect aEffect
= presentation::AnimationEffect_NONE
;
603 presentation::AnimationEffect aTextEffect
= presentation::AnimationEffect_NONE
;
606 xShapePropertySet
->getPropertyValue("Effect") >>= aEffect
;
607 xShapePropertySet
->getPropertyValue("TextEffect") >>= aTextEffect
;
609 catch (const beans::UnknownPropertyException
&)
612 if( aEffect
!= presentation::AnimationEffect_NONE
||
613 aTextEffect
!= presentation::AnimationEffect_NONE
)
615 bCustomAnimation
= true;
620 return bCustomAnimation
;
623 void PresenterController::SetAccessibilityActiveState (const bool bIsActive
)
625 if ( mbIsAccessibilityActive
!= bIsActive
)
627 mbIsAccessibilityActive
= bIsActive
;
633 void PresenterController::HandleMouseClick (const awt::MouseEvent
& rEvent
)
635 if (!mxSlideShowController
.is())
638 switch (rEvent
.Buttons
)
640 case awt::MouseButton::LEFT
:
641 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
642 mxSlideShowController
->gotoNextSlide();
644 mxSlideShowController
->gotoNextEffect();
647 case awt::MouseButton::RIGHT
:
648 mxSlideShowController
->gotoPreviousSlide();
652 // Other or multiple buttons.
657 void PresenterController::RequestViews (
658 const bool bIsSlideSorterActive
,
659 const bool bIsNotesViewActive
,
660 const bool bIsHelpViewActive
)
662 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
664 bool bActivate (true);
665 const OUString
sViewURL (rxPane
->msViewURL
);
666 if (sViewURL
== PresenterViewFactory::msNotesViewURL
)
668 bActivate
= bIsNotesViewActive
&& !bIsSlideSorterActive
&& !bIsHelpViewActive
;
670 else if (sViewURL
== PresenterViewFactory::msSlideSorterURL
)
672 bActivate
= bIsSlideSorterActive
;
674 else if (sViewURL
== PresenterViewFactory::msCurrentSlidePreviewViewURL
675 || sViewURL
== PresenterViewFactory::msNextSlidePreviewViewURL
)
677 bActivate
= !bIsSlideSorterActive
&& ! bIsHelpViewActive
;
679 else if (sViewURL
== PresenterViewFactory::msToolBarViewURL
)
683 else if (sViewURL
== PresenterViewFactory::msHelpViewURL
)
685 bActivate
= bIsHelpViewActive
;
695 void PresenterController::SetPresentationTime(IPresentationTime
* pPresentationTime
)
697 mpPresentationTime
= pPresentationTime
;
700 IPresentationTime
* PresenterController::GetPresentationTime()
702 return mpPresentationTime
;
705 //----- XConfigurationChangeListener ------------------------------------------
707 void SAL_CALL
PresenterController::notifyConfigurationChange (
708 const ConfigurationChangeEvent
& rEvent
)
710 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
712 throw lang::DisposedException (
713 "PresenterController object has already been disposed",
714 static_cast<uno::XWeak
*>(this));
718 if ( ! (rEvent
.UserData
>>= nType
))
723 case ResourceActivationEventType
:
724 if (rEvent
.ResourceId
->compareTo(mxMainPaneId
) == 0)
726 InitializeMainPane(Reference
<XPane
>(rEvent
.ResourceObject
,UNO_QUERY
));
728 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_DIRECT
))
730 // A pane bound to the main pane has been created and is
731 // stored in the pane container.
732 Reference
<XPane
> xPane (rEvent
.ResourceObject
,UNO_QUERY
);
735 mpPaneContainer
->FindPaneId(xPane
->getResourceId());
738 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
740 // A view bound to one of the panes has been created and is
741 // stored in the pane container along with its pane.
742 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
745 mpPaneContainer
->StoreView(xView
);
747 mpWindowManager
->NotifyViewCreation(xView
);
752 case ResourceDeactivationEventType
:
753 if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
755 // If this is a view then remove it from the pane container.
756 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
759 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
760 mpPaneContainer
->RemoveView(xView
));
762 // A possibly opaque view has been removed. Update()
763 // updates the clip polygon.
764 mpWindowManager
->Update();
765 // Request the repainting of the area previously
766 // occupied by the view.
768 GetPaintManager()->Invalidate(pDescriptor
->mxBorderWindow
);
773 case ConfigurationUpdateEndEventType
:
774 if (IsAccessibilityActive())
776 mpAccessibleObject
->UpdateAccessibilityHierarchy();
777 UpdateCurrentSlide(0);
783 //----- XEventListener --------------------------------------------------------
785 void SAL_CALL
PresenterController::disposing (
786 const lang::EventObject
& rEvent
)
788 if (rEvent
.Source
== mxController
)
789 mxController
= nullptr;
790 else if (rEvent
.Source
== mxConfigurationController
)
791 mxConfigurationController
= nullptr;
792 else if (rEvent
.Source
== mxSlideShowController
)
793 mxSlideShowController
= nullptr;
794 else if (rEvent
.Source
== mxMainWindow
)
795 mxMainWindow
= nullptr;
798 //----- XFrameActionListener --------------------------------------------------
800 void SAL_CALL
PresenterController::frameAction (
801 const frame::FrameActionEvent
& rEvent
)
803 if (rEvent
.Action
== frame::FrameAction_FRAME_ACTIVATED
)
805 if (mxSlideShowController
.is())
806 mxSlideShowController
->activate();
810 //----- XKeyListener ----------------------------------------------------------
812 void SAL_CALL
PresenterController::keyPressed (const awt::KeyEvent
& rEvent
)
814 // Tell all views about the unhandled key event.
815 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
817 if ( ! rxPane
->mbIsActive
)
820 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
821 if (xKeyListener
.is())
822 xKeyListener
->keyPressed(rEvent
);
826 void SAL_CALL
PresenterController::keyReleased (const awt::KeyEvent
& rEvent
)
828 if (rEvent
.Source
!= mxMainWindow
)
831 switch (rEvent
.KeyCode
)
833 case awt::Key::ESCAPE
:
834 case awt::Key::SUBTRACT
:
836 if( mxController
.is() )
838 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
841 Reference
< XPresentation
> xP( xPS
->getPresentation() );
849 case awt::Key::PAGEDOWN
:
850 if (mxSlideShowController
.is())
852 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
853 mxSlideShowController
->gotoNextSlide();
855 mxSlideShowController
->gotoNextEffect();
859 case awt::Key::RIGHT
:
860 case awt::Key::SPACE
:
862 if (mxSlideShowController
.is())
864 mxSlideShowController
->gotoNextEffect();
868 case awt::Key::PAGEUP
:
869 if (mxSlideShowController
.is())
871 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
872 mxSlideShowController
->gotoPreviousSlide();
874 mxSlideShowController
->gotoPreviousEffect();
880 case awt::Key::BACKSPACE
:
881 if (mxSlideShowController
.is())
883 mxSlideShowController
->gotoPreviousEffect();
888 if (mxSlideShowController
.is())
890 bool bPenEnabled
= mxSlideShowController
->getUsePen();
891 mxSlideShowController
->setUsePen( !bPenEnabled
);
896 if (mxSlideShowController
.is())
898 mxSlideShowController
->setEraseAllInk( true );
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.
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 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
982 if ( ! rxPane
->mbIsActive
)
985 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
986 if (xKeyListener
.is())
987 xKeyListener
->keyReleased(rEvent
);
993 void PresenterController::HandleNumericKeyPress (
994 const sal_Int32 nKey
,
995 const sal_Int32 nModifiers
)
1000 if (mnPendingSlideNumber
== -1)
1001 mnPendingSlideNumber
= 0;
1002 UpdatePendingSlideNumber(mnPendingSlideNumber
* 10 + nKey
);
1005 case awt::KeyModifier::MOD1
:
1006 // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
1007 // (slide view, notes view, normal). Ctrl-4 switches monitors
1008 mnPendingSlideNumber
= -1;
1009 if (!mpWindowManager
)
1014 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
1017 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
1020 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_SlideOverview
);
1026 // Ignore unsupported key.
1032 // Ignore unsupported modifiers.
1037 //----- XMouseListener --------------------------------------------------------
1039 void SAL_CALL
PresenterController::mousePressed (const css::awt::MouseEvent
&)
1041 if (mxMainWindow
.is())
1042 mxMainWindow
->setFocus();
1045 void SAL_CALL
PresenterController::mouseReleased (const css::awt::MouseEvent
&) {}
1047 void SAL_CALL
PresenterController::mouseEntered (const css::awt::MouseEvent
&) {}
1049 void SAL_CALL
PresenterController::mouseExited (const css::awt::MouseEvent
&) {}
1051 void PresenterController::InitializeMainPane (const Reference
<XPane
>& rxPane
)
1056 mpAccessibleObject
= new PresenterAccessible(
1063 // Main pane has been created and is now observed by the window
1065 mpWindowManager
->SetParentPane(rxPane
);
1066 mpWindowManager
->SetTheme(mpTheme
);
1068 if (mpPaneBorderPainter
)
1069 mpPaneBorderPainter
->SetTheme(mpTheme
);
1072 mxMainWindow
= rxPane
->getWindow();
1073 if (mxMainWindow
.is())
1075 mxMainWindow
->addKeyListener(this);
1076 mxMainWindow
->addMouseListener(this);
1078 Reference
<XPane2
> xPane2 (rxPane
, UNO_QUERY
);
1080 xPane2
->setVisible(true);
1082 mpPaintManager
= std::make_shared
<PresenterPaintManager
>(mxMainWindow
, mxPresenterHelper
, mpPaneContainer
);
1084 mxCanvas
.set(rxPane
->getCanvas(), UNO_QUERY
);
1086 if (mxSlideShowController
.is())
1087 mxSlideShowController
->activate();
1089 UpdateCurrentSlide(0);
1092 void PresenterController::LoadTheme (const Reference
<XPane
>& rxPane
)
1094 // Create (load) the current theme.
1096 mpTheme
= std::make_shared
<PresenterTheme
>(mxComponentContext
, rxPane
->getCanvas());
1099 double PresenterController::GetSlideAspectRatio() const
1101 double nSlideAspectRatio (28.0/21.0);
1105 if (mxController
.is())
1107 Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (
1108 mxController
->getModel(), UNO_QUERY_THROW
);
1109 Reference
<drawing::XDrawPages
> xSlides (xSlideSupplier
->getDrawPages());
1110 if (xSlides
.is() && xSlides
->getCount()>0)
1112 Reference
<beans::XPropertySet
> xProperties(xSlides
->getByIndex(0),UNO_QUERY_THROW
);
1113 sal_Int32
nWidth (28000);
1114 sal_Int32
nHeight (21000);
1115 if ((xProperties
->getPropertyValue("Width") >>= nWidth
)
1116 && (xProperties
->getPropertyValue("Height") >>= nHeight
)
1119 nSlideAspectRatio
= double(nWidth
) / double(nHeight
);
1124 catch (RuntimeException
&)
1129 return nSlideAspectRatio
;
1132 void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber
)
1134 mnPendingSlideNumber
= nPendingSlideNumber
;
1136 if (mpTheme
== nullptr)
1139 if ( ! mxMainWindow
.is())
1142 PresenterTheme::SharedFontDescriptor
pFont (
1143 mpTheme
->GetFont("PendingSlideNumberFont"));
1147 pFont
->PrepareFont(mxCanvas
);
1148 if ( ! pFont
->mxFont
.is())
1151 const OUString
sText (OUString::number(mnPendingSlideNumber
));
1152 rendering::StringContext
aContext (sText
, 0, sText
.getLength());
1153 pFont
->mxFont
->createTextLayout(
1155 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1159 void PresenterController::SwitchMonitors()
1161 Reference
<lang::XEventListener
> xScreen( mxScreen
);
1165 PresenterScreen
*pScreen
= dynamic_cast<PresenterScreen
*>(xScreen
.get());
1169 pScreen
->SwitchMonitors();
1172 void PresenterController::ExitPresenter()
1174 if( mxController
.is() )
1176 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
1179 Reference
< XPresentation
> xP( xPS
->getPresentation() );
1186 } // end of namespace ::sdext::presenter
1188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */