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>
39 #include <cppuhelper/supportsservice.hxx>
41 using namespace ::com::sun::star
;
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::drawing::framework
;
45 namespace sdext
{ namespace presenter
{
52 virtual void Execute() = 0;
53 virtual bool IsEnabled() const { return true; }
54 virtual Any
GetState() const { return Any(sal_False
); }
57 class GotoPreviousSlideCommand
: public Command
60 GotoPreviousSlideCommand (
61 const rtl::Reference
<PresenterController
>& rpPresenterController
);
62 virtual ~GotoPreviousSlideCommand() {}
63 virtual void Execute() SAL_OVERRIDE
;
64 virtual bool IsEnabled() const SAL_OVERRIDE
;
66 rtl::Reference
<PresenterController
> mpPresenterController
;
69 class GotoNextSlideCommand
: public Command
72 GotoNextSlideCommand (
73 const rtl::Reference
<PresenterController
>& rpPresenterController
);
74 virtual ~GotoNextSlideCommand() {}
75 virtual void Execute() SAL_OVERRIDE
;
76 // The next slide command is always enabled, even when the current slide
77 // is the last slide: from the last slide it goes to the pause slide,
78 // and from there it ends the slide show.
79 virtual bool IsEnabled() const SAL_OVERRIDE
{ return true; }
81 rtl::Reference
<PresenterController
> mpPresenterController
;
84 class GotoNextEffectCommand
: public Command
87 GotoNextEffectCommand (
88 const rtl::Reference
<PresenterController
>& rpPresenterController
);
89 virtual ~GotoNextEffectCommand() {}
90 virtual void Execute() SAL_OVERRIDE
;
92 rtl::Reference
<PresenterController
> mpPresenterController
;
95 class SwitchMonitorCommand
: public Command
98 SwitchMonitorCommand (
99 const rtl::Reference
<PresenterController
>& rpPresenterController
);
100 virtual ~SwitchMonitorCommand() {}
101 virtual void Execute() SAL_OVERRIDE
;
103 rtl::Reference
<PresenterController
> mpPresenterController
;
106 class SetNotesViewCommand
: public Command
109 SetNotesViewCommand (
111 const rtl::Reference
<PresenterController
>& rpPresenterController
);
112 virtual ~SetNotesViewCommand() {}
113 virtual void Execute() SAL_OVERRIDE
;
114 virtual Any
GetState() const SAL_OVERRIDE
;
117 rtl::Reference
<PresenterController
> mpPresenterController
;
118 static bool IsActive (const ::rtl::Reference
<PresenterWindowManager
>& rpWindowManager
);
121 class SetSlideSorterCommand
: public Command
124 SetSlideSorterCommand (
126 const rtl::Reference
<PresenterController
>& rpPresenterController
);
127 virtual ~SetSlideSorterCommand() {}
128 virtual void Execute() SAL_OVERRIDE
;
129 virtual Any
GetState() const SAL_OVERRIDE
;
132 rtl::Reference
<PresenterController
> mpPresenterController
;
135 class SetHelpViewCommand
: public Command
140 const rtl::Reference
<PresenterController
>& rpPresenterController
);
141 virtual ~SetHelpViewCommand() {}
142 virtual void Execute() SAL_OVERRIDE
;
143 virtual Any
GetState() const SAL_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 ~NotesFontSizeCommand() {}
156 virtual void Execute() SAL_OVERRIDE
;
157 virtual Any
GetState() const SAL_OVERRIDE
;
159 ::rtl::Reference
<PresenterNotesView
> GetNotesView() const;
161 rtl::Reference
<PresenterController
> mpPresenterController
;
162 const sal_Int32 mnSizeChange
;
165 } // end of anonymous namespace
168 typedef ::cppu::WeakComponentImplHelper2
<
169 css::frame::XDispatch
,
170 css::document::XEventListener
171 > PresenterDispatchInterfaceBase
;
174 class PresenterProtocolHandler::Dispatch
175 : protected ::cppu::BaseMutex
,
176 public PresenterDispatchInterfaceBase
179 typedef void (PresenterProtocolHandler::Dispatch::* Action
)(void);
181 /** Create a new Dispatch object. When the given command name
182 (rsURLPath) is not known then an empty reference is returned.
184 static Reference
<frame::XDispatch
> Create (
185 const OUString
& rsURLPath
,
186 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
188 void SAL_CALL
disposing() SAL_OVERRIDE
;
189 static Command
* CreateCommand (
190 const OUString
& rsURLPath
,
191 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
194 virtual void SAL_CALL
dispatch(
195 const css::util::URL
& aURL
,
196 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
)
197 throw(css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
199 virtual void SAL_CALL
addStatusListener(
200 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
201 const css::util::URL
& rURL
)
202 throw(css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
204 virtual void SAL_CALL
removeStatusListener (
205 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
206 const css::util::URL
& rURL
)
207 throw(css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
209 // document::XEventListener
211 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
)
212 throw(css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
214 // lang::XEventListener
216 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
)
217 throw(css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
221 ::boost::scoped_ptr
<Command
> mpCommand
;
222 ::rtl::Reference
<PresenterController
> mpPresenterController
;
223 typedef ::std::vector
<Reference
<frame::XStatusListener
> > StatusListenerContainer
;
224 StatusListenerContainer maStatusListenerContainer
;
225 bool mbIsListeningToWindowManager
;
228 const OUString
& rsURLPath
,
229 const ::rtl::Reference
<PresenterController
>& rpPresenterController
);
232 void ThrowIfDisposed() const throw (css::lang::DisposedException
);
235 //----- Service ---------------------------------------------------------------
237 OUString
PresenterProtocolHandler::getImplementationName_static()
239 return OUString("org.libreoffice.comp.PresenterScreenProtocolHandler");
242 Sequence
<OUString
> PresenterProtocolHandler::getSupportedServiceNames_static()
244 static const OUString
sServiceName("com.sun.star.frame.ProtocolHandler");
245 return Sequence
<OUString
>(&sServiceName
, 1);
248 Reference
<XInterface
> PresenterProtocolHandler::Create (
249 const Reference
<uno::XComponentContext
>& rxContext
)
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()
266 void SAL_CALL
PresenterProtocolHandler::disposing()
270 //----- XInitialize -----------------------------------------------------------
272 void SAL_CALL
PresenterProtocolHandler::initialize (const Sequence
<Any
>& aArguments
)
273 throw (Exception
, RuntimeException
, std::exception
)
276 if (aArguments
.getLength() > 0)
280 Reference
<frame::XFrame
> xFrame
;
281 if (aArguments
[0] >>= xFrame
)
283 mpPresenterController
= PresenterController::Instance(xFrame
);
286 catch (RuntimeException
&)
293 OUString
PresenterProtocolHandler::getImplementationName()
294 throw (css::uno::RuntimeException
, std::exception
)
296 return getImplementationName_static();
299 sal_Bool
PresenterProtocolHandler::supportsService(OUString
const & ServiceName
)
300 throw (css::uno::RuntimeException
, std::exception
)
302 return cppu::supportsService(this, ServiceName
);
305 css::uno::Sequence
<OUString
>
306 PresenterProtocolHandler::getSupportedServiceNames()
307 throw (css::uno::RuntimeException
, std::exception
)
309 return getSupportedServiceNames_static();
312 //----- XDispatchProvider -----------------------------------------------------
314 Reference
<frame::XDispatch
> SAL_CALL
PresenterProtocolHandler::queryDispatch (
315 const css::util::URL
& rURL
,
316 const OUString
& rsTargetFrameName
,
317 sal_Int32 nSearchFlags
)
318 throw(RuntimeException
, std::exception
)
320 (void)rsTargetFrameName
;
324 Reference
<frame::XDispatch
> xDispatch
;
326 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:")
328 xDispatch
.set(Dispatch::Create(rURL
.Path
, mpPresenterController
));
334 Sequence
<Reference
<frame::XDispatch
> > SAL_CALL
PresenterProtocolHandler::queryDispatches(
335 const Sequence
<frame::DispatchDescriptor
>& rDescriptors
)
336 throw(RuntimeException
, std::exception
)
340 return Sequence
<Reference
<frame::XDispatch
> >();
345 void PresenterProtocolHandler::ThrowIfDisposed() const
346 throw (::com::sun::star::lang::DisposedException
)
348 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
350 throw lang::DisposedException (
352 "PresenterProtocolHandler object has already been disposed"),
353 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
357 //===== PresenterProtocolHandler::Dispatch ====================================
359 Reference
<frame::XDispatch
> PresenterProtocolHandler::Dispatch::Create (
360 const OUString
& rsURLPath
,
361 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
363 ::rtl::Reference
<Dispatch
> pDispatch (new Dispatch (rsURLPath
, rpPresenterController
));
364 if (pDispatch
->mpCommand
.get() != NULL
)
365 return Reference
<frame::XDispatch
>(pDispatch
.get());
370 PresenterProtocolHandler::Dispatch::Dispatch (
371 const OUString
& rsURLPath
,
372 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
373 : PresenterDispatchInterfaceBase(m_aMutex
),
374 msURLPath(rsURLPath
),
375 mpCommand(CreateCommand(rsURLPath
, rpPresenterController
)),
376 mpPresenterController(rpPresenterController
),
377 maStatusListenerContainer(),
378 mbIsListeningToWindowManager(false)
380 if (mpCommand
.get() != NULL
)
382 mpPresenterController
->GetWindowManager()->AddLayoutListener(this);
383 mbIsListeningToWindowManager
= true;
387 Command
* PresenterProtocolHandler::Dispatch::CreateCommand (
388 const OUString
& rsURLPath
,
389 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
391 if (rsURLPath
.getLength() <= 5)
394 if (rsURLPath
== "CloseNotes")
395 return new SetNotesViewCommand(false, rpPresenterController
);
396 if (rsURLPath
== "CloseSlideSorter")
397 return new SetSlideSorterCommand(false, rpPresenterController
);
398 if (rsURLPath
== "CloseHelp")
399 return new SetHelpViewCommand(false, rpPresenterController
);
400 if (rsURLPath
== "GrowNotesFont")
401 return new NotesFontSizeCommand(rpPresenterController
, +1);
402 if (rsURLPath
== "NextEffect")
403 return new GotoNextEffectCommand(rpPresenterController
);
404 if (rsURLPath
== "NextSlide")
405 return new GotoNextSlideCommand(rpPresenterController
);
406 if (rsURLPath
== "PrevSlide")
407 return new GotoPreviousSlideCommand(rpPresenterController
);
408 if (rsURLPath
== "SwitchMonitor")
409 return new SwitchMonitorCommand(rpPresenterController
);
410 if (rsURLPath
== "ShowNotes")
411 return new SetNotesViewCommand(true, rpPresenterController
);
412 if (rsURLPath
== "ShowSlideSorter")
413 return new SetSlideSorterCommand(true, rpPresenterController
);
414 if (rsURLPath
== "ShowHelp")
415 return new SetHelpViewCommand(true, rpPresenterController
);
416 if (rsURLPath
== "ShrinkNotesFont")
417 return new NotesFontSizeCommand(rpPresenterController
, -1);
422 PresenterProtocolHandler::Dispatch::~Dispatch()
426 void PresenterProtocolHandler::Dispatch::disposing()
428 if (mbIsListeningToWindowManager
)
430 if (mpPresenterController
.get() != NULL
)
431 mpPresenterController
->GetWindowManager()->RemoveLayoutListener(this);
432 mbIsListeningToWindowManager
= false;
439 //----- XDispatch -------------------------------------------------------------
441 void SAL_CALL
PresenterProtocolHandler::Dispatch::dispatch(
442 const css::util::URL
& rURL
,
443 const css::uno::Sequence
<css::beans::PropertyValue
>& rArguments
)
444 throw(css::uno::RuntimeException
, std::exception
)
449 if (rURL
.Protocol
== "vnd.org.libreoffice.presenterscreen:"
450 && rURL
.Path
== msURLPath
)
452 if (mpCommand
.get() != NULL
)
453 mpCommand
->Execute();
457 // We can not throw an IllegalArgumentException
458 throw RuntimeException();
462 void SAL_CALL
PresenterProtocolHandler::Dispatch::addStatusListener(
463 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
464 const css::util::URL
& rURL
)
465 throw(css::uno::RuntimeException
, std::exception
)
467 if (rURL
.Path
== msURLPath
)
469 maStatusListenerContainer
.push_back(rxListener
);
471 frame::FeatureStateEvent aEvent
;
472 aEvent
.FeatureURL
= rURL
;
473 aEvent
.IsEnabled
= mpCommand
->IsEnabled();
474 aEvent
.Requery
= sal_False
;
475 aEvent
.State
= mpCommand
->GetState();
476 rxListener
->statusChanged(aEvent
);
479 throw RuntimeException();
482 void SAL_CALL
PresenterProtocolHandler::Dispatch::removeStatusListener (
483 const css::uno::Reference
<css::frame::XStatusListener
>& rxListener
,
484 const css::util::URL
& rURL
)
485 throw(css::uno::RuntimeException
, std::exception
)
487 if (rURL
.Path
== msURLPath
)
489 StatusListenerContainer::iterator
iListener (
491 maStatusListenerContainer
.begin(),
492 maStatusListenerContainer
.end(),
494 if (iListener
!= maStatusListenerContainer
.end())
495 maStatusListenerContainer
.erase(iListener
);
498 throw RuntimeException();
501 void PresenterProtocolHandler::Dispatch::ThrowIfDisposed() const
502 throw (::com::sun::star::lang::DisposedException
)
504 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
506 throw lang::DisposedException (
508 "PresenterProtocolHandler::Dispatch object has already been disposed"),
509 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
513 //----- document::XEventListener ----------------------------------------------
515 void SAL_CALL
PresenterProtocolHandler::Dispatch::notifyEvent (
516 const css::document::EventObject
& rEvent
)
517 throw(css::uno::RuntimeException
, std::exception
)
521 mpCommand
->GetState();
524 //----- lang::XEventListener --------------------------------------------------
526 void SAL_CALL
PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject
& rEvent
)
527 throw(css::uno::RuntimeException
, std::exception
)
530 mbIsListeningToWindowManager
= false;
533 //===== GotoPreviousSlideCommand ==============================================
535 GotoPreviousSlideCommand::GotoPreviousSlideCommand (
536 const rtl::Reference
<PresenterController
>& rpPresenterController
)
537 : mpPresenterController(rpPresenterController
)
541 void GotoPreviousSlideCommand::Execute()
543 if ( ! mpPresenterController
.is())
546 if ( ! mpPresenterController
->GetSlideShowController().is())
549 mpPresenterController
->GetSlideShowController()->gotoPreviousSlide();
552 bool GotoPreviousSlideCommand::IsEnabled() const
554 if ( ! mpPresenterController
.is())
557 if ( ! mpPresenterController
->GetSlideShowController().is())
560 return mpPresenterController
->GetSlideShowController()->getCurrentSlideIndex()>0;
563 //===== GotoNextEffect ========================================================
565 GotoNextEffectCommand::GotoNextEffectCommand (
566 const rtl::Reference
<PresenterController
>& rpPresenterController
)
567 : mpPresenterController(rpPresenterController
)
571 void GotoNextEffectCommand::Execute()
573 if ( ! mpPresenterController
.is())
576 if ( ! mpPresenterController
->GetSlideShowController().is())
579 mpPresenterController
->GetSlideShowController()->gotoNextEffect();
582 //===== GotoNextSlide =========================================================
584 GotoNextSlideCommand::GotoNextSlideCommand (
585 const rtl::Reference
<PresenterController
>& rpPresenterController
)
586 : mpPresenterController(rpPresenterController
)
590 void GotoNextSlideCommand::Execute()
592 if ( ! mpPresenterController
.is())
595 if ( ! mpPresenterController
->GetSlideShowController().is())
598 mpPresenterController
->GetSlideShowController()->gotoNextSlide();
601 //===== SwitchMonitorCommand ==============================================
603 SwitchMonitorCommand::SwitchMonitorCommand (
604 const rtl::Reference
<PresenterController
>& rpPresenterController
)
605 : mpPresenterController(rpPresenterController
)
609 void SwitchMonitorCommand::Execute()
611 mpPresenterController
->SwitchMonitors();
614 //===== SetNotesViewCommand ===================================================
616 SetNotesViewCommand::SetNotesViewCommand (
618 const rtl::Reference
<PresenterController
>& rpPresenterController
)
620 mpPresenterController(rpPresenterController
)
624 void SetNotesViewCommand::Execute()
626 if ( ! mpPresenterController
.is())
629 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
630 mpPresenterController
->GetWindowManager());
631 if ( ! pWindowManager
.is())
635 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Notes
);
637 pWindowManager
->SetViewMode(PresenterWindowManager::VM_Standard
);
640 Any
SetNotesViewCommand::GetState() const
642 if ( ! mpPresenterController
.is())
645 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
646 mpPresenterController
->GetWindowManager());
647 if ( ! pWindowManager
.is())
650 return Any(IsActive(pWindowManager
));
653 bool SetNotesViewCommand::IsActive (
654 const ::rtl::Reference
<PresenterWindowManager
>& rpWindowManager
)
656 return rpWindowManager
->GetViewMode() == PresenterWindowManager::VM_Notes
;
659 //===== SetSlideSorterCommand =================================================
661 SetSlideSorterCommand::SetSlideSorterCommand (
663 const rtl::Reference
<PresenterController
>& rpPresenterController
)
665 mpPresenterController(rpPresenterController
)
669 void SetSlideSorterCommand::Execute()
671 if ( ! mpPresenterController
.is())
674 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
675 mpPresenterController
->GetWindowManager());
676 if ( ! pWindowManager
.is())
679 pWindowManager
->SetSlideSorterState(mbOn
);
682 Any
SetSlideSorterCommand::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_SlideOverview
);
695 //===== SetHelpViewCommand ===================================================
697 SetHelpViewCommand::SetHelpViewCommand (
699 const rtl::Reference
<PresenterController
>& rpPresenterController
)
701 mpPresenterController(rpPresenterController
)
705 void SetHelpViewCommand::Execute()
707 if ( ! mpPresenterController
.is())
710 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
711 mpPresenterController
->GetWindowManager());
712 if ( ! pWindowManager
.is())
715 pWindowManager
->SetHelpViewState(mbOn
);
718 Any
SetHelpViewCommand::GetState() const
720 if ( ! mpPresenterController
.is())
723 ::rtl::Reference
<PresenterWindowManager
> pWindowManager (
724 mpPresenterController
->GetWindowManager());
725 if ( ! pWindowManager
.is())
728 return Any(pWindowManager
->GetViewMode()==PresenterWindowManager::VM_Help
);
731 //===== NotesFontSizeCommand ==================================================
733 NotesFontSizeCommand::NotesFontSizeCommand(
734 const rtl::Reference
<PresenterController
>& rpPresenterController
,
735 const sal_Int32 nSizeChange
)
736 : mpPresenterController(rpPresenterController
),
737 mnSizeChange(nSizeChange
)
741 ::rtl::Reference
<PresenterNotesView
> NotesFontSizeCommand::GetNotesView() const
743 if (mpPresenterController
.get() == NULL
)
746 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
747 mpPresenterController
->GetPaneContainer()->FindViewURL(
748 PresenterViewFactory::msNotesViewURL
));
749 if (pDescriptor
.get() == NULL
)
752 return dynamic_cast<PresenterNotesView
*>(pDescriptor
->mxView
.get());
755 void NotesFontSizeCommand::Execute()
757 ::rtl::Reference
<PresenterNotesView
> pView (GetNotesView());
759 pView
->ChangeFontSize(mnSizeChange
);
762 Any
NotesFontSizeCommand::GetState() const
767 } } // end of namespace ::sdext::presenter
769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */