summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorAndres Gomez <agomez@igalia.com>2013-09-26 20:35:48 +0300
committerMiklos Vajna <vmiklos@collabora.co.uk>2013-10-16 10:24:13 +0000
commitc0e3574ce0434d295f7e6f4c66c9656847b22e30 (patch)
tree97772f5d83186eb1999e512210eb09576a7244dc /oox
parent2eba5391d3fa3232ba2b0a187c4c51736ab2ec3d (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')
-rw-r--r--oox/Library_oox.mk2
-rw-r--r--oox/source/drawingml/shape.cxx173
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx1
3 files changed, 154 insertions, 22 deletions
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index a20b548c2e48..dd30e70c3735 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_Library_use_libraries,oox,\
cppu \
cppuhelper \
editeng \
+ drawinglayer \
msfilter \
sal \
i18nlangtag \
@@ -46,6 +47,7 @@ $(eval $(call gb_Library_use_libraries,oox,\
sfx \
svl \
svt \
+ svx \
svxcore \
sot \
tl \
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());