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 <com/sun/star/drawing/XShape.hpp>
37 
38 #include "mediashape.hxx"
39 #include "viewmediashape.hxx"
40 #include "externalshapebase.hxx"
41 #include "slideshowcontext.hxx"
42 #include "shape.hxx"
43 #include "tools.hxx"
44 
45 #include <boost/bind.hpp>
46 #include <algorithm>
47 
48 
49 using namespace ::com::sun::star;
50 
51 
52 namespace slideshow
53 {
54     namespace internal
55     {
56         /** Represents a media shape.
57 
58             This implementation offers support for media shapes.
59 			Such shapes need special treatment.
60          */
61         class MediaShape : public ExternalShapeBase
62         {
63         public:
64             /** Create a shape for the given XShape for a media 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             MediaShape( const ::com::sun::star::uno::Reference<
74                        		::com::sun::star::drawing::XShape >&	xShape,
75                         double										nPrio,
76                         const SlideShowContext&                     rContext ); // throw ShapeLoadFailedException;
77 
78         private:
79 
80             // View layer methods
81             //------------------------------------------------------------------
82 
83             virtual void addViewLayer( const ViewLayerSharedPtr& 	rNewLayer,
84                                        bool							bRedrawLayer );
85             virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer );
86             virtual bool clearAllViewLayers();
87 
88 
89             // ExternalShapeBase methods
90             //------------------------------------------------------------------
91 
92             virtual bool implRender( const ::basegfx::B2DRange& rCurrBounds ) const;
93             virtual void implViewChanged( const UnoViewSharedPtr& rView );
94             virtual void implViewsChanged();
95             virtual bool implStartIntrinsicAnimation();
96             virtual bool implEndIntrinsicAnimation();
97             virtual bool implPauseIntrinsicAnimation();
98             virtual bool implIsIntrinsicAnimationPlaying() const;
99             virtual void implSetIntrinsicAnimationTime(double);
100 
101             /// the list of active view shapes (one for each registered view layer)
102             typedef ::std::vector< ViewMediaShapeSharedPtr > ViewMediaShapeVector;
103             ViewMediaShapeVector                             maViewMediaShapes;
104             bool                                             mbIsPlaying;
105         };
106 
107 
108         MediaShape::MediaShape( const uno::Reference< drawing::XShape >& xShape,
109                               	double									 nPrio,
110                                 const SlideShowContext&                  rContext ) :
111             ExternalShapeBase( xShape, nPrio, rContext ),
112             maViewMediaShapes(),
113             mbIsPlaying(false)
114         {
115         }
116 
117 		// ---------------------------------------------------------------------
118 
119         void MediaShape::implViewChanged( const UnoViewSharedPtr& rView )
120         {
121             // determine ViewMediaShape that needs update
122             ViewMediaShapeVector::const_iterator       aIter(maViewMediaShapes.begin());
123             ViewMediaShapeVector::const_iterator const aEnd (maViewMediaShapes.end());
124             while( aIter != aEnd )
125             {
126                 if( (*aIter)->getViewLayer()->isOnView(rView) )
127                     (*aIter)->resize(getBounds());
128 
129                 ++aIter;
130             }
131         }
132 
133 		// ---------------------------------------------------------------------
134 
135         void MediaShape::implViewsChanged()
136         {
137             // resize all ViewShapes
138             ::std::for_each( maViewMediaShapes.begin(),
139                              maViewMediaShapes.end(),
140                              ::boost::bind(
141                                  &ViewMediaShape::resize,
142                                  _1,
143                                  ::boost::cref( getBounds())) );
144         }
145 
146 		// ---------------------------------------------------------------------
147 
148         void MediaShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
149                                        bool						 bRedrawLayer )
150         {
151             maViewMediaShapes.push_back(
152                 ViewMediaShapeSharedPtr( new ViewMediaShape( rNewLayer,
153                                                              getXShape(),
154                                                              mxComponentContext )));
155 
156             // push new size to view shape
157             maViewMediaShapes.back()->resize( getBounds() );
158 
159             // render the Shape on the newly added ViewLayer
160             if( bRedrawLayer )
161                 maViewMediaShapes.back()->render( getBounds() );
162         }
163 
164 		// ---------------------------------------------------------------------
165 
166         bool MediaShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
167         {
168             const ViewMediaShapeVector::iterator aEnd( maViewMediaShapes.end() );
169 
170             OSL_ENSURE( ::std::count_if(maViewMediaShapes.begin(),
171                                         aEnd,
172                                         ::boost::bind<bool>(
173                                             ::std::equal_to< ViewLayerSharedPtr >(),
174                                             ::boost::bind( &ViewMediaShape::getViewLayer, _1 ),
175                                             ::boost::cref( rLayer ) ) ) < 2,
176                         "MediaShape::removeViewLayer(): Duplicate ViewLayer entries!" );
177 
178             ViewMediaShapeVector::iterator aIter;
179 
180             if( (aIter=::std::remove_if( maViewMediaShapes.begin(),
181                                          aEnd,
182                                          ::boost::bind<bool>(
183                                              ::std::equal_to< ViewLayerSharedPtr >(),
184                                              ::boost::bind( &ViewMediaShape::getViewLayer,
185                                                             _1 ),
186                                              ::boost::cref( rLayer ) ) )) == aEnd )
187             {
188                 // view layer seemingly was not added, failed
189                 return false;
190             }
191 
192             // actually erase from container
193             maViewMediaShapes.erase( aIter, aEnd );
194 
195             return true;
196         }
197 
198 		// ---------------------------------------------------------------------
199 
200         bool MediaShape::clearAllViewLayers()
201         {
202             maViewMediaShapes.clear();
203             return true;
204         }
205 
206 		// ---------------------------------------------------------------------
207 
208         bool MediaShape::implRender( const ::basegfx::B2DRange& rCurrBounds ) const
209         {
210             // redraw all view shapes, by calling their update() method
211             if( ::std::count_if( maViewMediaShapes.begin(),
212                                  maViewMediaShapes.end(),
213                                  ::boost::bind<bool>(
214                                      ::boost::mem_fn( &ViewMediaShape::render ),
215                                      _1,
216                                      ::boost::cref( rCurrBounds ) ) )
217                 != static_cast<ViewMediaShapeVector::difference_type>(maViewMediaShapes.size()) )
218             {
219                 // at least one of the ViewShape::update() calls did return
220                 // false - update failed on at least one ViewLayer
221                 return false;
222             }
223 
224             return true;
225         }
226 
227 		// ---------------------------------------------------------------------
228 
229         bool MediaShape::implStartIntrinsicAnimation()
230         {
231             ::std::for_each( maViewMediaShapes.begin(),
232                              maViewMediaShapes.end(),
233                              ::boost::mem_fn( &ViewMediaShape::startMedia ) );
234 
235             mbIsPlaying = true;
236 
237             return true;
238         }
239 
240 		// ---------------------------------------------------------------------
241 
242         bool MediaShape::implEndIntrinsicAnimation()
243         {
244             ::std::for_each( maViewMediaShapes.begin(),
245                              maViewMediaShapes.end(),
246                              ::boost::mem_fn( &ViewMediaShape::endMedia ) );
247 
248             mbIsPlaying = false;
249 
250             return true;
251         }
252 
253 		// ---------------------------------------------------------------------
254 
255         bool MediaShape::implPauseIntrinsicAnimation()
256         {
257             ::std::for_each( maViewMediaShapes.begin(),
258                              maViewMediaShapes.end(),
259                              ::boost::mem_fn( &ViewMediaShape::pauseMedia ) );
260 
261             mbIsPlaying = false;
262 
263             return true;
264         }
265 
266 		// ---------------------------------------------------------------------
267 
268         bool MediaShape::implIsIntrinsicAnimationPlaying() const
269         {
270             return mbIsPlaying;
271         }
272 
273 		// ---------------------------------------------------------------------
274 
275         void MediaShape::implSetIntrinsicAnimationTime(double fTime)
276         {
277             ::std::for_each( maViewMediaShapes.begin(),
278                              maViewMediaShapes.end(),
279                              ::boost::bind( &ViewMediaShape::setMediaTime,
280                                             _1, boost::cref(fTime)) );
281         }
282 
283 		// ---------------------------------------------------------------------
284 
285         ShapeSharedPtr createMediaShape(
286             const uno::Reference< drawing::XShape >& xShape,
287             double                                   nPrio,
288             const SlideShowContext&                  rContext)
289         {
290             boost::shared_ptr< MediaShape > pMediaShape(
291                 new MediaShape(xShape, nPrio, rContext));
292 
293             return pMediaShape;
294         }
295 
296     }
297 }
298