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_slideshow.hxx"
30 
31 // must be first
32 #include <canvas/debug.hxx>
33 #include <canvas/verbosetrace.hxx>
34 #include <canvas/canvastools.hxx>
35 
36 #include <boost/shared_ptr.hpp>
37 
38 #include "appletshape.hxx"
39 #include "externalshapebase.hxx"
40 #include "vieweventhandler.hxx"
41 #include "viewappletshape.hxx"
42 #include "tools.hxx"
43 
44 #include <boost/bind.hpp>
45 #include <algorithm>
46 
47 
48 using namespace ::com::sun::star;
49 
50 
51 namespace slideshow
52 {
53     namespace internal
54     {
55         /** Represents an applet shape.
56 
57             This implementation offers support for applet shapes (both
58             Java applets, and Netscape plugins). Such shapes need
59             special treatment.
60          */
61         class AppletShape : public ExternalShapeBase
62         {
63         public:
64             /** Create a shape for the given XShape for a applet object
65 
66             	@param xShape
67                 The XShape to represent.
68 
69                 @param nPrio
70                 Externally-determined shape priority (used e.g. for
71                 paint ordering). This number _must be_ unique!
72 
73                 @param rServiceName
74                 Service name to use, when creating the actual viewer
75                 component
76 
77                 @param pPropCopyTable
78                 Table of plain ASCII property names, to copy from
79                 xShape to applet.
80 
81                 @param nNumPropEntries
82                 Number of property table entries (in pPropCopyTable)
83              */
84             AppletShape( const ::com::sun::star::uno::Reference<
85                        		::com::sun::star::drawing::XShape >&	xShape,
86                          double										nPrio,
87                          const ::rtl::OUString&                     rServiceName,
88                          const char**                               pPropCopyTable,
89                          sal_Size                                   nNumPropEntries,
90                          const SlideShowContext&                    rContext ); // throw ShapeLoadFailedException;
91 
92         private:
93 
94             // View layer methods
95             //------------------------------------------------------------------
96 
97             virtual void addViewLayer( const ViewLayerSharedPtr& 	rNewLayer,
98                                        bool							bRedrawLayer );
99             virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer );
100             virtual bool clearAllViewLayers();
101 
102 
103             // ExternalShapeBase methods
104             //------------------------------------------------------------------
105 
106             virtual bool implRender( const ::basegfx::B2DRange& rCurrBounds ) const;
107             virtual void implViewChanged( const UnoViewSharedPtr& rView );
108             virtual void implViewsChanged();
109             virtual bool implStartIntrinsicAnimation();
110             virtual bool implEndIntrinsicAnimation();
111             virtual bool implPauseIntrinsicAnimation();
112             virtual bool implIsIntrinsicAnimationPlaying() const;
113             virtual void implSetIntrinsicAnimationTime(double);
114 
115             const ::rtl::OUString                           maServiceName;
116             const char**                                    mpPropCopyTable;
117             const sal_Size                                  mnNumPropEntries;
118 
119             /// the list of active view shapes (one for each registered view layer)
120             typedef ::std::vector< ViewAppletShapeSharedPtr > ViewAppletShapeVector;
121             ViewAppletShapeVector                           maViewAppletShapes;
122             bool                                             mbIsPlaying;
123         };
124 
125         AppletShape::AppletShape( const uno::Reference< drawing::XShape >& xShape,
126                                   double                                   nPrio,
127                                   const ::rtl::OUString&                   rServiceName,
128                                   const char**                             pPropCopyTable,
129                                   sal_Size                                 nNumPropEntries,
130                                   const SlideShowContext&                  rContext ) :
131             ExternalShapeBase( xShape, nPrio, rContext ),
132             maServiceName( rServiceName ),
133             mpPropCopyTable( pPropCopyTable ),
134             mnNumPropEntries( nNumPropEntries ),
135             maViewAppletShapes(),
136             mbIsPlaying(false)
137         {
138         }
139 
140 		// ---------------------------------------------------------------------
141 
142         void AppletShape::implViewChanged( const UnoViewSharedPtr& rView )
143         {
144             // determine ViewAppletShape that needs update
145             ViewAppletShapeVector::const_iterator       aIter(maViewAppletShapes.begin());
146             ViewAppletShapeVector::const_iterator const aEnd (maViewAppletShapes.end());
147             while( aIter != aEnd )
148             {
149                 if( (*aIter)->getViewLayer()->isOnView(rView) )
150                     (*aIter)->resize(getBounds());
151 
152                 ++aIter;
153             }
154         }
155 
156 		// ---------------------------------------------------------------------
157 
158         void AppletShape::implViewsChanged()
159         {
160             // resize all ViewShapes
161             ::std::for_each( maViewAppletShapes.begin(),
162                              maViewAppletShapes.end(),
163                              ::boost::bind(
164                                  &ViewAppletShape::resize,
165                                  _1,
166                                  ::boost::cref( AppletShape::getBounds())) );
167         }
168 
169 		// ---------------------------------------------------------------------
170 
171         void AppletShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
172                                         bool                      bRedrawLayer )
173         {
174             try
175             {
176                 maViewAppletShapes.push_back(
177                     ViewAppletShapeSharedPtr( new ViewAppletShape( rNewLayer,
178                                                                    getXShape(),
179                                                                    maServiceName,
180                                                                    mpPropCopyTable,
181                                                                    mnNumPropEntries,
182                                                                    mxComponentContext )));
183 
184                 // push new size to view shape
185                 maViewAppletShapes.back()->resize( getBounds() );
186 
187                 // render the Shape on the newly added ViewLayer
188                 if( bRedrawLayer )
189                     maViewAppletShapes.back()->render( getBounds() );
190             }
191             catch(uno::Exception&)
192             {
193                 // ignore failed shapes - slideshow should run with
194                 // the remaining content
195             }
196         }
197 
198 		// ---------------------------------------------------------------------
199 
200         bool AppletShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
201         {
202             const ViewAppletShapeVector::iterator aEnd( maViewAppletShapes.end() );
203 
204             OSL_ENSURE( ::std::count_if(maViewAppletShapes.begin(),
205                                         aEnd,
206                                         ::boost::bind<bool>(
207                                             ::std::equal_to< ViewLayerSharedPtr >(),
208                                             ::boost::bind( &ViewAppletShape::getViewLayer, _1 ),
209                                             ::boost::cref( rLayer ) ) ) < 2,
210                         "AppletShape::removeViewLayer(): Duplicate ViewLayer entries!" );
211 
212             ViewAppletShapeVector::iterator aIter;
213 
214             if( (aIter=::std::remove_if( maViewAppletShapes.begin(),
215                                          aEnd,
216                                          ::boost::bind<bool>(
217                                              ::std::equal_to< ViewLayerSharedPtr >(),
218                                              ::boost::bind( &ViewAppletShape::getViewLayer,
219                                                             _1 ),
220                                              ::boost::cref( rLayer ) ) )) == aEnd )
221             {
222                 // view layer seemingly was not added, failed
223                 return false;
224             }
225 
226             // actually erase from container
227             maViewAppletShapes.erase( aIter, aEnd );
228 
229             return true;
230         }
231 
232 		// ---------------------------------------------------------------------
233 
234         bool AppletShape::clearAllViewLayers()
235         {
236             maViewAppletShapes.clear();
237             return true;
238         }
239 
240 		// ---------------------------------------------------------------------
241 
242         bool AppletShape::implRender( const ::basegfx::B2DRange& rCurrBounds ) const
243         {
244             // redraw all view shapes, by calling their update() method
245             if( ::std::count_if( maViewAppletShapes.begin(),
246                                  maViewAppletShapes.end(),
247                                  ::boost::bind<bool>(
248                                      ::boost::mem_fn( &ViewAppletShape::render ),
249                                      _1,
250                                      ::boost::cref( rCurrBounds ) ) )
251                 != static_cast<ViewAppletShapeVector::difference_type>(maViewAppletShapes.size()) )
252             {
253                 // at least one of the ViewShape::update() calls did return
254                 // false - update failed on at least one ViewLayer
255                 return false;
256             }
257 
258             return true;
259         }
260 
261 		// ---------------------------------------------------------------------
262 
263         bool AppletShape::implStartIntrinsicAnimation()
264         {
265             ::std::for_each( maViewAppletShapes.begin(),
266                              maViewAppletShapes.end(),
267                              ::boost::bind( &ViewAppletShape::startApplet,
268                                             _1,
269                                             ::boost::cref( getBounds() )));
270             mbIsPlaying = true;
271 
272             return true;
273         }
274 
275 		// ---------------------------------------------------------------------
276 
277         bool AppletShape::implEndIntrinsicAnimation()
278         {
279             ::std::for_each( maViewAppletShapes.begin(),
280                              maViewAppletShapes.end(),
281                              ::boost::mem_fn( &ViewAppletShape::endApplet ) );
282 
283             mbIsPlaying = false;
284 
285             return true;
286         }
287 
288 		// ---------------------------------------------------------------------
289 
290         bool AppletShape::implPauseIntrinsicAnimation()
291         {
292             // TODO(F1): any way of temporarily disabling/deactivating
293             // applets?
294             return true;
295         }
296 
297 		// ---------------------------------------------------------------------
298 
299         bool AppletShape::implIsIntrinsicAnimationPlaying() const
300         {
301             return mbIsPlaying;
302         }
303 
304 		// ---------------------------------------------------------------------
305 
306         void AppletShape::implSetIntrinsicAnimationTime(double)
307         {
308             // No way of doing this, or?
309         }
310 
311         boost::shared_ptr<Shape> createAppletShape(
312             const uno::Reference< drawing::XShape >& xShape,
313             double                                   nPrio,
314             const ::rtl::OUString&                   rServiceName,
315             const char**                             pPropCopyTable,
316             sal_Size                                 nNumPropEntries,
317             const SlideShowContext&                  rContext )
318         {
319             boost::shared_ptr< AppletShape > pAppletShape(
320                 new AppletShape(xShape,
321                                 nPrio,
322                                 rServiceName,
323                                 pPropCopyTable,
324                                 nNumPropEntries,
325                                 rContext) );
326 
327             return pAppletShape;
328         }
329     }
330 }
331