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 <vcl/cvtgrf.hxx>
34 #include <tools/urlobj.hxx>
35 #include <tools/stream.hxx>
36 #include <svtools/grfmgr.hxx>
37 #include <unotools/ucbstreamhelper.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <basegfx/point/b2dpoint.hxx>
40 #include <basegfx/polygon/b2dpolygon.hxx>
41 #include <cppcanvas/basegfxfactory.hxx>
42 #include <cppcanvas/polypolygon.hxx>
43 #include <com/sun/star/awt/Rectangle.hpp>
44 #include <com/sun/star/drawing/ColorMode.hpp>
45 #include <com/sun/star/text/GraphicCrop.hpp>
46 #include <com/sun/star/container/XNameContainer.hpp>
47 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
48 #include <com/sun/star/drawing/PointSequence.hpp>
49 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
50 #include <com/sun/star/drawing/XLayerSupplier.hpp>
51 #include <com/sun/star/drawing/XLayerManager.hpp>
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #include <com/sun/star/lang/XComponent.hpp>
54 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
55 
56 #include "drawshapesubsetting.hxx"
57 #include "drawshape.hxx"
58 #include "backgroundshape.hxx"
59 #include "mediashape.hxx"
60 #include "appletshape.hxx"
61 #include "shapeimporter.hxx"
62 #include "slideshowexceptions.hxx"
63 #include "gdimtftools.hxx"
64 #include "tools.hxx"
65 #include "slideshowcontext.hxx"
66 
67 #include <boost/shared_ptr.hpp>
68 #include <boost/scoped_ptr.hpp>
69 
70 using namespace com::sun::star;
71 
72 namespace slideshow {
73 namespace internal {
74 
75 namespace {
76 
77 bool importShapeGraphic(
78     GraphicObject & o_rGraphic,
79     uno::Reference<beans::XPropertySet> const& xPropSet )
80 {
81     rtl::OUString aURL;
82     if( !getPropertyValue( aURL, xPropSet, OUSTR("GraphicURL")) ||
83         aURL.getLength() == 0 )
84     {
85         // no or empty property - cannot import shape graphic
86         return false;
87     }
88 
89     rtl::OUString const aVndUrl(
90         RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
91     sal_Int32 nIndex( aURL.indexOf( aVndUrl ) );
92 
93     if(nIndex != -1)
94     {
95         // skip past the end of the "vnd..." prefix
96         nIndex += aVndUrl.getLength();
97 
98         if(nIndex >= aURL.getLength())
99         {
100             OSL_ENSURE( false, "ShapeImporter::importShape(): "
101                         "embedded graphic has no graphic ID" );
102             return false;
103         }
104 
105         // unique ID string found in URL, extract
106         // to separate string
107         rtl::OUString const aUniqueId(
108             aURL.copy( nIndex, aURL.getLength() - nIndex ) );
109 
110         // TODO(T2): Creating a GraphicObject is not
111         // thread safe (internally calls VCL, and has
112         // unguarded internal singleton mpGlobalMgr)
113 
114         // fetch already loaded graphic from graphic manager.
115         ByteString const aOldString( static_cast<String>(aUniqueId),
116                                      RTL_TEXTENCODING_UTF8 );
117         o_rGraphic = GraphicObject( aOldString );
118 
119 
120         if( GRAPHIC_DEFAULT == o_rGraphic.GetType()
121             || GRAPHIC_NONE == o_rGraphic.GetType() )
122         {
123             // even the GrfMgr does not seem to know this graphic
124             return false;
125         }
126     }
127     else
128     {
129         // no special string found, graphic must be
130         // external. Load via GraphicIm porter
131         INetURLObject aTmp( aURL );
132         boost::scoped_ptr<SvStream> pGraphicStream(
133             utl::UcbStreamHelper::CreateStream(
134                 aTmp.GetMainURL( INetURLObject::NO_DECODE ),
135                 STREAM_READ ) );
136         if( !pGraphicStream )
137         {
138             OSL_ENSURE( false, "ShapeImporter::importShape(): "
139                         "cannot create input stream for graphic" );
140             return false;
141         }
142 
143         Graphic aTmpGraphic;
144         if( GraphicConverter::Import(
145                 *pGraphicStream, aTmpGraphic ) != ERRCODE_NONE )
146         {
147             OSL_ENSURE( false, "ShapeImporter::importShape(): "
148                         "Failed to import shape graphic from given URL" );
149             return false;
150         }
151 
152         o_rGraphic = GraphicObject( aTmpGraphic );
153     }
154     return true;
155 }
156 
157 /** This shape implementation just acts as a dummy for the layermanager.
158     Its sole role is for hit test detection of group shapes.
159 */
160 class ShapeOfGroup : public Shape
161 {
162 public:
163     ShapeOfGroup( ShapeSharedPtr const&                      pGroupShape,
164                   uno::Reference<drawing::XShape> const&     xShape,
165                   uno::Reference<beans::XPropertySet> const& xPropSet,
166                   double                                     nPrio );
167 
168     // Shape:
169     virtual uno::Reference<drawing::XShape> getXShape() const;
170     virtual void addViewLayer( ViewLayerSharedPtr const& pNewLayer,
171                                bool                      bRedrawLayer );
172     virtual bool removeViewLayer( ViewLayerSharedPtr const& pNewLayer );
173     virtual bool clearAllViewLayers();
174     virtual bool update() const;
175     virtual bool render() const;
176     virtual bool isContentChanged() const;
177     virtual basegfx::B2DRectangle getBounds() const;
178     virtual basegfx::B2DRectangle getDomBounds() const;
179     virtual basegfx::B2DRectangle getUpdateArea() const;
180     virtual bool isVisible() const;
181     virtual double getPriority() const;
182     virtual bool isBackgroundDetached() const;
183 
184 private:
185     ShapeSharedPtr const                  mpGroupShape;
186     uno::Reference<drawing::XShape> const mxShape;
187     double const                          mnPrio;
188     basegfx::B2DPoint                     maPosOffset;
189     double                                mnWidth;
190     double                                mnHeight;
191 };
192 
193 ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr const&                      pGroupShape,
194                             uno::Reference<drawing::XShape> const&     xShape,
195                             uno::Reference<beans::XPropertySet> const& xPropSet,
196                             double                                     nPrio ) :
197     mpGroupShape(pGroupShape),
198     mxShape(xShape),
199     mnPrio(nPrio)
200 {
201     // read bound rect
202     uno::Any const aTmpRect_( xPropSet->getPropertyValue( OUSTR("BoundRect") ));
203     awt::Rectangle const aTmpRect( aTmpRect_.get<awt::Rectangle>() );
204     basegfx::B2DRectangle const groupPosSize( pGroupShape->getBounds() );
205     maPosOffset = basegfx::B2DPoint( aTmpRect.X - groupPosSize.getMinX(),
206                                      aTmpRect.Y - groupPosSize.getMinY() );
207     mnWidth = aTmpRect.Width;
208     mnHeight = aTmpRect.Height;
209 }
210 
211 uno::Reference<drawing::XShape> ShapeOfGroup::getXShape() const
212 {
213     return mxShape;
214 }
215 
216 void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/,
217                                  bool                      /*bRedrawLayer*/ )
218 {
219 }
220 
221 bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/ )
222 {
223     return true;
224 }
225 
226 bool ShapeOfGroup::clearAllViewLayers()
227 {
228     return true;
229 }
230 
231 bool ShapeOfGroup::update() const
232 {
233     return true;
234 }
235 
236 bool ShapeOfGroup::render() const
237 {
238     return true;
239 }
240 
241 bool ShapeOfGroup::isContentChanged() const
242 {
243     return false;
244 }
245 
246 basegfx::B2DRectangle ShapeOfGroup::getBounds() const
247 {
248     basegfx::B2DRectangle const groupPosSize( mpGroupShape->getBounds() );
249     double const posX = (groupPosSize.getMinX() + maPosOffset.getX());
250     double const posY = (groupPosSize.getMinY() + maPosOffset.getY());
251     return basegfx::B2DRectangle( posX, posY, posX + mnWidth, posY + mnHeight );
252 }
253 
254 basegfx::B2DRectangle ShapeOfGroup::getDomBounds() const
255 {
256     return getBounds();
257 }
258 
259 basegfx::B2DRectangle ShapeOfGroup::getUpdateArea() const
260 {
261     return getBounds();
262 }
263 
264 bool ShapeOfGroup::isVisible() const
265 {
266     return mpGroupShape->isVisible();
267 }
268 
269 double ShapeOfGroup::getPriority() const
270 {
271     return mnPrio;
272 }
273 
274 bool ShapeOfGroup::isBackgroundDetached() const
275 {
276     return false;
277 }
278 
279 } // anon namespace
280 
281 ShapeSharedPtr ShapeImporter::createShape(
282     uno::Reference<drawing::XShape> const& xCurrShape,
283     uno::Reference<beans::XPropertySet> const& xPropSet,
284     rtl::OUString const& shapeType ) const
285 {
286     if( shapeType.equalsAsciiL(
287             RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.MediaShape") ) ||
288 		shapeType.equalsAsciiL(
289             RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.MediaShape") ) )
290     {
291         // Media shape (video etc.). This is a special object
292         return createMediaShape(xCurrShape,
293                                 mnAscendingPrio,
294                                 mrContext);
295     }
296     else if( shapeType.equalsAsciiL(
297                  RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.PluginShape") ))
298     {
299         // PropertyValues to copy from XShape to plugin
300         static const char* aPropertyValues[] =
301             {
302                 "PluginURL",
303                 "PluginMimeType",
304                 "PluginCommands"
305             };
306 
307         // (Netscape)Plugin shape. This is a special object
308         return createAppletShape( xCurrShape,
309                                   mnAscendingPrio,
310                                   ::rtl::OUString(
311                                       RTL_CONSTASCII_USTRINGPARAM(
312                                           "com.sun.star.comp.sfx2.PluginObject" )),
313                                   aPropertyValues,
314                                   sizeof(aPropertyValues)/sizeof(*aPropertyValues),
315                                   mrContext );
316     }
317     else if( shapeType.equalsAsciiL(
318                  RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.AppletShape") ))
319     {
320         // PropertyValues to copy from XShape to applet
321         static const char* aPropertyValues[] =
322             {
323                 "AppletCodeBase",
324                 "AppletName",
325                 "AppletCode",
326                 "AppletCommands",
327                 "AppletIsScript"
328             };
329 
330         // (Java)Applet shape. This is a special object
331         return createAppletShape( xCurrShape,
332                                   mnAscendingPrio,
333                                   ::rtl::OUString(
334                                       RTL_CONSTASCII_USTRINGPARAM(
335                                           "com.sun.star.comp.sfx2.AppletObject" )),
336                                   aPropertyValues,
337                                   sizeof(aPropertyValues)/sizeof(*aPropertyValues),
338                                   mrContext );
339     }
340     else if( shapeType.equalsAsciiL(
341                  RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.OLE2Shape") ) ||
342              shapeType.equalsAsciiL(
343 				RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.OLE2Shape") ) )
344     {
345         // #i46224# Mark OLE shapes as foreign content - scan them for
346         // unsupported actions, and fallback to bitmap, if necessary
347         return DrawShape::create( xCurrShape,
348                                   mxPage,
349                                   mnAscendingPrio,
350                                   true,
351                                   mrContext );
352     }
353     else if( shapeType.equalsAsciiL(
354                  RTL_CONSTASCII_STRINGPARAM(
355                      "com.sun.star.drawing.GraphicObjectShape") ) ||
356 			 shapeType.equalsAsciiL(
357                  RTL_CONSTASCII_STRINGPARAM(
358                      "com.sun.star.presentation.GraphicObjectShape") ) )
359     {
360         GraphicObject aGraphicObject;
361 
362         // to get hold of GIF animations, inspect Graphic
363         // objects more thoroughly (the plain-jane shape
364         // metafile of course would only contain the first
365         // animation frame)
366         if( !importShapeGraphic( aGraphicObject, xPropSet ) )
367             return ShapeSharedPtr(); // error loading graphic -
368                                      // #142147# no placeholders in
369                                      // slideshow
370 
371         if( !aGraphicObject.IsAnimated() )
372         {
373             // no animation - simply utilize plain draw shape import
374 
375             // import shape as bitmap - either its a bitmap
376             // anyway, or its a metafile, which currently the
377             // metafile renderer might not display correctly.
378             return DrawShape::create( xCurrShape,
379                                       mxPage,
380                                       mnAscendingPrio,
381                                       true,
382                                       mrContext );
383         }
384 
385 
386         // now extract relevant shape attributes via API
387         // ---------------------------------------------
388 
389         drawing::ColorMode eColorMode( drawing::ColorMode_STANDARD );
390         sal_Int16 nLuminance(0);
391         sal_Int16 nContrast(0);
392         sal_Int16 nRed(0);
393         sal_Int16 nGreen(0);
394         sal_Int16 nBlue(0);
395         double    nGamma(1.0);
396         sal_Int16 nTransparency(0);
397         sal_Int32 nRotation(0);
398 
399         getPropertyValue( eColorMode, xPropSet, OUSTR("GraphicColorMode") );
400         getPropertyValue( nLuminance, xPropSet, OUSTR("AdjustLuminance") );
401         getPropertyValue( nContrast, xPropSet, OUSTR("AdjustContrast") );
402         getPropertyValue( nRed, xPropSet, OUSTR("AdjustRed") );
403         getPropertyValue( nGreen, xPropSet, OUSTR("AdjustGreen") );
404         getPropertyValue( nBlue, xPropSet, OUSTR("AdjustBlue") );
405         getPropertyValue( nGamma, xPropSet, OUSTR("Gamma") );
406         getPropertyValue( nTransparency, xPropSet, OUSTR("Transparency") );
407         getPropertyValue( nRotation, xPropSet, OUSTR("RotateAngle") );
408 
409         GraphicAttr aGraphAttrs;
410         aGraphAttrs.SetDrawMode( (GraphicDrawMode)eColorMode );
411         aGraphAttrs.SetLuminance( nLuminance );
412         aGraphAttrs.SetContrast( nContrast );
413         aGraphAttrs.SetChannelR( nRed );
414         aGraphAttrs.SetChannelG( nGreen );
415         aGraphAttrs.SetChannelB( nBlue );
416         aGraphAttrs.SetGamma( nGamma );
417         aGraphAttrs.SetTransparency( static_cast<sal_uInt8>(nTransparency) );
418         aGraphAttrs.SetRotation( static_cast<sal_uInt16>(nRotation*10) );
419 
420         text::GraphicCrop aGraphCrop;
421         if( getPropertyValue( aGraphCrop, xPropSet, OUSTR("GraphicCrop") ))
422         {
423             aGraphAttrs.SetCrop( aGraphCrop.Left,
424                                  aGraphCrop.Top,
425                                  aGraphCrop.Right,
426                                  aGraphCrop.Bottom );
427         }
428 
429         // fetch readily transformed and color-modified
430         // graphic
431         // ---------------------------------------------
432 
433         Graphic aGraphic(
434             aGraphicObject.GetTransformedGraphic(
435                 aGraphicObject.GetPrefSize(),
436                 aGraphicObject.GetPrefMapMode(),
437                 aGraphAttrs ) );
438 
439         return DrawShape::create( xCurrShape,
440                                   mxPage,
441                                   mnAscendingPrio,
442                                   aGraphic,
443                                   mrContext );
444     }
445     else
446     {
447         return DrawShape::create( xCurrShape,
448                                   mxPage,
449                                   mnAscendingPrio,
450                                   false,
451                                   mrContext );
452     }
453 }
454 
455 bool ShapeImporter::isSkip(
456     uno::Reference<beans::XPropertySet> const& xPropSet,
457     rtl::OUString const& shapeType,
458     uno::Reference< drawing::XLayer> const& xLayer )
459 {
460     // skip empty presentation objects:
461     bool bEmpty = false;
462     if( getPropertyValue( bEmpty,
463                           xPropSet,
464                           OUSTR("IsEmptyPresentationObject")) &&
465         bEmpty )
466     {
467         return true;
468     }
469 
470     //skip shapes which corresponds to annotations
471     if(xLayer.is())
472     {
473         rtl::OUString layerName;
474         uno::Reference<beans::XPropertySet> xPropLayerSet(
475                                                           xLayer, uno::UNO_QUERY );
476         const uno::Any& a(xPropLayerSet->getPropertyValue(rtl::OUString::createFromAscii("Name")) );
477         bool const bRet = (a >>= layerName);
478         if(bRet)
479         {
480             if( layerName.equals(rtl::OUString::createFromAscii("DrawnInSlideshow")))
481             {
482                 //Transform shapes into PolyPolygons
483                 importPolygons(xPropSet);
484 
485                 return true;
486             }
487         }
488     }
489 
490     // don't export presentation placeholders on masterpage
491     // they can be non empty when user edits the default texts
492     if(mbConvertingMasterPage)
493     {
494         if(shapeType.equalsAsciiL(
495                 RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation."
496                                            "TitleTextShape") ) ||
497             shapeType.equalsAsciiL(
498                 RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation."
499                                            "OutlinerShape") ))
500         {
501             return true;
502         }
503     }
504     return false;
505 }
506 
507 
508 void ShapeImporter::importPolygons(uno::Reference<beans::XPropertySet> const& xPropSet) {
509 
510     drawing::PointSequenceSequence aRetval;
511     sal_Int32			nLineColor=0;
512     double				fLineWidth;
513     getPropertyValue( aRetval, xPropSet, OUSTR("PolyPolygon") );
514     getPropertyValue( nLineColor, xPropSet, OUSTR("LineColor") );
515     getPropertyValue( fLineWidth, xPropSet, OUSTR("LineWidth") );
516 
517 	drawing::PointSequence* pOuterSequence = aRetval.getArray();
518 	awt::Point* pInnerSequence = pOuterSequence->getArray();
519 
520 	::basegfx::B2DPolygon aPoly;
521     basegfx::B2DPoint aPoint;
522     for( sal_Int32 nCurrPoly=0; nCurrPoly<pOuterSequence->getLength(); ++nCurrPoly, ++pInnerSequence )
523     {
524         aPoint.setX((*pInnerSequence).X);
525         aPoint.setY((*pInnerSequence).Y);
526         aPoly.append( aPoint );
527     }
528     UnoViewVector::const_iterator aIter=(mrContext.mrViewContainer).begin();
529     UnoViewVector::const_iterator aEnd=(mrContext.mrViewContainer).end();
530     while(aIter != aEnd)
531     {
532         ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
533             ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( (*aIter)->getCanvas(),
534                                                                           aPoly ) );
535         if( pPolyPoly )
536         {
537                 pPolyPoly->setRGBALineColor( unoColor2RGBColor( nLineColor ).getIntegerColor() );
538                 pPolyPoly->setStrokeWidth(fLineWidth);
539                 pPolyPoly->draw();
540                 maPolygons.push_back(pPolyPoly);
541         }
542         aIter++;
543     }
544 }
545 
546 ShapeSharedPtr ShapeImporter::importBackgroundShape() // throw (ShapeLoadFailedException)
547 {
548     if( maShapesStack.empty() )
549         throw ShapeLoadFailedException();
550 
551     XShapesEntry& rTop = maShapesStack.top();
552     ShapeSharedPtr pBgShape(
553         createBackgroundShape(mxPage,
554                               uno::Reference<drawing::XDrawPage>(
555                                   rTop.mxShapes,
556                                   uno::UNO_QUERY_THROW),
557                               mrContext) );
558     mnAscendingPrio += 1.0;
559 
560     return pBgShape;
561 }
562 
563 ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException)
564 {
565     ShapeSharedPtr pRet;
566     bool bIsGroupShape = false;
567 
568     while( !maShapesStack.empty() && !pRet )
569     {
570         XShapesEntry& rTop = maShapesStack.top();
571         if( rTop.mnPos < rTop.mnCount )
572         {
573             uno::Reference<drawing::XShape> const xCurrShape(
574                 rTop.mxShapes->getByIndex( rTop.mnPos ), uno::UNO_QUERY );
575             ++rTop.mnPos;
576             uno::Reference<beans::XPropertySet> xPropSet(
577                 xCurrShape, uno::UNO_QUERY );
578             if( !xPropSet.is() )
579             {
580                 // we definitely need the properties of
581                 // the shape here. This will also fail,
582                 // if getByIndex did not return a valid
583                 // shape
584                 throw ShapeLoadFailedException();
585             }
586 
587             //Retrieve the layer for the current shape
588             uno::Reference< drawing::XLayer > xDrawnInSlideshow;
589 
590             uno::Reference< drawing::XLayerSupplier > xLayerSupplier(mxPagesSupplier, uno::UNO_QUERY);
591 		    if(xLayerSupplier.is())
592             {
593                 uno::Reference< container::XNameAccess > xNameAccess = xLayerSupplier->getLayerManager();
594 
595 	    	    uno::Reference< drawing::XLayerManager > xLayerManager(xNameAccess, uno::UNO_QUERY);
596 
597 		   	    xDrawnInSlideshow = xLayerManager->getLayerForShape(xCurrShape);
598 		    }
599 
600             rtl::OUString const shapeType( xCurrShape->getShapeType());
601 
602             // is this shape presentation-invisible?
603             if( !isSkip(xPropSet, shapeType, xDrawnInSlideshow) )
604             {
605                 bIsGroupShape = shapeType.equalsAsciiL(
606                     RTL_CONSTASCII_STRINGPARAM(
607                         "com.sun.star.drawing.GroupShape") );
608 
609                 if( rTop.mpGroupShape ) // in group particle mode?
610                 {
611                     pRet.reset( new ShapeOfGroup(
612                                     rTop.mpGroupShape /* container shape */,
613                                     xCurrShape, xPropSet,
614                                     mnAscendingPrio ) );
615                 }
616                 else
617                 {
618                     pRet = createShape( xCurrShape, xPropSet, shapeType );
619                 }
620                 mnAscendingPrio += 1.0;
621             }
622         }
623         if( rTop.mnPos >= rTop.mnCount )
624         {
625             // group or top-level shapes finished:
626             maShapesStack.pop();
627         }
628         if( bIsGroupShape && pRet )
629         {
630             // push new group on the stack: group traversal
631             maShapesStack.push( XShapesEntry( pRet ) );
632         }
633     }
634 
635     return pRet;
636 }
637 
638 bool ShapeImporter::isImportDone() const
639 {
640     return maShapesStack.empty();
641 }
642 
643 PolyPolygonVector ShapeImporter::getPolygons()
644 {
645     return maPolygons;
646 }
647 
648 ShapeImporter::ShapeImporter( uno::Reference<drawing::XDrawPage> const&          xPage,
649                               uno::Reference<drawing::XDrawPage> const&          xActualPage,
650                               uno::Reference<drawing::XDrawPagesSupplier> const& xPagesSupplier,
651                               const SlideShowContext&                            rContext,
652                               sal_Int32                                          nOrdNumStart,
653                               bool                                               bConvertingMasterPage ) :
654     mxPage( xActualPage ),
655     mxPagesSupplier( xPagesSupplier ),
656     mrContext( rContext ),
657     maPolygons(),
658     maShapesStack(),
659     mnAscendingPrio( nOrdNumStart ),
660     mbConvertingMasterPage( bConvertingMasterPage )
661 {
662     uno::Reference<drawing::XShapes> const xShapes(
663         xPage, uno::UNO_QUERY_THROW );
664     maShapesStack.push( XShapesEntry(xShapes) );
665 }
666 
667 } // namespace internal
668 } // namespace presentation
669 
670