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