merge the formfield patch from ooo-build
[ooovba.git] / slideshow / source / engine / shapes / shapeimporter.cxx
blob9a7be9fbb2aa088aabdd615d5b039984081a3b90
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: shapeimporter.cxx,v $
10 * $Revision: 1.4 $
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"
34 // must be first
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"
54 #include "tools.hxx"
56 #include <boost/shared_ptr.hpp>
57 #include <boost/scoped_ptr.hpp>
59 using namespace com::sun::star;
61 namespace slideshow {
62 namespace internal {
64 namespace {
66 bool importShapeGraphic(
67 GraphicObject & o_rGraphic,
68 uno::Reference<beans::XPropertySet> const& xPropSet )
70 rtl::OUString aURL;
71 if( !getPropertyValue( aURL, xPropSet, OUSTR("GraphicURL")) ||
72 aURL.getLength() == 0 )
74 // no or empty property - cannot import shape graphic
75 return false;
78 rtl::OUString const aVndUrl(
79 RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
80 sal_Int32 nIndex( aURL.indexOf( aVndUrl ) );
82 if(nIndex != -1)
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" );
91 return false;
94 // unique ID string found in URL, extract
95 // to separate string
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
113 return false;
116 else
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 ),
124 STREAM_READ ) );
125 if( !pGraphicStream )
127 OSL_ENSURE( false, "ShapeImporter::importShape(): "
128 "cannot create input stream for graphic" );
129 return false;
132 Graphic aTmpGraphic;
133 if( GraphicConverter::Import(
134 *pGraphicStream, aTmpGraphic ) != ERRCODE_NONE )
136 OSL_ENSURE( false, "ShapeImporter::importShape(): "
137 "Failed to import shape graphic from given URL" );
138 return false;
141 o_rGraphic = GraphicObject( aTmpGraphic );
143 return true;
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
151 public:
152 ShapeOfGroup( ShapeSharedPtr const& pGroupShape,
153 uno::Reference<drawing::XShape> const& xShape,
154 uno::Reference<beans::XPropertySet> const& xPropSet,
155 double nPrio );
157 // Shape:
158 virtual uno::Reference<drawing::XShape> getXShape() const;
159 virtual void addViewLayer( ViewLayerSharedPtr const& pNewLayer,
160 bool bRedrawLayer );
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;
173 private:
174 ShapeSharedPtr const mpGroupShape;
175 uno::Reference<drawing::XShape> const mxShape;
176 double const mnPrio;
177 basegfx::B2DPoint maPosOffset;
178 double mnWidth;
179 double mnHeight;
182 ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr const& pGroupShape,
183 uno::Reference<drawing::XShape> const& xShape,
184 uno::Reference<beans::XPropertySet> const& xPropSet,
185 double nPrio ) :
186 mpGroupShape(pGroupShape),
187 mxShape(xShape),
188 mnPrio(nPrio)
190 // read bound rect
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
202 return mxShape;
205 void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/,
206 bool /*bRedrawLayer*/ )
210 bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/ )
212 return true;
215 bool ShapeOfGroup::clearAllViewLayers()
217 return true;
220 bool ShapeOfGroup::update() const
222 return true;
225 bool ShapeOfGroup::render() const
227 return true;
230 bool ShapeOfGroup::isContentChanged() const
232 return false;
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
245 return getBounds();
248 basegfx::B2DRectangle ShapeOfGroup::getUpdateArea() const
250 return getBounds();
253 bool ShapeOfGroup::isVisible() const
255 return mpGroupShape->isVisible();
258 double ShapeOfGroup::getPriority() const
260 return mnPrio;
263 bool ShapeOfGroup::isBackgroundDetached() const
265 return false;
268 } // anon namespace
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,
280 mnAscendingPrio,
281 mrContext);
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[] =
289 "PluginURL",
290 "PluginMimeType",
291 "PluginCommands"
294 // (Netscape)Plugin shape. This is a special object
295 return createAppletShape( xCurrShape,
296 mnAscendingPrio,
297 ::rtl::OUString(
298 RTL_CONSTASCII_USTRINGPARAM(
299 "com.sun.star.comp.sfx2.PluginObject" )),
300 aPropertyValues,
301 sizeof(aPropertyValues)/sizeof(*aPropertyValues),
302 mrContext );
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[] =
310 "AppletCodeBase",
311 "AppletName",
312 "AppletCode",
313 "AppletCommands",
314 "AppletIsScript"
317 // (Java)Applet shape. This is a special object
318 return createAppletShape( xCurrShape,
319 mnAscendingPrio,
320 ::rtl::OUString(
321 RTL_CONSTASCII_USTRINGPARAM(
322 "com.sun.star.comp.sfx2.AppletObject" )),
323 aPropertyValues,
324 sizeof(aPropertyValues)/sizeof(*aPropertyValues),
325 mrContext );
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,
333 mxPage,
334 mnAscendingPrio,
335 true,
336 mrContext );
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
347 // animation frame)
348 if( !importShapeGraphic( aGraphicObject, xPropSet ) )
349 return ShapeSharedPtr(); // error loading graphic -
350 // #142147# no placeholders in
351 // slideshow
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,
361 mxPage,
362 mnAscendingPrio,
363 true,
364 mrContext );
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);
374 sal_Int16 nRed(0);
375 sal_Int16 nGreen(0);
376 sal_Int16 nBlue(0);
377 double nGamma(1.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,
406 aGraphCrop.Top,
407 aGraphCrop.Right,
408 aGraphCrop.Bottom );
411 // fetch readily transformed and color-modified
412 // graphic
413 // ---------------------------------------------
415 Graphic aGraphic(
416 aGraphicObject.GetTransformedGraphic(
417 aGraphicObject.GetPrefSize(),
418 aGraphicObject.GetPrefMapMode(),
419 aGraphAttrs ) );
421 return DrawShape::create( xCurrShape,
422 mxPage,
423 mnAscendingPrio,
424 aGraphic,
425 mrContext );
427 else
429 return DrawShape::create( xCurrShape,
430 mxPage,
431 mnAscendingPrio,
432 false,
433 mrContext );
437 bool ShapeImporter::isSkip(
438 uno::Reference<beans::XPropertySet> const& xPropSet,
439 rtl::OUString const& shapeType ) const
441 // skip empty presentation objects:
442 bool bEmpty = false;
443 if( getPropertyValue( bEmpty,
444 xPropSet,
445 OUSTR("IsEmptyPresentationObject")) &&
446 bEmpty )
448 return true;
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."
460 "OutlinerShape") ))
462 return true;
465 return false;
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>(
477 rTop.mxShapes,
478 uno::UNO_QUERY_THROW),
479 mrContext) );
480 mnAscendingPrio += 1.0;
482 return pBgShape;
485 ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException)
487 ShapeSharedPtr pRet;
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 );
497 ++rTop.mnPos;
498 uno::Reference<beans::XPropertySet> xPropSet(
499 xCurrShape, uno::UNO_QUERY );
500 if( !xPropSet.is() )
502 // we definitely need the properties of
503 // the shape here. This will also fail,
504 // if getByIndex did not return a valid
505 // shape
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,
523 mnAscendingPrio ) );
525 else
527 pRet = createShape( xCurrShape, xPropSet, shapeType );
529 mnAscendingPrio += 1.0;
532 if( rTop.mnPos >= rTop.mnCount )
534 // group or top-level shapes finished:
535 maShapesStack.pop();
537 if( bIsGroupShape && pRet )
539 // push new group on the stack: group traversal
540 maShapesStack.push( XShapesEntry( pRet ) );
544 return 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 ),
559 maShapesStack(),
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