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