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 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include "SlideShowRestarter.hxx"
27 #include "framework/ConfigurationController.hxx"
28 #include "framework/FrameworkHelper.hxx"
29 #include <comphelper/processfactory.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <svx/svxids.hrc>
33 #include <vcl/svapp.hxx>
34 #include <boost/bind.hpp>
35 
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::lang;
38 using ::rtl::OUString;
39 using ::sd::framework::FrameworkHelper;
40 
41 #define C2U(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
42 
43 namespace sd {
44 
SlideShowRestarter(const::rtl::Reference<SlideShow> & rpSlideShow,ViewShellBase * pViewShellBase)45 SlideShowRestarter::SlideShowRestarter (
46     const ::rtl::Reference<SlideShow>& rpSlideShow,
47     ViewShellBase* pViewShellBase)
48     : mnEventId(0),
49       mpSlideShow(rpSlideShow),
50       mpViewShellBase(pViewShellBase),
51       mnDisplayCount(GetDisplayCount()),
52       mpDispatcher(pViewShellBase->GetViewFrame()->GetDispatcher()),
53       mnCurrentSlideNumber(0)
54 {
55 }
56 
57 
58 
59 
~SlideShowRestarter(void)60 SlideShowRestarter::~SlideShowRestarter (void)
61 {
62 }
63 
64 
65 
66 
Restart(void)67 void SlideShowRestarter::Restart (void)
68 {
69     // Prevent multiple and concurrently restarts.
70     if (mnEventId != 0)
71         return;
72 
73     // Remember the current slide in order to restore it after the slide
74     // show has been restarted.
75     if (mpSlideShow.is())
76         mnCurrentSlideNumber = mpSlideShow->getCurrentPageNumber();
77 
78     // Remember a shared pointer to this object to prevent its destruction
79     // before the whole restarting process has finished.
80     mpSelf = shared_from_this();
81 
82     // We do not know in what situation this method was called.  So, in
83     // order to be able to cleanly stop the presentation, we do that
84     // asynchronously.
85     mnEventId = Application::PostUserEvent(
86         LINK(this, SlideShowRestarter, EndPresentation));
87 }
88 
89 
90 
91 
GetDisplayCount(void)92 sal_Int32 SlideShowRestarter::GetDisplayCount (void)
93 {
94     const Reference<XComponentContext> xContext (
95         ::comphelper::getProcessComponentContext() );
96     Reference<XMultiComponentFactory> xFactory (
97         xContext->getServiceManager(), UNO_QUERY);
98     if ( ! xFactory.is())
99         return 0;
100 
101     Reference<com::sun::star::container::XIndexAccess> xIndexAccess (
102         xFactory->createInstanceWithContext(C2U("com.sun.star.awt.DisplayAccess"),xContext),
103         UNO_QUERY);
104     if ( ! xIndexAccess.is())
105         return 0;
106 
107     return xIndexAccess->getCount();
108 }
109 
110 
111 
112 
IMPL_LINK(SlideShowRestarter,EndPresentation,void *,EMPTYARG)113 IMPL_LINK(SlideShowRestarter, EndPresentation, void*, EMPTYARG)
114 {
115     mnEventId = 0;
116     if (mpSlideShow.is())
117     {
118         if (mnDisplayCount!=GetDisplayCount())
119         {
120             mpSlideShow->end();
121 
122             // The following piece of code should not be here because the
123             // slide show should be aware of the existence of the presenter
124             // console (which is displayed in the FullScreenPane).  But the
125             // timing has to be right and I did not find a better place for
126             // it.
127 
128             // Wait for the full screen pane, which displays the presenter
129             // console, to disappear.  Only when it is gone, call
130             // InitiatePresenterStart(), in order to begin the asynchronous
131             // restart of the slide show.
132             if (mpViewShellBase != NULL)
133             {
134                 ::boost::shared_ptr<FrameworkHelper> pHelper(
135                     FrameworkHelper::Instance(*mpViewShellBase));
136                 if (pHelper->GetConfigurationController()->getResource(
137                     pHelper->CreateResourceId(FrameworkHelper::msFullScreenPaneURL)).is())
138                 {
139                     ::sd::framework::ConfigurationController::Lock aLock (
140                         pHelper->GetConfigurationController());
141 
142                     pHelper->RunOnConfigurationEvent(
143                         FrameworkHelper::msConfigurationUpdateEndEvent,
144                         ::boost::bind(&SlideShowRestarter::StartPresentation, shared_from_this()));
145                     pHelper->UpdateConfiguration();
146                 }
147                 else
148                 {
149                     StartPresentation();
150                 }
151             }
152         }
153     }
154     return 0;
155 }
156 
157 
158 
159 
StartPresentation(void)160 void SlideShowRestarter::StartPresentation (void)
161 {
162     if (mpDispatcher == NULL && mpViewShellBase!=NULL)
163         mpDispatcher = mpViewShellBase->GetViewFrame()->GetDispatcher();
164 
165     // Start the slide show on the saved current slide.
166     if (mpDispatcher != NULL)
167     {
168         mpDispatcher->Execute(SID_PRESENTATION, SFX_CALLMODE_ASYNCHRON);
169         if (mpSlideShow.is())
170         {
171             Sequence<css::beans::PropertyValue> aProperties (1);
172             aProperties[0].Name = C2U("FirstPage");
173             aProperties[0].Value <<= C2U("page") + OUString::valueOf(mnCurrentSlideNumber+1);
174             mpSlideShow->startWithArguments(aProperties);
175         }
176         mpSelf.reset();
177     }
178 }
179 
180 } // end of namespace sd
181