[Libreoffice-commits] .: Branch 'distro/suse/suse-3.6' - oox/inc oox/source sw/qa writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Dec 17 04:01:18 PST 2012


 oox/inc/oox/vml/vmlshape.hxx                          |    6 +
 oox/inc/oox/vml/vmltextbox.hxx                        |   11 ++
 oox/inc/oox/vml/vmltextboxcontext.hxx                 |    1 
 oox/source/vml/vmlshape.cxx                           |   81 +++++++++---------
 oox/source/vml/vmlshapecontext.cxx                    |   11 +-
 oox/source/vml/vmltextbox.cxx                         |   38 +++++++-
 oox/source/vml/vmltextboxcontext.cxx                  |   45 ++++++++++
 sw/qa/extras/ooxmltok/ooxmltok.cxx                    |   35 ++-----
 sw/qa/extras/swmodeltestbase.hxx                      |   10 ++
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   42 +++++----
 10 files changed, 190 insertions(+), 90 deletions(-)

New commits:
commit 2f47c9525f293481fdb07761de25cef83e76e2e8
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Wed Aug 29 09:25:40 2012 +0100

    n#792778 DOCX import: parse group shapes in oox only
    
    Previously textframes inside groupshapes were tried to be imported as
    TextFrames, but then their addition to a GroupShape failed, so the text
    simply ended up as a normal paragraph. Fix this by importing members of
    groupshapes as drawinglayer objects, just like how the WW8 import does.
    
    Also fix two testcases, which implicitely tested that the groupshape VML
    element is ignored on import.
    
    (cherry picked from commits 7fe05dc95d0c9a584e07483c04b13c071d55293f and
    d5c934d150cb6cea5f96cbbee4fb5e8312bf027e)
    
    Conflicts:
    	oox/source/vml/vmlshape.cxx
    	oox/source/vml/vmltextbox.cxx
    
    Change-Id: I1a9fba8a5fd532203a825e55b1d5996277ea12fa

diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx
index 2bdf16e..68ae1cd 100644
--- a/oox/inc/oox/vml/vmlshape.hxx
+++ b/oox/inc/oox/vml/vmlshape.hxx
@@ -208,7 +208,7 @@ struct ShapeModel
                         ~ShapeModel();
 
     /** Creates and returns a new shape textbox structure. */
-    TextBox&            createTextBox();
+    TextBox&            createTextBox(ShapeTypeModel& rModel);
     /** Creates and returns a new shape client data structure. */
     ClientData&         createClientData();
 };
@@ -290,6 +290,10 @@ protected:
                         implConvertAndInsert(
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                             const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+    /** Used by both RectangleShape and ComplexShape. */
+    com::sun::star::uno::Reference<com::sun::star::drawing::XShape>createPictureObject(
+            const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rxShapes,
+            const com::sun::star::awt::Rectangle& rShapeRect, rtl::OUString& rGraphicPath ) const;
 
 private:
     ::rtl::OUString     maService;          /// Name of the UNO shape service.
diff --git a/oox/inc/oox/vml/vmltextbox.hxx b/oox/inc/oox/vml/vmltextbox.hxx
index ed716de..3f40136 100644
--- a/oox/inc/oox/vml/vmltextbox.hxx
+++ b/oox/inc/oox/vml/vmltextbox.hxx
@@ -33,10 +33,17 @@
 #include <rtl/ustring.hxx>
 #include "oox/helper/helper.hxx"
 #include "oox/dllapi.h"
+#include <com/sun/star/uno/Reference.h>
+
+namespace com { namespace sun { namespace star {
+    namespace drawing { class XShape; }
+} } }
 
 namespace oox {
 namespace vml {
 
+class ShapeTypeModel;
+
 // ============================================================================
 
 /** Font settings for a text portion in a textbox. */
@@ -71,7 +78,7 @@ struct TextPortionModel
 class OOX_DLLPUBLIC TextBox
 {
 public:
-    explicit            TextBox();
+    explicit            TextBox(ShapeTypeModel& rTypeModel);
 
     /** Appends a new text portion to the textbox. */
     void                appendPortion( const TextFontModel& rFont, const ::rtl::OUString& rText );
@@ -82,7 +89,9 @@ public:
     const TextFontModel* getFirstFont() const;
     /** Returns the entire text of all text portions. */
     ::rtl::OUString     getText() const;
+    void convert(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape) const;
 
+    ShapeTypeModel&     mrTypeModel;
     /// Text distance from the border (inset attribute of v:textbox), valid only if set.
     bool borderDistanceSet;
     int borderDistanceLeft, borderDistanceTop, borderDistanceRight, borderDistanceBottom;
diff --git a/oox/inc/oox/vml/vmltextboxcontext.hxx b/oox/inc/oox/vml/vmltextboxcontext.hxx
index abe6395..9aa0998 100644
--- a/oox/inc/oox/vml/vmltextboxcontext.hxx
+++ b/oox/inc/oox/vml/vmltextboxcontext.hxx
@@ -50,6 +50,7 @@ public:
     virtual ::oox::core::ContextHandlerRef
                         onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
     virtual void        onCharacters( const ::rtl::OUString& rChars );
+    virtual void        onStartElement(const AttributeList& rAttribs);
     virtual void        onEndElement();
 
 private:
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index fde972c..e3f2c62 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -236,9 +236,9 @@ ShapeModel::~ShapeModel()
 {
 }
 
-TextBox& ShapeModel::createTextBox()
+TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
 {
-    mxTextBox.reset( new TextBox );
+    mxTextBox.reset( new TextBox(rModel) );
     return *mxTextBox;
 }
 
@@ -480,6 +480,9 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
                     PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
             }
         }
+
+        if (getTextBox())
+            getTextBox()->convert(xShape);
     }
 
     // Import Legacy Fragments (if any)
@@ -504,6 +507,37 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
     return xShape;
 }
 
+Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect, OUString& rGraphicPath ) const
+{
+    Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
+    if( xShape.is() )
+    {
+        XmlFilterBase& rFilter = mrDrawing.getFilter();
+        OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
+        PropertySet aPropSet( xShape );
+        if( !aGraphicUrl.isEmpty() )
+        {
+            aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
+        }
+        uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
+        // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
+        if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
+        {
+            aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
+            aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
+            aPropSet.setProperty(PROP_Opaque, sal_False);
+        }
+
+        lcl_SetAnchorType(aPropSet, maTypeModel);
+
+        if ( maTypeModel.maPositionVerticalRelative == "page" )
+        {
+            aPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
+        }
+    }
+    return xShape;
+}
+
 // ============================================================================
 
 RectangleShape::RectangleShape( Drawing& rDrawing ) :
@@ -513,21 +547,11 @@ RectangleShape::RectangleShape( Drawing& rDrawing ) :
 
 Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const Rectangle& rShapeRect) const
 {
-    XmlFilterBase& rFilter = mrDrawing.getFilter();
     OUString aGraphicPath = getGraphicPath();
 
     // try to create a picture object
     if(!aGraphicPath.isEmpty())
-    {
-        Reference<XShape> xShape = mrDrawing.createAndInsertXShape(CREATE_OUSTRING("com.sun.star.drawing.GraphicObjectShape"), rxShapes, rShapeRect);
-        if (xShape.is())
-        {
-            OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject(aGraphicPath);
-            PropertySet aPropSet(xShape);
-            aPropSet.setProperty(PROP_GraphicURL, aGraphicUrl);
-        }
-        return xShape;
-    }
+        return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
 
     // default: try to create a rectangle shape
     Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
@@ -704,33 +728,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes
 
     // try to create a picture object
     if( !aGraphicPath.isEmpty() )
-    {
-        Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rxShapes, rShapeRect );
-        if( xShape.is() )
-        {
-            OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath );
-            PropertySet aPropSet( xShape );
-            if( !aGraphicUrl.isEmpty() )
-            {
-                aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
-            }
-            // If the shape has an absolute position, set the properties accordingly.
-            if ( maTypeModel.maPosition == "absolute" )
-            {
-                aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
-                aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
-                aPropSet.setProperty(PROP_Opaque, sal_False);
-            }
-
-            lcl_SetAnchorType(aPropSet, maTypeModel);
-
-            if ( maTypeModel.maPositionVerticalRelative == "page" )
-            {
-                aPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
-            }
-        }
-        return xShape;
-    }
+        return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
 
     // default: try to create a custom shape
     return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
