diff options
author | Andres Gomez <agomez@igalia.com> | 2013-09-26 20:35:48 +0300 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2013-10-16 10:24:13 +0000 |
commit | c0e3574ce0434d295f7e6f4c66c9656847b22e30 (patch) | |
tree | 97772f5d83186eb1999e512210eb09576a7244dc /oox/source | |
parent | 2eba5391d3fa3232ba2b0a187c4c51736ab2ec3d (diff) |
oox: added methods to lock Smart-Art edition
Added the possibility of rendering the basic shapes generated for a
Smart-Art into a bitmap and replacing them with it in order to not
letting to edit the Smart-Art. This possibility is controlled using a
configuration parameter located at Options -> Load/Save -> MS Office
-> SmartArt to LibreOffice shapes or reverse.
Made the "oox" library to depend on the "drawinglayer" and "svx"
libraries.
Made the "ooxmlexport" C++ unit tests in the "sw" module to depend on
the "drawinglayer" and "svx" components.
Fixed to set to diagram type a new "oox::drawingml::Shape"
representing a Smart-Art in the "getShape" method of the
"oox::shape::ShapeContextHandler" class.
Added the "keepDiagramCompatibilityInfo" and "renderDiagramToGraphic"
protected methods to the "oox::drawingml::Shape"
class. "keepDiagramCompatibilityInfo" is now called after an instance
of type "FRAMETYPE_DIAGRAM" has added all its children in the
"addShape" method and the proper setting is in place.
"keepDiagramCompatibilityInfo" substitutes previous similar code in
the "createAndInsert" method and also calls "renderDiagramToGraphic".
The "renderDiagramToGraphic" renders the basic shapes in a Smart-Art
into a PNG image and replaces these basic shapes with a new
"GraphicObjectShape" filled with the new PNG image. It also sets the
"MoveProtect" and "SizeProtect" properties of the
"GraphicObjectShape".
Change-Id: Ie4002238ff5fae758a5881b03735bf1f0721ed5b
Reviewed-on: https://gerrit.libreoffice.org/6059
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/drawingml/shape.cxx | 173 | ||||
-rw-r--r-- | oox/source/shape/ShapeContextHandler.cxx | 1 |
2 files changed, 152 insertions, 22 deletions
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index f174b34ac98b..f9aa426139c0 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -37,7 +37,10 @@ #include "oox/helper/propertyset.hxx" #include <tools/solar.h> // for the F_PI180 define +#include <tools/gen.hxx> +#include <tools/mapunit.hxx> #include <editeng/unoprnms.hxx> +#include <com/sun/star/awt/Size.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/container/XNameContainer.hpp> @@ -46,14 +49,23 @@ #include <com/sun/star/xml/AttributeData.hpp> #include <com/sun/star/drawing/HomogenMatrix3.hpp> #include <com/sun/star/drawing/TextVerticalAdjust.hpp> +#include <com/sun/star/drawing/GraphicExportFilter.hpp> #include <com/sun/star/text/XText.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/io/XOutputStream.hpp> + #include <basegfx/point/b2dpoint.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <com/sun/star/document/XActionLockable.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include <svl/outstrm.hxx> +#include <unotools/streamwrap.hxx> +#include <unotools/fltrcfg.hxx> +#include <vcl/graph.hxx> +#include <vcl/graphicfilter.hxx> +#include <vcl/svapp.hxx> using namespace ::oox::core; using namespace ::com::sun::star; @@ -222,10 +234,18 @@ void Shape::addShape( Reference< XShapes > xShapes( xShape, UNO_QUERY ); if ( xShapes.is() ) addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap, aMatrix ); + + + if( meFrameType == FRAMETYPE_DIAGRAM ) + { + if( !SvtFilterOptions::Get().IsSmartArt2Shape() ) + keepDiagramCompatibilityInfo( rFilterBase ); + } } } - catch( const Exception& ) + catch( const Exception& e ) { + SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message ); } } @@ -587,27 +607,6 @@ Reference< XShape > Shape::createAndInsert( } } - // ... but for the InteropGrabBag property - const OUString& aGrabBagPropName = OUString::createFromAscii(UNO_NAME_MISC_OBJ_INTEROPGRABBAG); - if( maDiagramDoms.hasElements() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) ) - { - Sequence<PropertyValue> aGrabBag; - xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; - - // we keep the previous items, if present - if (aGrabBag.hasElements()) - { - sal_Int32 length = aGrabBag.getLength(); - aGrabBag.realloc(length+maDiagramDoms.getLength()); - - for(sal_Int32 i = 0; i < maDiagramDoms.getLength(); ++i) - aGrabBag[length+i] = maDiagramDoms[i]; - - xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) ); - } else - xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) ); - } - if( bIsCustomShape ) { if ( mbFlipH ) @@ -654,6 +653,136 @@ Reference< XShape > Shape::createAndInsert( return mxShape; } +void Shape::keepDiagramCompatibilityInfo( XmlFilterBase& rFilterBase ) +{ + try + { + if( !maDiagramDoms.hasElements() ) + return; + + Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW ); + Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); + if ( !xSetInfo.is() ) + return; + + const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ); + if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) ) + return; + + Sequence < PropertyValue > aGrabBag; + xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; + + // We keep the previous items, if present + if ( aGrabBag.hasElements() ) + { + sal_Int32 length = aGrabBag.getLength(); + aGrabBag.realloc( length+maDiagramDoms.getLength() ); + + for( sal_Int32 i = 0; i < maDiagramDoms.getLength(); ++i ) + aGrabBag[length+i] = maDiagramDoms[i]; + + xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) ); + } else + xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) ); + + xSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) ); + xSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) ); + + // Replace existing shapes with a new Graphic Object rendered + // from them + Reference < XShape > xShape( renderDiagramToGraphic( rFilterBase ) ); + Reference < XShapes > xShapes( mxShape, UNO_QUERY_THROW ); + while( xShapes->hasElements() ) + xShapes->remove( Reference < XShape > ( xShapes->getByIndex( 0 ), UNO_QUERY_THROW ) ); + xShapes->add( xShape ); + } + catch( const Exception& e ) + { + SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message ); + } +} + +Reference < XShape > Shape::renderDiagramToGraphic( XmlFilterBase& rFilterBase ) +{ + Reference< XShape > xShape; + + try + { + if( !maDiagramDoms.hasElements() ) + return xShape; + + // Stream in which to place the rendered shape + SvMemoryStream mpTempStream; + Reference < io::XStream > xStream( new utl::OStreamWrapper( mpTempStream ) ); + Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() ); + + // Rendering format + OUString sFormat( "PNG" ); + + // Size of the rendering + awt::Size aActualSize = mxShape->getSize(); + Size aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MAP_CM ) ); + double fPixelsPer100thmm = static_cast < double > ( aResolution.Width() ) / 100000.0; + awt::Size aSize = awt::Size( static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Width ) + 0.5 ), + static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Height ) + 0.5 ) ); + + Sequence< PropertyValue > aFilterData( 7 ); + aFilterData[ 0 ].Name = OUString( "Compression" ); + aFilterData[ 0 ].Value <<= static_cast < sal_Int32 > ( 9 ); + aFilterData[ 1 ].Name = OUString( "Interlaced" ); + aFilterData[ 1 ].Value <<= static_cast < sal_Int32 > ( 1 ); + aFilterData[ 2 ].Name = OUString( "Translucent" ); + aFilterData[ 2 ].Value <<= static_cast < sal_Int32 > ( 1 ); + aFilterData[ 3 ].Name = OUString( "PixelWidth" ); + aFilterData[ 3 ].Value <<= aSize.Width; + aFilterData[ 4 ].Name = OUString( "PixelHeight" ); + aFilterData[ 4 ].Value <<= aSize.Height; + aFilterData[ 5 ].Name = OUString( "LogicalWidth" ); + aFilterData[ 5 ].Value <<= aActualSize.Width; + aFilterData[ 6 ].Name = OUString( "LogicalHeight" ); + aFilterData[ 6 ].Value <<= aActualSize.Height; + + Sequence < PropertyValue > aDescriptor( 3 ); + aDescriptor[ 0 ].Name = OUString( "OutputStream" ); + aDescriptor[ 0 ].Value <<= xOutputStream; + aDescriptor[ 1 ].Name = OUString( "FilterName" ); + aDescriptor[ 1 ].Value <<= sFormat; + aDescriptor[ 2 ].Name = OUString( "FilterData" ); + aDescriptor[ 2 ].Value <<= aFilterData; + + Reference < lang::XComponent > xSourceDoc( mxShape, UNO_QUERY_THROW ); + Reference < XGraphicExportFilter > xGraphicExporter = GraphicExportFilter::create( rFilterBase.getComponentContext() ); + xGraphicExporter->setSourceDocument( xSourceDoc ); + xGraphicExporter->filter( aDescriptor ); + + mpTempStream.Seek( STREAM_SEEK_TO_BEGIN ); + + Graphic aGraphic; + GraphicFilter aFilter( sal_False ); + if ( !aFilter.ImportGraphic( aGraphic, "", mpTempStream, GRFILTER_FORMAT_NOTFOUND, NULL, 0, static_cast < Sequence < PropertyValue >* > ( NULL ), NULL ) == GRFILTER_OK ) + { + SAL_WARN( "oox.drawingml", OSL_THIS_FUNC + << "Unable to import rendered stream into graphic object" ); + return xShape; + } + + Reference < graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() ); + Reference < lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW ); + xShape = Reference < XShape > ( xServiceFact->createInstance( OUString( "com.sun.star.drawing.GraphicObjectShape" ) ), UNO_QUERY_THROW ); + Reference < XPropertySet > xPropSet( xShape, UNO_QUERY_THROW ); + xPropSet->setPropertyValue( OUString( "Graphic" ), Any( xGraphic ) ); + xPropSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) ); + xPropSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) ); + xPropSet->setPropertyValue( OUString( "Name" ), Any( OUString( "RenderedShapes" ) ) ); + } + catch( const Exception& e ) + { + SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message ); + } + + return xShape; +} + void Shape::setTextBody(const TextBodyPtr & pTextBody) { mpTextBody = pTextBody; diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index 96d484937975..dbbd41d71623 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -356,6 +356,7 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException) DiagramGraphicDataContext* pDiagramGraphicDataContext = dynamic_cast<DiagramGraphicDataContext*>(mxDiagramShapeContext.get()); OUString aFragmentPath(pDiagramGraphicDataContext->getFragmentPathFromRelId(*aIt)); oox::drawingml::ShapePtr pShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) ); + pShapePtr->setDiagramType(); mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr)); uno::Sequence<beans::PropertyValue> aValue(mpShape->getDiagramDoms()); |