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 "PresenterPaneContainer.hxx"
32 #include "PresenterPaneBase.hxx"
33 #include <com/sun/star/awt/XGraphics.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/drawing/framework/ResourceId.hpp>
37 #include <vector>
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::drawing::framework;
42 using ::rtl::OUString;
43 
44 namespace sdext { namespace presenter {
45 
46 PresenterPaneContainer::PresenterPaneContainer (
47     const Reference<XComponentContext>& rxContext)
48     : PresenterPaneContainerInterfaceBase(m_aMutex),
49       maPanes(),
50       mxPresenterHelper()
51 {
52     Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
53     if (xFactory.is())
54     {
55         mxPresenterHelper = Reference<drawing::XPresenterHelper>(
56             xFactory->createInstanceWithContext(
57                 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
58                 rxContext),
59             UNO_QUERY_THROW);
60     }
61 }
62 
63 
64 
65 
66 PresenterPaneContainer::~PresenterPaneContainer (void)
67 {
68 }
69 
70 
71 
72 
73 void PresenterPaneContainer::PreparePane (
74     const Reference<XResourceId>& rxPaneId,
75     const OUString& rsViewURL,
76     const OUString& rsTitle,
77     const OUString& rsAccessibleTitle,
78     const bool bIsOpaque,
79     const ViewInitializationFunction& rViewInitialization,
80     const double nLeft,
81     const double nTop,
82     const double nRight,
83     const double nBottom)
84 {
85     if ( ! rxPaneId.is())
86         return;
87 
88     SharedPaneDescriptor pPane (FindPaneURL(rxPaneId->getResourceURL()));
89     if (pPane.get() == NULL)
90     {
91         // No entry found for the given pane id.  Create a new one.
92         SharedPaneDescriptor pDescriptor (new PaneDescriptor());
93         pDescriptor->mxPaneId = rxPaneId;
94         pDescriptor->msViewURL = rsViewURL;
95         pDescriptor->mxPane = NULL;
96         if (rsTitle.indexOf('%') < 0)
97         {
98             pDescriptor->msTitle = rsTitle;
99             pDescriptor->msTitleTemplate = OUString();
100         }
101         else
102         {
103             pDescriptor->msTitleTemplate = rsTitle;
104             pDescriptor->msTitle = OUString();
105         }
106         pDescriptor->msAccessibleTitleTemplate = rsAccessibleTitle;
107         pDescriptor->maViewInitialization = rViewInitialization;
108         pDescriptor->mnLeft = nLeft;
109         pDescriptor->mnTop = nTop;
110         pDescriptor->mnRight = nRight;
111         pDescriptor->mnBottom = nBottom;
112         pDescriptor->mbIsActive = true;
113         pDescriptor->mbIsOpaque = bIsOpaque;
114         pDescriptor->maSpriteProvider = PaneDescriptor::SpriteProvider();
115         pDescriptor->mbIsSprite = false;
116         pDescriptor->maCalloutAnchorLocation = awt::Point(-1,-1);
117         pDescriptor->mbHasCalloutAnchor = false;
118 
119         maPanes.push_back(pDescriptor);
120     }
121 }
122 
123 
124 
125 
126 void SAL_CALL PresenterPaneContainer::disposing (void)
127 {
128     PaneList::iterator iPane (maPanes.begin());
129     PaneList::const_iterator iEnd (maPanes.end());
130     for ( ; iPane!=iEnd; ++iPane)
131         if ((*iPane)->mxPaneId.is())
132             RemovePane((*iPane)->mxPaneId);
133 }
134 
135 
136 
137 
138 PresenterPaneContainer::SharedPaneDescriptor
139     PresenterPaneContainer::StorePane (const rtl::Reference<PresenterPaneBase>& rxPane)
140 {
141     SharedPaneDescriptor pDescriptor;
142 
143     if (rxPane.is())
144     {
145         OUString sPaneURL;
146         Reference<XResourceId> xPaneId (rxPane->getResourceId());
147         if (xPaneId.is())
148             sPaneURL = xPaneId->getResourceURL();
149 
150         pDescriptor = FindPaneURL(sPaneURL);
151         if (pDescriptor.get() == NULL)
152             PreparePane(xPaneId, OUString(), OUString(), OUString(),
153                 false, ViewInitializationFunction(), 0,0,0,0);
154         pDescriptor = FindPaneURL(sPaneURL);
155         if (pDescriptor.get() != NULL)
156         {
157             Reference<awt::XWindow> xWindow (rxPane->getWindow());
158             pDescriptor->mxContentWindow = xWindow;
159             pDescriptor->mxPaneId = xPaneId;
160             pDescriptor->mxPane = rxPane;
161             pDescriptor->mxPane->SetTitle(pDescriptor->msTitle);
162 
163             // When there is a call out anchor location set then tell the
164             // window about it.
165             if (pDescriptor->mbHasCalloutAnchor)
166                 pDescriptor->mxPane->SetCalloutAnchor(pDescriptor->maCalloutAnchorLocation);
167 
168             if (xWindow.is())
169                 xWindow->addEventListener(this);
170         }
171     }
172 
173     return pDescriptor;
174 }
175 
176 
177 
178 
179 PresenterPaneContainer::SharedPaneDescriptor
180     PresenterPaneContainer::StoreBorderWindow(
181         const Reference<XResourceId>& rxPaneId,
182         const Reference<awt::XWindow>& rxBorderWindow)
183 {
184     // The content window may not be present.  Use the resource URL of the
185     // pane id as key.
186     OUString sPaneURL;
187     if (rxPaneId.is())
188         sPaneURL = rxPaneId->getResourceURL();
189 
190     SharedPaneDescriptor pDescriptor (FindPaneURL(sPaneURL));
191     if (pDescriptor.get() != NULL)
192     {
193         pDescriptor->mxBorderWindow = rxBorderWindow;
194         return pDescriptor;
195     }
196     else
197         return SharedPaneDescriptor();
198 }
199 
200 
201 
202 
203 PresenterPaneContainer::SharedPaneDescriptor
204     PresenterPaneContainer::StoreView (
205         const Reference<XView>& rxView,
206         const SharedBitmapDescriptor& rpViewBackground)
207 {
208     SharedPaneDescriptor pDescriptor;
209 
210     if (rxView.is())
211     {
212         OUString sPaneURL;
213         Reference<XResourceId> xViewId (rxView->getResourceId());
214         if (xViewId.is())
215         {
216             Reference<XResourceId> xPaneId (xViewId->getAnchor());
217             if (xPaneId.is())
218                 sPaneURL = xPaneId->getResourceURL();
219         }
220 
221         pDescriptor = FindPaneURL(sPaneURL);
222         if (pDescriptor.get() != NULL)
223         {
224             pDescriptor->mxView = rxView;
225             pDescriptor->mpViewBackground = rpViewBackground;
226             pDescriptor->mxPane->SetBackground(rpViewBackground);
227             try
228             {
229                 if ( ! pDescriptor->maViewInitialization.empty())
230                     pDescriptor->maViewInitialization(rxView);
231 
232                 // Activate or deactivate the pane/view.
233                 if ( ! pDescriptor->maActivator.empty())
234                     pDescriptor->maActivator(pDescriptor->mbIsActive);
235             }
236             catch (RuntimeException&)
237             {
238                 OSL_ASSERT(false);
239             }
240         }
241     }
242 
243     return pDescriptor;
244 }
245 
246 
247 
248 
249 PresenterPaneContainer::SharedPaneDescriptor
250     PresenterPaneContainer::RemovePane (const Reference<XResourceId>& rxPaneId)
251 {
252     SharedPaneDescriptor pDescriptor (FindPaneId(rxPaneId));
253     if (pDescriptor.get() != NULL)
254     {
255         if (pDescriptor->mxContentWindow.is())
256             pDescriptor->mxContentWindow->removeEventListener(this);
257         pDescriptor->mxContentWindow = NULL;
258         pDescriptor->mxBorderWindow = NULL;
259         pDescriptor->mxPane = NULL;
260         pDescriptor->mxView = NULL;
261         pDescriptor->mbIsActive = false;
262     }
263     return pDescriptor;
264 }
265 
266 
267 
268 
269 
270 PresenterPaneContainer::SharedPaneDescriptor
271     PresenterPaneContainer::RemoveView (const Reference<XView>& rxView)
272 {
273     SharedPaneDescriptor pDescriptor;
274 
275     if (rxView.is())
276     {
277         OUString sPaneURL;
278         Reference<XResourceId> xViewId (rxView->getResourceId());
279         if (xViewId.is())
280         {
281             Reference<XResourceId> xPaneId (xViewId->getAnchor());
282             if (xPaneId.is())
283                 sPaneURL = xPaneId->getResourceURL();
284         }
285 
286         pDescriptor = FindPaneURL(sPaneURL);
287         if (pDescriptor.get() != NULL)
288         {
289             pDescriptor->mxView = NULL;
290             pDescriptor->mpViewBackground = SharedBitmapDescriptor();
291         }
292     }
293 
294     return pDescriptor;
295 }
296 
297 
298 
299 
300 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindBorderWindow (
301     const Reference<awt::XWindow>& rxBorderWindow)
302 {
303     PaneList::const_iterator iPane;
304     PaneList::iterator iEnd (maPanes.end());
305     for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
306     {
307         if ((*iPane)->mxBorderWindow == rxBorderWindow)
308             return *iPane;
309     }
310     return SharedPaneDescriptor();
311 }
312 
313 
314 
315 
316 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindContentWindow (
317     const Reference<awt::XWindow>& rxContentWindow)
318 {
319     PaneList::const_iterator iPane;
320     PaneList::iterator iEnd (maPanes.end());
321     for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
322     {
323         if ((*iPane)->mxContentWindow == rxContentWindow)
324             return *iPane;
325     }
326     return SharedPaneDescriptor();
327 }
328 
329 
330 
331 
332 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneURL (
333     const OUString& rsPaneURL)
334 {
335     PaneList::const_iterator iPane;
336     PaneList::const_iterator iEnd (maPanes.end());
337     for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
338     {
339         if ((*iPane)->mxPaneId->getResourceURL() == rsPaneURL)
340             return *iPane;
341     }
342     return SharedPaneDescriptor();
343 }
344 
345 
346 
347 
348 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneId (
349     const Reference<XResourceId>& rxPaneId)
350 {
351     PaneList::iterator iEnd (maPanes.end());
352 
353     if ( ! rxPaneId.is())
354         return SharedPaneDescriptor();
355 
356     PaneList::iterator iPane;
357     for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
358     {
359         if (rxPaneId->compareTo((*iPane)->mxPaneId) == 0)
360             return *iPane;
361     }
362     return SharedPaneDescriptor();
363 }
364 
365 
366 
367 
368 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindViewURL (
369     const OUString& rsViewURL)
370 {
371     PaneList::iterator iEnd (maPanes.end());
372     PaneList::iterator iPane;
373     for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
374     {
375         if (rsViewURL == (*iPane)->msViewURL)
376             return *iPane;
377     }
378     return SharedPaneDescriptor();
379 }
380 
381 
382 
383 
384 ::rtl::OUString PresenterPaneContainer::GetPaneURLForViewURL (const ::rtl::OUString& rsViewURL)
385 {
386     SharedPaneDescriptor pDescriptor (FindViewURL(rsViewURL));
387     if (pDescriptor.get() != NULL)
388         if (pDescriptor->mxPaneId.is())
389             return pDescriptor->mxPaneId->getResourceURL();
390     return OUString();
391 }
392 
393 
394 
395 
396 void PresenterPaneContainer::ToTop (const SharedPaneDescriptor& rpDescriptor)
397 {
398     if (rpDescriptor.get() != NULL)
399     {
400         // Find iterator for pDescriptor.
401         PaneList::iterator iPane;
402         PaneList::iterator iEnd (maPanes.end());
403         for (iPane=maPanes.begin(); iPane!=iEnd; ++iPane)
404             if (iPane->get() == rpDescriptor.get())
405                 break;
406         OSL_ASSERT(iPane!=iEnd);
407         if (iPane == iEnd)
408             return;
409 
410         if (mxPresenterHelper.is())
411             mxPresenterHelper->toTop(rpDescriptor->mxBorderWindow);
412 
413         maPanes.erase(iPane);
414         maPanes.push_back(rpDescriptor);
415     }
416 }
417 
418 
419 
420 
421 //----- XEventListener --------------------------------------------------------
422 
423 void SAL_CALL PresenterPaneContainer::disposing (
424     const com::sun::star::lang::EventObject& rEvent)
425     throw (com::sun::star::uno::RuntimeException)
426 {
427     SharedPaneDescriptor pDescriptor (
428         FindContentWindow(Reference<awt::XWindow>(rEvent.Source, UNO_QUERY)));
429     if (pDescriptor.get() != NULL)
430     {
431         RemovePane(pDescriptor->mxPaneId);
432     }
433 }
434 
435 
436 
437 
438 //===== PresenterPaneContainer::PaneDescriptor ================================
439 
440 void PresenterPaneContainer::PaneDescriptor::SetActivationState (const bool bIsActive)
441 {
442     mbIsActive = bIsActive;
443     if ( ! maActivator.empty())
444         maActivator(mbIsActive);
445 }
446 
447 } } // end of namespace ::sdext::presenter
448