vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / sdext / source / presenter / PresenterProtocolHandler.cxx
blob32739fdd2b1d43a1861c572454a2e525742c73e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
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>
29 #include <algorithm>
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 {
37 namespace {
38 class Command
40 public:
41 virtual ~Command() {}
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
49 public:
50 explicit GotoPreviousSlideCommand (
51 const rtl::Reference<PresenterController>& rpPresenterController);
52 virtual void Execute() override;
53 virtual bool IsEnabled() const override;
54 private:
55 rtl::Reference<PresenterController> mpPresenterController;
58 class GotoNextSlideCommand : public Command
60 public:
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; }
68 private:
69 rtl::Reference<PresenterController> mpPresenterController;
72 class GotoNextEffectCommand : public Command
74 public:
75 explicit GotoNextEffectCommand (
76 const rtl::Reference<PresenterController>& rpPresenterController);
77 virtual void Execute() override;
78 virtual bool IsEnabled() const override;
79 private:
80 rtl::Reference<PresenterController> mpPresenterController;
83 class SwitchMonitorCommand : public Command
85 public:
86 explicit SwitchMonitorCommand (
87 const rtl::Reference<PresenterController>& rpPresenterController);
88 virtual void Execute() override;
89 private:
90 rtl::Reference<PresenterController> mpPresenterController;
93 /// This command restarts the presentation timer.
94 class RestartTimerCommand : public Command
96 public:
97 explicit RestartTimerCommand(const rtl::Reference<PresenterController>& rpPresenterController);
98 virtual void Execute() override;
99 private:
100 rtl::Reference<PresenterController> mpPresenterController;
103 class SetNotesViewCommand : public Command
105 public:
106 SetNotesViewCommand (
107 const bool bOn,
108 const rtl::Reference<PresenterController>& rpPresenterController);
109 virtual void Execute() override;
110 virtual Any GetState() const override;
111 private:
112 bool const mbOn;
113 rtl::Reference<PresenterController> mpPresenterController;
116 class SetSlideSorterCommand : public Command
118 public:
119 SetSlideSorterCommand (
120 const bool bOn,
121 const rtl::Reference<PresenterController>& rpPresenterController);
122 virtual void Execute() override;
123 virtual Any GetState() const override;
124 private:
125 bool const mbOn;
126 rtl::Reference<PresenterController> mpPresenterController;
129 class SetHelpViewCommand : public Command
131 public:
132 SetHelpViewCommand (
133 const bool bOn,
134 const rtl::Reference<PresenterController>& rpPresenterController);
135 virtual void Execute() override;
136 virtual Any GetState() const override;
137 private:
138 bool const mbOn;
139 rtl::Reference<PresenterController> mpPresenterController;
142 class NotesFontSizeCommand : public Command
144 public:
145 NotesFontSizeCommand(
146 const rtl::Reference<PresenterController>& rpPresenterController,
147 const sal_Int32 nSizeChange);
148 virtual void Execute() override;
149 virtual Any GetState() const override;
150 protected:
151 ::rtl::Reference<PresenterNotesView> GetNotesView() const;
152 private:
153 rtl::Reference<PresenterController> mpPresenterController;
154 const sal_Int32 mnSizeChange;
157 } // end of anonymous namespace
159 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
170 public:
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);
185 // XDispatch
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;
206 private:
207 OUString msURLPath;
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;
214 Dispatch (
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)
257 ThrowIfDisposed();
258 if (aArguments.getLength() <= 0)
259 return;
263 Reference<frame::XFrame> xFrame;
264 if (aArguments[0] >>= xFrame)
266 mpPresenterController = PresenterController::Instance(xFrame);
269 catch (RuntimeException&)
271 OSL_ASSERT(false);
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,
295 const OUString&,
296 sal_Int32)
298 ThrowIfDisposed();
300 Reference<frame::XDispatch> xDispatch;
302 if (rURL.Protocol == "vnd.org.libreoffice.presenterscreen:")
304 xDispatch.set(Dispatch::Create(rURL.Path, mpPresenterController));
307 return xDispatch;
310 Sequence<Reference<frame::XDispatch> > SAL_CALL PresenterProtocolHandler::queryDispatches(
311 const Sequence<frame::DispatchDescriptor>&)
313 ThrowIfDisposed();
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());
337 else
338 return nullptr;
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)
363 return nullptr;
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);
392 return nullptr;
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;
408 msURLPath.clear();
409 mpCommand.reset();
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 (
461 ::std::find(
462 maStatusListenerContainer.begin(),
463 maStatusListenerContainer.end(),
464 rxListener));
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())
495 return;
497 if ( ! mpPresenterController->GetSlideShowController().is())
498 return;
500 mpPresenterController->GetSlideShowController()->gotoPreviousSlide();
503 bool GotoPreviousSlideCommand::IsEnabled() const
505 if ( ! mpPresenterController.is())
506 return false;
508 if ( ! mpPresenterController->GetSlideShowController().is())
509 return false;
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())
525 return;
527 if ( ! mpPresenterController->GetSlideShowController().is())
528 return;
530 mpPresenterController->GetSlideShowController()->gotoNextEffect();
533 bool GotoNextEffectCommand::IsEnabled() const
535 if ( ! mpPresenterController.is())
536 return false;
538 if ( ! mpPresenterController->GetSlideShowController().is())
539 return false;
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())
556 return;
558 if ( ! mpPresenterController->GetSlideShowController().is())
559 return;
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 (
591 const bool bOn,
592 const rtl::Reference<PresenterController>& rpPresenterController)
593 : mbOn(bOn),
594 mpPresenterController(rpPresenterController)
598 void SetNotesViewCommand::Execute()
600 if ( ! mpPresenterController.is())
601 return;
603 ::rtl::Reference<PresenterWindowManager> pWindowManager (
604 mpPresenterController->GetWindowManager());
605 if ( ! pWindowManager.is())
606 return;
608 if (mbOn)
609 pWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
610 else
611 pWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
614 Any SetNotesViewCommand::GetState() const
616 if ( ! mpPresenterController.is())
617 return Any(false);
619 ::rtl::Reference<PresenterWindowManager> pWindowManager (
620 mpPresenterController->GetWindowManager());
621 if ( ! pWindowManager.is())
622 return Any(false);
624 return Any(pWindowManager->GetViewMode() == PresenterWindowManager::VM_Notes);
627 //===== SetSlideSorterCommand =================================================
629 SetSlideSorterCommand::SetSlideSorterCommand (
630 const bool bOn,
631 const rtl::Reference<PresenterController>& rpPresenterController)
632 : mbOn(bOn),
633 mpPresenterController(rpPresenterController)
637 void SetSlideSorterCommand::Execute()
639 if ( ! mpPresenterController.is())
640 return;
642 ::rtl::Reference<PresenterWindowManager> pWindowManager (
643 mpPresenterController->GetWindowManager());
644 if ( ! pWindowManager.is())
645 return;
647 pWindowManager->SetSlideSorterState(mbOn);
650 Any SetSlideSorterCommand::GetState() const
652 if ( ! mpPresenterController.is())
653 return Any(false);
655 ::rtl::Reference<PresenterWindowManager> pWindowManager (
656 mpPresenterController->GetWindowManager());
657 if ( ! pWindowManager.is())
658 return Any(false);
660 return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_SlideOverview);
663 //===== SetHelpViewCommand ===================================================
665 SetHelpViewCommand::SetHelpViewCommand (
666 const bool bOn,
667 const rtl::Reference<PresenterController>& rpPresenterController)
668 : mbOn(bOn),
669 mpPresenterController(rpPresenterController)
673 void SetHelpViewCommand::Execute()
675 if ( ! mpPresenterController.is())
676 return;
678 ::rtl::Reference<PresenterWindowManager> pWindowManager (
679 mpPresenterController->GetWindowManager());
680 if ( ! pWindowManager.is())
681 return;
683 pWindowManager->SetHelpViewState(mbOn);
686 Any SetHelpViewCommand::GetState() const
688 if ( ! mpPresenterController.is())
689 return Any(false);
691 ::rtl::Reference<PresenterWindowManager> pWindowManager (
692 mpPresenterController->GetWindowManager());
693 if ( ! pWindowManager.is())
694 return Any(false);
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)
712 return nullptr;
714 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
715 mpPresenterController->GetPaneContainer()->FindViewURL(
716 PresenterViewFactory::msNotesViewURL));
717 if (pDescriptor.get() == nullptr)
718 return nullptr;
720 return dynamic_cast<PresenterNotesView*>(pDescriptor->mxView.get());
723 void NotesFontSizeCommand::Execute()
725 ::rtl::Reference<PresenterNotesView> pView (GetNotesView());
726 if (pView.is())
727 pView->ChangeFontSize(mnSizeChange);
730 Any NotesFontSizeCommand::GetState() const
732 return Any();
735 } } // end of namespace ::sdext::presenter
737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */