xref: /trunk/main/sdext/source/presenter/PresenterPaneFactory.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
142     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
143     if (xCC.is())
144         xCC->removeResourceFactoryForReference(this);
145     mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
146 
147     // Dispose the panes in the cache.
148     if (mpResourceCache.get() != NULL)
149     {
150         ResourceContainer::const_iterator iPane (mpResourceCache->begin());
151         ResourceContainer::const_iterator iEnd (mpResourceCache->end());
152         for ( ; iPane!=iEnd; ++iPane)
153         {
154             Reference<lang::XComponent> xPaneComponent (iPane->second, UNO_QUERY);
155             if (xPaneComponent.is())
156                 xPaneComponent->dispose();
157         }
158         mpResourceCache.reset();
159     }
160 }
161 
162 
163 
164 
165 //----- XPaneFactory ----------------------------------------------------------
166 
createResource(const Reference<XResourceId> & rxPaneId)167 Reference<XResource> SAL_CALL PresenterPaneFactory::createResource (
168     const Reference<XResourceId>& rxPaneId)
169 {
170     ThrowIfDisposed();
171 
172     if ( ! rxPaneId.is())
173         return NULL;
174 
175     const OUString sPaneURL (rxPaneId->getResourceURL());
176     if (sPaneURL.getLength() == 0)
177         return NULL;
178 
179     if (mpResourceCache.get() != NULL)
180     {
181         // Has the requested resource already been created?
182         ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL));
183         if (iResource != mpResourceCache->end())
184         {
185             // Yes.  Mark it as active.
186             rtl::Reference<PresenterPaneContainer> pPaneContainer(
187                 mpPresenterController->GetPaneContainer());
188             PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
189                 pPaneContainer->FindPaneURL(sPaneURL));
190             if (pDescriptor.get() != NULL)
191             {
192                 pDescriptor->SetActivationState(true);
193                 if (pDescriptor->mxBorderWindow.is())
194                     pDescriptor->mxBorderWindow->setVisible(sal_True);
195                 pPaneContainer->StorePane(pDescriptor->mxPane);
196             }
197 
198             return iResource->second;
199         }
200     }
201 
202     // No.  Create a new one.
203     Reference<XResource> xResource = CreatePane(rxPaneId, OUString());
204     return xResource;
205 }
206 
207 
208 
209 
releaseResource(const Reference<XResource> & rxResource)210 void SAL_CALL PresenterPaneFactory::releaseResource (const Reference<XResource>& rxResource)
211 {
212     ThrowIfDisposed();
213 
214     if ( ! rxResource.is())
215         throw lang::IllegalArgumentException();
216 
217     // Mark the pane as inactive.
218     rtl::Reference<PresenterPaneContainer> pPaneContainer(
219         mpPresenterController->GetPaneContainer());
220     const OUString sPaneURL (rxResource->getResourceId()->getResourceURL());
221     PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
222         pPaneContainer->FindPaneURL(sPaneURL));
223     if (pDescriptor.get() != NULL)
224     {
225         pDescriptor->SetActivationState(false);
226         if (pDescriptor->mxBorderWindow.is())
227             pDescriptor->mxBorderWindow->setVisible(sal_False);
228 
229         if (mpResourceCache.get() != NULL)
230         {
231             // Store the pane in the cache.
232             (*mpResourceCache)[sPaneURL] = rxResource;
233         }
234         else
235         {
236             // Dispose the pane.
237             Reference<lang::XComponent> xPaneComponent (rxResource, UNO_QUERY);
238             if (xPaneComponent.is())
239                 xPaneComponent->dispose();
240         }
241     }
242 }
243 
244 
245 
246 
247 //-----------------------------------------------------------------------------
248 
CreatePane(const Reference<XResourceId> & rxPaneId,const OUString & rsTitle)249 Reference<XResource> PresenterPaneFactory::CreatePane (
250     const Reference<XResourceId>& rxPaneId,
251     const OUString& rsTitle)
252 {
253     if ( ! rxPaneId.is())
254         return NULL;
255 
256     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
257     if ( ! xCC.is())
258         return NULL;
259 
260     Reference<XComponentContext> xContext (mxComponentContextWeak);
261     if ( ! xContext.is())
262         return NULL;
263 
264     Reference<XPane> xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY);
265     if ( ! xParentPane.is())
266         return NULL;
267 
268     try
269     {
270         return CreatePane(
271             rxPaneId,
272             rsTitle,
273             xParentPane,
274             rxPaneId->getFullResourceURL().Arguments.compareToAscii("Sprite=1") == 0);
275     }
276     catch (Exception&)
277     {
278         OSL_ASSERT(false);
279     }
280 
281     return NULL;
282 }
283 
284 
285 
286 
CreatePane(const Reference<XResourceId> & rxPaneId,const OUString & rsTitle,const Reference<drawing::framework::XPane> & rxParentPane,const bool bIsSpritePane)287 Reference<XResource> PresenterPaneFactory::CreatePane (
288     const Reference<XResourceId>& rxPaneId,
289     const OUString& rsTitle,
290     const Reference<drawing::framework::XPane>& rxParentPane,
291     const bool bIsSpritePane)
292 {
293     Reference<XComponentContext> xContext (mxComponentContextWeak);
294     Reference<lang::XMultiComponentFactory> xFactory (
295         xContext->getServiceManager(), UNO_QUERY_THROW);
296 
297     // Create a border window and canvas and store it in the pane
298     // container.
299 
300     // Create the pane.
301     ::rtl::Reference<PresenterPaneBase> xPane;
302     if (bIsSpritePane)
303     {
304         xPane = ::rtl::Reference<PresenterPaneBase>(
305             new PresenterSpritePane(xContext, mpPresenterController));
306     }
307     else
308     {
309         xPane = ::rtl::Reference<PresenterPaneBase>(
310             new PresenterPane(xContext, mpPresenterController));
311     }
312 
313     // Supply arguments.
314     Sequence<Any> aArguments (6);
315     aArguments[0] <<= rxPaneId;
316     aArguments[1] <<= rxParentPane->getWindow();
317     aArguments[2] <<= rxParentPane->getCanvas();
318     aArguments[3] <<= rsTitle;
319     aArguments[4] <<= Reference<drawing::framework::XPaneBorderPainter>(
320         static_cast<XWeak*>(mpPresenterController->GetPaneBorderPainter().get()),
321         UNO_QUERY);
322     aArguments[5] <<= bIsSpritePane ? false : true;
323     xPane->initialize(aArguments);
324 
325     // Store pane and canvases and windows in container.
326     ::rtl::Reference<PresenterPaneContainer> pContainer (
327         mpPresenterController->GetPaneContainer());
328     PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
329         pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow()));
330     pContainer->StorePane(xPane);
331     if (pDescriptor.get() != NULL)
332     {
333         if (bIsSpritePane)
334         {
335             pDescriptor->maSpriteProvider = ::boost::bind(
336                 &PresenterSpritePane::GetSprite,
337                 dynamic_cast<PresenterSpritePane*>(xPane.get()));
338             pDescriptor->mbIsSprite = true;
339             pDescriptor->mbNeedsClipping = false;
340         }
341         else
342         {
343             pDescriptor->mbIsSprite = false;
344             pDescriptor->mbNeedsClipping = true;
345         }
346 
347         // Get the window of the frame and make that visible.
348         Reference<awt::XWindow> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY_THROW);
349         xWindow->setVisible(sal_True);
350     }
351 
352     return Reference<XResource>(static_cast<XWeak*>(xPane.get()), UNO_QUERY_THROW);
353 }
354 
355 
356 
357 
ThrowIfDisposed(void) const358 void PresenterPaneFactory::ThrowIfDisposed (void) const
359 {
360     if (rBHelper.bDisposed || rBHelper.bInDispose)
361     {
362         throw lang::DisposedException (
363             OUString(RTL_CONSTASCII_USTRINGPARAM(
364                 "PresenterPaneFactory object has already been disposed")),
365             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
366     }
367 }
368 
369 
370 } } // end of namespace sdext::presenter
371