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 "PresenterController.hxx"
24 #include "PresenterAccessibility.hxx"
25 #include "PresenterCanvasHelper.hxx"
26 #include "PresenterCurrentSlideObserver.hxx"
27 #include "PresenterScreen.hxx"
28 #include "PresenterPaintManager.hxx"
29 #include "PresenterPaneBase.hxx"
30 #include "PresenterPaneContainer.hxx"
31 #include "PresenterPaneBorderPainter.hxx"
32 #include "PresenterTheme.hxx"
33 #include "PresenterViewFactory.hxx"
34 #include "PresenterWindowManager.hxx"
35 #include <DrawController.hxx>
37 #include <com/sun/star/awt/Key.hpp>
38 #include <com/sun/star/awt/KeyModifier.hpp>
39 #include <com/sun/star/awt/MouseButton.hpp>
40 #include <com/sun/star/container/XNamed.hpp>
41 #include <com/sun/star/drawing/XDrawView.hpp>
42 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
43 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
44 #include <com/sun/star/drawing/framework/ResourceId.hpp>
45 #include <com/sun/star/frame/FrameSearchFlag.hpp>
46 #include <com/sun/star/frame/XDispatchProvider.hpp>
47 #include <com/sun/star/presentation/AnimationEffect.hpp>
48 #include <com/sun/star/presentation/XPresentation.hpp>
49 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
50 #include <com/sun/star/rendering/TextDirection.hpp>
51 #include <com/sun/star/util/URLTransformer.hpp>
53 #include <rtl/ustrbuf.hxx>
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::presentation
;
59 using namespace ::com::sun::star::drawing::framework
;
62 const sal_Int32 ResourceActivationEventType
= 0;
63 const sal_Int32 ResourceDeactivationEventType
= 1;
64 const sal_Int32 ConfigurationUpdateEndEventType
= 2;
67 namespace sdext::presenter
{
69 IPresentationTime::~IPresentationTime()
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 unotools::WeakReference
<PresenterScreen
> xScreen
,
87 const Reference
<XComponentContext
>& rxContext
,
88 const rtl::Reference
<::sd::DrawController
>& rxController
,
89 const Reference
<presentation::XSlideShowController
>& rxSlideShowController
,
90 rtl::Reference
<PresenterPaneContainer
> xPaneContainer
,
91 const Reference
<XResourceId
>& rxMainPaneId
)
92 : PresenterControllerInterfaceBase(m_aMutex
),
93 mxScreen(std::move(xScreen
)),
94 mxComponentContext(rxContext
),
95 mxController(rxController
),
96 mxSlideShowController(rxSlideShowController
),
97 mxMainPaneId(rxMainPaneId
),
98 mpPaneContainer(std::move(xPaneContainer
)),
99 mnCurrentSlideIndex(-1),
100 mpWindowManager(new PresenterWindowManager(rxContext
,mpPaneContainer
,this)),
101 mpCanvasHelper(std::make_shared
<PresenterCanvasHelper
>()),
102 mnPendingSlideNumber(-1),
103 mbIsAccessibilityActive(false)
105 OSL_ASSERT(mxController
.is());
107 if ( ! mxSlideShowController
.is())
108 throw lang::IllegalArgumentException(
109 "missing slide show controller",
110 static_cast<XWeak
*>(this),
113 new PresenterCurrentSlideObserver(this,rxSlideShowController
);
115 // Listen for configuration changes.
116 mxConfigurationController
= mxController
->getConfigurationController();
117 if (mxConfigurationController
.is())
119 mxConfigurationController
->addConfigurationChangeListener(
121 "ResourceActivation",
122 Any(ResourceActivationEventType
));
123 mxConfigurationController
->addConfigurationChangeListener(
125 "ResourceDeactivation",
126 Any(ResourceDeactivationEventType
));
127 mxConfigurationController
->addConfigurationChangeListener(
129 "ConfigurationUpdateEnd",
130 Any(ConfigurationUpdateEndEventType
));
133 // Listen for the frame being activated.
134 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
136 xFrame
->addFrameActionListener(this);
138 // Create the border painter.
139 mpPaneBorderPainter
= new PresenterPaneBorderPainter(rxContext
);
140 mpWindowManager
->SetPaneBorderPainter(mpPaneBorderPainter
);
142 // Create an object that is able to load the bitmaps in a format that is
143 // supported by the canvas.
144 Reference
<lang::XMultiComponentFactory
> xFactory
=
145 rxContext
->getServiceManager();
146 if ( ! xFactory
.is())
148 mxPresenterHelper
.set(
149 xFactory
->createInstanceWithContext(
150 "com.sun.star.drawing.PresenterHelper",
154 if (mxSlideShowController
.is())
156 mxSlideShowController
->activate();
157 Reference
<beans::XPropertySet
> xProperties (mxSlideShowController
, UNO_QUERY
);
158 if (xProperties
.is())
160 Reference
<awt::XWindow
> xWindow (
161 xProperties
->getPropertyValue("ParentWindow"), UNO_QUERY
);
163 xWindow
->addKeyListener(this);
167 UpdateCurrentSlide(0);
169 maInstances
[mxController
->getFrame()] = this;
171 // Create a URLTransformer.
174 mxUrlTransformer
.set(util::URLTransformer::create(mxComponentContext
));
178 PresenterController::~PresenterController()
182 void PresenterController::disposing()
184 maInstances
.erase(mxController
->getFrame());
186 if (mxMainWindow
.is())
188 mxMainWindow
->removeKeyListener(this);
189 mxMainWindow
->removeMouseListener(this);
190 mxMainWindow
= nullptr;
192 if (mxConfigurationController
.is())
193 mxConfigurationController
->removeConfigurationChangeListener(this);
195 if (mxController
.is())
197 Reference
<frame::XFrame
> xFrame (mxController
->getFrame());
199 xFrame
->removeFrameActionListener(this);
200 mxController
= nullptr;
203 Reference
<XComponent
> xWindowManagerComponent
= mpWindowManager
;
204 mpWindowManager
= nullptr;
205 if (xWindowManagerComponent
.is())
206 xWindowManagerComponent
->dispose();
208 mxComponentContext
= nullptr;
209 mxConfigurationController
= nullptr;
210 mxSlideShowController
= nullptr;
211 mxMainPaneId
= nullptr;
212 mpPaneContainer
= nullptr;
213 mnCurrentSlideIndex
= -1;
214 mxCurrentSlide
= nullptr;
215 mxNextSlide
= nullptr;
218 Reference
<lang::XComponent
> xComponent
= mpPaneBorderPainter
;
219 mpPaneBorderPainter
= nullptr;
221 xComponent
->dispose();
223 mpCanvasHelper
.reset();
225 Reference
<lang::XComponent
> xComponent (mxPresenterHelper
, UNO_QUERY
);
226 mxPresenterHelper
= nullptr;
228 xComponent
->dispose();
230 mpPaintManager
.reset();
231 mnPendingSlideNumber
= -1;
233 Reference
<lang::XComponent
> xComponent (mxUrlTransformer
, UNO_QUERY
);
234 mxUrlTransformer
= nullptr;
236 xComponent
->dispose();
240 void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset
)
242 // std::cerr << "Updating current Slide to " << nOffset << std::endl;
247 // Update the accessibility object.
248 if (IsAccessibilityActive())
250 mpAccessibleObject
->NotifyCurrentSlideChange();
254 void PresenterController::GetSlides (const sal_Int32 nOffset
)
256 if ( ! mxSlideShowController
.is())
259 // Get the current slide from the slide show controller.
260 mxCurrentSlide
= nullptr;
261 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
264 sal_Int32 nSlideIndex
= mxSlideShowController
->getCurrentSlideIndex() + nOffset
;
265 if (mxSlideShowController
->isPaused())
268 if (xIndexAccess
.is() && nSlideIndex
>=0)
270 if (nSlideIndex
< xIndexAccess
->getCount())
272 mnCurrentSlideIndex
= nSlideIndex
;
273 mxCurrentSlide
.set( xIndexAccess
->getByIndex(nSlideIndex
), UNO_QUERY
);
277 catch (RuntimeException
&)
281 // Get the next slide.
282 mxNextSlide
= nullptr;
285 const sal_Int32
nNextSlideIndex (mxSlideShowController
->getNextSlideIndex()+nOffset
);
286 if (nNextSlideIndex
>= 0)
288 if (xIndexAccess
.is())
290 if (nNextSlideIndex
< xIndexAccess
->getCount())
291 mxNextSlide
.set( xIndexAccess
->getByIndex(nNextSlideIndex
), UNO_QUERY
);
295 catch (RuntimeException
&)
300 void PresenterController::UpdatePaneTitles()
302 if ( ! mxSlideShowController
.is())
305 // Get placeholders and their values.
306 static const OUStringLiteral
sCurrentSlideNumberPlaceholder (u
"CURRENT_SLIDE_NUMBER");
307 static const OUStringLiteral
sCurrentSlideNamePlaceholder (u
"CURRENT_SLIDE_NAME");
308 static const OUStringLiteral
sSlideCountPlaceholder (u
"SLIDE_COUNT");
310 // Get string for slide count.
311 OUString
sSlideCount ("---");
312 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
313 if (xIndexAccess
.is())
314 sSlideCount
= OUString::number(xIndexAccess
->getCount());
316 // Get string for current slide index.
317 OUString
sCurrentSlideNumber (OUString::number(mnCurrentSlideIndex
+ 1));
319 // Get name of the current slide.
320 OUString sCurrentSlideName
;
321 Reference
<container::XNamed
> xNamedSlide (mxCurrentSlide
, UNO_QUERY
);
322 if (xNamedSlide
.is())
323 sCurrentSlideName
= xNamedSlide
->getName();
324 Reference
<beans::XPropertySet
> xSlideProperties (mxCurrentSlide
, UNO_QUERY
);
325 if (xSlideProperties
.is())
330 if (xSlideProperties
->getPropertyValue("LinkDisplayName") >>= sName
)
332 // Find out whether the name of the current slide has been
333 // automatically created or has been set by the user.
334 if (sName
!= sCurrentSlideName
)
335 sCurrentSlideName
= sName
;
338 catch (const beans::UnknownPropertyException
&)
343 // Replace the placeholders with their current values.
344 for (auto& rxPane
: mpPaneContainer
->maPanes
)
346 OSL_ASSERT(rxPane
!= nullptr);
348 OUString
sTemplate (IsAccessibilityActive()
349 ? rxPane
->msAccessibleTitleTemplate
350 : rxPane
->msTitleTemplate
);
351 if (sTemplate
.isEmpty())
354 OUStringBuffer sResult
;
355 sResult
.ensureCapacity(sTemplate
.getLength());
357 sal_Int32
nIndex (0);
360 sal_Int32 nStartIndex
= sTemplate
.indexOf('%', nIndex
);
363 // Add the remaining part of the string.
364 sResult
.append(sTemplate
.subView(nIndex
));
369 // Add the part preceding the next %.
370 sResult
.append(sTemplate
.subView(nIndex
, nStartIndex
-nIndex
));
372 // Get the placeholder
374 const sal_Int32
nEndIndex (sTemplate
.indexOf('%', nStartIndex
+1));
375 const std::u16string_view
sPlaceholder (sTemplate
.subView(nStartIndex
, nEndIndex
-nStartIndex
));
376 nIndex
= nEndIndex
+1;
378 // Replace the placeholder with its current value.
379 if (sPlaceholder
== sCurrentSlideNumberPlaceholder
)
380 sResult
.append(sCurrentSlideNumber
);
381 else if (sPlaceholder
== sCurrentSlideNamePlaceholder
)
382 sResult
.append(sCurrentSlideName
);
383 else if (sPlaceholder
== sSlideCountPlaceholder
)
384 sResult
.append(sSlideCount
);
388 rxPane
->msTitle
= sResult
.makeStringAndClear();
389 if (rxPane
->mxPane
.is())
390 rxPane
->mxPane
->SetTitle(rxPane
->msTitle
);
394 void PresenterController::UpdateViews()
396 // Tell all views about the slides they should display.
397 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
399 Reference
<drawing::XDrawView
> xDrawView (rxPane
->mxView
, UNO_QUERY
);
401 xDrawView
->setCurrentPage(mxCurrentSlide
);
405 SharedBitmapDescriptor
406 PresenterController::GetViewBackground (const OUString
& rsViewURL
) const
408 if (mpTheme
!= nullptr)
410 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
411 return mpTheme
->GetBitmap(sStyleName
, "Background");
413 return SharedBitmapDescriptor();
416 PresenterTheme::SharedFontDescriptor
417 PresenterController::GetViewFont (const OUString
& rsViewURL
) const
419 if (mpTheme
!= nullptr)
421 const OUString
sStyleName (mpTheme
->GetStyleName(rsViewURL
));
422 return mpTheme
->GetFont(sStyleName
);
424 return PresenterTheme::SharedFontDescriptor();
427 const std::shared_ptr
<PresenterTheme
>& PresenterController::GetTheme() const
432 const ::rtl::Reference
<PresenterWindowManager
>& PresenterController::GetWindowManager() const
434 return mpWindowManager
;
437 const Reference
<presentation::XSlideShowController
>&
438 PresenterController::GetSlideShowController() const
440 return mxSlideShowController
;
443 const rtl::Reference
<PresenterPaneContainer
>& PresenterController::GetPaneContainer() const
445 return mpPaneContainer
;
448 const ::rtl::Reference
<PresenterPaneBorderPainter
>& PresenterController::GetPaneBorderPainter() const
450 return mpPaneBorderPainter
;
453 const std::shared_ptr
<PresenterCanvasHelper
>& PresenterController::GetCanvasHelper() const
455 return mpCanvasHelper
;
458 const Reference
<drawing::XPresenterHelper
>& PresenterController::GetPresenterHelper() const
460 return mxPresenterHelper
;
463 const std::shared_ptr
<PresenterPaintManager
>& PresenterController::GetPaintManager() const
465 return mpPaintManager
;
468 void PresenterController::ShowView (const OUString
& rsViewURL
)
470 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
471 mpPaneContainer
->FindViewURL(rsViewURL
));
475 pDescriptor
->mbIsActive
= true;
476 mxConfigurationController
->requestResourceActivation(
477 pDescriptor
->mxPaneId
,
478 ResourceActivationMode_ADD
);
479 mxConfigurationController
->requestResourceActivation(
480 ResourceId::createWithAnchor(
483 pDescriptor
->mxPaneId
),
484 ResourceActivationMode_REPLACE
);
487 void PresenterController::HideView (const OUString
& rsViewURL
)
489 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
490 mpPaneContainer
->FindViewURL(rsViewURL
));
493 mxConfigurationController
->requestResourceDeactivation(
494 ResourceId::createWithAnchor(
497 pDescriptor
->mxPaneId
));
501 void PresenterController::DispatchUnoCommand (const OUString
& rsCommand
) const
503 if ( ! mxUrlTransformer
.is())
507 aURL
.Complete
= rsCommand
;
508 mxUrlTransformer
->parseStrict(aURL
);
510 Reference
<frame::XDispatch
> xDispatch (GetDispatch(aURL
));
511 if ( ! xDispatch
.is())
514 xDispatch
->dispatch(aURL
, Sequence
<beans::PropertyValue
>());
517 Reference
<css::frame::XDispatch
> PresenterController::GetDispatch (const util::URL
& rURL
) const
519 if ( ! mxController
.is())
522 Reference
<frame::XDispatchProvider
> xDispatchProvider (mxController
->getFrame(), UNO_QUERY
);
523 if ( ! xDispatchProvider
.is())
526 return xDispatchProvider
->queryDispatch(
529 frame::FrameSearchFlag::SELF
);
532 util::URL
PresenterController::CreateURLFromString (const OUString
& rsURL
) const
536 if (mxUrlTransformer
.is())
538 aURL
.Complete
= rsURL
;
539 mxUrlTransformer
->parseStrict(aURL
);
545 const Reference
<drawing::framework::XConfigurationController
>&
546 PresenterController::GetConfigurationController() const
548 return mxConfigurationController
;
551 const Reference
<drawing::XDrawPage
>& PresenterController::GetCurrentSlide() const
553 return mxCurrentSlide
;
556 bool PresenterController::HasTransition (Reference
<drawing::XDrawPage
> const & rxPage
)
558 bool bTransition
= false;
561 Reference
<beans::XPropertySet
> xSlidePropertySet (rxPage
, UNO_QUERY
);
564 sal_uInt16 aTransitionType
= 0;
565 xSlidePropertySet
->getPropertyValue("TransitionType") >>= aTransitionType
;
566 if (aTransitionType
> 0)
571 catch (const beans::UnknownPropertyException
&)
578 bool PresenterController::HasCustomAnimation (Reference
<drawing::XDrawPage
> const & rxPage
)
580 bool bCustomAnimation
= false;
583 sal_uInt32 i
, nCount
= rxPage
->getCount();
584 for ( i
= 0; i
< nCount
; i
++ )
586 Reference
<drawing::XShape
> xShape(rxPage
->getByIndex(i
), UNO_QUERY
);
587 Reference
<beans::XPropertySet
> xShapePropertySet(xShape
, UNO_QUERY
);
588 presentation::AnimationEffect aEffect
= presentation::AnimationEffect_NONE
;
589 presentation::AnimationEffect aTextEffect
= presentation::AnimationEffect_NONE
;
592 xShapePropertySet
->getPropertyValue("Effect") >>= aEffect
;
593 xShapePropertySet
->getPropertyValue("TextEffect") >>= aTextEffect
;
595 catch (const beans::UnknownPropertyException
&)
598 if( aEffect
!= presentation::AnimationEffect_NONE
||
599 aTextEffect
!= presentation::AnimationEffect_NONE
)
601 bCustomAnimation
= true;
606 return bCustomAnimation
;
609 void PresenterController::SetAccessibilityActiveState (const bool bIsActive
)
611 if ( mbIsAccessibilityActive
!= bIsActive
)
613 mbIsAccessibilityActive
= bIsActive
;
619 void PresenterController::HandleMouseClick (const awt::MouseEvent
& rEvent
)
621 if (!mxSlideShowController
.is())
624 switch (rEvent
.Buttons
)
626 case awt::MouseButton::LEFT
:
627 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
628 mxSlideShowController
->gotoNextSlide();
630 mxSlideShowController
->gotoNextEffect();
633 case awt::MouseButton::RIGHT
:
634 mxSlideShowController
->gotoPreviousSlide();
638 // Other or multiple buttons.
643 void PresenterController::RequestViews (
644 const bool bIsSlideSorterActive
,
645 const bool bIsNotesViewActive
,
646 const bool bIsHelpViewActive
)
648 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
650 bool bActivate (true);
651 const OUString
sViewURL (rxPane
->msViewURL
);
652 if (sViewURL
== PresenterViewFactory::msNotesViewURL
)
654 bActivate
= bIsNotesViewActive
&& !bIsSlideSorterActive
&& !bIsHelpViewActive
;
656 else if (sViewURL
== PresenterViewFactory::msSlideSorterURL
)
658 bActivate
= bIsSlideSorterActive
;
660 else if (sViewURL
== PresenterViewFactory::msCurrentSlidePreviewViewURL
661 || sViewURL
== PresenterViewFactory::msNextSlidePreviewViewURL
)
663 bActivate
= !bIsSlideSorterActive
&& ! bIsHelpViewActive
;
665 else if (sViewURL
== PresenterViewFactory::msToolBarViewURL
)
669 else if (sViewURL
== PresenterViewFactory::msHelpViewURL
)
671 bActivate
= bIsHelpViewActive
;
681 void PresenterController::SetPresentationTime(IPresentationTime
* pPresentationTime
)
683 mpPresentationTime
= pPresentationTime
;
686 IPresentationTime
* PresenterController::GetPresentationTime()
688 return mpPresentationTime
;
691 //----- XConfigurationChangeListener ------------------------------------------
693 void SAL_CALL
PresenterController::notifyConfigurationChange (
694 const ConfigurationChangeEvent
& rEvent
)
696 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
698 throw lang::DisposedException (
699 "PresenterController object has already been disposed",
700 static_cast<uno::XWeak
*>(this));
704 if ( ! (rEvent
.UserData
>>= nType
))
709 case ResourceActivationEventType
:
710 if (rEvent
.ResourceId
->compareTo(mxMainPaneId
) == 0)
712 InitializeMainPane(Reference
<XPane
>(rEvent
.ResourceObject
,UNO_QUERY
));
714 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_DIRECT
))
716 // A pane bound to the main pane has been created and is
717 // stored in the pane container.
718 Reference
<XPane
> xPane (rEvent
.ResourceObject
,UNO_QUERY
);
721 mpPaneContainer
->FindPaneId(xPane
->getResourceId());
724 else if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
726 // A view bound to one of the panes has been created and is
727 // stored in the pane container along with its pane.
728 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
731 mpPaneContainer
->StoreView(xView
);
733 mpWindowManager
->NotifyViewCreation(xView
);
738 case ResourceDeactivationEventType
:
739 if (rEvent
.ResourceId
->isBoundTo(mxMainPaneId
,AnchorBindingMode_INDIRECT
))
741 // If this is a view then remove it from the pane container.
742 Reference
<XView
> xView (rEvent
.ResourceObject
,UNO_QUERY
);
745 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
746 mpPaneContainer
->RemoveView(xView
));
748 // A possibly opaque view has been removed. Update()
749 // updates the clip polygon.
750 mpWindowManager
->Update();
751 // Request the repainting of the area previously
752 // occupied by the view.
754 GetPaintManager()->Invalidate(pDescriptor
->mxBorderWindow
);
759 case ConfigurationUpdateEndEventType
:
760 if (IsAccessibilityActive())
762 mpAccessibleObject
->UpdateAccessibilityHierarchy();
763 UpdateCurrentSlide(0);
769 //----- XEventListener --------------------------------------------------------
771 void SAL_CALL
PresenterController::disposing (
772 const lang::EventObject
& rEvent
)
774 if (rEvent
.Source
.get() == static_cast<cppu::OWeakObject
*>(mxController
.get()))
775 mxController
= nullptr;
776 else if (rEvent
.Source
== mxConfigurationController
)
777 mxConfigurationController
= nullptr;
778 else if (rEvent
.Source
== mxSlideShowController
)
779 mxSlideShowController
= nullptr;
780 else if (rEvent
.Source
== mxMainWindow
)
781 mxMainWindow
= nullptr;
784 //----- XFrameActionListener --------------------------------------------------
786 void SAL_CALL
PresenterController::frameAction (
787 const frame::FrameActionEvent
& rEvent
)
789 if (rEvent
.Action
== frame::FrameAction_FRAME_ACTIVATED
)
791 if (mxSlideShowController
.is())
792 mxSlideShowController
->activate();
796 //----- XKeyListener ----------------------------------------------------------
798 void SAL_CALL
PresenterController::keyPressed (const awt::KeyEvent
& rEvent
)
800 // Tell all views about the unhandled key event.
801 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
803 if ( ! rxPane
->mbIsActive
)
806 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
807 if (xKeyListener
.is())
808 xKeyListener
->keyPressed(rEvent
);
812 void SAL_CALL
PresenterController::keyReleased (const awt::KeyEvent
& rEvent
)
814 if (rEvent
.Source
!= mxMainWindow
)
817 switch (rEvent
.KeyCode
)
819 case awt::Key::ESCAPE
:
820 case awt::Key::SUBTRACT
:
822 if( mxController
.is() )
824 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
827 Reference
< XPresentation
> xP( xPS
->getPresentation() );
835 case awt::Key::PAGEDOWN
:
836 if (mxSlideShowController
.is())
838 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
839 mxSlideShowController
->gotoNextSlide();
841 mxSlideShowController
->gotoNextEffect();
845 case awt::Key::RIGHT
:
846 case awt::Key::SPACE
:
848 if (mxSlideShowController
.is())
850 mxSlideShowController
->gotoNextEffect();
854 case awt::Key::PAGEUP
:
855 if (mxSlideShowController
.is())
857 if (rEvent
.Modifiers
== awt::KeyModifier::MOD2
)
858 mxSlideShowController
->gotoPreviousSlide();
860 mxSlideShowController
->gotoPreviousEffect();
866 case awt::Key::BACKSPACE
:
867 if (mxSlideShowController
.is())
869 mxSlideShowController
->gotoPreviousEffect();
874 if (mxSlideShowController
.is())
876 bool bPenEnabled
= mxSlideShowController
->getUsePen();
877 mxSlideShowController
->setUsePen( !bPenEnabled
);
881 // tdf#149351 Ctrl+A disables pointer as pen mode
883 if (mxSlideShowController
.is())
885 if (rEvent
.Modifiers
== awt::KeyModifier::MOD1
)
887 mxSlideShowController
->setUsePen( false );
893 if (mxSlideShowController
.is())
895 mxSlideShowController
->setEraseAllInk( true );
900 if (mxSlideShowController
.is())
902 mxSlideShowController
->gotoFirstSlide();
907 if (mxSlideShowController
.is())
909 mxSlideShowController
->gotoLastSlide();
914 case awt::Key::COMMA
:
915 if (mxSlideShowController
.is())
917 if (mxSlideShowController
->isPaused())
918 mxSlideShowController
->resume();
920 mxSlideShowController
->blankScreen(0x00ffffff);
925 case awt::Key::POINT
:
926 if (mxSlideShowController
.is())
928 if (mxSlideShowController
->isPaused())
929 mxSlideShowController
->resume();
931 mxSlideShowController
->blankScreen(0x00000000);
945 HandleNumericKeyPress(rEvent
.KeyCode
-awt::Key::NUM0
, rEvent
.Modifiers
);
948 case awt::Key::RETURN
:
949 if (mnPendingSlideNumber
> 0)
951 if (mxSlideShowController
.is())
952 mxSlideShowController
->gotoSlideIndex(mnPendingSlideNumber
- 1);
953 mnPendingSlideNumber
= -1;
957 if (mxSlideShowController
.is())
958 mxSlideShowController
->gotoNextEffect();
964 // Toggle the help view.
967 if (mpWindowManager
->GetViewMode() != PresenterWindowManager::VM_Help
)
968 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Help
);
970 mpWindowManager
->SetHelpViewState(false);
976 // Tell all views about the unhandled key event.
977 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
979 if ( ! rxPane
->mbIsActive
)
982 Reference
<awt::XKeyListener
> xKeyListener (rxPane
->mxView
, UNO_QUERY
);
983 if (xKeyListener
.is())
984 xKeyListener
->keyReleased(rEvent
);
990 void PresenterController::HandleNumericKeyPress (
991 const sal_Int32 nKey
,
992 const sal_Int32 nModifiers
)
997 if (mnPendingSlideNumber
== -1)
998 mnPendingSlideNumber
= 0;
999 UpdatePendingSlideNumber(mnPendingSlideNumber
* 10 + nKey
);
1002 case awt::KeyModifier::MOD1
:
1003 // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views
1004 // (slide view, notes view, normal). Ctrl-4 switches monitors
1005 mnPendingSlideNumber
= -1;
1006 if (!mpWindowManager
)
1011 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
1014 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
1017 mpWindowManager
->SetViewMode(PresenterWindowManager::VM_SlideOverview
);
1023 // Ignore unsupported key.
1029 // Ignore unsupported modifiers.
1034 //----- XMouseListener --------------------------------------------------------
1036 void SAL_CALL
PresenterController::mousePressed (const css::awt::MouseEvent
&)
1038 if (mxMainWindow
.is())
1039 mxMainWindow
->setFocus();
1042 void SAL_CALL
PresenterController::mouseReleased (const css::awt::MouseEvent
&) {}
1044 void SAL_CALL
PresenterController::mouseEntered (const css::awt::MouseEvent
&) {}
1046 void SAL_CALL
PresenterController::mouseExited (const css::awt::MouseEvent
&) {}
1048 void PresenterController::InitializeMainPane (const Reference
<XPane
>& rxPane
)
1053 mpAccessibleObject
= new PresenterAccessible(
1060 // Main pane has been created and is now observed by the window
1062 mpWindowManager
->SetParentPane(rxPane
);
1063 mpWindowManager
->SetTheme(mpTheme
);
1065 if (mpPaneBorderPainter
)
1066 mpPaneBorderPainter
->SetTheme(mpTheme
);
1069 mxMainWindow
= rxPane
->getWindow();
1070 if (mxMainWindow
.is())
1072 mxMainWindow
->addKeyListener(this);
1073 mxMainWindow
->addMouseListener(this);
1075 Reference
<XPane2
> xPane2 (rxPane
, UNO_QUERY
);
1077 xPane2
->setVisible(true);
1079 mpPaintManager
= std::make_shared
<PresenterPaintManager
>(mxMainWindow
, mxPresenterHelper
, mpPaneContainer
);
1081 mxCanvas
.set(rxPane
->getCanvas(), UNO_QUERY
);
1083 if (mxSlideShowController
.is())
1084 mxSlideShowController
->activate();
1086 UpdateCurrentSlide(0);
1089 void PresenterController::LoadTheme (const Reference
<XPane
>& rxPane
)
1091 // Create (load) the current theme.
1093 mpTheme
= std::make_shared
<PresenterTheme
>(mxComponentContext
, rxPane
->getCanvas());
1096 double PresenterController::GetSlideAspectRatio() const
1098 double nSlideAspectRatio (28.0/21.0);
1102 if (mxController
.is())
1104 Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (
1105 mxController
->getModel(), UNO_QUERY_THROW
);
1106 Reference
<drawing::XDrawPages
> xSlides (xSlideSupplier
->getDrawPages());
1107 if (xSlides
.is() && xSlides
->getCount()>0)
1109 Reference
<beans::XPropertySet
> xProperties(xSlides
->getByIndex(0),UNO_QUERY_THROW
);
1110 sal_Int32
nWidth (28000);
1111 sal_Int32
nHeight (21000);
1112 if ((xProperties
->getPropertyValue("Width") >>= nWidth
)
1113 && (xProperties
->getPropertyValue("Height") >>= nHeight
)
1116 nSlideAspectRatio
= double(nWidth
) / double(nHeight
);
1121 catch (RuntimeException
&)
1126 return nSlideAspectRatio
;
1129 void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber
)
1131 mnPendingSlideNumber
= nPendingSlideNumber
;
1133 if (mpTheme
== nullptr)
1136 if ( ! mxMainWindow
.is())
1139 PresenterTheme::SharedFontDescriptor
pFont (
1140 mpTheme
->GetFont("PendingSlideNumberFont"));
1144 pFont
->PrepareFont(mxCanvas
);
1145 if ( ! pFont
->mxFont
.is())
1148 const OUString
sText (OUString::number(mnPendingSlideNumber
));
1149 rendering::StringContext
aContext (sText
, 0, sText
.getLength());
1150 pFont
->mxFont
->createTextLayout(
1152 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1156 void PresenterController::SwitchMonitors()
1158 rtl::Reference
<PresenterScreen
> pScreen( mxScreen
);
1162 pScreen
->SwitchMonitors();
1165 void PresenterController::ExitPresenter()
1167 if( mxController
.is() )
1169 Reference
< XPresentationSupplier
> xPS( mxController
->getModel(), UNO_QUERY
);
1172 Reference
< XPresentation
> xP( xPS
->getPresentation() );
1179 } // end of namespace ::sdext::presenter
1181 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */