Updated core
[LibreOffice.git] / sdext / source / presenter / PresenterProtocolHandler.cxx
blob60068de88daf69b38874a1f0ceaa54a0697d835b
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 "PresenterProtocolHandler.hxx"
21 #include "PresenterConfigurationAccess.hxx"
22 #include "PresenterController.hxx"
23 #include "PresenterHelper.hxx"
24 #include "PresenterNotesView.hxx"
25 #include "PresenterPaneContainer.hxx"
26 #include "PresenterPaneFactory.hxx"
27 #include "PresenterViewFactory.hxx"
28 #include "PresenterWindowManager.hxx"
29 #include <com/sun/star/frame/XController.hpp>
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 <com/sun/star/presentation/XSlideShow.hpp>
36 #include <com/sun/star/presentation/XSlideShowView.hpp>
37 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
38 #include <cppuhelper/compbase2.hxx>
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::drawing::framework;
44 namespace sdext { namespace presenter {
46 namespace {
47 class Command
49 public:
50 virtual ~Command() {}
51 virtual void Execute (void) = 0;
52 virtual bool IsEnabled (void) const { return true; }
53 virtual Any GetState (void) const { return Any(sal_False); }
56 class GotoPreviousSlideCommand : public Command
58 public:
59 GotoPreviousSlideCommand (
60 const rtl::Reference<PresenterController>& rpPresenterController);
61 virtual ~GotoPreviousSlideCommand (void) {}
62 virtual void Execute (void);
63 virtual bool IsEnabled (void) const;
64 private:
65 rtl::Reference<PresenterController> mpPresenterController;
68 class GotoNextSlideCommand : public Command
70 public:
71 GotoNextSlideCommand (
72 const rtl::Reference<PresenterController>& rpPresenterController);
73 virtual ~GotoNextSlideCommand (void) {}
74 virtual void Execute (void);
75 // The next slide command is always enabled, even when the current slide
76 // is the last slide: from the last slide it goes to the pause slide,
77 // and from there it ends the slide show.
78 virtual bool IsEnabled (void) const { return true; }
79 private:
80 rtl::Reference<PresenterController> mpPresenterController;
83 class GotoNextEffectCommand : public Command
85 public:
86 GotoNextEffectCommand (
87 const rtl::Reference<PresenterController>& rpPresenterController);
88 virtual ~GotoNextEffectCommand (void) {}
89 virtual void Execute (void);
90 private:
91 rtl::Reference<PresenterController> mpPresenterController;
94 class SwitchMonitorCommand : public Command
96 public:
97 SwitchMonitorCommand (
98 const rtl::Reference<PresenterController>& rpPresenterController);
99 virtual ~SwitchMonitorCommand (void) {}
100 virtual void Execute (void);
101 private:
102 rtl::Reference<PresenterController> mpPresenterController;
105 class SetNotesViewCommand : public Command
107 public:
108 SetNotesViewCommand (
109 const bool bOn,
110 const rtl::Reference<PresenterController>& rpPresenterController);
111 virtual ~SetNotesViewCommand (void) {}
112 virtual void Execute (void);
113 virtual Any GetState (void) const;
114 private:
115 bool mbOn;
116 rtl::Reference<PresenterController> mpPresenterController;
117 bool IsActive (const ::rtl::Reference<PresenterWindowManager>& rpWindowManager) const;
120 class SetSlideSorterCommand : public Command
122 public:
123 SetSlideSorterCommand (
124 const bool bOn,
125 const rtl::Reference<PresenterController>& rpPresenterController);
126 virtual ~SetSlideSorterCommand (void) {}
127 virtual void Execute (void);
128 virtual Any GetState (void) const;
129 private:
130 bool mbOn;
131 rtl::Reference<PresenterController> mpPresenterController;
134 class SetHelpViewCommand : public Command
136 public:
137 SetHelpViewCommand (
138 const bool bOn,
139 const rtl::Reference<PresenterController>& rpPresenterController);
140 virtual ~SetHelpViewCommand (void) {}
141 virtual void Execute (void);
142 virtual Any GetState (void) const;
143 private:
144 bool mbOn;
145 rtl::Reference<PresenterController> mpPresenterController;
148 class NotesFontSizeCommand : public Command
150 public:
151 NotesFontSizeCommand(
152 const rtl::Reference<PresenterController>& rpPresenterController,
153 const sal_Int32 nSizeChange);
154 virtual ~NotesFontSizeCommand (void) {}
155 virtual void Execute (void);
156 virtual Any GetState (void) const;
157 protected:
158 ::rtl::Reference<PresenterNotesView> GetNotesView (void) const;
159 private:
160 rtl::Reference<PresenterController> mpPresenterController;
161 const sal_Int32 mnSizeChange;
164 } // end of anonymous namespace
166 namespace {
167 typedef ::cppu::WeakComponentImplHelper2 <
168 css::frame::XDispatch,
169 css::document::XEventListener
170 > PresenterDispatchInterfaceBase;
173 class PresenterProtocolHandler::Dispatch
174 : protected ::cppu::BaseMutex,
175 public PresenterDispatchInterfaceBase
177 public:
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 (void);
188 static Command* CreateCommand (
189 const OUString& rsURLPath,
190 const ::rtl::Reference<PresenterController>& rpPresenterController);
192 // XDispatch
193 virtual void SAL_CALL dispatch(
194 const css::util::URL& aURL,
195 const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
196 throw(css::uno::RuntimeException);
198 virtual void SAL_CALL addStatusListener(
199 const css::uno::Reference<css::frame::XStatusListener>& rxListener,
200 const css::util::URL& rURL)
201 throw(css::uno::RuntimeException);
203 virtual void SAL_CALL removeStatusListener (
204 const css::uno::Reference<css::frame::XStatusListener>& rxListener,
205 const css::util::URL& rURL)
206 throw(css::uno::RuntimeException);
208 // document::XEventListener
210 virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent)
211 throw(css::uno::RuntimeException);
213 // lang::XEventListener
215 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
216 throw(css::uno::RuntimeException);
218 private:
219 OUString msURLPath;
220 ::boost::scoped_ptr<Command> mpCommand;
221 ::rtl::Reference<PresenterController> mpPresenterController;
222 typedef ::std::vector<Reference<frame::XStatusListener> > StatusListenerContainer;
223 StatusListenerContainer maStatusListenerContainer;
224 bool mbIsListeningToWindowManager;
226 Dispatch (
227 const OUString& rsURLPath,
228 const ::rtl::Reference<PresenterController>& rpPresenterController);
229 virtual ~Dispatch (void);
231 void ThrowIfDisposed (void) const throw (css::lang::DisposedException);
234 //----- Service ---------------------------------------------------------------
236 OUString PresenterProtocolHandler::getImplementationName_static (void)
238 return OUString("org.libreoffice.comp.PresenterScreenProtocolHandler");
241 Sequence<OUString> PresenterProtocolHandler::getSupportedServiceNames_static (void)
243 static const OUString sServiceName("com.sun.star.frame.ProtocolHandler");
244 return Sequence<OUString>(&sServiceName, 1);
247 Reference<XInterface> PresenterProtocolHandler::Create (
248 const Reference<uno::XComponentContext>& rxContext)
249 SAL_THROW((Exception))
251 return Reference<XInterface>(static_cast<XWeak*>(new PresenterProtocolHandler(rxContext)));
254 //===== PresenterProtocolHandler =========================================================
256 PresenterProtocolHandler::PresenterProtocolHandler (const Reference<XComponentContext>& rxContext)
257 : PresenterProtocolHandlerInterfaceBase(m_aMutex)
259 (void)rxContext;
262 PresenterProtocolHandler::~PresenterProtocolHandler (void)
266 void SAL_CALL PresenterProtocolHandler::disposing (void)
270 //----- XInitialize -----------------------------------------------------------
272 void SAL_CALL PresenterProtocolHandler::initialize (const Sequence<Any>& aArguments)
273 throw (Exception, RuntimeException)
275 ThrowIfDisposed();
276 if (aArguments.getLength() > 0)
280 Reference<frame::XFrame> xFrame;
281 if (aArguments[0] >>= xFrame)
283 mpPresenterController = PresenterController::Instance(xFrame);
286 catch (RuntimeException&)
288 OSL_ASSERT(false);
293 //----- XDispatchProvider -----------------------------------------------------
295 Reference<frame::XDispatch> SAL_CALL PresenterProtocolHandler::queryDispatch (
296 const css::util::URL& rURL,
297 const OUString& rsTargetFrameName,
298 sal_Int32 nSearchFlags)
299 throw(RuntimeException)
301 (void)rsTargetFrameName;
302 (void)nSearchFlags;
303 ThrowIfDisposed();
305 Reference<frame::XDispatch> xDispatch;
307 if (rURL.Protocol == "vnd.org.libreoffice.presenterscreen:")
309 xDispatch.set(Dispatch::Create(rURL.Path, mpPresenterController));
312 return xDispatch;
315 Sequence<Reference<frame::XDispatch> > SAL_CALL PresenterProtocolHandler::queryDispatches(
316 const Sequence<frame::DispatchDescriptor>& rDescriptors)
317 throw(RuntimeException)
319 (void)rDescriptors;
320 ThrowIfDisposed();
321 return Sequence<Reference<frame::XDispatch> >();
324 //-----------------------------------------------------------------------------
326 void PresenterProtocolHandler::ThrowIfDisposed (void) const
327 throw (::com::sun::star::lang::DisposedException)
329 if (rBHelper.bDisposed || rBHelper.bInDispose)
331 throw lang::DisposedException (
332 OUString(
333 "PresenterProtocolHandler object has already been disposed"),
334 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
338 //===== PresenterProtocolHandler::Dispatch ====================================
340 Reference<frame::XDispatch> PresenterProtocolHandler::Dispatch::Create (
341 const OUString& rsURLPath,
342 const ::rtl::Reference<PresenterController>& rpPresenterController)
344 ::rtl::Reference<Dispatch> pDispatch (new Dispatch (rsURLPath, rpPresenterController));
345 if (pDispatch->mpCommand.get() != NULL)
346 return Reference<frame::XDispatch>(pDispatch.get());
347 else
348 return NULL;
351 PresenterProtocolHandler::Dispatch::Dispatch (
352 const OUString& rsURLPath,
353 const ::rtl::Reference<PresenterController>& rpPresenterController)
354 : PresenterDispatchInterfaceBase(m_aMutex),
355 msURLPath(rsURLPath),
356 mpCommand(CreateCommand(rsURLPath, rpPresenterController)),
357 mpPresenterController(rpPresenterController),
358 maStatusListenerContainer(),
359 mbIsListeningToWindowManager(false)
361 if (mpCommand.get() != NULL)
363 mpPresenterController->GetWindowManager()->AddLayoutListener(this);
364 mbIsListeningToWindowManager = true;
368 Command* PresenterProtocolHandler::Dispatch::CreateCommand (
369 const OUString& rsURLPath,
370 const ::rtl::Reference<PresenterController>& rpPresenterController)
372 if (rsURLPath.getLength() <= 5)
373 return NULL;
375 if (rsURLPath == "CloseNotes")
376 return new SetNotesViewCommand(false, rpPresenterController);
377 if (rsURLPath == "CloseSlideSorter")
378 return new SetSlideSorterCommand(false, rpPresenterController);
379 if (rsURLPath == "CloseHelp")
380 return new SetHelpViewCommand(false, rpPresenterController);
381 if (rsURLPath == "GrowNotesFont")
382 return new NotesFontSizeCommand(rpPresenterController, +1);
383 if (rsURLPath == "NextEffect")
384 return new GotoNextEffectCommand(rpPresenterController);
385 if (rsURLPath == "NextSlide")
386 return new GotoNextSlideCommand(rpPresenterController);
387 if (rsURLPath == "PrevSlide")
388 return new GotoPreviousSlideCommand(rpPresenterController);
389 if (rsURLPath == "SwitchMonitor")
390 return new SwitchMonitorCommand(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);
400 return NULL;
403 PresenterProtocolHandler::Dispatch::~Dispatch (void)
407 void PresenterProtocolHandler::Dispatch::disposing (void)
409 if (mbIsListeningToWindowManager)
411 if (mpPresenterController.get() != NULL)
412 mpPresenterController->GetWindowManager()->RemoveLayoutListener(this);
413 mbIsListeningToWindowManager = false;
416 msURLPath = OUString();
417 mpCommand.reset();
420 //----- XDispatch -------------------------------------------------------------
422 void SAL_CALL PresenterProtocolHandler::Dispatch::dispatch(
423 const css::util::URL& rURL,
424 const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
425 throw(css::uno::RuntimeException)
427 (void)rArguments;
428 ThrowIfDisposed();
430 if (rURL.Protocol == "vnd.org.libreoffice.presenterscreen:"
431 && rURL.Path == msURLPath)
433 if (mpCommand.get() != NULL)
434 mpCommand->Execute();
436 else
438 // We can not throw an IllegalArgumentException
439 throw RuntimeException();
443 void SAL_CALL PresenterProtocolHandler::Dispatch::addStatusListener(
444 const css::uno::Reference<css::frame::XStatusListener>& rxListener,
445 const css::util::URL& rURL)
446 throw(css::uno::RuntimeException)
448 if (rURL.Path == msURLPath)
450 maStatusListenerContainer.push_back(rxListener);
452 frame::FeatureStateEvent aEvent;
453 aEvent.FeatureURL = rURL;
454 aEvent.IsEnabled = mpCommand->IsEnabled();
455 aEvent.Requery = sal_False;
456 aEvent.State = mpCommand->GetState();
457 rxListener->statusChanged(aEvent);
459 else
460 throw RuntimeException();
463 void SAL_CALL PresenterProtocolHandler::Dispatch::removeStatusListener (
464 const css::uno::Reference<css::frame::XStatusListener>& rxListener,
465 const css::util::URL& rURL)
466 throw(css::uno::RuntimeException)
468 if (rURL.Path == msURLPath)
470 StatusListenerContainer::iterator iListener (
471 ::std::find(
472 maStatusListenerContainer.begin(),
473 maStatusListenerContainer.end(),
474 rxListener));
475 if (iListener != maStatusListenerContainer.end())
476 maStatusListenerContainer.erase(iListener);
478 else
479 throw RuntimeException();
482 void PresenterProtocolHandler::Dispatch::ThrowIfDisposed (void) const
483 throw (::com::sun::star::lang::DisposedException)
485 if (rBHelper.bDisposed || rBHelper.bInDispose)
487 throw lang::DisposedException (
488 OUString(
489 "PresenterProtocolHandler::Dispatch object has already been disposed"),
490 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
494 //----- document::XEventListener ----------------------------------------------
496 void SAL_CALL PresenterProtocolHandler::Dispatch::notifyEvent (
497 const css::document::EventObject& rEvent)
498 throw(css::uno::RuntimeException)
500 (void)rEvent;
502 mpCommand->GetState();
505 //----- lang::XEventListener --------------------------------------------------
507 void SAL_CALL PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject& rEvent)
508 throw(css::uno::RuntimeException)
510 (void)rEvent;
511 mbIsListeningToWindowManager = false;
514 //===== GotoPreviousSlideCommand ==============================================
516 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
517 const rtl::Reference<PresenterController>& rpPresenterController)
518 : mpPresenterController(rpPresenterController)
522 void GotoPreviousSlideCommand::Execute (void)
524 if ( ! mpPresenterController.is())
525 return;
527 if ( ! mpPresenterController->GetSlideShowController().is())
528 return;
530 mpPresenterController->GetSlideShowController()->gotoPreviousSlide();
533 bool GotoPreviousSlideCommand::IsEnabled (void) const
535 if ( ! mpPresenterController.is())
536 return false;
538 if ( ! mpPresenterController->GetSlideShowController().is())
539 return false;
541 return mpPresenterController->GetSlideShowController()->getCurrentSlideIndex()>0;
544 //===== GotoNextEffect ========================================================
546 GotoNextEffectCommand::GotoNextEffectCommand (
547 const rtl::Reference<PresenterController>& rpPresenterController)
548 : mpPresenterController(rpPresenterController)
552 void GotoNextEffectCommand::Execute (void)
554 if ( ! mpPresenterController.is())
555 return;
557 if ( ! mpPresenterController->GetSlideShowController().is())
558 return;
560 mpPresenterController->GetSlideShowController()->gotoNextEffect();
563 //===== GotoNextSlide =========================================================
565 GotoNextSlideCommand::GotoNextSlideCommand (
566 const rtl::Reference<PresenterController>& rpPresenterController)
567 : mpPresenterController(rpPresenterController)
571 void GotoNextSlideCommand::Execute (void)
573 if ( ! mpPresenterController.is())
574 return;
576 if ( ! mpPresenterController->GetSlideShowController().is())
577 return;
579 mpPresenterController->GetSlideShowController()->gotoNextSlide();
582 //===== SwitchMonitorCommand ==============================================
584 SwitchMonitorCommand::SwitchMonitorCommand (
585 const rtl::Reference<PresenterController>& rpPresenterController)
586 : mpPresenterController(rpPresenterController)
590 void SwitchMonitorCommand::Execute (void)
592 mpPresenterController->SwitchMonitors();
595 //===== SetNotesViewCommand ===================================================
597 SetNotesViewCommand::SetNotesViewCommand (
598 const bool bOn,
599 const rtl::Reference<PresenterController>& rpPresenterController)
600 : mbOn(bOn),
601 mpPresenterController(rpPresenterController)
605 void SetNotesViewCommand::Execute (void)
607 if ( ! mpPresenterController.is())
608 return;
610 ::rtl::Reference<PresenterWindowManager> pWindowManager (
611 mpPresenterController->GetWindowManager());
612 if ( ! pWindowManager.is())
613 return;
615 if (mbOn)
616 pWindowManager->SetViewMode(PresenterWindowManager::VM_Notes);
617 else
618 pWindowManager->SetViewMode(PresenterWindowManager::VM_Standard);
621 Any SetNotesViewCommand::GetState (void) const
623 if ( ! mpPresenterController.is())
624 return Any(false);
626 ::rtl::Reference<PresenterWindowManager> pWindowManager (
627 mpPresenterController->GetWindowManager());
628 if ( ! pWindowManager.is())
629 return Any(false);
631 return Any(IsActive(pWindowManager));
634 bool SetNotesViewCommand::IsActive (
635 const ::rtl::Reference<PresenterWindowManager>& rpWindowManager) const
637 return rpWindowManager->GetViewMode() == PresenterWindowManager::VM_Notes;
640 //===== SetSlideSorterCommand =================================================
642 SetSlideSorterCommand::SetSlideSorterCommand (
643 const bool bOn,
644 const rtl::Reference<PresenterController>& rpPresenterController)
645 : mbOn(bOn),
646 mpPresenterController(rpPresenterController)
650 void SetSlideSorterCommand::Execute (void)
652 if ( ! mpPresenterController.is())
653 return;
655 ::rtl::Reference<PresenterWindowManager> pWindowManager (
656 mpPresenterController->GetWindowManager());
657 if ( ! pWindowManager.is())
658 return;
660 pWindowManager->SetSlideSorterState(mbOn);
663 Any SetSlideSorterCommand::GetState (void) const
665 if ( ! mpPresenterController.is())
666 return Any(false);
668 ::rtl::Reference<PresenterWindowManager> pWindowManager (
669 mpPresenterController->GetWindowManager());
670 if ( ! pWindowManager.is())
671 return Any(false);
673 return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_SlideOverview);
676 //===== SetHelpViewCommand ===================================================
678 SetHelpViewCommand::SetHelpViewCommand (
679 const bool bOn,
680 const rtl::Reference<PresenterController>& rpPresenterController)
681 : mbOn(bOn),
682 mpPresenterController(rpPresenterController)
686 void SetHelpViewCommand::Execute (void)
688 if ( ! mpPresenterController.is())
689 return;
691 ::rtl::Reference<PresenterWindowManager> pWindowManager (
692 mpPresenterController->GetWindowManager());
693 if ( ! pWindowManager.is())
694 return;
696 pWindowManager->SetHelpViewState(mbOn);
699 Any SetHelpViewCommand::GetState (void) const
701 if ( ! mpPresenterController.is())
702 return Any(false);
704 ::rtl::Reference<PresenterWindowManager> pWindowManager (
705 mpPresenterController->GetWindowManager());
706 if ( ! pWindowManager.is())
707 return Any(false);
709 return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_Help);
712 //===== NotesFontSizeCommand ==================================================
714 NotesFontSizeCommand::NotesFontSizeCommand(
715 const rtl::Reference<PresenterController>& rpPresenterController,
716 const sal_Int32 nSizeChange)
717 : mpPresenterController(rpPresenterController),
718 mnSizeChange(nSizeChange)
722 ::rtl::Reference<PresenterNotesView> NotesFontSizeCommand::GetNotesView (void) const
724 if (mpPresenterController.get() == NULL)
725 return NULL;
727 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
728 mpPresenterController->GetPaneContainer()->FindViewURL(
729 PresenterViewFactory::msNotesViewURL));
730 if (pDescriptor.get() == NULL)
731 return NULL;
733 return dynamic_cast<PresenterNotesView*>(pDescriptor->mxView.get());
736 void NotesFontSizeCommand::Execute (void)
738 ::rtl::Reference<PresenterNotesView> pView (GetNotesView());
739 if (pView.is())
740 pView->ChangeFontSize(mnSizeChange);
743 Any NotesFontSizeCommand::GetState (void) const
745 return Any();
748 } } // end of namespace ::sdext::presenter
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */