1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "precompiled_sd.hxx"
29 
30 #include "SlideShowRestarter.hxx"
31 #include "framework/ConfigurationController.hxx"
32 #include "framework/FrameworkHelper.hxx"
33 #include <comphelper/processfactory.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <svx/svxids.hrc>
37 #include <vcl/svapp.hxx>
38 #include <boost/bind.hpp>
39 
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::lang;
42 using ::rtl::OUString;
43 using ::sd::framework::FrameworkHelper;
44 
45 #define C2U(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
46 
47 namespace sd {
48 
49 SlideShowRestarter::SlideShowRestarter (
50     const ::rtl::Reference<SlideShow>& rpSlideShow,
51     ViewShellBase* pViewShellBase)
52     : mnEventId(0),
53       mpSlideShow(rpSlideShow),
54       mpViewShellBase(pViewShellBase),
55       mnDisplayCount(GetDisplayCount()),
56       mpDispatcher(pViewShellBase->GetViewFrame()->GetDispatcher()),
57       mnCurrentSlideNumber(0)
58 {
59 }
60 
61 
62 
63 
64 SlideShowRestarter::~SlideShowRestarter (void)
65 {
66 }
67 
68 
69 
70 
71 void SlideShowRestarter::Restart (void)
72 {
73     // Prevent multiple and concurrently restarts.
74     if (mnEventId != 0)
75         return;
76 
77     // Remember the current slide in order to restore it after the slide
78     // show has been restarted.
79     if (mpSlideShow.is())
80         mnCurrentSlideNumber = mpSlideShow->getCurrentPageNumber();
81 
82     // Remember a shared pointer to this object to prevent its destruction
83     // before the whole restarting process has finished.
84     mpSelf = shared_from_this();
85 
86     // We do not know in what situation this method was called.  So, in
87     // order to be able to cleanly stop the presentation, we do that
88     // asynchronously.
89     mnEventId = Application::PostUserEvent(
90         LINK(this, SlideShowRestarter, EndPresentation));
91 }
92 
93 
94 
95 
96 sal_Int32 SlideShowRestarter::GetDisplayCount (void)
97 {
98     const Reference<XComponentContext> xContext (
99         ::comphelper::getProcessComponentContext() );
100     Reference<XMultiComponentFactory> xFactory (
101         xContext->getServiceManager(), UNO_QUERY);
102     if ( ! xFactory.is())
103         return 0;
104 
105     Reference<com::sun::star::container::XIndexAccess> xIndexAccess (
106         xFactory->createInstanceWithContext(C2U("com.sun.star.awt.DisplayAccess"),xContext),
107         UNO_QUERY);
108     if ( ! xIndexAccess.is())
109         return 0;
110 
111     return xIndexAccess->getCount();
112 }
113 
114 
115 
116 
117 IMPL_LINK(SlideShowRestarter, EndPresentation, void*, EMPTYARG)
118 {
119     mnEventId = 0;
120     if (mpSlideShow.is())
121     {
122         if (mnDisplayCount!=GetDisplayCount())
123         {
124             mpSlideShow->end();
125 
126             // The following piece of code should not be here because the
127             // slide show should be aware of the existence of the presenter
128             // console (which is displayed in the FullScreenPane).  But the
129             // timing has to be right and I did not find a better place for
130             // it.
131 
132             // Wait for the full screen pane, which displays the presenter
133             // console, to disappear.  Only when it is gone, call
134             // InitiatePresenterStart(), in order to begin the asynchronous
135             // restart of the slide show.
136             if (mpViewShellBase != NULL)
137             {
138                 ::boost::shared_ptr<FrameworkHelper> pHelper(
139                     FrameworkHelper::Instance(*mpViewShellBase));
140                 if (pHelper->GetConfigurationController()->getResource(
141                     pHelper->CreateResourceId(FrameworkHelper::msFullScreenPaneURL)).is())
142                 {
143                     ::sd::framework::ConfigurationController::Lock aLock (
144                         pHelper->GetConfigurationController());
145 
146                     pHelper->RunOnConfigurationEvent(
147                         FrameworkHelper::msConfigurationUpdateEndEvent,
148                         ::boost::bind(&SlideShowRestarter::StartPresentation, shared_from_this()));
149                     pHelper->UpdateConfiguration();
150                 }
151                 else
152                 {
153                     StartPresentation();
154                 }
155             }
156         }
157     }
158     return 0;
159 }
160 
161 
162 
163 
164 void SlideShowRestarter::StartPresentation (void)
165 {
166     if (mpDispatcher == NULL && mpViewShellBase!=NULL)
167         mpDispatcher = mpViewShellBase->GetViewFrame()->GetDispatcher();
168 
169     // Start the slide show on the saved current slide.
170     if (mpDispatcher != NULL)
171     {
172         mpDispatcher->Execute(SID_PRESENTATION, SFX_CALLMODE_ASYNCHRON);
173         if (mpSlideShow.is())
174         {
175             Sequence<css::beans::PropertyValue> aProperties (1);
176             aProperties[0].Name = C2U("FirstPage");
177             aProperties[0].Value <<= C2U("page") + OUString::valueOf(mnCurrentSlideNumber+1);
178             mpSlideShow->startWithArguments(aProperties);
179         }
180         mpSelf.reset();
181     }
182 }
183 
184 } // end of namespace sd
185