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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26 
27 #include "PresenterPaneFactory.hxx"
28 #include "PresenterController.hxx"
29 #include "PresenterPane.hxx"
30 #include "PresenterPaneBorderPainter.hxx"
31 #include "PresenterPaneContainer.hxx"
32 #include "PresenterSpritePane.hxx"
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/drawing/framework/ResourceId.hpp>
35 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
36 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
37 #include <com/sun/star/frame/XController.hpp>
38 #include <com/sun/star/lang/XComponent.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <boost/bind.hpp>
41 
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::drawing::framework;
46 using ::rtl::OUString;
47 
48 namespace sdext { namespace presenter {
49 
50 const ::rtl::OUString PresenterPaneFactory::msCurrentSlidePreviewPaneURL(
51     OUString::createFromAscii("private:resource/pane/Presenter/Pane1"));
52 const ::rtl::OUString PresenterPaneFactory::msNextSlidePreviewPaneURL(
53     OUString::createFromAscii("private:resource/pane/Presenter/Pane2"));
54 const ::rtl::OUString PresenterPaneFactory::msNotesPaneURL(
55     OUString::createFromAscii("private:resource/pane/Presenter/Pane3"));
56 const ::rtl::OUString PresenterPaneFactory::msToolBarPaneURL(
57     OUString::createFromAscii("private:resource/pane/Presenter/Pane4"));
58 const ::rtl::OUString PresenterPaneFactory::msSlideSorterPaneURL(
59     OUString::createFromAscii("private:resource/pane/Presenter/Pane5"));
60 const ::rtl::OUString PresenterPaneFactory::msHelpPaneURL(
61     OUString::createFromAscii("private:resource/pane/Presenter/Pane6"));
62 
63 const ::rtl::OUString PresenterPaneFactory::msOverlayPaneURL(
64     OUString::createFromAscii("private:resource/pane/Presenter/Overlay"));
65 
66 
67 
68 //===== PresenterPaneFactory ==================================================
69 
Create(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)70 Reference<drawing::framework::XResourceFactory> PresenterPaneFactory::Create (
71     const Reference<uno::XComponentContext>& rxContext,
72     const Reference<frame::XController>& rxController,
73     const ::rtl::Reference<PresenterController>& rpPresenterController)
74 {
75     rtl::Reference<PresenterPaneFactory> pFactory (
76         new PresenterPaneFactory(rxContext,rpPresenterController));
77     pFactory->Register(rxController);
78     return Reference<drawing::framework::XResourceFactory>(
79         static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
80 }
81 
82 
83 
84 
PresenterPaneFactory(const Reference<uno::XComponentContext> & rxContext,const::rtl::Reference<PresenterController> & rpPresenterController)85 PresenterPaneFactory::PresenterPaneFactory (
86     const Reference<uno::XComponentContext>& rxContext,
87     const ::rtl::Reference<PresenterController>& rpPresenterController)
88     : PresenterPaneFactoryInterfaceBase(m_aMutex),
89       mxComponentContextWeak(rxContext),
90       mxConfigurationControllerWeak(),
91       mpPresenterController(rpPresenterController),
92       mpResourceCache()
93 {
94 }
95 
96 
97 
98 
Register(const Reference<frame::XController> & rxController)99 void PresenterPaneFactory::Register (const Reference<frame::XController>& rxController)
100 {
101     Reference<XConfigurationController> xCC;
102     try
103     {
104         // Get the configuration controller.
105         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
106         xCC = Reference<XConfigurationController>(xCM->getConfigurationController());
107         mxConfigurationControllerWeak = xCC;
108         if ( ! xCC.is())
109         {
110             throw RuntimeException();
111         }
112         else
113         {
114             xCC->addResourceFactory(
115                 OUString::createFromAscii("private:resource/pane/Presenter/*"),
116                 this);
117         }
118     }
119     catch (RuntimeException&)
120     {
121         OSL_ASSERT(false);
122         if (xCC.is())
123             xCC->removeResourceFactoryForReference(this);
124         mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
125 
126         throw;
127     }
128 }
129 
130 
131 
132 
~PresenterPaneFactory(void)133 PresenterPaneFactory::~PresenterPaneFactory (void)
134 {
135 }
136 
137 
138 
139 
disposing(void)140 void SAL_CALL PresenterPaneFactory::disposing (void)
141     throw (RuntimeException)
142 {
143     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
144     if (xCC.is())
145         xCC->removeResourceFactoryForReference(this);
146     mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
147 
148     // Dispose the panes in the cache.
149     if (mpResourceCache.get() != NULL)
150     {
151         ResourceContainer::const_iterator iPane (mpResourceCache->begin());
152         ResourceContainer::const_iterator iEnd (mpResourceCache->end());
153         for ( ; iPane!=iEnd; ++iPane)
154         {
155             Reference<lang::XComponent> xPaneComponent (iPane->second, UNO_QUERY);
156             if (xPaneComponent.is())
157                 xPaneComponent->dispose();
158         }
159         mpResourceCache.reset();
160     }
161 }
162 
163 
164 
165 
166 //----- XPaneFactory ----------------------------------------------------------
167 
createResource(const Reference<XResourceId> & rxPaneId)168 Reference<XResource> SAL_CALL PresenterPaneFactory::createResource (
169     const Reference<XResourceId>& rxPaneId)
170     throw (RuntimeException, IllegalArgumentException, WrappedTargetException)
171 {
172     ThrowIfDisposed();
173 
174     if ( ! rxPaneId.is())
175         return NULL;
176 
177     const OUString sPaneURL (rxPaneId->getResourceURL());
178     if (sPaneURL.getLength() == 0)
179         return NULL;
180 
181     if (mpResourceCache.get() != NULL)
182     {
183         // Has the requested resource already been created?
184         ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL));
185         if (iResource != mpResourceCache->end())
186         {
187             // Yes.  Mark it as active.
188             rtl::Reference<PresenterPaneContainer> pPaneContainer(
189                 mpPresenterController->GetPaneContainer());
190             PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
191                 pPaneContainer->FindPaneURL(sPaneURL));
192             if (pDescriptor.get() != NULL)
193             {
194                 pDescriptor->SetActivationState(true);
195                 if (pDescriptor->mxBorderWindow.is())
196                     pDescriptor->mxBorderWindow->setVisible(sal_True);
197                 pPaneContainer->StorePane(pDescriptor->mxPane);
198             }
199 
200             return iResource->second;
201         }
202     }
203 
204     // No.  Create a new one.
205     Reference<XResource> xResource = CreatePane(rxPaneId, OUString());
206     return xResource;
207 }
208 
209 
210 
211 
releaseResource(const Reference<XResource> & rxResource)212 void SAL_CALL PresenterPaneFactory::releaseResource (const Reference<XResource>& rxResource)
213     throw (RuntimeException)
214 {
215     ThrowIfDisposed();
216 
217     if ( ! rxResource.is())
218         throw lang::IllegalArgumentException();
219 
220     // Mark the pane as inactive.
221     rtl::Reference<PresenterPaneContainer> pPaneContainer(
222         mpPresenterController->GetPaneContainer());
223     const OUString sPaneURL (rxResource->getResourceId()->getResourceURL());
224     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
225         pPaneContainer->FindPaneURL(sPaneURL));
226     if (pDescriptor.get() != NULL)
227     {
228         pDescriptor->SetActivationState(false);
229         if (pDescriptor->mxBorderWindow.is())
230             pDescriptor->mxBorderWindow->setVisible(sal_False);
231 
232         if (mpResourceCache.get() != NULL)
233         {
234             // Store the pane in the cache.
235             (*mpResourceCache)[sPaneURL] = rxResource;
236         }
237         else
238         {
239             // Dispose the pane.
240             Reference<lang::XComponent> xPaneComponent (rxResource, UNO_QUERY);
241             if (xPaneComponent.is())
242                 xPaneComponent->dispose();
243         }
244     }
245 }
246 
247 
248 
249 
250 //-----------------------------------------------------------------------------
251 
CreatePane(const Reference<XResourceId> & rxPaneId,const OUString & rsTitle)252 Reference<XResource> PresenterPaneFactory::CreatePane (
253     const Reference<XResourceId>& rxPaneId,
254     const OUString& rsTitle)
255 {
256     if ( ! rxPaneId.is())
257         return NULL;
258 
259     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
260     if ( ! xCC.is())
261         return NULL;
262 
263     Reference<XComponentContext> xContext (mxComponentContextWeak);
264     if ( ! xContext.is())
265         return NULL;
266 
267     Reference<XPane> xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY);
268     if ( ! xParentPane.is())
269         return NULL;
270 
271     try
272     {
273         return CreatePane(
274             rxPaneId,
275             rsTitle,
276             xParentPane,
277             rxPaneId->getFullResourceURL().Arguments.compareToAscii("Sprite=1") == 0);
278     }
279     catch (Exception&)
280     {
281         OSL_ASSERT(false);
282     }
283 
284     return NULL;
285 }
286 
287 
288 
289 
CreatePane(const Reference<XResourceId> & rxPaneId,const OUString & rsTitle,const Reference<drawing::framework::XPane> & rxParentPane,const bool bIsSpritePane)290 Reference<XResource> PresenterPaneFactory::CreatePane (
291     const Reference<XResourceId>& rxPaneId,
292     const OUString& rsTitle,
293     const Reference<drawing::framework::XPane>& rxParentPane,
294     const bool bIsSpritePane)
295 {
296     Reference<XComponentContext> xContext (mxComponentContextWeak);
297     Reference<lang::XMultiComponentFactory> xFactory (
298         xContext->getServiceManager(), UNO_QUERY_THROW);
299 
300     // Create a border window and canvas and store it in the pane
301     // container.
302 
303     // Create the pane.
304     ::rtl::Reference<PresenterPaneBase> xPane;
305     if (bIsSpritePane)
306     {
307         xPane = ::rtl::Reference<PresenterPaneBase>(
308             new PresenterSpritePane(xContext, mpPresenterController));
309     }
310     else
311     {
312         xPane = ::rtl::Reference<PresenterPaneBase>(
313             new PresenterPane(xContext, mpPresenterController));
314     }
315 
316     // Supply arguments.
317     Sequence<Any> aArguments (6);
318     aArguments[0] <<= rxPaneId;
319     aArguments[1] <<= rxParentPane->getWindow();
320     aArguments[2] <<= rxParentPane->getCanvas();
321     aArguments[3] <<= rsTitle;
322     aArguments[4] <<= Reference<drawing::framework::XPaneBorderPainter>(
323         static_cast<XWeak*>(mpPresenterController->GetPaneBorderPainter().get()),
324         UNO_QUERY);
325     aArguments[5] <<= bIsSpritePane ? false : true;
326     xPane->initialize(aArguments);
327 
328     // Store pane and canvases and windows in container.
329     ::rtl::Reference<PresenterPaneContainer> pContainer (
330         mpPresenterController->GetPaneContainer());
331     PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
332         pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow()));
333     pContainer->StorePane(xPane);
334     if (pDescriptor.get() != NULL)
335     {
336         if (bIsSpritePane)
337         {
338             pDescriptor->maSpriteProvider = ::boost::bind(
339                 &PresenterSpritePane::GetSprite,
340                 dynamic_cast<PresenterSpritePane*>(xPane.get()));
341             pDescriptor->mbIsSprite = true;
342             pDescriptor->mbNeedsClipping = false;
343         }
344         else
345         {
346             pDescriptor->mbIsSprite = false;
347             pDescriptor->mbNeedsClipping = true;
348         }
349 
350         // Get the window of the frame and make that visible.
351         Reference<awt::XWindow> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY_THROW);
352         xWindow->setVisible(sal_True);
353     }
354 
355     return Reference<XResource>(static_cast<XWeak*>(xPane.get()), UNO_QUERY_THROW);
356 }
357 
358 
359 
360 
ThrowIfDisposed(void) const361 void PresenterPaneFactory::ThrowIfDisposed (void) const
362     throw (::com::sun::star::lang::DisposedException)
363 {
364 	if (rBHelper.bDisposed || rBHelper.bInDispose)
365 	{
366         throw lang::DisposedException (
367             OUString(RTL_CONSTASCII_USTRINGPARAM(
368                 "PresenterPaneFactory object has already been disposed")),
369             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
370     }
371 }
372 
373 
374 } } // end of namespace sdext::presenter
375