1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 #include "precompiled_sd.hxx"
23
24 #include "SlideShowRestarter.hxx"
25 #include "framework/ConfigurationController.hxx"
26 #include "framework/FrameworkHelper.hxx"
27 #include <comphelper/processfactory.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <svx/svxids.hrc>
31 #include <vcl/svapp.hxx>
32 #include <boost/bind.hpp>
33
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::lang;
36 using ::rtl::OUString;
37 using ::sd::framework::FrameworkHelper;
38
39 #define C2U(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
40
41 namespace sd {
42
SlideShowRestarter(const::rtl::Reference<SlideShow> & rpSlideShow,ViewShellBase * pViewShellBase)43 SlideShowRestarter::SlideShowRestarter (
44 const ::rtl::Reference<SlideShow>& rpSlideShow,
45 ViewShellBase* pViewShellBase)
46 : mnEventId(0),
47 mpSlideShow(rpSlideShow),
48 mpViewShellBase(pViewShellBase),
49 mnDisplayCount(GetDisplayCount()),
50 mpDispatcher(pViewShellBase->GetViewFrame()->GetDispatcher()),
51 mnCurrentSlideNumber(0)
52 {
53 }
54
~SlideShowRestarter(void)55 SlideShowRestarter::~SlideShowRestarter (void)
56 {
57 }
58
Restart(void)59 void SlideShowRestarter::Restart (void)
60 {
61 // Prevent multiple and concurrently restarts.
62 if (mnEventId != 0)
63 return;
64
65 // Remember the current slide in order to restore it after the slide
66 // show has been restarted.
67 if (mpSlideShow.is())
68 mnCurrentSlideNumber = mpSlideShow->getCurrentPageNumber();
69
70 // Remember a shared pointer to this object to prevent its destruction
71 // before the whole restarting process has finished.
72 mpSelf = shared_from_this();
73
74 // We do not know in what situation this method was called. So, in
75 // order to be able to cleanly stop the presentation, we do that
76 // asynchronously.
77 mnEventId = Application::PostUserEvent(
78 LINK(this, SlideShowRestarter, EndPresentation));
79 }
80
GetDisplayCount(void)81 sal_Int32 SlideShowRestarter::GetDisplayCount (void)
82 {
83 const Reference<XComponentContext> xContext (
84 ::comphelper::getProcessComponentContext() );
85 Reference<XMultiComponentFactory> xFactory (
86 xContext->getServiceManager(), UNO_QUERY);
87 if ( ! xFactory.is())
88 return 0;
89
90 Reference<com::sun::star::container::XIndexAccess> xIndexAccess (
91 xFactory->createInstanceWithContext(C2U("com.sun.star.awt.DisplayAccess"),xContext),
92 UNO_QUERY);
93 if ( ! xIndexAccess.is())
94 return 0;
95
96 return xIndexAccess->getCount();
97 }
98
IMPL_LINK(SlideShowRestarter,EndPresentation,void *,EMPTYARG)99 IMPL_LINK(SlideShowRestarter, EndPresentation, void*, EMPTYARG)
100 {
101 mnEventId = 0;
102 if (mpSlideShow.is())
103 {
104 if (mnDisplayCount!=GetDisplayCount())
105 {
106 mpSlideShow->end();
107
108 // The following piece of code should not be here because the
109 // slide show should be aware of the existence of the presenter
110 // console (which is displayed in the FullScreenPane). But the
111 // timing has to be right and I did not find a better place for
112 // it.
113
114 // Wait for the full screen pane, which displays the presenter
115 // console, to disappear. Only when it is gone, call
116 // InitiatePresenterStart(), in order to begin the asynchronous
117 // restart of the slide show.
118 if (mpViewShellBase != NULL)
119 {
120 ::boost::shared_ptr<FrameworkHelper> pHelper(
121 FrameworkHelper::Instance(*mpViewShellBase));
122 if (pHelper->GetConfigurationController()->getResource(
123 pHelper->CreateResourceId(FrameworkHelper::msFullScreenPaneURL)).is())
124 {
125 ::sd::framework::ConfigurationController::Lock aLock (
126 pHelper->GetConfigurationController());
127
128 pHelper->RunOnConfigurationEvent(
129 FrameworkHelper::msConfigurationUpdateEndEvent,
130 ::boost::bind(&SlideShowRestarter::StartPresentation, shared_from_this()));
131 pHelper->UpdateConfiguration();
132 }
133 else
134 {
135 StartPresentation();
136 }
137 }
138 }
139 }
140 return 0;
141 }
142
StartPresentation(void)143 void SlideShowRestarter::StartPresentation (void)
144 {
145 if (mpDispatcher == NULL && mpViewShellBase!=NULL)
146 mpDispatcher = mpViewShellBase->GetViewFrame()->GetDispatcher();
147
148 // Start the slide show on the saved current slide.
149 if (mpDispatcher != NULL)
150 {
151 mpDispatcher->Execute(SID_PRESENTATION, SFX_CALLMODE_ASYNCHRON);
152 if (mpSlideShow.is())
153 {
154 Sequence<css::beans::PropertyValue> aProperties (1);
155 aProperties[0].Name = C2U("FirstPage");
156 aProperties[0].Value <<= C2U("page") + OUString::valueOf(mnCurrentSlideNumber+1);
157 mpSlideShow->startWithArguments(aProperties);
158 }
159 mpSelf.reset();
160 }
161 }
162
163 } // end of namespace sd
164
165 /* vim: set noet sw=4 ts=4: */
166