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
{ namespace 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 /// This command restarts the presentation timer.
94 class RestartTimerCommand
: public Command
97 explicit RestartTimerCommand(const rtl::Reference
<PresenterController
>& rpPresenterController
);
98 virtual void Execute() override
;
100 rtl::Reference
<PresenterController
> mpPresenterController
;
103 class SetNotesViewCommand
: public Command
106 SetNotesViewCommand (
108 const rtl::Reference
<PresenterController
>& rpPresenterController
);
109 virtual void Execute() override
;
110 virtual Any
GetState() const override
;
113 rtl::Reference
<PresenterController
> mpPresenterController
;
116 class SetSlideSorterCommand
: public Command
119 SetSlideSorterCommand (
121 const rtl::Reference
<PresenterController
>& rpPresenterController
);
122 virtual void Execute() override
;
123 virtual Any
GetState() const override
;
126 rtl::Reference
<PresenterController
> mpPresenterController
;
129 class SetHelpViewCommand
: public Command
134 const rtl::Reference
<PresenterController
>& rpPresenterController
);
135 virtual void Execute() override
;
136 virtual Any
GetState() const override
;
139 rtl::Reference
<PresenterController
> mpPresenterController
;
142 class NotesFontSizeCommand
: public Command
145 NotesFontSizeCommand(
146 const rtl::Reference
<PresenterController
>& rpPresenterController
,
147 const sal_Int32 nSizeChange
);
148 virtual void Execute() override
;
149 virtual Any
GetState() const override
;
151 ::rtl::Reference
<PresenterNotesView
> GetNotesView() const;
153 rtl::Reference
<PresenterController
> mpPresenterController
;
154 const sal_Int32 mnSizeChange
;
157 } // end of anonymous namespace
160 typedef ::cppu::WeakComponentImplHelper
<
161 css::frame::XDispatch
,
162 css::document::XEventListener
163 > PresenterDispatchInterfaceBase
;
166 class PresenterProtocolHandler::Dispatch
167 : protected ::cppu::BaseMutex
,
168 public PresenterDispatchInterfaceBase
171 typedef void (PresenterProtocolHandler::Dispatch::* Action
)();
173 /** Create a new Dispatch object. When the given command name
174 (rsURLPath) is not known then an empty reference is returned.
176 static Reference
<frame::XDispatch
> Create (
177 const OUString
& rsURLPath
,
178 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
180 void SAL_CALL
disposing() override
;
181 static Command
* CreateCommand (
182 const OUString
& rsURLPath
,
183 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
186 virtual void SAL_CALL
dispatch(
187 const css::util::URL
& aURL
,
188 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
) override
;
190 virtual void SAL_CALL
addStatusListener(
191 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
192 const css::util::URL
& rURL
) override
;
194 virtual void SAL_CALL
removeStatusListener (
195 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
196 const css::util::URL
& rURL
) override
;
198 // document::XEventListener
200 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
202 // lang::XEventListener
204 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
208 std::unique_ptr
<Command
> mpCommand
;
209 ::rtl::Reference
<PresenterController
> mpPresenterController
;
210 typedef ::std::vector
<Reference
<frame::XStatusListener
> > StatusListenerContainer
;
211 StatusListenerContainer maStatusListenerContainer
;
212 bool mbIsListeningToWindowManager
;
215 const OUString
& rsURLPath
,
216 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
217 virtual ~Dispatch() override
;
220 //----- Service ---------------------------------------------------------------
222 OUString
PresenterProtocolHandler::getImplementationName_static()
224 return "org.libreoffice.comp.PresenterScreenProtocolHandler";
227 Sequence
<OUString
> PresenterProtocolHandler::getSupportedServiceNames_static()
229 return { "com.sun.star.frame.ProtocolHandler" };
232 Reference
<XInterface
> PresenterProtocolHandler::Create (
233 SAL_UNUSED_PARAMETER
const Reference
<uno::XComponentContext
>&)
235 return Reference
<XInterface
>(static_cast<XWeak
*>(new PresenterProtocolHandler
));
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 getImplementationName_static();
280 sal_Bool
PresenterProtocolHandler::supportsService(OUString
const & ServiceName
)
282 return cppu::supportsService(this, ServiceName
);
285 css::uno::Sequence
<OUString
>
286 PresenterProtocolHandler::getSupportedServiceNames()
288 return getSupportedServiceNames_static();
291 //----- XDispatchProvider -----------------------------------------------------
293 Reference
<frame::XDispatch
> SAL_CALL
PresenterProtocolHandler::queryDispatch (
294 const css::util::URL
& rURL
,
300 Reference
<frame::XDispatch
> xDispatch
;
302 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:")
304 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
310 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
311 const Sequence
<frame::DispatchDescriptor
>&)
314 return Sequence
<Reference
<frame::XDispatch
> >();
318 void PresenterProtocolHandler::ThrowIfDisposed() const
320 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
322 throw lang::DisposedException (
323 "PresenterProtocolHandler object has already been disposed",
324 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
328 //===== PresenterProtocolHandler::Dispatch ====================================
330 Reference
<frame::XDispatch
> PresenterProtocolHandler::Dispatch::Create (
331 const OUString
& rsURLPath
,
332 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
334 ::rtl::Reference
<Dispatch
> pDispatch (new Dispatch (rsURLPath
, rpPresenterController
));
335 if (pDispatch
->mpCommand
!= nullptr)
336 return Reference
<frame::XDispatch
>(pDispatch
.get());
341 PresenterProtocolHandler::Dispatch::Dispatch (
342 const OUString
& rsURLPath
,
343 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
344 : PresenterDispatchInterfaceBase(m_aMutex
),
345 msURLPath(rsURLPath
),
346 mpCommand(CreateCommand(rsURLPath
, rpPresenterController
)),
347 mpPresenterController(rpPresenterController
),
348 maStatusListenerContainer(),
349 mbIsListeningToWindowManager(false)
351 if (mpCommand
!= nullptr)
353 mpPresenterController
->GetWindowManager()->AddLayoutListener(this);
354 mbIsListeningToWindowManager
= true;
358 Command
* PresenterProtocolHandler::Dispatch::CreateCommand (
359 const OUString
& rsURLPath
,
360 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
362 if (rsURLPath
.getLength() <= 5)
365 if (rsURLPath
== "CloseNotes")
366 return new SetNotesViewCommand(false, rpPresenterController
);
367 if (rsURLPath
== "CloseSlideSorter")
368 return new SetSlideSorterCommand(false, rpPresenterController
);
369 if (rsURLPath
== "CloseHelp")
370 return new SetHelpViewCommand(false, rpPresenterController
);
371 if (rsURLPath
== "GrowNotesFont")
372 return new NotesFontSizeCommand(rpPresenterController
, +1);
373 if (rsURLPath
== "NextEffect")
374 return new GotoNextEffectCommand(rpPresenterController
);
375 if (rsURLPath
== "NextSlide")
376 return new GotoNextSlideCommand(rpPresenterController
);
377 if (rsURLPath
== "PrevSlide")
378 return new GotoPreviousSlideCommand(rpPresenterController
);
379 if (rsURLPath
== "SwitchMonitor")
380 return new SwitchMonitorCommand(rpPresenterController
);
381 if (rsURLPath
== "RestartTimer")
382 return new RestartTimerCommand(rpPresenterController
);
383 if (rsURLPath
== "ShowNotes")
384 return new SetNotesViewCommand(true, rpPresenterController
);
385 if (rsURLPath
== "ShowSlideSorter")
386 return new SetSlideSorterCommand(true, rpPresenterController
);
387 if (rsURLPath
== "ShowHelp")
388 return new SetHelpViewCommand(true, rpPresenterController
);
389 if (rsURLPath
== "ShrinkNotesFont")
390 return new NotesFontSizeCommand(rpPresenterController
, -1);
395 PresenterProtocolHandler::Dispatch::~Dispatch()
399 void PresenterProtocolHandler::Dispatch::disposing()
401 if (mbIsListeningToWindowManager
)
403 if (mpPresenterController
.get() != nullptr)
404 mpPresenterController
->GetWindowManager()->RemoveLayoutListener(this);
405 mbIsListeningToWindowManager
= false;
412 //----- XDispatch -------------------------------------------------------------
414 void SAL_CALL
PresenterProtocolHandler::Dispatch::dispatch(
415 const css::util::URL
& rURL
,
416 const css::uno::Sequence
<css::beans::PropertyValue
>& /*rArguments*/)
418 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
420 throw lang::DisposedException (
421 "PresenterProtocolHandler::Dispatch object has already been disposed",
422 static_cast<uno::XWeak
*>(this));
425 if (rURL
.Protocol
!= "vnd.org.libreoffice.presenterscreen:"
426 || rURL
.Path
!= msURLPath
)
428 // We can not throw an IllegalArgumentException
429 throw RuntimeException();
432 if (mpCommand
!= nullptr)
433 mpCommand
->Execute();
436 void SAL_CALL
PresenterProtocolHandler::Dispatch::addStatusListener(
437 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
438 const css::util::URL
& rURL
)
440 if (rURL
.Path
!= msURLPath
)
441 throw RuntimeException();
443 maStatusListenerContainer
.push_back(rxListener
);
445 frame::FeatureStateEvent aEvent
;
446 aEvent
.FeatureURL
= rURL
;
447 aEvent
.IsEnabled
= mpCommand
->IsEnabled();
448 aEvent
.Requery
= false;
449 aEvent
.State
= mpCommand
->GetState();
450 rxListener
->statusChanged(aEvent
);
453 void SAL_CALL
PresenterProtocolHandler::Dispatch::removeStatusListener (
454 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
455 const css::util::URL
& rURL
)
457 if (rURL
.Path
!= msURLPath
)
458 throw RuntimeException();
460 StatusListenerContainer::iterator
iListener (
462 maStatusListenerContainer
.begin(),
463 maStatusListenerContainer
.end(),
465 if (iListener
!= maStatusListenerContainer
.end())
466 maStatusListenerContainer
.erase(iListener
);
469 //----- document::XEventListener ----------------------------------------------
471 void SAL_CALL
PresenterProtocolHandler::Dispatch::notifyEvent (
472 const css::document::EventObject
&)
474 mpCommand
->GetState();
477 //----- lang::XEventListener --------------------------------------------------
479 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
&)
481 mbIsListeningToWindowManager
= false;
484 //===== GotoPreviousSlideCommand ==============================================
486 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
487 const rtl::Reference
<PresenterController
>& rpPresenterController
)
488 : mpPresenterController(rpPresenterController
)
492 void GotoPreviousSlideCommand::Execute()
494 if ( ! mpPresenterController
.is())
497 if ( ! mpPresenterController
->GetSlideShowController().is())
500 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
503 bool GotoPreviousSlideCommand::IsEnabled() const
505 if ( ! mpPresenterController
.is())
508 if ( ! mpPresenterController
->GetSlideShowController().is())
511 return mpPresenterController
->GetSlideShowController()->getCurrentSlideIndex()>0;
514 //===== GotoNextEffect ========================================================
516 GotoNextEffectCommand::GotoNextEffectCommand (
517 const rtl::Reference
<PresenterController
>& rpPresenterController
)
518 : mpPresenterController(rpPresenterController
)
522 void GotoNextEffectCommand::Execute()
524 if ( ! mpPresenterController
.is())
527 if ( ! mpPresenterController
->GetSlideShowController().is())
530 mpPresenterController
->GetSlideShowController()->gotoNextEffect();
533 bool GotoNextEffectCommand::IsEnabled() const
535 if ( ! mpPresenterController
.is())
538 if ( ! mpPresenterController
->GetSlideShowController().is())
541 return ( mpPresenterController
->GetSlideShowController()->getNextSlideIndex() < mpPresenterController
->GetSlideShowController()->getSlideCount() );
545 //===== GotoNextSlide =========================================================
547 GotoNextSlideCommand::GotoNextSlideCommand (
548 const rtl::Reference
<PresenterController
>& rpPresenterController
)
549 : mpPresenterController(rpPresenterController
)
553 void GotoNextSlideCommand::Execute()
555 if ( ! mpPresenterController
.is())
558 if ( ! mpPresenterController
->GetSlideShowController().is())
561 mpPresenterController
->GetSlideShowController()->gotoNextSlide();
564 //===== SwitchMonitorCommand ==============================================
566 SwitchMonitorCommand::SwitchMonitorCommand (
567 const rtl::Reference
<PresenterController
>& rpPresenterController
)
568 : mpPresenterController(rpPresenterController
)
572 void SwitchMonitorCommand::Execute()
574 mpPresenterController
->SwitchMonitors();
577 RestartTimerCommand::RestartTimerCommand (const rtl::Reference
<PresenterController
>& rpPresenterController
)
578 : mpPresenterController(rpPresenterController
)
582 void RestartTimerCommand::Execute()
584 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
585 pPresentationTime
->restart();
588 //===== SetNotesViewCommand ===================================================
590 SetNotesViewCommand::SetNotesViewCommand (
592 const rtl::Reference
<PresenterController
>& rpPresenterController
)
594 mpPresenterController(rpPresenterController
)
598 void SetNotesViewCommand::Execute()
600 if ( ! mpPresenterController
.is())
603 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
604 mpPresenterController
->GetWindowManager());
605 if ( ! pWindowManager
.is())
609 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
611 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
614 Any
SetNotesViewCommand::GetState() const
616 if ( ! mpPresenterController
.is())
619 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
620 mpPresenterController
->GetWindowManager());
621 if ( ! pWindowManager
.is())
624 return Any(pWindowManager
->GetViewMode() == PresenterWindowManager::VM_Notes
);
627 //===== SetSlideSorterCommand =================================================
629 SetSlideSorterCommand::SetSlideSorterCommand (
631 const rtl::Reference
<PresenterController
>& rpPresenterController
)
633 mpPresenterController(rpPresenterController
)
637 void SetSlideSorterCommand::Execute()
639 if ( ! mpPresenterController
.is())
642 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
643 mpPresenterController
->GetWindowManager());
644 if ( ! pWindowManager
.is())
647 pWindowManager
->SetSlideSorterState(mbOn
);
650 Any
SetSlideSorterCommand::GetState() const
652 if ( ! mpPresenterController
.is())
655 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
656 mpPresenterController
->GetWindowManager());
657 if ( ! pWindowManager
.is())
660 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_SlideOverview
);
663 //===== SetHelpViewCommand ===================================================
665 SetHelpViewCommand::SetHelpViewCommand (
667 const rtl::Reference
<PresenterController
>& rpPresenterController
)
669 mpPresenterController(rpPresenterController
)
673 void SetHelpViewCommand::Execute()
675 if ( ! mpPresenterController
.is())
678 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
679 mpPresenterController
->GetWindowManager());
680 if ( ! pWindowManager
.is())
683 pWindowManager
->SetHelpViewState(mbOn
);
686 Any
SetHelpViewCommand::GetState() const
688 if ( ! mpPresenterController
.is())
691 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
692 mpPresenterController
->GetWindowManager());
693 if ( ! pWindowManager
.is())
696 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_Help
);
699 //===== NotesFontSizeCommand ==================================================
701 NotesFontSizeCommand::NotesFontSizeCommand(
702 const rtl::Reference
<PresenterController
>& rpPresenterController
,
703 const sal_Int32 nSizeChange
)
704 : mpPresenterController(rpPresenterController
),
705 mnSizeChange(nSizeChange
)
709 ::rtl::Reference
<PresenterNotesView
> NotesFontSizeCommand::GetNotesView() const
711 if (mpPresenterController
.get() == nullptr)
714 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
715 mpPresenterController
->GetPaneContainer()->FindViewURL(
716 PresenterViewFactory::msNotesViewURL
));
717 if (pDescriptor
.get() == nullptr)
720 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
723 void NotesFontSizeCommand::Execute()
725 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
727 pView
->ChangeFontSize(mnSizeChange
);
730 Any
NotesFontSizeCommand::GetState() const
735 } } // end of namespace ::sdext::presenter
737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */