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 "PresenterConfigurationAccess.hxx"
23 #include "PresenterController.hxx"
24 #include "PresenterHelper.hxx"
25 #include "PresenterNotesView.hxx"
26 #include "PresenterPaneContainer.hxx"
27 #include "PresenterPaneFactory.hxx"
28 #include "PresenterViewFactory.hxx"
29 #include "PresenterWindowManager.hxx"
30 #include <com/sun/star/drawing/SlideSorter.hpp>
31 #include <com/sun/star/drawing/framework/Configuration.hpp>
32 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
33 #include <com/sun/star/drawing/framework/ResourceId.hpp>
34 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
35 #include <cppuhelper/compbase.hxx>
36 #include <cppuhelper/supportsservice.hxx>
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::uno
;
41 using namespace ::com::sun::star::drawing::framework
;
43 namespace sdext
{ namespace presenter
{
50 virtual void Execute() = 0;
51 virtual bool IsEnabled() const { return true; }
52 virtual Any
GetState() const { return Any(false); }
55 class GotoPreviousSlideCommand
: public Command
58 explicit GotoPreviousSlideCommand (
59 const rtl::Reference
<PresenterController
>& rpPresenterController
);
60 virtual void Execute() override
;
61 virtual bool IsEnabled() const override
;
63 rtl::Reference
<PresenterController
> mpPresenterController
;
66 class GotoNextSlideCommand
: public Command
69 explicit GotoNextSlideCommand (
70 const rtl::Reference
<PresenterController
>& rpPresenterController
);
71 virtual void Execute() override
;
72 // The next slide command is always enabled, even when the current slide
73 // is the last slide: from the last slide it goes to the pause slide,
74 // and from there it ends the slide show.
75 virtual bool IsEnabled() const override
{ return true; }
77 rtl::Reference
<PresenterController
> mpPresenterController
;
80 class GotoNextEffectCommand
: public Command
83 explicit GotoNextEffectCommand (
84 const rtl::Reference
<PresenterController
>& rpPresenterController
);
85 virtual void Execute() override
;
87 rtl::Reference
<PresenterController
> mpPresenterController
;
90 class SwitchMonitorCommand
: public Command
93 explicit SwitchMonitorCommand (
94 const rtl::Reference
<PresenterController
>& rpPresenterController
);
95 virtual void Execute() override
;
97 rtl::Reference
<PresenterController
> mpPresenterController
;
100 /// This command restarts the presentation timer.
101 class RestartTimerCommand
: public Command
104 explicit RestartTimerCommand(const rtl::Reference
<PresenterController
>& rpPresenterController
);
105 virtual void Execute() override
;
107 rtl::Reference
<PresenterController
> mpPresenterController
;
110 class SetNotesViewCommand
: public Command
113 SetNotesViewCommand (
115 const rtl::Reference
<PresenterController
>& rpPresenterController
);
116 virtual void Execute() override
;
117 virtual Any
GetState() const override
;
120 rtl::Reference
<PresenterController
> mpPresenterController
;
123 class SetSlideSorterCommand
: public Command
126 SetSlideSorterCommand (
128 const rtl::Reference
<PresenterController
>& rpPresenterController
);
129 virtual void Execute() override
;
130 virtual Any
GetState() const override
;
133 rtl::Reference
<PresenterController
> mpPresenterController
;
136 class SetHelpViewCommand
: public Command
141 const rtl::Reference
<PresenterController
>& rpPresenterController
);
142 virtual void Execute() override
;
143 virtual Any
GetState() const override
;
146 rtl::Reference
<PresenterController
> mpPresenterController
;
149 class NotesFontSizeCommand
: public Command
152 NotesFontSizeCommand(
153 const rtl::Reference
<PresenterController
>& rpPresenterController
,
154 const sal_Int32 nSizeChange
);
155 virtual void Execute() override
;
156 virtual Any
GetState() const override
;
158 ::rtl::Reference
<PresenterNotesView
> GetNotesView() const;
160 rtl::Reference
<PresenterController
> mpPresenterController
;
161 const sal_Int32 mnSizeChange
;
164 } // end of anonymous namespace
167 typedef ::cppu::WeakComponentImplHelper
<
168 css::frame::XDispatch
,
169 css::document::XEventListener
170 > PresenterDispatchInterfaceBase
;
173 class PresenterProtocolHandler::Dispatch
174 : protected ::cppu::BaseMutex
,
175 public PresenterDispatchInterfaceBase
178 typedef void (PresenterProtocolHandler::Dispatch::* Action
)(void);
180 /** Create a new Dispatch object. When the given command name
181 (rsURLPath) is not known then an empty reference is returned.
183 static Reference
<frame::XDispatch
> Create (
184 const OUString
& rsURLPath
,
185 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
187 void SAL_CALL
disposing() override
;
188 static Command
* CreateCommand (
189 const OUString
& rsURLPath
,
190 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
193 virtual void SAL_CALL
dispatch(
194 const css::util::URL
& aURL
,
195 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
) override
;
197 virtual void SAL_CALL
addStatusListener(
198 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
199 const css::util::URL
& rURL
) override
;
201 virtual void SAL_CALL
removeStatusListener (
202 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
203 const css::util::URL
& rURL
) override
;
205 // document::XEventListener
207 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
209 // lang::XEventListener
211 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
215 std::unique_ptr
<Command
> mpCommand
;
216 ::rtl::Reference
<PresenterController
> mpPresenterController
;
217 typedef ::std::vector
<Reference
<frame::XStatusListener
> > StatusListenerContainer
;
218 StatusListenerContainer maStatusListenerContainer
;
219 bool mbIsListeningToWindowManager
;
222 const OUString
& rsURLPath
,
223 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
224 virtual ~Dispatch() override
;
227 //----- Service ---------------------------------------------------------------
229 OUString
PresenterProtocolHandler::getImplementationName_static()
231 return OUString("org.libreoffice.comp.PresenterScreenProtocolHandler");
234 Sequence
<OUString
> PresenterProtocolHandler::getSupportedServiceNames_static()
236 static const OUString
sServiceName("com.sun.star.frame.ProtocolHandler");
237 return Sequence
<OUString
>(&sServiceName
, 1);
240 Reference
<XInterface
> PresenterProtocolHandler::Create (
241 SAL_UNUSED_PARAMETER
const Reference
<uno::XComponentContext
>&)
243 return Reference
<XInterface
>(static_cast<XWeak
*>(new PresenterProtocolHandler
));
246 //===== PresenterProtocolHandler =========================================================
248 PresenterProtocolHandler::PresenterProtocolHandler ()
249 : PresenterProtocolHandlerInterfaceBase(m_aMutex
)
253 PresenterProtocolHandler::~PresenterProtocolHandler()
257 void SAL_CALL
PresenterProtocolHandler::disposing()
261 //----- XInitialize -----------------------------------------------------------
263 void SAL_CALL
PresenterProtocolHandler::initialize (const Sequence
<Any
>& aArguments
)
266 if (aArguments
.getLength() > 0)
270 Reference
<frame::XFrame
> xFrame
;
271 if (aArguments
[0] >>= xFrame
)
273 mpPresenterController
= PresenterController::Instance(xFrame
);
276 catch (RuntimeException
&)
283 OUString
PresenterProtocolHandler::getImplementationName()
285 return getImplementationName_static();
288 sal_Bool
PresenterProtocolHandler::supportsService(OUString
const & ServiceName
)
290 return cppu::supportsService(this, ServiceName
);
293 css::uno::Sequence
<OUString
>
294 PresenterProtocolHandler::getSupportedServiceNames()
296 return getSupportedServiceNames_static();
299 //----- XDispatchProvider -----------------------------------------------------
301 Reference
<frame::XDispatch
> SAL_CALL
PresenterProtocolHandler::queryDispatch (
302 const css::util::URL
& rURL
,
308 Reference
<frame::XDispatch
> xDispatch
;
310 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:")
312 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
318 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
319 const Sequence
<frame::DispatchDescriptor
>&)
322 return Sequence
<Reference
<frame::XDispatch
> >();
326 void PresenterProtocolHandler::ThrowIfDisposed() const
328 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
330 throw lang::DisposedException (
331 "PresenterProtocolHandler object has already been disposed",
332 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
336 //===== PresenterProtocolHandler::Dispatch ====================================
338 Reference
<frame::XDispatch
> PresenterProtocolHandler::Dispatch::Create (
339 const OUString
& rsURLPath
,
340 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
342 ::rtl::Reference
<Dispatch
> pDispatch (new Dispatch (rsURLPath
, rpPresenterController
));
343 if (pDispatch
->mpCommand
.get() != nullptr)
344 return Reference
<frame::XDispatch
>(pDispatch
.get());
349 PresenterProtocolHandler::Dispatch::Dispatch (
350 const OUString
& rsURLPath
,
351 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
352 : PresenterDispatchInterfaceBase(m_aMutex
),
353 msURLPath(rsURLPath
),
354 mpCommand(CreateCommand(rsURLPath
, rpPresenterController
)),
355 mpPresenterController(rpPresenterController
),
356 maStatusListenerContainer(),
357 mbIsListeningToWindowManager(false)
359 if (mpCommand
.get() != nullptr)
361 mpPresenterController
->GetWindowManager()->AddLayoutListener(this);
362 mbIsListeningToWindowManager
= true;
366 Command
* PresenterProtocolHandler::Dispatch::CreateCommand (
367 const OUString
& rsURLPath
,
368 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
370 if (rsURLPath
.getLength() <= 5)
373 if (rsURLPath
== "CloseNotes")
374 return new SetNotesViewCommand(false, rpPresenterController
);
375 if (rsURLPath
== "CloseSlideSorter")
376 return new SetSlideSorterCommand(false, rpPresenterController
);
377 if (rsURLPath
== "CloseHelp")
378 return new SetHelpViewCommand(false, rpPresenterController
);
379 if (rsURLPath
== "GrowNotesFont")
380 return new NotesFontSizeCommand(rpPresenterController
, +1);
381 if (rsURLPath
== "NextEffect")
382 return new GotoNextEffectCommand(rpPresenterController
);
383 if (rsURLPath
== "NextSlide")
384 return new GotoNextSlideCommand(rpPresenterController
);
385 if (rsURLPath
== "PrevSlide")
386 return new GotoPreviousSlideCommand(rpPresenterController
);
387 if (rsURLPath
== "SwitchMonitor")
388 return new SwitchMonitorCommand(rpPresenterController
);
389 if (rsURLPath
== "RestartTimer")
390 return new RestartTimerCommand(rpPresenterController
);
391 if (rsURLPath
== "ShowNotes")
392 return new SetNotesViewCommand(true, rpPresenterController
);
393 if (rsURLPath
== "ShowSlideSorter")
394 return new SetSlideSorterCommand(true, rpPresenterController
);
395 if (rsURLPath
== "ShowHelp")
396 return new SetHelpViewCommand(true, rpPresenterController
);
397 if (rsURLPath
== "ShrinkNotesFont")
398 return new NotesFontSizeCommand(rpPresenterController
, -1);
403 PresenterProtocolHandler::Dispatch::~Dispatch()
407 void PresenterProtocolHandler::Dispatch::disposing()
409 if (mbIsListeningToWindowManager
)
411 if (mpPresenterController
.get() != nullptr)
412 mpPresenterController
->GetWindowManager()->RemoveLayoutListener(this);
413 mbIsListeningToWindowManager
= false;
420 //----- XDispatch -------------------------------------------------------------
422 void SAL_CALL
PresenterProtocolHandler::Dispatch::dispatch(
423 const css::util::URL
& rURL
,
424 const css::uno::Sequence
<css::beans::PropertyValue
>& /*rArguments*/)
426 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
428 throw lang::DisposedException (
429 "PresenterProtocolHandler::Dispatch object has already been disposed",
430 static_cast<uno::XWeak
*>(this));
433 if (rURL
.Protocol
!= "vnd.org.libreoffice.presenterscreen:"
434 || rURL
.Path
!= msURLPath
)
436 // We can not throw an IllegalArgumentException
437 throw RuntimeException();
440 if (mpCommand
.get() != nullptr)
441 mpCommand
->Execute();
444 void SAL_CALL
PresenterProtocolHandler::Dispatch::addStatusListener(
445 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
446 const css::util::URL
& rURL
)
448 if (rURL
.Path
!= msURLPath
)
449 throw RuntimeException();
451 maStatusListenerContainer
.push_back(rxListener
);
453 frame::FeatureStateEvent aEvent
;
454 aEvent
.FeatureURL
= rURL
;
455 aEvent
.IsEnabled
= mpCommand
->IsEnabled();
456 aEvent
.Requery
= false;
457 aEvent
.State
= mpCommand
->GetState();
458 rxListener
->statusChanged(aEvent
);
461 void SAL_CALL
PresenterProtocolHandler::Dispatch::removeStatusListener (
462 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
463 const css::util::URL
& rURL
)
465 if (rURL
.Path
!= msURLPath
)
466 throw RuntimeException();
468 StatusListenerContainer::iterator
iListener (
470 maStatusListenerContainer
.begin(),
471 maStatusListenerContainer
.end(),
473 if (iListener
!= maStatusListenerContainer
.end())
474 maStatusListenerContainer
.erase(iListener
);
477 //----- document::XEventListener ----------------------------------------------
479 void SAL_CALL
PresenterProtocolHandler::Dispatch::notifyEvent (
480 const css::document::EventObject
&)
482 mpCommand
->GetState();
485 //----- lang::XEventListener --------------------------------------------------
487 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
&)
489 mbIsListeningToWindowManager
= false;
492 //===== GotoPreviousSlideCommand ==============================================
494 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
495 const rtl::Reference
<PresenterController
>& rpPresenterController
)
496 : mpPresenterController(rpPresenterController
)
500 void GotoPreviousSlideCommand::Execute()
502 if ( ! mpPresenterController
.is())
505 if ( ! mpPresenterController
->GetSlideShowController().is())
508 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
511 bool GotoPreviousSlideCommand::IsEnabled() const
513 if ( ! mpPresenterController
.is())
516 if ( ! mpPresenterController
->GetSlideShowController().is())
519 return mpPresenterController
->GetSlideShowController()->getCurrentSlideIndex()>0;
522 //===== GotoNextEffect ========================================================
524 GotoNextEffectCommand::GotoNextEffectCommand (
525 const rtl::Reference
<PresenterController
>& rpPresenterController
)
526 : mpPresenterController(rpPresenterController
)
530 void GotoNextEffectCommand::Execute()
532 if ( ! mpPresenterController
.is())
535 if ( ! mpPresenterController
->GetSlideShowController().is())
538 mpPresenterController
->GetSlideShowController()->gotoNextEffect();
541 //===== GotoNextSlide =========================================================
543 GotoNextSlideCommand::GotoNextSlideCommand (
544 const rtl::Reference
<PresenterController
>& rpPresenterController
)
545 : mpPresenterController(rpPresenterController
)
549 void GotoNextSlideCommand::Execute()
551 if ( ! mpPresenterController
.is())
554 if ( ! mpPresenterController
->GetSlideShowController().is())
557 mpPresenterController
->GetSlideShowController()->gotoNextSlide();
560 //===== SwitchMonitorCommand ==============================================
562 SwitchMonitorCommand::SwitchMonitorCommand (
563 const rtl::Reference
<PresenterController
>& rpPresenterController
)
564 : mpPresenterController(rpPresenterController
)
568 void SwitchMonitorCommand::Execute()
570 mpPresenterController
->SwitchMonitors();
573 RestartTimerCommand::RestartTimerCommand (const rtl::Reference
<PresenterController
>& rpPresenterController
)
574 : mpPresenterController(rpPresenterController
)
578 void RestartTimerCommand::Execute()
580 if (IPresentationTime
* pPresentationTime
= mpPresenterController
->GetPresentationTime())
581 pPresentationTime
->restart();
584 //===== SetNotesViewCommand ===================================================
586 SetNotesViewCommand::SetNotesViewCommand (
588 const rtl::Reference
<PresenterController
>& rpPresenterController
)
590 mpPresenterController(rpPresenterController
)
594 void SetNotesViewCommand::Execute()
596 if ( ! mpPresenterController
.is())
599 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
600 mpPresenterController
->GetWindowManager());
601 if ( ! pWindowManager
.is())
605 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
607 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
610 Any
SetNotesViewCommand::GetState() const
612 if ( ! mpPresenterController
.is())
615 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
616 mpPresenterController
->GetWindowManager());
617 if ( ! pWindowManager
.is())
620 return Any(pWindowManager
->GetViewMode() == PresenterWindowManager::VM_Notes
);
623 //===== SetSlideSorterCommand =================================================
625 SetSlideSorterCommand::SetSlideSorterCommand (
627 const rtl::Reference
<PresenterController
>& rpPresenterController
)
629 mpPresenterController(rpPresenterController
)
633 void SetSlideSorterCommand::Execute()
635 if ( ! mpPresenterController
.is())
638 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
639 mpPresenterController
->GetWindowManager());
640 if ( ! pWindowManager
.is())
643 pWindowManager
->SetSlideSorterState(mbOn
);
646 Any
SetSlideSorterCommand::GetState() const
648 if ( ! mpPresenterController
.is())
651 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
652 mpPresenterController
->GetWindowManager());
653 if ( ! pWindowManager
.is())
656 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_SlideOverview
);
659 //===== SetHelpViewCommand ===================================================
661 SetHelpViewCommand::SetHelpViewCommand (
663 const rtl::Reference
<PresenterController
>& rpPresenterController
)
665 mpPresenterController(rpPresenterController
)
669 void SetHelpViewCommand::Execute()
671 if ( ! mpPresenterController
.is())
674 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
675 mpPresenterController
->GetWindowManager());
676 if ( ! pWindowManager
.is())
679 pWindowManager
->SetHelpViewState(mbOn
);
682 Any
SetHelpViewCommand::GetState() const
684 if ( ! mpPresenterController
.is())
687 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
688 mpPresenterController
->GetWindowManager());
689 if ( ! pWindowManager
.is())
692 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_Help
);
695 //===== NotesFontSizeCommand ==================================================
697 NotesFontSizeCommand::NotesFontSizeCommand(
698 const rtl::Reference
<PresenterController
>& rpPresenterController
,
699 const sal_Int32 nSizeChange
)
700 : mpPresenterController(rpPresenterController
),
701 mnSizeChange(nSizeChange
)
705 ::rtl::Reference
<PresenterNotesView
> NotesFontSizeCommand::GetNotesView() const
707 if (mpPresenterController
.get() == nullptr)
710 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
711 mpPresenterController
->GetPaneContainer()->FindViewURL(
712 PresenterViewFactory::msNotesViewURL
));
713 if (pDescriptor
.get() == nullptr)
716 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
719 void NotesFontSizeCommand::Execute()
721 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
723 pView
->ChangeFontSize(mnSizeChange
);
726 Any
NotesFontSizeCommand::GetState() const
731 } } // end of namespace ::sdext::presenter
733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */