From 962df736eff0eea1cd159caa414ef5feb4ed1df4 Mon Sep 17 00:00:00 2001 From: Oliver Bolte Date: Tue, 17 Jul 2007 13:54:35 +0000 Subject: [PATCH] INTEGRATION: CWS presfixes12 (1.1.2); FILE ADDED 2007/01/30 16:43:49 thb 1.1.2.3: #i37778# Made view update/repaint/resize work again; swapped BackgroundShape parameters for correct mtf import 2007/01/29 14:53:39 thb 1.1.2.2: #i37778# Fixed gcc3.4 build breakages; merged in a few fixes from HEAD; added PCH stuff to new files 2007/01/29 14:02:09 thb 1.1.2.1: Issue number: #i37778# Larger slideshow refactoring. Wrote design and coding style manifest, and adapted the code to actually conform to this. In detail: - cleaned up ownership/disposable/weak_ptr story. removed hacks and explicit Disposable implementations, where workaround were available - removed object mutices, where superfluous - reworked EventMultiplexer (using templatized listener class now), added more events. EventMultiplexer now serves as a true blackboard - reworked directory structure: disjunct parts are now physically separated into directories, instantiation happens via factories & abstract interfaces - added CursorManager, to make setting mouse cursor less hackish - reworked DrawShape, to implement SeparateListener pattern - reworked IntrinsicAnimationActivity, to avoid cyclic references - modified hyperlink & shape cursor handling to communicate via EventMultiplexer - renamed & cleaned up files (presentation.cxx now named slideshowimpl.cxx, etc.) - added first version of the z-order fix to layer/layermanager - cleaned up include guards and include syntax --- .../source/engine/shapes/shapeimporter.cxx | 575 ++++++++++++++++++ 1 file changed, 575 insertions(+) create mode 100644 slideshow/source/engine/shapes/shapeimporter.cxx diff --git a/slideshow/source/engine/shapes/shapeimporter.cxx b/slideshow/source/engine/shapes/shapeimporter.cxx new file mode 100644 index 000000000000..0b15ccb4af88 --- /dev/null +++ b/slideshow/source/engine/shapes/shapeimporter.cxx @@ -0,0 +1,575 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: shapeimporter.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2007-07-17 14:54:35 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_slideshow.hxx" + +// must be first +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drawshapesubsetting.hxx" +#include "drawshape.hxx" +#include "backgroundshape.hxx" +#include "mediashape.hxx" +#include "appletshape.hxx" +#include "shapeimporter.hxx" +#include "slideshowexceptions.hxx" +#include "gdimtftools.hxx" +#include "tools.hxx" + +#include +#include + +using namespace com::sun::star; + +namespace slideshow { +namespace internal { + +namespace { + +bool importShapeGraphic( + GraphicObject & o_rGraphic, + uno::Reference const& xPropSet ) +{ + rtl::OUString aURL; + if( !getPropertyValue( aURL, xPropSet, OUSTR("GraphicURL")) || + aURL.getLength() == 0 ) + { + // no or empty property - cannot import shape graphic + return false; + } + + rtl::OUString const aVndUrl( + RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) ); + sal_Int32 nIndex( aURL.indexOf( aVndUrl ) ); + + if(nIndex != -1) + { + // skip past the end of the "vnd..." prefix + nIndex += aVndUrl.getLength(); + + if(nIndex >= aURL.getLength()) + { + OSL_ENSURE( false, "ShapeImporter::importShape(): " + "embedded graphic has no graphic ID" ); + return false; + } + + // unique ID string found in URL, extract + // to separate string + rtl::OUString const aUniqueId( + aURL.copy( nIndex, aURL.getLength() - nIndex ) ); + + // TODO(T2): Creating a GraphicObject is not + // thread safe (internally calls VCL, and has + // unguarded internal singleton mpGlobalMgr) + + // fetch already loaded graphic from graphic manager. + ByteString const aOldString( static_cast(aUniqueId), + RTL_TEXTENCODING_UTF8 ); + o_rGraphic = GraphicObject( aOldString ); + + + if( GRAPHIC_DEFAULT == o_rGraphic.GetType() + || GRAPHIC_NONE == o_rGraphic.GetType() ) + { + // even the GrfMgr does not seem to know this graphic + return false; + } + } + else + { + // no special string found, graphic must be + // external. Load via GraphicIm porter + INetURLObject aTmp( aURL ); + boost::scoped_ptr pGraphicStream( + utl::UcbStreamHelper::CreateStream( + aTmp.GetMainURL( INetURLObject::NO_DECODE ), + STREAM_READ ) ); + if( !pGraphicStream ) + { + OSL_ENSURE( false, "ShapeImporter::importShape(): " + "cannot create input stream for graphic" ); + return false; + } + + Graphic aTmpGraphic; + if( GraphicConverter::Import( + *pGraphicStream, aTmpGraphic ) != ERRCODE_NONE ) + { + OSL_ENSURE( false, "ShapeImporter::importShape(): " + "Failed to import shape graphic from given URL" ); + return false; + } + + o_rGraphic = GraphicObject( aTmpGraphic ); + } + return true; +} + +/** This shape implementation just acts as a dummy for the layermanager. + Its sole role is for hit test detection of group shapes. +*/ +class ShapeOfGroup : public Shape +{ +public: + ShapeOfGroup( ShapeSharedPtr const& pGroupShape, + uno::Reference const& xShape, + uno::Reference const& xPropSet, + double nPrio ); + + // Shape: + virtual uno::Reference getXShape() const; + virtual void addViewLayer( ViewLayerSharedPtr const& pNewLayer, + bool bRedrawLayer ); + virtual bool removeViewLayer( ViewLayerSharedPtr const& pNewLayer ); + virtual bool clearAllViewLayers(); + virtual bool update() const; + virtual bool render() const; + virtual bool isContentChanged() const; + virtual basegfx::B2DRectangle getBounds() const; + virtual basegfx::B2DRectangle getDomBounds() const; + virtual basegfx::B2DRectangle getUpdateArea() const; + virtual bool isVisible() const; + virtual double getPriority() const; + virtual bool isBackgroundDetached() const; + +private: + ShapeSharedPtr const mpGroupShape; + uno::Reference const mxShape; + double const mnPrio; + basegfx::B2DPoint maPosOffset; + double mnWidth; + double mnHeight; +}; + +ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr const& pGroupShape, + uno::Reference const& xShape, + uno::Reference const& xPropSet, + double nPrio ) : + mpGroupShape(pGroupShape), + mxShape(xShape), + mnPrio(nPrio) +{ + // read bound rect + uno::Any const aTmpRect_( xPropSet->getPropertyValue( OUSTR("BoundRect") )); + awt::Rectangle const aTmpRect( aTmpRect_.get() ); + basegfx::B2DRectangle const groupPosSize( pGroupShape->getBounds() ); + maPosOffset = basegfx::B2DPoint( aTmpRect.X - groupPosSize.getMinX(), + aTmpRect.Y - groupPosSize.getMinY() ); + mnWidth = aTmpRect.Width; + mnHeight = aTmpRect.Height; +} + +uno::Reference ShapeOfGroup::getXShape() const +{ + return mxShape; +} + +void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/, + bool /*bRedrawLayer*/ ) +{ +} + +bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/ ) +{ + return true; +} + +bool ShapeOfGroup::clearAllViewLayers() +{ + return true; +} + +bool ShapeOfGroup::update() const +{ + return true; +} + +bool ShapeOfGroup::render() const +{ + return true; +} + +bool ShapeOfGroup::isContentChanged() const +{ + return false; +} + +basegfx::B2DRectangle ShapeOfGroup::getBounds() const +{ + basegfx::B2DRectangle const groupPosSize( mpGroupShape->getBounds() ); + double const posX = (groupPosSize.getMinX() + maPosOffset.getX()); + double const posY = (groupPosSize.getMinY() + maPosOffset.getY()); + return basegfx::B2DRectangle( posX, posY, posX + mnWidth, posY + mnHeight ); +} + +basegfx::B2DRectangle ShapeOfGroup::getDomBounds() const +{ + return getBounds(); +} + +basegfx::B2DRectangle ShapeOfGroup::getUpdateArea() const +{ + return getBounds(); +} + +bool ShapeOfGroup::isVisible() const +{ + return mpGroupShape->isVisible(); +} + +double ShapeOfGroup::getPriority() const +{ + return mnPrio; +} + +bool ShapeOfGroup::isBackgroundDetached() const +{ + return false; +} + +} // anon namespace + +ShapeSharedPtr ShapeImporter::createShape( + uno::Reference const& xCurrShape, + uno::Reference const& xPropSet, + rtl::OUString const& shapeType ) const +{ + if( shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.MediaShape") )) + { + // Media shape (video etc.). This is a special object + return createMediaShape(xCurrShape, + mnAscendingPrio, + mrContext); + } + else if( shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.PluginShape") )) + { + // PropertyValues to copy from XShape to plugin + static const char* aPropertyValues[] = + { + "PluginURL", + "PluginMimeType", + "PluginCommands" + }; + + // (Netscape)Plugin shape. This is a special object + return createAppletShape( xCurrShape, + mnAscendingPrio, + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + " com.sun.star.comp.sfx2.PluginObject" )), + aPropertyValues, + sizeof(aPropertyValues)/sizeof(*aPropertyValues), + mrContext ); + } + else if( shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.AppletShape") )) + { + // PropertyValues to copy from XShape to applet + static const char* aPropertyValues[] = + { + "AppletCodeBase", + "AppletName", + "AppletCode", + "AppletCommands", + "AppletIsScript" + }; + + // (Java)Applet shape. This is a special object + return createAppletShape( xCurrShape, + mnAscendingPrio, + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.su n.star.comp.sfx2.AppletObject" )), + aPropertyValues, + sizeof(aPropertyValues)/sizeof(*aPropertyValues), + mrContext ); + } + else if( shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.OLE2Shape") )) + { + // #i46224# Mark OLE shapes as foreign content - scan them for + // unsupported actions, and fallback to bitmap, if necessary + return DrawShape::create( xCurrShape, + mxPage, + mnAscendingPrio, + true, + mrContext ); + } + else if( shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "com.sun.star.drawing.GraphicObjectShape") )) + { + GraphicObject aGraphicObject; + + // to get hold of GIF animations, inspect Graphic + // objects more thoroughly (the plain-jane shape + // metafile of course would only contain the first + // animation frame) + if( !importShapeGraphic( aGraphicObject, xPropSet ) ) + return ShapeSharedPtr(); // error loading graphic - + // #142147# no placeholders in + // slideshow + + if( !aGraphicObject.IsAnimated() ) + { + // no animation - simply utilize plain draw shape import + + // import shape as bitmap - either its a bitmap + // anyway, or its a metafile, which currently the + // metafile renderer might not display correctly. + return DrawShape::create( xCurrShape, + mxPage, + mnAscendingPrio, + true, + mrContext ); + } + + + // now extract relevant shape attributes via API + // --------------------------------------------- + + drawing::ColorMode eColorMode( drawing::ColorMode_STANDARD ); + sal_Int16 nLuminance(0); + sal_Int16 nContrast(0); + sal_Int16 nRed(0); + sal_Int16 nGreen(0); + sal_Int16 nBlue(0); + double nGamma(1.0); + sal_Int16 nTransparency(0); + sal_Int32 nRotation(0); + + getPropertyValue( eColorMode, xPropSet, OUSTR("GraphicColorMode") ); + getPropertyValue( nLuminance, xPropSet, OUSTR("AdjustLuminance") ); + getPropertyValue( nContrast, xPropSet, OUSTR("AdjustContrast") ); + getPropertyValue( nRed, xPropSet, OUSTR("AdjustRed") ); + getPropertyValue( nGreen, xPropSet, OUSTR("AdjustGreen") ); + getPropertyValue( nBlue, xPropSet, OUSTR("AdjustBlue") ); + getPropertyValue( nGamma, xPropSet, OUSTR("Gamma") ); + getPropertyValue( nTransparency, xPropSet, OUSTR("Transparency") ); + getPropertyValue( nRotation, xPropSet, OUSTR("RotateAngle") ); + + GraphicAttr aGraphAttrs; + aGraphAttrs.SetDrawMode( (GraphicDrawMode)eColorMode ); + aGraphAttrs.SetLuminance( nLuminance ); + aGraphAttrs.SetContrast( nContrast ); + aGraphAttrs.SetChannelR( nRed ); + aGraphAttrs.SetChannelG( nGreen ); + aGraphAttrs.SetChannelB( nBlue ); + aGraphAttrs.SetGamma( nGamma ); + aGraphAttrs.SetTransparency( static_cast(nTransparency) ); + aGraphAttrs.SetRotation( static_cast(nRotation*10) ); + + text::GraphicCrop aGraphCrop; + if( getPropertyValue( aGraphCrop, xPropSet, OUSTR("GraphicCrop") )) + { + aGraphAttrs.SetCrop( aGraphCrop.Left, + aGraphCrop.Top, + aGraphCrop.Right, + aGraphCrop.Bottom ); + } + + // fetch readily transformed and color-modified + // graphic + // --------------------------------------------- + + Graphic aGraphic( + aGraphicObject.GetTransformedGraphic( + aGraphicObject.GetPrefSize(), + aGraphicObject.GetPrefMapMode(), + aGraphAttrs ) ); + + return DrawShape::create( xCurrShape, + mxPage, + mnAscendingPrio, + aGraphic, + mrContext ); + } + else + { + return DrawShape::create( xCurrShape, + mxPage, + mnAscendingPrio, + false, + mrContext ); + } +} + +bool ShapeImporter::isSkip( + uno::Reference const& xPropSet, + rtl::OUString const& shapeType ) const +{ + // skip empty presentation objects: + bool bEmpty = false; + if( getPropertyValue( bEmpty, + xPropSet, + OUSTR("IsEmptyPresentationObject")) && + bEmpty ) + { + return true; + } + + // don't export presentation placeholders on masterpage + // they can be non empty when user edits the default texts + if(mbConvertingMasterPage) + { + if(shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation." + "TitleTextShape") ) || + shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation." + "OutlinerShape") )) + { + return true; + } + } + return false; +} + +ShapeSharedPtr ShapeImporter::importBackgroundShape() // throw (ShapeLoadFailedException) +{ + if( maShapesStack.empty() ) + throw ShapeLoadFailedException(); + + XShapesEntry& rTop = maShapesStack.top(); + ShapeSharedPtr pBgShape( + createBackgroundShape(mxPage, + uno::Reference( + rTop.mxShapes, + uno::UNO_QUERY_THROW), + mrContext) ); + mnAscendingPrio += 1.0; + + return pBgShape; +} + +ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException) +{ + ShapeSharedPtr pRet; + bool bIsGroupShape = false; + + while( !maShapesStack.empty() && !pRet ) + { + XShapesEntry& rTop = maShapesStack.top(); + if( rTop.mnPos < rTop.mnCount ) + { + uno::Reference const xCurrShape( + rTop.mxShapes->getByIndex( rTop.mnPos ), uno::UNO_QUERY ); + ++rTop.mnPos; + uno::Reference xPropSet( + xCurrShape, uno::UNO_QUERY ); + if( !xPropSet.is() ) + { + // we definitely need the properties of + // the shape here. This will also fail, + // if getByIndex did not return a valid + // shape + throw ShapeLoadFailedException(); + } + + rtl::OUString const shapeType( xCurrShape->getShapeType() ); + + // is this shape presentation-invisible? + if( !isSkip(xPropSet, shapeType) ) + { + bIsGroupShape = shapeType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "com.sun.star.drawing.GroupShape") ); + + if( rTop.mpGroupShape ) // in group particle mode? + { + pRet.reset( new ShapeOfGroup( + rTop.mpGroupShape /* container shape */, + xCurrShape, xPropSet, + mnAscendingPrio ) ); + } + else + { + pRet = createShape( xCurrShape, xPropSet, shapeType ); + } + mnAscendingPrio += 1.0; + } + } + if( rTop.mnPos >= rTop.mnCount ) + { + // group or top-level shapes finished: + maShapesStack.pop(); + } + if( bIsGroupShape && pRet ) + { + // push new group on the stack: group traversal + maShapesStack.push( XShapesEntry( pRet ) ); + } + } + + return pRet; +} + +bool ShapeImporter::isImportDone() const +{ + return maShapesStack.empty(); +} + +ShapeImporter::ShapeImporter( uno::Reference const& xPage, + uno::Reference const& xActualPage, + const SlideShowContext& rContext, + sal_Int32 nOrdNumStart, + bool bConvertingMasterPage ) : + mxPage( xActualPage ), + mrContext( rContext ), + maShapesStack(), + mnAscendingPrio( nOrdNumStart ), + mbConvertingMasterPage( bConvertingMasterPage ) +{ + uno::Reference const xShapes( + xPage, uno::UNO_QUERY_THROW ); + maShapesStack.push( XShapesEntry(xShapes) ); +} + +} // namespace internal +} // namespace presentation +