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 .
21 #include "PresenterProtocolHandler.hxx"
22 #include "PresenterController.hxx"
23 #include "PresenterNotesView.hxx"
24 #include "PresenterPaneContainer.hxx"
25 #include "PresenterViewFactory.hxx"
26 #include "PresenterWindowManager.hxx"
27 #include <cppuhelper/compbase.hxx>
28 #include <cppuhelper/supportsservice.hxx>
32 using namespace ::com::sun::star
;
33 using namespace ::com::sun::star::uno
;
34 using namespace ::com::sun::star::drawing::framework
;
36 namespace sdext::presenter
{
43 virtual void Execute() = 0;
44 virtual bool IsEnabled() const { return true; }
45 virtual Any
GetState() const { return Any(false); }
48 class GotoPreviousSlideCommand
: public Command
51 explicit GotoPreviousSlideCommand (
52 rtl::Reference
<PresenterController
> xPresenterController
);
53 virtual void Execute() override
;
54 virtual bool IsEnabled() const override
;
56 rtl::Reference
<PresenterController
> mpPresenterController
;
59 class GotoNextSlideCommand
: public Command
62 explicit GotoNextSlideCommand (
63 rtl::Reference
<PresenterController
> xPresenterController
);
64 virtual void Execute() override
;
65 // The next slide command is always enabled, even when the current slide
66 // is the last slide: from the last slide it goes to the pause slide,
67 // and from there it ends the slide show.
68 virtual bool IsEnabled() const override
{ return true; }
70 rtl::Reference
<PresenterController
> mpPresenterController
;
73 class GotoNextEffectCommand
: public Command
76 explicit GotoNextEffectCommand (
77 rtl::Reference
<PresenterController
> xPresenterController
);
78 virtual void Execute() override
;
79 virtual bool IsEnabled() const override
;
81 rtl::Reference
<PresenterController
> mpPresenterController
;
84 class SwitchMonitorCommand
: public Command
87 explicit SwitchMonitorCommand (
88 rtl::Reference
<PresenterController
> xPresenterController
);
89 virtual void Execute() override
;
91 rtl::Reference
<PresenterController
> mpPresenterController
;
94 class PauseResumeCommand
: public Command
97 explicit PauseResumeCommand(rtl::Reference
<PresenterController
> xPresenterController
);
98 virtual void Execute() override
;
99 virtual Any
GetState() const override
;
101 rtl::Reference
<PresenterController
> mpPresenterController
;
104 /// This command restarts the presentation timer.
105 class RestartTimerCommand
: public Command
108 explicit RestartTimerCommand(rtl::Reference
<PresenterController
> xPresenterController
);
109 virtual void Execute() override
;
111 rtl::Reference
<PresenterController
> mpPresenterController
;
114 class SetNotesViewCommand
: public Command
117 SetNotesViewCommand (
119 rtl::Reference
<PresenterController
> xPresenterController
);
120 virtual void Execute() override
;
121 virtual Any
GetState() const override
;
124 rtl::Reference
<PresenterController
> mpPresenterController
;
127 class SetSlideSorterCommand
: public Command
130 SetSlideSorterCommand (
132 rtl::Reference
<PresenterController
> xPresenterController
);
133 virtual void Execute() override
;
134 virtual Any
GetState() const override
;
137 rtl::Reference
<PresenterController
> mpPresenterController
;
140 class SetHelpViewCommand
: public Command
145 rtl::Reference
<PresenterController
> xPresenterController
);
146 virtual void Execute() override
;
147 virtual Any
GetState() const override
;
150 rtl::Reference
<PresenterController
> mpPresenterController
;
153 class NotesFontSizeCommand
: public Command
156 NotesFontSizeCommand(
157 rtl::Reference
<PresenterController
> xPresenterController
,
158 const sal_Int32 nSizeChange
);
159 virtual void Execute() override
;
160 virtual Any
GetState() const override
;
162 ::rtl::Reference
<PresenterNotesView
> GetNotesView() const;
164 rtl::Reference
<PresenterController
> mpPresenterController
;
165 const sal_Int32 mnSizeChange
;
168 class ExitPresenterCommand
: public Command
171 explicit ExitPresenterCommand(rtl::Reference
<PresenterController
> xPresenterController
);
172 virtual void Execute() override
;
174 rtl::Reference
<PresenterController
> mpPresenterController
;
177 } // end of anonymous namespace
180 typedef ::cppu::WeakComponentImplHelper
<
181 css::frame::XDispatch
,
182 css::document::XEventListener
183 > PresenterDispatchInterfaceBase
;
186 class PresenterProtocolHandler::Dispatch
187 : protected ::cppu::BaseMutex
,
188 public PresenterDispatchInterfaceBase
191 /** Create a new Dispatch object. When the given command name
192 (rsURLPath) is not known then an empty reference is returned.
194 static Reference
<frame::XDispatch
> Create (
195 const OUString
& rsURLPath
,
196 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
198 void SAL_CALL
disposing() override
;
199 static Command
* CreateCommand (
200 std::u16string_view rsURLPath
,
201 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
204 virtual void SAL_CALL
dispatch(
205 const css::util::URL
& aURL
,
206 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
) override
;
208 virtual void SAL_CALL
addStatusListener(
209 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
210 const css::util::URL
& rURL
) override
;
212 virtual void SAL_CALL
removeStatusListener (
213 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
214 const css::util::URL
& rURL
) override
;
216 // document::XEventListener
218 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
220 // lang::XEventListener
222 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
226 std::unique_ptr
<Command
> mpCommand
;
227 ::rtl::Reference
<PresenterController
> mpPresenterController
;
228 typedef ::std::vector
<Reference
<frame::XStatusListener
> > StatusListenerContainer
;
229 StatusListenerContainer maStatusListenerContainer
;
230 bool mbIsListeningToWindowManager
;
233 const OUString
& rsURLPath
,
234 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
235 virtual ~Dispatch() override
;
239 //===== PresenterProtocolHandler =========================================================
241 PresenterProtocolHandler::PresenterProtocolHandler ()
242 : PresenterProtocolHandlerInterfaceBase(m_aMutex
)
246 PresenterProtocolHandler::~PresenterProtocolHandler()
250 void SAL_CALL
PresenterProtocolHandler::disposing()
254 //----- XInitialize -----------------------------------------------------------
256 void SAL_CALL
PresenterProtocolHandler::initialize (const Sequence
<Any
>& aArguments
)
259 if (aArguments
.getLength() <= 0)
264 Reference
<frame::XFrame
> xFrame
;
265 if (aArguments
[0] >>= xFrame
)
267 mpPresenterController
= PresenterController::Instance(xFrame
);
270 catch (RuntimeException
&)
276 OUString
PresenterProtocolHandler::getImplementationName()
278 return "org.libreoffice.comp.PresenterScreenProtocolHandler";
281 sal_Bool
PresenterProtocolHandler::supportsService(OUString
const & ServiceName
)
283 return cppu::supportsService(this, ServiceName
);
286 css::uno::Sequence
<OUString
>
287 PresenterProtocolHandler::getSupportedServiceNames()
289 return { "com.sun.star.frame.ProtocolHandler" };
292 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
293 sd_PresenterProtocolHandler_get_implementation(
294 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const&)
296 return cppu::acquire(new PresenterProtocolHandler());
299 //----- XDispatchProvider -----------------------------------------------------
301 Reference
<frame::XDispatch
> SAL_CALL
PresenterProtocolHandler::queryDispatch (
302 const css::util::URL
& rURL
,
308 Reference
<frame::XDispatch
> xDispatch
;
310 // tdf#154546 skip dispatch when presenter controller is not set
311 // mpPresenterController is sometimes unset and this will cause a
312 // crash when pressing the presenter console's Exchange button.
313 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:" && mpPresenterController
.is())
315 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
321 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
322 const Sequence
<frame::DispatchDescriptor
>&)
325 return Sequence
<Reference
<frame::XDispatch
> >();
329 void PresenterProtocolHandler::ThrowIfDisposed() const
331 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
333 throw lang::DisposedException (
334 "PresenterProtocolHandler object has already been disposed",
335 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
339 //===== PresenterProtocolHandler::Dispatch ====================================
341 Reference
<frame::XDispatch
> PresenterProtocolHandler::Dispatch::Create (
342 const OUString
& rsURLPath
,
343 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
345 ::rtl::Reference
<Dispatch
> pDispatch (new Dispatch (rsURLPath
, rpPresenterController
));
346 if (pDispatch
->mpCommand
!= nullptr)
352 PresenterProtocolHandler::Dispatch::Dispatch (
353 const OUString
& rsURLPath
,
354 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
355 : PresenterDispatchInterfaceBase(m_aMutex
),
356 msURLPath(rsURLPath
),
357 mpCommand(CreateCommand(rsURLPath
, rpPresenterController
)),
358 mpPresenterController(rpPresenterController
),
359 mbIsListeningToWindowManager(false)
361 if (mpCommand
!= nullptr)
363 mpPresenterController
->GetWindowManager()->AddLayoutListener(this);
364 mbIsListeningToWindowManager
= true;
368 Command
* PresenterProtocolHandler::Dispatch::CreateCommand (
369 std::u16string_view rsURLPath
,
370 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
372 if (rsURLPath
.size() <= 5)
375 if (rsURLPath
== u
"CloseNotes")
376 return new SetNotesViewCommand(false, rpPresenterController
);
377 if (rsURLPath
== u
"CloseSlideSorter")
378 return new SetSlideSorterCommand(false, rpPresenterController
);
379 if (rsURLPath
== u
"CloseHelp")
380 return new SetHelpViewCommand(false, rpPresenterController
);
381 if (rsURLPath
== u
"GrowNotesFont")
382 return new NotesFontSizeCommand(rpPresenterController
, +1);
383 if (rsURLPath
== u
"NextEffect")
384 return new GotoNextEffectCommand(rpPresenterController
);
385 if (rsURLPath
== u
"NextSlide")
386 return new GotoNextSlideCommand(rpPresenterController
);
387 if (rsURLPath
== u
"PrevSlide")
388 return new GotoPreviousSlideCommand(rpPresenterController
);
389 if (rsURLPath
== u
"SwitchMonitor")
390 return new SwitchMonitorCommand(rpPresenterController
);
391 if (rsURLPath
== u
"PauseResumeTimer")
392 return new PauseResumeCommand(rpPresenterController
);
393 if (rsURLPath
== u
"RestartTimer")
394 return new RestartTimerCommand(rpPresenterController
);
395 if (rsURLPath
== u
"ShowNotes")
396 return new SetNotesViewCommand(true, rpPresenterController
);
397 if (rsURLPath
== u
"ShowSlideSorter")
398 return new SetSlideSorterCommand(true, rpPresenterController
);
399 if (rsURLPath
== u
"ShowHelp")
400 return new SetHelpViewCommand(true, rpPresenterController
);
401 if (rsURLPath
== u
"ShrinkNotesFont")
402 return new NotesFontSizeCommand(rpPresenterController
, -1);
403 if (rsURLPath
== u
"ExitPresenter")
404 return new ExitPresenterCommand(rpPresenterController
);
409 PresenterProtocolHandler::Dispatch::~Dispatch()
413 void PresenterProtocolHandler::Dispatch::disposing()
415 if (mbIsListeningToWindowManager
)
417 if (mpPresenterController
)
418 mpPresenterController
->GetWindowManager()->RemoveLayoutListener(this);
419 mbIsListeningToWindowManager
= false;
426 //----- XDispatch -------------------------------------------------------------
428 void SAL_CALL
PresenterProtocolHandler::Dispatch::dispatch(
429 const css::util::URL
& rURL
,
430 const css::uno::Sequence
<css::beans::PropertyValue
>& /*rArguments*/)
432 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
434 throw lang::DisposedException (
435 "PresenterProtocolHandler::Dispatch object has already been disposed",
436 static_cast<uno::XWeak
*>(this));
439 if (rURL
.Protocol
!= "vnd.org.libreoffice.presenterscreen:"
440 || rURL
.Path
!= msURLPath
)
442 // We can not throw an IllegalArgumentException
443 throw RuntimeException();
446 if (mpCommand
!= nullptr)
447 mpCommand
->Execute();
450 void SAL_CALL
PresenterProtocolHandler::Dispatch::addStatusListener(
451 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
452 const css::util::URL
& rURL
)
454 if (rURL
.Path
!= msURLPath
)
455 throw RuntimeException();
457 maStatusListenerContainer
.push_back(rxListener
);
459 frame::FeatureStateEvent aEvent
;
460 aEvent
.FeatureURL
= rURL
;
461 aEvent
.IsEnabled
= mpCommand
->IsEnabled();
462 aEvent
.Requery
= false;
463 aEvent
.State
= mpCommand
->GetState();
464 rxListener
->statusChanged(aEvent
);
467 void SAL_CALL
PresenterProtocolHandler::Dispatch::removeStatusListener (
468 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
469 const css::util::URL
& rURL
)
471 if (rURL
.Path
!= msURLPath
)
472 throw RuntimeException();
474 StatusListenerContainer::iterator
iListener (
476 maStatusListenerContainer
.begin(),
477 maStatusListenerContainer
.end(),
479 if (iListener
!= maStatusListenerContainer
.end())
480 maStatusListenerContainer
.erase(iListener
);
483 //----- document::XEventListener ----------------------------------------------
485 void SAL_CALL
PresenterProtocolHandler::Dispatch::notifyEvent (
486 const css::document::EventObject
&)
488 mpCommand
->GetState();
491 //----- lang::XEventListener --------------------------------------------------
493 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
&)
495 mbIsListeningToWindowManager
= false;
498 //===== GotoPreviousSlideCommand ==============================================
500 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
501 rtl::Reference
<PresenterController
> xPresenterController
)
502 : mpPresenterController(std::move(xPresenterController
))
506 void GotoPreviousSlideCommand::Execute()
508 if ( ! mpPresenterController
.is())
511 if ( ! mpPresenterController
->GetSlideShowController().is())
514 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
517 bool GotoPreviousSlideCommand::IsEnabled() const
519 if ( ! mpPresenterController
.is())
522 if ( ! mpPresenterController
->GetSlideShowController().is())
525 return mpPresenterController
->GetSlideShowController()->getCurrentSlideIndex()>0;
528 //===== GotoNextEffect ========================================================
530 GotoNextEffectCommand::GotoNextEffectCommand (
531 rtl::Reference
<PresenterController
> xPresenterController
)
532 : mpPresenterController(std::move(xPresenterController
))
536 void GotoNextEffectCommand::Execute()
538 if ( ! mpPresenterController
.is())
541 if ( ! mpPresenterController
->GetSlideShowController().is())
544 mpPresenterController
->GetSlideShowController()->gotoNextEffect();
547 bool GotoNextEffectCommand::IsEnabled() const
549 if ( ! mpPresenterController
.is())
552 if ( ! mpPresenterController
->GetSlideShowController().is())
555 return ( mpPresenterController
->GetSlideShowController()->getNextSlideIndex() < mpPresenterController
->GetSlideShowController()->getSlideCount() );
559 //===== GotoNextSlide =========================================================
561 GotoNextSlideCommand::GotoNextSlideCommand (
562 rtl::Reference
<PresenterController
> xPresenterController
)
563 : mpPresenterController(std::move(xPresenterController
))
567 void GotoNextSlideCommand::Execute()
569 if ( ! mpPresenterController
.is())
572 if ( ! mpPresenterController
->GetSlideShowController().is())
575 mpPresenterController
->GetSlideShowController()->gotoNextSlide();
578 //===== SwitchMonitorCommand ==============================================
580 SwitchMonitorCommand::SwitchMonitorCommand (
581 rtl::Reference
<PresenterController
> xPresenterController
)
582 : mpPresenterController(std::move(xPresenterController
))
586 void SwitchMonitorCommand::Execute()
588 mpPresenterController
->SwitchMonitors();
591 //===== PauseResumeCommand ==============================================
593 PauseResumeCommand::PauseResumeCommand (rtl::Reference
<PresenterController
> xPresenterController
)
594 : mpPresenterController(std::move(xPresenterController
))
598 void PauseResumeCommand::Execute()
600 if ( ! mpPresenterController
.is())
603 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
604 mpPresenterController
->GetWindowManager());
605 if ( ! pWindowManager
.is())
608 IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime();
609 if (!pPresentationTime
)
612 if(pPresentationTime
->isPaused())
614 pPresentationTime
->setPauseStatus(false);
615 pWindowManager
->SetPauseState(false);
619 pPresentationTime
->setPauseStatus(true);
620 pWindowManager
->SetPauseState(true);
624 Any
PauseResumeCommand::GetState() const
626 if ( ! mpPresenterController
.is())
629 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
630 mpPresenterController
->GetWindowManager());
631 if ( ! pWindowManager
.is())
634 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
636 return Any(pPresentationTime
->isPaused());
642 RestartTimerCommand::RestartTimerCommand (rtl::Reference
<PresenterController
> xPresenterController
)
643 : mpPresenterController(std::move(xPresenterController
))
647 void RestartTimerCommand::Execute()
649 if ( ! mpPresenterController
.is())
652 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
653 mpPresenterController
->GetWindowManager());
654 if ( ! pWindowManager
.is())
657 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
659 //Resets the pause status and restarts the timer
660 pPresentationTime
->setPauseStatus(false);
661 pWindowManager
->SetPauseState(false);
662 pPresentationTime
->restart();
666 //===== SetNotesViewCommand ===================================================
668 SetNotesViewCommand::SetNotesViewCommand (
670 rtl::Reference
<PresenterController
> xPresenterController
)
672 mpPresenterController(std::move(xPresenterController
))
676 void SetNotesViewCommand::Execute()
678 if ( ! mpPresenterController
.is())
681 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
682 mpPresenterController
->GetWindowManager());
683 if ( ! pWindowManager
.is())
687 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
689 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
692 Any
SetNotesViewCommand::GetState() const
694 if ( ! mpPresenterController
.is())
697 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
698 mpPresenterController
->GetWindowManager());
699 if ( ! pWindowManager
.is())
702 return Any(pWindowManager
->GetViewMode() == PresenterWindowManager::VM_Notes
);
705 //===== SetSlideSorterCommand =================================================
707 SetSlideSorterCommand::SetSlideSorterCommand (
709 rtl::Reference
<PresenterController
> xPresenterController
)
711 mpPresenterController(std::move(xPresenterController
))
715 void SetSlideSorterCommand::Execute()
717 if ( ! mpPresenterController
.is())
720 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
721 mpPresenterController
->GetWindowManager());
722 if ( ! pWindowManager
.is())
725 pWindowManager
->SetSlideSorterState(mbOn
);
728 Any
SetSlideSorterCommand::GetState() const
730 if ( ! mpPresenterController
.is())
733 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
734 mpPresenterController
->GetWindowManager());
735 if ( ! pWindowManager
.is())
738 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_SlideOverview
);
741 //===== SetHelpViewCommand ===================================================
743 SetHelpViewCommand::SetHelpViewCommand (
745 rtl::Reference
<PresenterController
> xPresenterController
)
747 mpPresenterController(std::move(xPresenterController
))
751 void SetHelpViewCommand::Execute()
753 if ( ! mpPresenterController
.is())
756 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
757 mpPresenterController
->GetWindowManager());
758 if ( ! pWindowManager
.is())
761 pWindowManager
->SetHelpViewState(mbOn
);
764 Any
SetHelpViewCommand::GetState() const
766 if ( ! mpPresenterController
.is())
769 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
770 mpPresenterController
->GetWindowManager());
771 if ( ! pWindowManager
.is())
774 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_Help
);
777 //===== NotesFontSizeCommand ==================================================
779 NotesFontSizeCommand::NotesFontSizeCommand(
780 rtl::Reference
<PresenterController
> xPresenterController
,
781 const sal_Int32 nSizeChange
)
782 : mpPresenterController(std::move(xPresenterController
)),
783 mnSizeChange(nSizeChange
)
787 ::rtl::Reference
<PresenterNotesView
> NotesFontSizeCommand::GetNotesView() const
789 if (!mpPresenterController
)
792 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
793 mpPresenterController
->GetPaneContainer()->FindViewURL(
794 PresenterViewFactory::msNotesViewURL
));
798 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
801 void NotesFontSizeCommand::Execute()
803 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
805 pView
->ChangeFontSize(mnSizeChange
);
808 Any
NotesFontSizeCommand::GetState() const
813 //===== ExitPresenterCommand ==================================================
815 ExitPresenterCommand::ExitPresenterCommand (rtl::Reference
<PresenterController
> xPresenterController
)
816 : mpPresenterController(std::move(xPresenterController
))
820 void ExitPresenterCommand::Execute()
822 if ( ! mpPresenterController
.is())
825 mpPresenterController
->ExitPresenter();
828 } // end of namespace ::sdext::presenter
830 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */