summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/oox/vml/vmlshape.hxx4
-rw-r--r--include/oox/vml/vmlshapecontainer.hxx1
-rw-r--r--oox/qa/unit/data/group-spt202.docxbin0 -> 28238 bytes
-rw-r--r--oox/qa/unit/vml.cxx19
-rw-r--r--oox/source/vml/vmlshape.cxx4
-rw-r--r--oox/source/vml/vmlshapecontainer.cxx5
-rw-r--r--oox/source/vml/vmlshapecontext.cxx21
7 files changed, 53 insertions, 1 deletions
diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index 5ec471299f3f..a4584cad2b7f 100644
--- a/include/oox/vml/vmlshape.hxx
+++ b/include/oox/vml/vmlshape.hxx
@@ -264,6 +264,9 @@ public:
void convertFormatting(
const css::uno::Reference< css::drawing::XShape >& rxShape ) const;
+ void setContainer(ShapeContainer* pContainer);
+ ShapeContainer* getContainer() const;
+
protected:
explicit ShapeBase( Drawing& rDrawing );
@@ -284,6 +287,7 @@ protected:
protected:
ShapeModel maShapeModel; ///< The model structure containing shape data.
+ ShapeContainer* mpContainer = nullptr;
};
diff --git a/include/oox/vml/vmlshapecontainer.hxx b/include/oox/vml/vmlshapecontainer.hxx
index 6be9020051c2..1b72c8a38f3b 100644
--- a/include/oox/vml/vmlshapecontainer.hxx
+++ b/include/oox/vml/vmlshapecontainer.hxx
@@ -126,6 +126,7 @@ template< typename ShapeT >
std::shared_ptr<ShapeT> ShapeContainer::createShape()
{
auto xShape = std::make_shared<ShapeT>( mrDrawing );
+ xShape->setContainer(this);
maShapes.push_back( xShape );
return xShape;
}
diff --git a/oox/qa/unit/data/group-spt202.docx b/oox/qa/unit/data/group-spt202.docx
new file mode 100644
index 000000000000..14bf00b50ed5
--- /dev/null
+++ b/oox/qa/unit/data/group-spt202.docx
Binary files differ
diff --git a/oox/qa/unit/vml.cxx b/oox/qa/unit/vml.cxx
index 833fc449d84c..b27876426956 100644
--- a/oox/qa/unit/vml.cxx
+++ b/oox/qa/unit/vml.cxx
@@ -72,6 +72,25 @@ CPPUNIT_TEST_FIXTURE(OoxVmlTest, testLayoutFlowAltAlone)
CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, nWritingMode);
}
+CPPUNIT_TEST_FIXTURE(OoxVmlTest, testSpt202ShapeType)
+{
+ // Load a document with a groupshape, 2nd child is a <v:shape>, its type has o:spt set to 202
+ // (TextBox).
+ load("group-spt202.docx");
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(1), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: com.sun.star.drawing.TextShape
+ // - Actual : com.sun.star.drawing.CustomShape
+ // and then the size of the group shape was incorrect, e.g. its right edge was outside the page
+ // boundaries.
+ CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.TextShape"), xShape->getShapeType());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index c28f9c44ca5d..3444c1cd2743 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -488,6 +488,10 @@ void ShapeBase::convertFormatting( const Reference< XShape >& rxShape ) const
}
}
+void ShapeBase::setContainer(ShapeContainer* pContainer) { mpContainer = pContainer; }
+
+ShapeContainer* ShapeBase::getContainer() const { return mpContainer; }
+
// protected ------------------------------------------------------------------
awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
index beaac27ea153..d9aa7d9aab6b 100644
--- a/oox/source/vml/vmlshapecontainer.cxx
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -78,6 +78,11 @@ void ShapeContainer::finalizeFragmentImport()
const ShapeType* ShapeContainer::getShapeTypeById( const OUString& rShapeId ) const
{
+ if (maTypesById.empty() && !maTypes.empty())
+ {
+ lclMapShapesById(const_cast<ShapeTypeMap&>(maTypesById), maTypes);
+ }
+
// search in own shape template list
if( const ShapeType* pType = maTypesById.get( rShapeId ).get() )
return pType;
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index d82d22ec2d7f..dbec50102fd1 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -30,6 +30,7 @@
#include <oox/vml/vmltextboxcontext.hxx>
#include <osl/diagnose.h>
+#include <filter/msfilter/escherex.hxx>
namespace oox::vml {
@@ -477,17 +478,35 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const Attri
if( isRootElement() ) switch( nElement )
{
case VML_TOKEN( textbox ):
+ {
+ // Calculate the shape type: map both <rect> and <v:shape> with a textbox shape type to
+ // a TextShape.
+ sal_Int32 nShapeType = 0;
+ if (ShapeContainer* pShapeContainer = mrShape.getContainer())
+ {
+ OUString aType = mrShapeModel.maType;
+ if (!aType.isEmpty() && aType[0] == '#')
+ {
+ aType = aType.copy(1);
+ }
+ if (const ShapeType* pShapeType = pShapeContainer->getShapeTypeById(aType))
+ {
+ nShapeType = pShapeType->getTypeModel().moShapeType.get();
+ }
+ }
+
if (getParentElement() != VML_TOKEN( group ))
{
// Custom shape in Writer with a textbox are transformed into a frame
dynamic_cast<SimpleShape&>( mrShape ).setService(
"com.sun.star.text.TextFrame");
}
- else if (getCurrentElement() == VML_TOKEN(rect))
+ else if (getCurrentElement() == VML_TOKEN(rect) || nShapeType == ESCHER_ShpInst_TextBox)
// Transform only rectangles into a TextShape inside a groupshape.
dynamic_cast<SimpleShape&>(mrShape).setService("com.sun.star.drawing.TextShape");
return new TextBoxContext( *this, mrShapeModel.createTextBox(mrShape.getTypeModel()), rAttribs,
mrShape.getDrawing().getFilter().getGraphicHelper());
+ }
case VMLX_TOKEN( ClientData ):
return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs );
case VMLPPT_TOKEN( textdata ):