@@ -788,6 +786,9 @@ Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >
     catch( Exception& )
     {
     }
+    // Make sure group shapes are inline as well, unless there is an explicit different style.
+    PropertySet aPropertySet(xGroupShape);
+    lcl_SetAnchorType(aPropertySet, maTypeModel);
     return xGroupShape;
 }
 
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index ae00af2..4e21ce9 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -407,10 +407,13 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const Attri
     if( isRootElement() ) switch( nElement )
     {
         case VML_TOKEN( textbox ):
-            // Custom shape in Writer with a textbox are transformed into a frame
-            dynamic_cast<SimpleShape&>( mrShape ).setService(
-                    "com.sun.star.text.TextFrame");
-            return new TextBoxContext( *this, mrShapeModel.createTextBox(), rAttribs,
+            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");
+            }
+            return new TextBoxContext( *this, mrShapeModel.createTextBox(mrShape.getTypeModel()), rAttribs,
                 mrShape.getDrawing().getFilter().getGraphicHelper());
         case VMLX_TOKEN( ClientData ):
             return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs );
diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx
index b4dc7db..965cdfc 100644
--- a/oox/source/vml/vmltextbox.cxx
+++ b/oox/source/vml/vmltextbox.cxx
@@ -29,6 +29,8 @@
 #include "oox/vml/vmltextbox.hxx"
 
 #include <rtl/ustrbuf.hxx>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/text/XTextAppend.hpp>
 
 namespace oox {
 namespace vml {
@@ -37,6 +39,7 @@ namespace vml {
 
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
+using namespace com::sun::star;
 
 // ============================================================================
 
@@ -52,10 +55,9 @@ TextPortionModel::TextPortionModel( const TextFontModel& rFont, const OUString&
 {
 }
 
-// ============================================================================
-
-TextBox::TextBox()
-    : borderDistanceSet( false )
+TextBox::TextBox(ShapeTypeModel& rTypeModel)
+    : mrTypeModel(rTypeModel),
+    borderDistanceSet( false )
 {
 }
 
@@ -77,7 +79,33 @@ OUString TextBox::getText() const
     return aBuffer.makeStringAndClear();
 }
 
-// ============================================================================
+void TextBox::convert(uno::Reference<drawing::XShape> xShape) const
+{
+    uno::Reference<text::XTextAppend> xTextAppend(xShape, uno::UNO_QUERY);
+    for (PortionVector::const_iterator aIt = maPortions.begin(), aEnd = maPortions.end(); aIt != aEnd; ++aIt)
+    {
+        beans::PropertyValue aPropertyValue;
+        std::vector<beans::PropertyValue> aPropVec;
+        const TextFontModel& rFont = aIt->maFont;
+        if (rFont.mobBold.has())
+        {
+            aPropertyValue.Name = "CharWeight";
+            aPropertyValue.Value = uno::makeAny(rFont.mobBold.get() ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL);
+            aPropVec.push_back(aPropertyValue);
+        }
+        if (rFont.monSize.has())
+        {
+            aPropertyValue.Name = "CharHeight";
+            aPropertyValue.Value = uno::makeAny(double(rFont.monSize.get()) / 2.);
+            aPropVec.push_back(aPropertyValue);
+        }
+        uno::Sequence<beans::PropertyValue> aPropSeq(aPropVec.size());
+        beans::PropertyValue* pValues = aPropSeq.getArray();
+        for (std::vector<beans::PropertyValue>::iterator i = aPropVec.begin(); i != aPropVec.end(); ++i)
+            *pValues++ = *i;
+        xTextAppend->appendTextPortion(aIt->maText, aPropSeq);
+    }
+}
 
 } // namespace vml
 } // namespace oox
diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx
index 3f188e3..a808f43 100644
--- a/oox/source/vml/vmltextboxcontext.cxx
+++ b/oox/source/vml/vmltextboxcontext.cxx
@@ -28,6 +28,8 @@
 
 #include "oox/vml/vmlformatting.hxx"
 #include "oox/vml/vmltextboxcontext.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include <com/sun/star/drawing/XShape.hpp>
 
 namespace oox {
 namespace vml {
@@ -77,7 +79,22 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
             OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
             maFont.mobStrikeout = true;
         break;
+        case OOX_TOKEN(dml, blip):
+            {
+                OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(embed));
+                if (oRelId.has())
+                    mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
+            }
+        break;
+        case VML_TOKEN(imagedata):
+            {
+                OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(id));
+                if (oRelId.has())
+                    mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
+            }
+        break;
         case XML_span:
+        case OOX_TOKEN(doc, r):
         break;
         default:
             OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
@@ -87,11 +104,16 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
 ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
 {
     OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" );
+    if (getNamespace(getCurrentElement()) == NMSP_doc)
+        return this;
     return new TextPortionContext( *this, mrTextBox, maFont, nElement, rAttribs );
 }
 
 void TextPortionContext::onCharacters( const OUString& rChars )
 {
+    if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
+        return;
+
     switch( getCurrentElement() )
     {
         case XML_span:
@@ -103,8 +125,24 @@ void TextPortionContext::onCharacters( const OUString& rChars )
     }
 }
 
+void TextPortionContext::onStartElement(const AttributeList& rAttribs)
+{
+    switch (getCurrentElement())
+    {
+        case OOX_TOKEN(doc, b):
+            maFont.mobBold = true;
+        break;
+        case OOX_TOKEN(doc, sz):
+            maFont.monSize = rAttribs.getInteger( OOX_TOKEN(doc, val) );
+        break;
+    }
+}
+
 void TextPortionContext::onEndElement()
 {
+    if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
+        return;
+
     /*  A child element without own child elements may contain a single space
         character, for example:
 
@@ -158,10 +196,17 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att
     {
         case VML_TOKEN( textbox ):
             if( nElement == XML_div ) return this;
+            else if (nElement == OOX_TOKEN(doc, txbxContent)) return this;
         break;
         case XML_div:
             if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs );
         break;
+        case OOX_TOKEN(doc, txbxContent):
+            if (nElement == OOX_TOKEN(doc, p)) return this;
+        break;
+        case OOX_TOKEN(doc, p):
+            if (nElement == OOX_TOKEN(doc, r)) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs );
+        break;
     }
     return 0;
 }
diff --git a/sw/qa/extras/ooxmltok/ooxmltok.cxx b/sw/qa/extras/ooxmltok/ooxmltok.cxx
index 6dd7927..e812c06 100644
--- a/sw/qa/extras/ooxmltok/ooxmltok.cxx
+++ b/sw/qa/extras/ooxmltok/ooxmltok.cxx
@@ -228,29 +228,19 @@ void Test::testN751077()
     load( "n751077.docx" );
 
 /*
-enum = ThisComponent.Text.createEnumeration
-enum.NextElement
-para = enum.NextElement
-xray para.String
-xray para.PageStyleName
+xray ThisComponent.DrawPage(1).getByIndex(0).String
+xray ThisComponent.DrawPage(1).getByIndex(0).Anchor.PageStyleName
 */
-    uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
-    uno::Reference<container::XEnumerationAccess> paraEnumAccess(textDocument->getText(), uno::UNO_QUERY);
-    // list of paragraphs
-    uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
-    // go to 1st paragraph
-    (void) paraEnum->nextElement();
-    // get the 2nd paragraph
-    uno::Reference<uno::XInterface> paragraph(paraEnum->nextElement(), uno::UNO_QUERY);
-    // text of the paragraph
-    uno::Reference<text::XTextRange> text(paragraph, uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL( OUString( "TEXT1" ), text->getString());
-    // we want to test the paragraph is on the first page (it was put onto another page without the fix),
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xTextDocument, uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+    uno::Reference<drawing::XShapes> xShapes(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xShape(xShapes->getByIndex(0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("TEXT1"), xShape->getString());
+    // we want to test the textbox is on the first page (it was put onto another page without the fix),
     // use a small trick and instead of checking the page layout, check the page style
-    uno::Reference<beans::XPropertySet> paragraphProperties(paragraph, uno::UNO_QUERY);
-    OUString pageStyle;
-    paragraphProperties->getPropertyValue( "PageStyleName" ) >>= pageStyle;
-    CPPUNIT_ASSERT_EQUAL( OUString( "First Page" ), pageStyle );
+    uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("First Page"), getProperty<OUString>(xTextContent->getAnchor(), "PageStyleName"));
 }
 
 void Test::testN705956_1()
@@ -266,8 +256,9 @@ xray graphic.Size
     uno::Reference<drawing::XDrawPageSupplier> drawPageSupplier(textDocument, uno::UNO_QUERY);
     uno::Reference<drawing::XDrawPage> drawPage = drawPageSupplier->getDrawPage();
     CPPUNIT_ASSERT_EQUAL( sal_Int32( 1 ), drawPage->getCount());
+    uno::Reference<drawing::XShapes> shapes(drawPage->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<drawing::XShape> image;
-    drawPage->getByIndex(0) >>= image;
+    shapes->getByIndex(0) >>= image;
     uno::Reference<beans::XPropertySet> imageProperties(image, uno::UNO_QUERY);
     uno::Reference<graphic::XGraphic> graphic;
     imageProperties->getPropertyValue( "Graphic" ) >>= graphic;
diff --git a/sw/qa/extras/swmodeltestbase.hxx b/sw/qa/extras/swmodeltestbase.hxx
index 347d408..46c5426 100644
--- a/sw/qa/extras/swmodeltestbase.hxx
+++ b/sw/qa/extras/swmodeltestbase.hxx
@@ -26,6 +26,7 @@
  */
 
 #include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
 
 #include <test/bootstrapfixture.hxx>
 #include <unotest/macros_test.hxx>
@@ -74,6 +75,15 @@ protected:
         return aBuf.getLength();
     }
 
+    template< typename T >
+    T getProperty( uno::Reference< uno::XInterface > obj, const rtl::OUString& name ) const
+    {
+        uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
+        T data = T();
+        properties->getPropertyValue( name ) >>= data;
+        return data;
+    }
+
     uno::Reference<lang::XComponent> mxComponent;
 };
 
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index cc02c62..46ff0c5 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -2078,6 +2078,7 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext
 {
     uno::Reference< xml::sax::XFastContextHandler > xContextHandler;
 
+    bool bGroupShape = Element == Token_t(NS_vml | OOXML_group);
     sal_uInt32 nNamespace = Element & 0xffff0000;
 
     switch (nNamespace)
@@ -2085,26 +2086,33 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext
         case NS_wordprocessingml:
         case NS_vml_wordprocessingDrawing:
         case NS_office:
-            xContextHandler.set(OOXMLFactory::getInstance()->createFastChildContextFromStart(this, Element));
-            break;
+            if (!bGroupShape)
+                xContextHandler.set(OOXMLFactory::getInstance()->createFastChildContextFromStart(this, Element));
+        // no break;
         default:
-            if (mrShapeContext.is())
+            if (!xContextHandler.is())
             {
-                uno::Reference<XFastContextHandler> pChildContext =
-                mrShapeContext->createFastChildContext(Element, Attribs);
-
-                OOXMLFastContextHandlerWrapper * pWrapper =
-                new OOXMLFastContextHandlerWrapper(this, pChildContext);
-
-                pWrapper->addNamespace(NS_wordprocessingml);
-                pWrapper->addNamespace(NS_vml_wordprocessingDrawing);
-                pWrapper->addNamespace(NS_office);
-                pWrapper->addToken( NS_vml|OOXML_textbox );
-
-                xContextHandler.set(pWrapper);
+                if (mrShapeContext.is())
+                {
+                    uno::Reference<XFastContextHandler> pChildContext =
+                        mrShapeContext->createFastChildContext(Element, Attribs);
+
+                    OOXMLFastContextHandlerWrapper * pWrapper =
+                        new OOXMLFastContextHandlerWrapper(this, pChildContext);
+
+                    if (!bGroupShape)
+                    {
+                        pWrapper->addNamespace(NS_wordprocessingml);
+                        pWrapper->addNamespace(NS_vml_wordprocessingDrawing);
+                        pWrapper->addNamespace(NS_office);
+                        pWrapper->addToken( NS_vml|OOXML_textbox );
+                    }
+
+                    xContextHandler.set(pWrapper);
+                }
+                else
+                    xContextHandler.set(this);
             }
-            else
-                xContextHandler.set(this);
             break;
     }
 


More information about the Libreoffice-commits mailing list