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 .
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
{
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
59 GotoPreviousSlideCommand (
60 const rtl::Reference
<PresenterController
>& rpPresenterController
);
61 virtual ~GotoPreviousSlideCommand (void) {}
62 virtual void Execute (void);
63 virtual bool IsEnabled (void) const;
65 rtl::Reference
<PresenterController
> mpPresenterController
;
68 class GotoNextSlideCommand
: public Command
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; }
80 rtl::Reference
<PresenterController
> mpPresenterController
;
83 class GotoNextEffectCommand
: public Command
86 GotoNextEffectCommand (
87 const rtl::Reference
<PresenterController
>& rpPresenterController
);
88 virtual ~GotoNextEffectCommand (void) {}
89 virtual void Execute (void);
91 rtl::Reference
<PresenterController
> mpPresenterController
;
94 class SwitchMonitorCommand
: public Command
97 SwitchMonitorCommand (
98 const rtl::Reference
<PresenterController
>& rpPresenterController
);
99 virtual ~SwitchMonitorCommand (void) {}
100 virtual void Execute (void);
102 rtl::Reference
<PresenterController
> mpPresenterController
;
105 class SetNotesViewCommand
: public Command
108 SetNotesViewCommand (
110 const rtl::Reference
<PresenterController
>& rpPresenterController
);
111 virtual ~SetNotesViewCommand (void) {}
112 virtual void Execute (void);
113 virtual Any
GetState (void) const;
116 rtl::Reference
<PresenterController
> mpPresenterController
;
117 bool IsActive (const ::rtl::Reference
<PresenterWindowManager
>& rpWindowManager
) const;
120 class SetSlideSorterCommand
: public Command
123 SetSlideSorterCommand (
125 const rtl::Reference
<PresenterController
>& rpPresenterController
);
126 virtual ~SetSlideSorterCommand (void) {}
127 virtual void Execute (void);
128 virtual Any
GetState (void) const;
131 rtl::Reference
<PresenterController
> mpPresenterController
;
134 class SetHelpViewCommand
: public Command
139 const rtl::Reference
<PresenterController
>& rpPresenterController
);
140 virtual ~SetHelpViewCommand (void) {}
141 virtual void Execute (void);
142 virtual Any
GetState (void) const;
145 rtl::Reference
<PresenterController
> mpPresenterController
;
148 class NotesFontSizeCommand
: public Command
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;
158 ::rtl::Reference
<PresenterNotesView
> GetNotesView (void) const;
160 rtl::Reference
<PresenterController
> mpPresenterController
;
161 const sal_Int32 mnSizeChange
;
164 } // end of anonymous 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
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
);
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
);
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
;
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
)
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
)
276 if (aArguments
.getLength() > 0)
280 Reference
<frame::XFrame
> xFrame
;
281 if (aArguments
[0] >>= xFrame
)
283 mpPresenterController
= PresenterController::Instance(xFrame
);
286 catch (RuntimeException
&)
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
;
305 Reference
<frame::XDispatch
> xDispatch
;
307 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:")
309 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
315 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
316 const Sequence
<frame::DispatchDescriptor
>& rDescriptors
)
317 throw(RuntimeException
)
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 (
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());
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)
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);
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();
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
)
430 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:"
431 && rURL
.Path
== msURLPath
)
433 if (mpCommand
.get() != NULL
)
434 mpCommand
->Execute();
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
);
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 (
472 maStatusListenerContainer
.begin(),
473 maStatusListenerContainer
.end(),
475 if (iListener
!= maStatusListenerContainer
.end())
476 maStatusListenerContainer
.erase(iListener
);
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 (
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
)
502 mpCommand
->GetState();
505 //----- lang::XEventListener --------------------------------------------------
507 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
& rEvent
)
508 throw(css::uno::RuntimeException
)
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())
527 if ( ! mpPresenterController
->GetSlideShowController().is())
530 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
533 bool GotoPreviousSlideCommand::IsEnabled (void) const
535 if ( ! mpPresenterController
.is())
538 if ( ! mpPresenterController
->GetSlideShowController().is())
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())
557 if ( ! mpPresenterController
->GetSlideShowController().is())
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())
576 if ( ! mpPresenterController
->GetSlideShowController().is())
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 (
599 const rtl::Reference
<PresenterController
>& rpPresenterController
)
601 mpPresenterController(rpPresenterController
)
605 void SetNotesViewCommand::Execute (void)
607 if ( ! mpPresenterController
.is())
610 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
611 mpPresenterController
->GetWindowManager());
612 if ( ! pWindowManager
.is())
616 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
618 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
621 Any
SetNotesViewCommand::GetState (void) const
623 if ( ! mpPresenterController
.is())
626 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
627 mpPresenterController
->GetWindowManager());
628 if ( ! pWindowManager
.is())
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 (
644 const rtl::Reference
<PresenterController
>& rpPresenterController
)
646 mpPresenterController(rpPresenterController
)
650 void SetSlideSorterCommand::Execute (void)
652 if ( ! mpPresenterController
.is())
655 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
656 mpPresenterController
->GetWindowManager());
657 if ( ! pWindowManager
.is())
660 pWindowManager
->SetSlideSorterState(mbOn
);
663 Any
SetSlideSorterCommand::GetState (void) const
665 if ( ! mpPresenterController
.is())
668 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
669 mpPresenterController
->GetWindowManager());
670 if ( ! pWindowManager
.is())
673 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_SlideOverview
);
676 //===== SetHelpViewCommand ===================================================
678 SetHelpViewCommand::SetHelpViewCommand (
680 const rtl::Reference
<PresenterController
>& rpPresenterController
)
682 mpPresenterController(rpPresenterController
)
686 void SetHelpViewCommand::Execute (void)
688 if ( ! mpPresenterController
.is())
691 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
692 mpPresenterController
->GetWindowManager());
693 if ( ! pWindowManager
.is())
696 pWindowManager
->SetHelpViewState(mbOn
);
699 Any
SetHelpViewCommand::GetState (void) const
701 if ( ! mpPresenterController
.is())
704 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
705 mpPresenterController
->GetWindowManager());
706 if ( ! pWindowManager
.is())
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
)
727 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
728 mpPresenterController
->GetPaneContainer()->FindViewURL(
729 PresenterViewFactory::msNotesViewURL
));
730 if (pDescriptor
.get() == NULL
)
733 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
736 void NotesFontSizeCommand::Execute (void)
738 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
740 pView
->ChangeFontSize(mnSizeChange
);
743 Any
NotesFontSizeCommand::GetState (void) const
748 } } // end of namespace ::sdext::presenter
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */