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>
31 using namespace ::com::sun::star
;
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::drawing::framework
;
35 namespace sdext::presenter
{
42 virtual void Execute() = 0;
43 virtual bool IsEnabled() const { return true; }
44 virtual Any
GetState() const { return Any(false); }
47 class GotoPreviousSlideCommand
: public Command
50 explicit GotoPreviousSlideCommand (
51 const rtl::Reference
<PresenterController
>& rpPresenterController
);
52 virtual void Execute() override
;
53 virtual bool IsEnabled() const override
;
55 rtl::Reference
<PresenterController
> mpPresenterController
;
58 class GotoNextSlideCommand
: public Command
61 explicit GotoNextSlideCommand (
62 const rtl::Reference
<PresenterController
>& rpPresenterController
);
63 virtual void Execute() override
;
64 // The next slide command is always enabled, even when the current slide
65 // is the last slide: from the last slide it goes to the pause slide,
66 // and from there it ends the slide show.
67 virtual bool IsEnabled() const override
{ return true; }
69 rtl::Reference
<PresenterController
> mpPresenterController
;
72 class GotoNextEffectCommand
: public Command
75 explicit GotoNextEffectCommand (
76 const rtl::Reference
<PresenterController
>& rpPresenterController
);
77 virtual void Execute() override
;
78 virtual bool IsEnabled() const override
;
80 rtl::Reference
<PresenterController
> mpPresenterController
;
83 class SwitchMonitorCommand
: public Command
86 explicit SwitchMonitorCommand (
87 const rtl::Reference
<PresenterController
>& rpPresenterController
);
88 virtual void Execute() override
;
90 rtl::Reference
<PresenterController
> mpPresenterController
;
93 class PauseResumeCommand
: public Command
96 explicit PauseResumeCommand(const rtl::Reference
<PresenterController
>& rpPresenterController
);
97 virtual void Execute() override
;
98 virtual Any
GetState() const override
;
100 rtl::Reference
<PresenterController
> mpPresenterController
;
103 /// This command restarts the presentation timer.
104 class RestartTimerCommand
: public Command
107 explicit RestartTimerCommand(const rtl::Reference
<PresenterController
>& rpPresenterController
);
108 virtual void Execute() override
;
110 rtl::Reference
<PresenterController
> mpPresenterController
;
113 class SetNotesViewCommand
: public Command
116 SetNotesViewCommand (
118 const rtl::Reference
<PresenterController
>& rpPresenterController
);
119 virtual void Execute() override
;
120 virtual Any
GetState() const override
;
123 rtl::Reference
<PresenterController
> mpPresenterController
;
126 class SetSlideSorterCommand
: public Command
129 SetSlideSorterCommand (
131 const rtl::Reference
<PresenterController
>& rpPresenterController
);
132 virtual void Execute() override
;
133 virtual Any
GetState() const override
;
136 rtl::Reference
<PresenterController
> mpPresenterController
;
139 class SetHelpViewCommand
: public Command
144 const rtl::Reference
<PresenterController
>& rpPresenterController
);
145 virtual void Execute() override
;
146 virtual Any
GetState() const override
;
149 rtl::Reference
<PresenterController
> mpPresenterController
;
152 class NotesFontSizeCommand
: public Command
155 NotesFontSizeCommand(
156 const rtl::Reference
<PresenterController
>& rpPresenterController
,
157 const sal_Int32 nSizeChange
);
158 virtual void Execute() override
;
159 virtual Any
GetState() const override
;
161 ::rtl::Reference
<PresenterNotesView
> GetNotesView() const;
163 rtl::Reference
<PresenterController
> mpPresenterController
;
164 const sal_Int32 mnSizeChange
;
167 class ExitPresenterCommand
: public Command
170 explicit ExitPresenterCommand(const rtl::Reference
<PresenterController
>& rpPresenterController
);
171 virtual void Execute() override
;
173 rtl::Reference
<PresenterController
> mpPresenterController
;
176 } // end of anonymous namespace
179 typedef ::cppu::WeakComponentImplHelper
<
180 css::frame::XDispatch
,
181 css::document::XEventListener
182 > PresenterDispatchInterfaceBase
;
185 class PresenterProtocolHandler::Dispatch
186 : protected ::cppu::BaseMutex
,
187 public PresenterDispatchInterfaceBase
190 /** Create a new Dispatch object. When the given command name
191 (rsURLPath) is not known then an empty reference is returned.
193 static Reference
<frame::XDispatch
> Create (
194 const OUString
& rsURLPath
,
195 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
197 void SAL_CALL
disposing() override
;
198 static Command
* CreateCommand (
199 const OUString
& rsURLPath
,
200 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
203 virtual void SAL_CALL
dispatch(
204 const css::util::URL
& aURL
,
205 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
) override
;
207 virtual void SAL_CALL
addStatusListener(
208 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
209 const css::util::URL
& rURL
) override
;
211 virtual void SAL_CALL
removeStatusListener (
212 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
213 const css::util::URL
& rURL
) override
;
215 // document::XEventListener
217 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
219 // lang::XEventListener
221 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
225 std::unique_ptr
<Command
> mpCommand
;
226 ::rtl::Reference
<PresenterController
> mpPresenterController
;
227 typedef ::std::vector
<Reference
<frame::XStatusListener
> > StatusListenerContainer
;
228 StatusListenerContainer maStatusListenerContainer
;
229 bool mbIsListeningToWindowManager
;
232 const OUString
& rsURLPath
,
233 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
234 virtual ~Dispatch() override
;
238 //===== PresenterProtocolHandler =========================================================
240 PresenterProtocolHandler::PresenterProtocolHandler ()
241 : PresenterProtocolHandlerInterfaceBase(m_aMutex
)
245 PresenterProtocolHandler::~PresenterProtocolHandler()
249 void SAL_CALL
PresenterProtocolHandler::disposing()
253 //----- XInitialize -----------------------------------------------------------
255 void SAL_CALL
PresenterProtocolHandler::initialize (const Sequence
<Any
>& aArguments
)
258 if (aArguments
.getLength() <= 0)
263 Reference
<frame::XFrame
> xFrame
;
264 if (aArguments
[0] >>= xFrame
)
266 mpPresenterController
= PresenterController::Instance(xFrame
);
269 catch (RuntimeException
&)
275 OUString
PresenterProtocolHandler::getImplementationName()
277 return "org.libreoffice.comp.PresenterScreenProtocolHandler";
280 sal_Bool
PresenterProtocolHandler::supportsService(OUString
const & ServiceName
)
282 return cppu::supportsService(this, ServiceName
);
285 css::uno::Sequence
<OUString
>
286 PresenterProtocolHandler::getSupportedServiceNames()
288 return { "com.sun.star.frame.ProtocolHandler" };
291 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
292 sdext_PresenterProtocolHandler_get_implementation(
293 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const&)
295 return cppu::acquire(new PresenterProtocolHandler());
298 //----- XDispatchProvider -----------------------------------------------------
300 Reference
<frame::XDispatch
> SAL_CALL
PresenterProtocolHandler::queryDispatch (
301 const css::util::URL
& rURL
,
307 Reference
<frame::XDispatch
> xDispatch
;
309 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:")
311 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
317 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
318 const Sequence
<frame::DispatchDescriptor
>&)
321 return Sequence
<Reference
<frame::XDispatch
> >();
325 void PresenterProtocolHandler::ThrowIfDisposed() const
327 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
329 throw lang::DisposedException (
330 "PresenterProtocolHandler object has already been disposed",
331 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
335 //===== PresenterProtocolHandler::Dispatch ====================================
337 Reference
<frame::XDispatch
> PresenterProtocolHandler::Dispatch::Create (
338 const OUString
& rsURLPath
,
339 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
341 ::rtl::Reference
<Dispatch
> pDispatch (new Dispatch (rsURLPath
, rpPresenterController
));
342 if (pDispatch
->mpCommand
!= nullptr)
348 PresenterProtocolHandler::Dispatch::Dispatch (
349 const OUString
& rsURLPath
,
350 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
351 : PresenterDispatchInterfaceBase(m_aMutex
),
352 msURLPath(rsURLPath
),
353 mpCommand(CreateCommand(rsURLPath
, rpPresenterController
)),
354 mpPresenterController(rpPresenterController
),
355 maStatusListenerContainer(),
356 mbIsListeningToWindowManager(false)
358 if (mpCommand
!= nullptr)
360 mpPresenterController
->GetWindowManager()->AddLayoutListener(this);
361 mbIsListeningToWindowManager
= true;
365 Command
* PresenterProtocolHandler::Dispatch::CreateCommand (
366 const OUString
& rsURLPath
,
367 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
369 if (rsURLPath
.getLength() <= 5)
372 if (rsURLPath
== "CloseNotes")
373 return new SetNotesViewCommand(false, rpPresenterController
);
374 if (rsURLPath
== "CloseSlideSorter")
375 return new SetSlideSorterCommand(false, rpPresenterController
);
376 if (rsURLPath
== "CloseHelp")
377 return new SetHelpViewCommand(false, rpPresenterController
);
378 if (rsURLPath
== "GrowNotesFont")
379 return new NotesFontSizeCommand(rpPresenterController
, +1);
380 if (rsURLPath
== "NextEffect")
381 return new GotoNextEffectCommand(rpPresenterController
);
382 if (rsURLPath
== "NextSlide")
383 return new GotoNextSlideCommand(rpPresenterController
);
384 if (rsURLPath
== "PrevSlide")
385 return new GotoPreviousSlideCommand(rpPresenterController
);
386 if (rsURLPath
== "SwitchMonitor")
387 return new SwitchMonitorCommand(rpPresenterController
);
388 if (rsURLPath
== "PauseResumeTimer")
389 return new PauseResumeCommand(rpPresenterController
);
390 if (rsURLPath
== "RestartTimer")
391 return new RestartTimerCommand(rpPresenterController
);
392 if (rsURLPath
== "ShowNotes")
393 return new SetNotesViewCommand(true, rpPresenterController
);
394 if (rsURLPath
== "ShowSlideSorter")
395 return new SetSlideSorterCommand(true, rpPresenterController
);
396 if (rsURLPath
== "ShowHelp")
397 return new SetHelpViewCommand(true, rpPresenterController
);
398 if (rsURLPath
== "ShrinkNotesFont")
399 return new NotesFontSizeCommand(rpPresenterController
, -1);
400 if (rsURLPath
== "ExitPresenter")
401 return new ExitPresenterCommand(rpPresenterController
);
406 PresenterProtocolHandler::Dispatch::~Dispatch()
410 void PresenterProtocolHandler::Dispatch::disposing()
412 if (mbIsListeningToWindowManager
)
414 if (mpPresenterController
)
415 mpPresenterController
->GetWindowManager()->RemoveLayoutListener(this);
416 mbIsListeningToWindowManager
= false;
423 //----- XDispatch -------------------------------------------------------------
425 void SAL_CALL
PresenterProtocolHandler::Dispatch::dispatch(
426 const css::util::URL
& rURL
,
427 const css::uno::Sequence
<css::beans::PropertyValue
>& /*rArguments*/)
429 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
431 throw lang::DisposedException (
432 "PresenterProtocolHandler::Dispatch object has already been disposed",
433 static_cast<uno::XWeak
*>(this));
436 if (rURL
.Protocol
!= "vnd.org.libreoffice.presenterscreen:"
437 || rURL
.Path
!= msURLPath
)
439 // We can not throw an IllegalArgumentException
440 throw RuntimeException();
443 if (mpCommand
!= nullptr)
444 mpCommand
->Execute();
447 void SAL_CALL
PresenterProtocolHandler::Dispatch::addStatusListener(
448 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
449 const css::util::URL
& rURL
)
451 if (rURL
.Path
!= msURLPath
)
452 throw RuntimeException();
454 maStatusListenerContainer
.push_back(rxListener
);
456 frame::FeatureStateEvent aEvent
;
457 aEvent
.FeatureURL
= rURL
;
458 aEvent
.IsEnabled
= mpCommand
->IsEnabled();
459 aEvent
.Requery
= false;
460 aEvent
.State
= mpCommand
->GetState();
461 rxListener
->statusChanged(aEvent
);
464 void SAL_CALL
PresenterProtocolHandler::Dispatch::removeStatusListener (
465 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
466 const css::util::URL
& rURL
)
468 if (rURL
.Path
!= msURLPath
)
469 throw RuntimeException();
471 StatusListenerContainer::iterator
iListener (
473 maStatusListenerContainer
.begin(),
474 maStatusListenerContainer
.end(),
476 if (iListener
!= maStatusListenerContainer
.end())
477 maStatusListenerContainer
.erase(iListener
);
480 //----- document::XEventListener ----------------------------------------------
482 void SAL_CALL
PresenterProtocolHandler::Dispatch::notifyEvent (
483 const css::document::EventObject
&)
485 mpCommand
->GetState();
488 //----- lang::XEventListener --------------------------------------------------
490 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
&)
492 mbIsListeningToWindowManager
= false;
495 //===== GotoPreviousSlideCommand ==============================================
497 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
498 const rtl::Reference
<PresenterController
>& rpPresenterController
)
499 : mpPresenterController(rpPresenterController
)
503 void GotoPreviousSlideCommand::Execute()
505 if ( ! mpPresenterController
.is())
508 if ( ! mpPresenterController
->GetSlideShowController().is())
511 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
514 bool GotoPreviousSlideCommand::IsEnabled() const
516 if ( ! mpPresenterController
.is())
519 if ( ! mpPresenterController
->GetSlideShowController().is())
522 return mpPresenterController
->GetSlideShowController()->getCurrentSlideIndex()>0;
525 //===== GotoNextEffect ========================================================
527 GotoNextEffectCommand::GotoNextEffectCommand (
528 const rtl::Reference
<PresenterController
>& rpPresenterController
)
529 : mpPresenterController(rpPresenterController
)
533 void GotoNextEffectCommand::Execute()
535 if ( ! mpPresenterController
.is())
538 if ( ! mpPresenterController
->GetSlideShowController().is())
541 mpPresenterController
->GetSlideShowController()->gotoNextEffect();
544 bool GotoNextEffectCommand::IsEnabled() const
546 if ( ! mpPresenterController
.is())
549 if ( ! mpPresenterController
->GetSlideShowController().is())
552 return ( mpPresenterController
->GetSlideShowController()->getNextSlideIndex() < mpPresenterController
->GetSlideShowController()->getSlideCount() );
556 //===== GotoNextSlide =========================================================
558 GotoNextSlideCommand::GotoNextSlideCommand (
559 const rtl::Reference
<PresenterController
>& rpPresenterController
)
560 : mpPresenterController(rpPresenterController
)
564 void GotoNextSlideCommand::Execute()
566 if ( ! mpPresenterController
.is())
569 if ( ! mpPresenterController
->GetSlideShowController().is())
572 mpPresenterController
->GetSlideShowController()->gotoNextSlide();
575 //===== SwitchMonitorCommand ==============================================
577 SwitchMonitorCommand::SwitchMonitorCommand (
578 const rtl::Reference
<PresenterController
>& rpPresenterController
)
579 : mpPresenterController(rpPresenterController
)
583 void SwitchMonitorCommand::Execute()
585 mpPresenterController
->SwitchMonitors();
588 //===== PauseResumeCommand ==============================================
590 PauseResumeCommand::PauseResumeCommand (const rtl::Reference
<PresenterController
>& rpPresenterController
)
591 : mpPresenterController(rpPresenterController
)
595 void PauseResumeCommand::Execute()
597 if ( ! mpPresenterController
.is())
600 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
601 mpPresenterController
->GetWindowManager());
602 if ( ! pWindowManager
.is())
605 IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime();
606 if (!pPresentationTime
)
609 if(pPresentationTime
->isPaused())
611 pPresentationTime
->setPauseStatus(false);
612 pWindowManager
->SetPauseState(false);
616 pPresentationTime
->setPauseStatus(true);
617 pWindowManager
->SetPauseState(true);
621 Any
PauseResumeCommand::GetState() const
623 if ( ! mpPresenterController
.is())
626 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
627 mpPresenterController
->GetWindowManager());
628 if ( ! pWindowManager
.is())
631 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
633 return Any(pPresentationTime
->isPaused());
639 RestartTimerCommand::RestartTimerCommand (const rtl::Reference
<PresenterController
>& rpPresenterController
)
640 : mpPresenterController(rpPresenterController
)
644 void RestartTimerCommand::Execute()
646 if ( ! mpPresenterController
.is())
649 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
650 mpPresenterController
->GetWindowManager());
651 if ( ! pWindowManager
.is())
654 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
656 //Resets the pause status and restarts the timer
657 pPresentationTime
->setPauseStatus(false);
658 pWindowManager
->SetPauseState(false);
659 pPresentationTime
->restart();
663 //===== SetNotesViewCommand ===================================================
665 SetNotesViewCommand::SetNotesViewCommand (
667 const rtl::Reference
<PresenterController
>& rpPresenterController
)
669 mpPresenterController(rpPresenterController
)
673 void SetNotesViewCommand::Execute()
675 if ( ! mpPresenterController
.is())
678 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
679 mpPresenterController
->GetWindowManager());
680 if ( ! pWindowManager
.is())
684 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
686 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
689 Any
SetNotesViewCommand::GetState() const
691 if ( ! mpPresenterController
.is())
694 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
695 mpPresenterController
->GetWindowManager());
696 if ( ! pWindowManager
.is())
699 return Any(pWindowManager
->GetViewMode() == PresenterWindowManager::VM_Notes
);
702 //===== SetSlideSorterCommand =================================================
704 SetSlideSorterCommand::SetSlideSorterCommand (
706 const rtl::Reference
<PresenterController
>& rpPresenterController
)
708 mpPresenterController(rpPresenterController
)
712 void SetSlideSorterCommand::Execute()
714 if ( ! mpPresenterController
.is())
717 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
718 mpPresenterController
->GetWindowManager());
719 if ( ! pWindowManager
.is())
722 pWindowManager
->SetSlideSorterState(mbOn
);
725 Any
SetSlideSorterCommand::GetState() const
727 if ( ! mpPresenterController
.is())
730 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
731 mpPresenterController
->GetWindowManager());
732 if ( ! pWindowManager
.is())
735 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_SlideOverview
);
738 //===== SetHelpViewCommand ===================================================
740 SetHelpViewCommand::SetHelpViewCommand (
742 const rtl::Reference
<PresenterController
>& rpPresenterController
)
744 mpPresenterController(rpPresenterController
)
748 void SetHelpViewCommand::Execute()
750 if ( ! mpPresenterController
.is())
753 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
754 mpPresenterController
->GetWindowManager());
755 if ( ! pWindowManager
.is())
758 pWindowManager
->SetHelpViewState(mbOn
);
761 Any
SetHelpViewCommand::GetState() const
763 if ( ! mpPresenterController
.is())
766 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
767 mpPresenterController
->GetWindowManager());
768 if ( ! pWindowManager
.is())
771 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_Help
);
774 //===== NotesFontSizeCommand ==================================================
776 NotesFontSizeCommand::NotesFontSizeCommand(
777 const rtl::Reference
<PresenterController
>& rpPresenterController
,
778 const sal_Int32 nSizeChange
)
779 : mpPresenterController(rpPresenterController
),
780 mnSizeChange(nSizeChange
)
784 ::rtl::Reference
<PresenterNotesView
> NotesFontSizeCommand::GetNotesView() const
786 if (!mpPresenterController
)
789 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
790 mpPresenterController
->GetPaneContainer()->FindViewURL(
791 PresenterViewFactory::msNotesViewURL
));
795 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
798 void NotesFontSizeCommand::Execute()
800 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
802 pView
->ChangeFontSize(mnSizeChange
);
805 Any
NotesFontSizeCommand::GetState() const
810 //===== ExitPresenterCommand ==================================================
812 ExitPresenterCommand::ExitPresenterCommand (const rtl::Reference
<PresenterController
>& rpPresenterController
)
813 : mpPresenterController(rpPresenterController
)
817 void ExitPresenterCommand::Execute()
819 if ( ! mpPresenterController
.is())
822 mpPresenterController
->ExitPresenter();
825 } // end of namespace ::sdext::presenter
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */