1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: shapeimporter.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
35 #include <canvas/debug.hxx>
36 #include <vcl/cvtgrf.hxx>
37 #include <tools/urlobj.hxx>
38 #include <tools/stream.hxx>
39 #include <goodies/grfmgr.hxx>
40 #include <unotools/ucbstreamhelper.hxx>
41 #include <unotools/streamwrap.hxx>
42 #include <com/sun/star/awt/Rectangle.hpp>
43 #include <com/sun/star/drawing/ColorMode.hpp>
44 #include <com/sun/star/text/GraphicCrop.hpp>
46 #include "drawshapesubsetting.hxx"
47 #include "drawshape.hxx"
48 #include "backgroundshape.hxx"
49 #include "mediashape.hxx"
50 #include "appletshape.hxx"
51 #include "shapeimporter.hxx"
52 #include "slideshowexceptions.hxx"
53 #include "gdimtftools.hxx"
56 #include <boost/shared_ptr.hpp>
57 #include <boost/scoped_ptr.hpp>
59 using namespace com::sun::star
;
66 bool importShapeGraphic(
67 GraphicObject
& o_rGraphic
,
68 uno::Reference
<beans::XPropertySet
> const& xPropSet
)
71 if( !getPropertyValue( aURL
, xPropSet
, OUSTR("GraphicURL")) ||
72 aURL
.getLength() == 0 )
74 // no or empty property - cannot import shape graphic
78 rtl::OUString
const aVndUrl(
79 RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
80 sal_Int32
nIndex( aURL
.indexOf( aVndUrl
) );
84 // skip past the end of the "vnd..." prefix
85 nIndex
+= aVndUrl
.getLength();
87 if(nIndex
>= aURL
.getLength())
89 OSL_ENSURE( false, "ShapeImporter::importShape(): "
90 "embedded graphic has no graphic ID" );
94 // unique ID string found in URL, extract
96 rtl::OUString
const aUniqueId(
97 aURL
.copy( nIndex
, aURL
.getLength() - nIndex
) );
99 // TODO(T2): Creating a GraphicObject is not
100 // thread safe (internally calls VCL, and has
101 // unguarded internal singleton mpGlobalMgr)
103 // fetch already loaded graphic from graphic manager.
104 ByteString
const aOldString( static_cast<String
>(aUniqueId
),
105 RTL_TEXTENCODING_UTF8
);
106 o_rGraphic
= GraphicObject( aOldString
);
109 if( GRAPHIC_DEFAULT
== o_rGraphic
.GetType()
110 || GRAPHIC_NONE
== o_rGraphic
.GetType() )
112 // even the GrfMgr does not seem to know this graphic
118 // no special string found, graphic must be
119 // external. Load via GraphicIm porter
120 INetURLObject
aTmp( aURL
);
121 boost::scoped_ptr
<SvStream
> pGraphicStream(
122 utl::UcbStreamHelper::CreateStream(
123 aTmp
.GetMainURL( INetURLObject::NO_DECODE
),
125 if( !pGraphicStream
)
127 OSL_ENSURE( false, "ShapeImporter::importShape(): "
128 "cannot create input stream for graphic" );
133 if( GraphicConverter::Import(
134 *pGraphicStream
, aTmpGraphic
) != ERRCODE_NONE
)
136 OSL_ENSURE( false, "ShapeImporter::importShape(): "
137 "Failed to import shape graphic from given URL" );
141 o_rGraphic
= GraphicObject( aTmpGraphic
);
146 /** This shape implementation just acts as a dummy for the layermanager.
147 Its sole role is for hit test detection of group shapes.
149 class ShapeOfGroup
: public Shape
152 ShapeOfGroup( ShapeSharedPtr
const& pGroupShape
,
153 uno::Reference
<drawing::XShape
> const& xShape
,
154 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
158 virtual uno::Reference
<drawing::XShape
> getXShape() const;
159 virtual void addViewLayer( ViewLayerSharedPtr
const& pNewLayer
,
161 virtual bool removeViewLayer( ViewLayerSharedPtr
const& pNewLayer
);
162 virtual bool clearAllViewLayers();
163 virtual bool update() const;
164 virtual bool render() const;
165 virtual bool isContentChanged() const;
166 virtual basegfx::B2DRectangle
getBounds() const;
167 virtual basegfx::B2DRectangle
getDomBounds() const;
168 virtual basegfx::B2DRectangle
getUpdateArea() const;
169 virtual bool isVisible() const;
170 virtual double getPriority() const;
171 virtual bool isBackgroundDetached() const;
174 ShapeSharedPtr
const mpGroupShape
;
175 uno::Reference
<drawing::XShape
> const mxShape
;
177 basegfx::B2DPoint maPosOffset
;
182 ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr
const& pGroupShape
,
183 uno::Reference
<drawing::XShape
> const& xShape
,
184 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
186 mpGroupShape(pGroupShape
),
191 uno::Any
const aTmpRect_( xPropSet
->getPropertyValue( OUSTR("BoundRect") ));
192 awt::Rectangle
const aTmpRect( aTmpRect_
.get
<awt::Rectangle
>() );
193 basegfx::B2DRectangle
const groupPosSize( pGroupShape
->getBounds() );
194 maPosOffset
= basegfx::B2DPoint( aTmpRect
.X
- groupPosSize
.getMinX(),
195 aTmpRect
.Y
- groupPosSize
.getMinY() );
196 mnWidth
= aTmpRect
.Width
;
197 mnHeight
= aTmpRect
.Height
;
200 uno::Reference
<drawing::XShape
> ShapeOfGroup::getXShape() const
205 void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr
const& /*pNewLayer*/,
206 bool /*bRedrawLayer*/ )
210 bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr
const& /*pNewLayer*/ )
215 bool ShapeOfGroup::clearAllViewLayers()
220 bool ShapeOfGroup::update() const
225 bool ShapeOfGroup::render() const
230 bool ShapeOfGroup::isContentChanged() const
235 basegfx::B2DRectangle
ShapeOfGroup::getBounds() const
237 basegfx::B2DRectangle
const groupPosSize( mpGroupShape
->getBounds() );
238 double const posX
= (groupPosSize
.getMinX() + maPosOffset
.getX());
239 double const posY
= (groupPosSize
.getMinY() + maPosOffset
.getY());
240 return basegfx::B2DRectangle( posX
, posY
, posX
+ mnWidth
, posY
+ mnHeight
);
243 basegfx::B2DRectangle
ShapeOfGroup::getDomBounds() const
248 basegfx::B2DRectangle
ShapeOfGroup::getUpdateArea() const
253 bool ShapeOfGroup::isVisible() const
255 return mpGroupShape
->isVisible();
258 double ShapeOfGroup::getPriority() const
263 bool ShapeOfGroup::isBackgroundDetached() const
270 ShapeSharedPtr
ShapeImporter::createShape(
271 uno::Reference
<drawing::XShape
> const& xCurrShape
,
272 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
273 rtl::OUString
const& shapeType
) const
275 if( shapeType
.equalsAsciiL(
276 RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.MediaShape") ))
278 // Media shape (video etc.). This is a special object
279 return createMediaShape(xCurrShape
,
283 else if( shapeType
.equalsAsciiL(
284 RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.PluginShape") ))
286 // PropertyValues to copy from XShape to plugin
287 static const char* aPropertyValues
[] =
294 // (Netscape)Plugin shape. This is a special object
295 return createAppletShape( xCurrShape
,
298 RTL_CONSTASCII_USTRINGPARAM(
299 "com.sun.star.comp.sfx2.PluginObject" )),
301 sizeof(aPropertyValues
)/sizeof(*aPropertyValues
),
304 else if( shapeType
.equalsAsciiL(
305 RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.AppletShape") ))
307 // PropertyValues to copy from XShape to applet
308 static const char* aPropertyValues
[] =
317 // (Java)Applet shape. This is a special object
318 return createAppletShape( xCurrShape
,
321 RTL_CONSTASCII_USTRINGPARAM(
322 "com.sun.star.comp.sfx2.AppletObject" )),
324 sizeof(aPropertyValues
)/sizeof(*aPropertyValues
),
327 else if( shapeType
.equalsAsciiL(
328 RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.OLE2Shape") ))
330 // #i46224# Mark OLE shapes as foreign content - scan them for
331 // unsupported actions, and fallback to bitmap, if necessary
332 return DrawShape::create( xCurrShape
,
338 else if( shapeType
.equalsAsciiL(
339 RTL_CONSTASCII_STRINGPARAM(
340 "com.sun.star.drawing.GraphicObjectShape") ))
342 GraphicObject aGraphicObject
;
344 // to get hold of GIF animations, inspect Graphic
345 // objects more thoroughly (the plain-jane shape
346 // metafile of course would only contain the first
348 if( !importShapeGraphic( aGraphicObject
, xPropSet
) )
349 return ShapeSharedPtr(); // error loading graphic -
350 // #142147# no placeholders in
353 if( !aGraphicObject
.IsAnimated() )
355 // no animation - simply utilize plain draw shape import
357 // import shape as bitmap - either its a bitmap
358 // anyway, or its a metafile, which currently the
359 // metafile renderer might not display correctly.
360 return DrawShape::create( xCurrShape
,
368 // now extract relevant shape attributes via API
369 // ---------------------------------------------
371 drawing::ColorMode
eColorMode( drawing::ColorMode_STANDARD
);
372 sal_Int16
nLuminance(0);
373 sal_Int16
nContrast(0);
378 sal_Int16
nTransparency(0);
379 sal_Int32
nRotation(0);
381 getPropertyValue( eColorMode
, xPropSet
, OUSTR("GraphicColorMode") );
382 getPropertyValue( nLuminance
, xPropSet
, OUSTR("AdjustLuminance") );
383 getPropertyValue( nContrast
, xPropSet
, OUSTR("AdjustContrast") );
384 getPropertyValue( nRed
, xPropSet
, OUSTR("AdjustRed") );
385 getPropertyValue( nGreen
, xPropSet
, OUSTR("AdjustGreen") );
386 getPropertyValue( nBlue
, xPropSet
, OUSTR("AdjustBlue") );
387 getPropertyValue( nGamma
, xPropSet
, OUSTR("Gamma") );
388 getPropertyValue( nTransparency
, xPropSet
, OUSTR("Transparency") );
389 getPropertyValue( nRotation
, xPropSet
, OUSTR("RotateAngle") );
391 GraphicAttr aGraphAttrs
;
392 aGraphAttrs
.SetDrawMode( (GraphicDrawMode
)eColorMode
);
393 aGraphAttrs
.SetLuminance( nLuminance
);
394 aGraphAttrs
.SetContrast( nContrast
);
395 aGraphAttrs
.SetChannelR( nRed
);
396 aGraphAttrs
.SetChannelG( nGreen
);
397 aGraphAttrs
.SetChannelB( nBlue
);
398 aGraphAttrs
.SetGamma( nGamma
);
399 aGraphAttrs
.SetTransparency( static_cast<BYTE
>(nTransparency
) );
400 aGraphAttrs
.SetRotation( static_cast<USHORT
>(nRotation
*10) );
402 text::GraphicCrop aGraphCrop
;
403 if( getPropertyValue( aGraphCrop
, xPropSet
, OUSTR("GraphicCrop") ))
405 aGraphAttrs
.SetCrop( aGraphCrop
.Left
,
411 // fetch readily transformed and color-modified
413 // ---------------------------------------------
416 aGraphicObject
.GetTransformedGraphic(
417 aGraphicObject
.GetPrefSize(),
418 aGraphicObject
.GetPrefMapMode(),
421 return DrawShape::create( xCurrShape
,
429 return DrawShape::create( xCurrShape
,
437 bool ShapeImporter::isSkip(
438 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
439 rtl::OUString
const& shapeType
) const
441 // skip empty presentation objects:
443 if( getPropertyValue( bEmpty
,
445 OUSTR("IsEmptyPresentationObject")) &&
451 // don't export presentation placeholders on masterpage
452 // they can be non empty when user edits the default texts
453 if(mbConvertingMasterPage
)
455 if(shapeType
.equalsAsciiL(
456 RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation."
457 "TitleTextShape") ) ||
458 shapeType
.equalsAsciiL(
459 RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation."
468 ShapeSharedPtr
ShapeImporter::importBackgroundShape() // throw (ShapeLoadFailedException)
470 if( maShapesStack
.empty() )
471 throw ShapeLoadFailedException();
473 XShapesEntry
& rTop
= maShapesStack
.top();
474 ShapeSharedPtr
pBgShape(
475 createBackgroundShape(mxPage
,
476 uno::Reference
<drawing::XDrawPage
>(
478 uno::UNO_QUERY_THROW
),
480 mnAscendingPrio
+= 1.0;
485 ShapeSharedPtr
ShapeImporter::importShape() // throw (ShapeLoadFailedException)
488 bool bIsGroupShape
= false;
490 while( !maShapesStack
.empty() && !pRet
)
492 XShapesEntry
& rTop
= maShapesStack
.top();
493 if( rTop
.mnPos
< rTop
.mnCount
)
495 uno::Reference
<drawing::XShape
> const xCurrShape(
496 rTop
.mxShapes
->getByIndex( rTop
.mnPos
), uno::UNO_QUERY
);
498 uno::Reference
<beans::XPropertySet
> xPropSet(
499 xCurrShape
, uno::UNO_QUERY
);
502 // we definitely need the properties of
503 // the shape here. This will also fail,
504 // if getByIndex did not return a valid
506 throw ShapeLoadFailedException();
509 rtl::OUString
const shapeType( xCurrShape
->getShapeType() );
511 // is this shape presentation-invisible?
512 if( !isSkip(xPropSet
, shapeType
) )
514 bIsGroupShape
= shapeType
.equalsAsciiL(
515 RTL_CONSTASCII_STRINGPARAM(
516 "com.sun.star.drawing.GroupShape") );
518 if( rTop
.mpGroupShape
) // in group particle mode?
520 pRet
.reset( new ShapeOfGroup(
521 rTop
.mpGroupShape
/* container shape */,
522 xCurrShape
, xPropSet
,
527 pRet
= createShape( xCurrShape
, xPropSet
, shapeType
);
529 mnAscendingPrio
+= 1.0;
532 if( rTop
.mnPos
>= rTop
.mnCount
)
534 // group or top-level shapes finished:
537 if( bIsGroupShape
&& pRet
)
539 // push new group on the stack: group traversal
540 maShapesStack
.push( XShapesEntry( pRet
) );
547 bool ShapeImporter::isImportDone() const
549 return maShapesStack
.empty();
552 ShapeImporter::ShapeImporter( uno::Reference
<drawing::XDrawPage
> const& xPage
,
553 uno::Reference
<drawing::XDrawPage
> const& xActualPage
,
554 const SlideShowContext
& rContext
,
555 sal_Int32 nOrdNumStart
,
556 bool bConvertingMasterPage
) :
557 mxPage( xActualPage
),
558 mrContext( rContext
),
560 mnAscendingPrio( nOrdNumStart
),
561 mbConvertingMasterPage( bConvertingMasterPage
)
563 uno::Reference
<drawing::XShapes
> const xShapes(
564 xPage
, uno::UNO_QUERY_THROW
);
565 maShapesStack
.push( XShapesEntry(xShapes
) );
568 } // namespace internal
569 } // namespace presentation