From 3272c1eb5563f3bda2caa24f32b1018372622109 Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Mon, 1 Oct 2018 03:21:59 +0200 Subject: related tdf#100074: prepare group shapes text input via writerfilter Put various preps into place, that enable us to read txbxContent from group shape children via the writerfilter parser, which gets us much more features Also: - store shapecontexthandler on wrapper class in writerfilter - move adding children shapes to ctor, not dtor - remove RuntimeException in Writer's XShapes::add(), aligns this with Draw/Impress API semantics, and helps here when trying to add the same shape a 2nd time (which we then simply ignore) - make oox's Shape notion of 'inside group' less ad-hoc - make SwTextBoxHelper::getTextRectangle() cope with more than CustomShape - so passing in a group shape will also yield some sensible bounding box - have SwTextBoxHelper handle group content, too - derive WpsContext from ShapeContext, so we can later substitute it for that inside WpgContext - keep WpgContext::onCreateContext() _for the moment_ with the old delegation to ShapeContext (needs to use WpsContext to enable writerfilter text input) Change-Id: I2b0f0583e21137f3321a8dc13823058b14d19773 Reviewed-on: https://gerrit.libreoffice.org/65914 Tested-by: Jenkins Reviewed-by: Thorsten Behrens --- oox/source/drawingml/shape.cxx | 16 ++++++++------- oox/source/drawingml/shapecontext.cxx | 4 ++-- oox/source/drawingml/shapegroupcontext.cxx | 4 ++-- oox/source/shape/ShapeContextHandler.cxx | 10 +++++++-- oox/source/shape/WpgContext.cxx | 4 ++++ oox/source/shape/WpsContext.cxx | 33 ++++++++++++------------------ oox/source/shape/WpsContext.hxx | 14 ++++++------- 7 files changed, 44 insertions(+), 41 deletions(-) (limited to 'oox') diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 45d7946816d3..8449082bc774 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -256,7 +256,8 @@ void Shape::addShape( const Reference< XShapes >& rxShapes, const basegfx::B2DHomMatrix& aTransformation, FillProperties& rShapeOrParentShapeFillProps, - ShapeIdMap* pShapeMap ) + ShapeIdMap* pShapeMap, + bool bInGroup ) { SAL_INFO("oox.drawingml", "Shape::addShape: id='" << msId << "'"); @@ -266,7 +267,7 @@ void Shape::addShape( if( !sServiceName.isEmpty() ) { basegfx::B2DHomMatrix aMatrix( aTransformation ); - Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, false, false, aMatrix, rShapeOrParentShapeFillProps ) ); + Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, false, false, aMatrix, rShapeOrParentShapeFillProps, bInGroup ) ); if( pShapeMap && !msId.isEmpty() ) { @@ -391,7 +392,7 @@ void Shape::addChildren( for (auto const& child : rMaster.maChildren) { child->setMasterTextListStyle( mpMasterTextListStyle ); - child->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), pShapeMap ); + child->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), pShapeMap, true ); } } @@ -586,7 +587,8 @@ Reference< XShape > const & Shape::createAndInsert( bool bClearText, bool bDoNotInsertEmptyTextBody, basegfx::B2DHomMatrix& aParentTransformation, - FillProperties& rShapeOrParentShapeFillProps ) + FillProperties& rShapeOrParentShapeFillProps, + bool bInGroup ) { bool bIsEmbMedia = false; SAL_INFO("oox.drawingml", "Shape::createAndInsert: id='" << msId << "' service='" << rServiceName << "'"); @@ -672,8 +674,8 @@ Reference< XShape > const & Shape::createAndInsert( maSize.Height ? maSize.Height : 1.0 ); } - bool bInGroup = !aParentTransformation.isIdentity(); - if( mbFlipH || mbFlipV || mnRotation != 0 || bInGroup ) + bool bNoTranslation = !aParentTransformation.isIdentity(); + if( mbFlipH || mbFlipV || mnRotation != 0 || bNoTranslation ) { // calculate object's center basegfx::B2DPoint aCenter(0.5, 0.5); @@ -768,7 +770,7 @@ Reference< XShape > const & Shape::createAndInsert( // tdf#106792 Not needed anymore due to the change in SdrPathObj::NbcResize: // tdf#96674: Guard against zero width or height. - if (bIsWriter && bInGroup) + if (bIsWriter && bNoTranslation) // Writer's draw page is in twips, and these points get passed // to core without any unit conversion when Writer // postprocesses only the group shape itself. diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx index decf063d9dd6..eae01bfe5a6c 100644 --- a/oox/source/drawingml/shapecontext.cxx +++ b/oox/source/drawingml/shapecontext.cxx @@ -54,12 +54,12 @@ ShapeContext::ShapeContext( ContextHandler2Helper const & rParent, ShapePtr cons , mpMasterShapePtr( pMasterShapePtr ) , mpShapePtr( pShapePtr ) { + if( mpMasterShapePtr.get() && mpShapePtr.get() ) + mpMasterShapePtr->addChild( mpShapePtr ); } ShapeContext::~ShapeContext() { - if ( mpMasterShapePtr.get() && mpShapePtr.get() ) - mpMasterShapePtr->addChild( mpShapePtr ); } ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) diff --git a/oox/source/drawingml/shapegroupcontext.cxx b/oox/source/drawingml/shapegroupcontext.cxx index 695cce70bb8f..c916642f1fcc 100644 --- a/oox/source/drawingml/shapegroupcontext.cxx +++ b/oox/source/drawingml/shapegroupcontext.cxx @@ -51,12 +51,12 @@ ShapeGroupContext::ShapeGroupContext( ContextHandler2Helper const & rParent, Sha { if( pMasterShapePtr ) mpGroupShapePtr->setWps(pMasterShapePtr->getWps()); + if( mpMasterShapePtr.get() && mpGroupShapePtr.get() ) + mpMasterShapePtr->addChild( mpGroupShapePtr ); } ShapeGroupContext::~ShapeGroupContext() { - if ( mpMasterShapePtr.get() && mpGroupShapePtr.get() ) - mpMasterShapePtr->addChild( mpGroupShapePtr ); } ContextHandlerRef ShapeGroupContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index b80af12ac15e..2d2894e6e4a7 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -119,7 +119,13 @@ uno::Reference const & ShapeContextHandler::getWp switch (getBaseToken(nStartElement)) { case XML_wsp: - mxWpsContext.set(new WpsContext(*rFragmentHandler, xShape)); + mxWpsContext.set(new WpsContext( + *rFragmentHandler, + xShape, + pMasterShape, + ShapePtr( + new oox::drawingml::Shape( + "com.sun.star.drawing.CustomShape")))); break; default: break; @@ -500,7 +506,7 @@ ShapeContextHandler::getShape() pShape->setPosition(maPosition); pShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties()); xResult = pShape->getXShape(); - mxWpgContext.clear(); + mxSavedShape = xResult; } } else if (mpShape.get() != nullptr) diff --git a/oox/source/shape/WpgContext.cxx b/oox/source/shape/WpgContext.cxx index 95264e53ce15..c297ff16d822 100644 --- a/oox/source/shape/WpgContext.cxx +++ b/oox/source/shape/WpgContext.cxx @@ -9,7 +9,9 @@ #include "WpgContext.hxx" +#include "WpsContext.hxx" #include +#include #include #include #include @@ -49,6 +51,8 @@ oox::core::ContextHandlerRef WpgContext::onCreateContext(sal_Int32 nElementToken // it. oox::drawingml::ShapePtr pShape(new oox::drawingml::Shape("com.sun.star.drawing.CustomShape", /*bDefaultHeight=*/false)); return new oox::drawingml::ShapeContext(*this, mpShape, pShape); + // return new oox::shape::WpsContext(*this, uno::Reference(), + // mpShape, pShape); } case XML_pic: return new oox::drawingml::GraphicShapeContext(*this, mpShape, std::make_shared("com.sun.star.drawing.GraphicObjectShape")); diff --git a/oox/source/shape/WpsContext.cxx b/oox/source/shape/WpsContext.cxx index e196449ec7ed..069c6386462d 100644 --- a/oox/source/shape/WpsContext.cxx +++ b/oox/source/shape/WpsContext.cxx @@ -35,12 +35,11 @@ namespace oox namespace shape { -WpsContext::WpsContext(ContextHandler2Helper const& rParent, uno::Reference xShape) - : ContextHandler2(rParent), +WpsContext::WpsContext(ContextHandler2Helper const& rParent, uno::Reference xShape, const drawingml::ShapePtr& pMasterShapePtr, const drawingml::ShapePtr& pShapePtr ) + : ShapeContext( rParent, pMasterShapePtr, pShapePtr ), mxShape(std::move(xShape)) { - mpShape.reset(new oox::drawingml::Shape("com.sun.star.drawing.CustomShape")); - mpShape->setWps(true); + mpShapePtr->setWps(true); } WpsContext::~WpsContext() = default; @@ -53,12 +52,6 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken break; case XML_cNvCnPr: break; - case XML_cNvSpPr: - break; - case XML_spPr: - return new oox::drawingml::ShapePropertiesContext(*this, *mpShape); - case XML_style: - return new oox::drawingml::ShapeStyleContext(*this, *mpShape); case XML_bodyPr: if (mxShape.is()) { @@ -189,8 +182,8 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken break; case XML_txbx: { - mpShape->getCustomShapeProperties()->setShapeTypeOverride(true); - mpShape->setTextBox(true); + mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true); + mpShapePtr->setTextBox(true); //in case if the textbox is linked, save the attributes //for further processing. if (rAttribs.hasAttribute(XML_id)) @@ -200,18 +193,19 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken { oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ; linkedTxtBoxAttr.id = id.get().toInt32(); - mpShape->setTxbxHasLinkedTxtBox(true); - mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr); + mpShapePtr->setTxbxHasLinkedTxtBox(true); + mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr); } } + return this; } break; case XML_linkedTxbx: { //in case if the textbox is linked, save the attributes //for further processing. - mpShape->getCustomShapeProperties()->setShapeTypeOverride(true); - mpShape->setTextBox(true); + mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true); + mpShapePtr->setTextBox(true); OptValue id = rAttribs.getString(XML_id); OptValue seq = rAttribs.getString(XML_seq); if (id.has() && seq.has()) @@ -219,14 +213,13 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr ; linkedTxtBoxAttr.id = id.get().toInt32(); linkedTxtBoxAttr.seq = seq.get().toInt32(); - mpShape->setTxbxHasLinkedTxtBox(true); - mpShape->setLinkedTxbxAttributes(linkedTxtBoxAttr); + mpShapePtr->setTxbxHasLinkedTxtBox(true); + mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr); } } break; default: - SAL_WARN("oox", "WpsContext::createFastChildContext: unhandled element: " << getBaseToken(nElementToken)); - break; + return ShapeContext::onCreateContext(nElementToken, rAttribs); } return nullptr; } diff --git a/oox/source/shape/WpsContext.hxx b/oox/source/shape/WpsContext.hxx index e05a706c612e..45715606b874 100644 --- a/oox/source/shape/WpsContext.hxx +++ b/oox/source/shape/WpsContext.hxx @@ -11,6 +11,7 @@ #define INCLUDED_OOX_SOURCE_SHAPE_WPSCONTEXT_HXX #include +#include #include namespace com @@ -33,21 +34,18 @@ namespace shape { /// Wps is the drawingML equivalent of v:shape. -class WpsContext final : public oox::core::ContextHandler2 +class WpsContext final : public oox::drawingml::ShapeContext { public: - WpsContext(oox::core::ContextHandler2Helper const& rParent, css::uno::Reference xShape); + WpsContext(oox::core::ContextHandler2Helper const& rParent, + css::uno::Reference xShape, + oox::drawingml::ShapePtr const & pMasterShapePtr, + oox::drawingml::ShapePtr const & pShapePtr); ~WpsContext() override; oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElementToken, const oox::AttributeList& rAttribs) override; - const oox::drawingml::ShapePtr& getShape() const - { - return mpShape; - } - private: - oox::drawingml::ShapePtr mpShape; css::uno::Reference mxShape; }; -- cgit