[Libreoffice-commits] .: Branch 'libreoffice-3-6' - 3 commits - oox/inc oox/source

Lubos Lunak llunak at kemper.freedesktop.org
Tue Jun 19 02:59:14 PDT 2012


 oox/inc/oox/vml/vmlshapecontainer.hxx    |   31 ++++++++++++++++++++++++-------
 oox/source/shape/ShapeContextHandler.cxx |   13 ++++++++++++-
 oox/source/vml/vmlshapecontainer.cxx     |   22 +++++++++++++++++-----
 3 files changed, 53 insertions(+), 13 deletions(-)

New commits:
commit a8d062de8863bc17eb28675d2aa4f338c08ed061
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Wed Jun 13 18:04:51 2012 +0200

    rework handling the case of recursive ooxml shapes again
    
    Another attempt, whoever has written this apparently didn't consider
    the possibility of recursion at all, and this still feels a bit hackish.
    
    Writerfilter keeps just one oox::shape::ShapeContextHandler object during
    the entire time of parsing the document, because e.g. <v:shapetype> needs
    to be reachable even across VML block (see sw testcases for bnc#705956).
    This however presents a problem when VML contains <w:txbxContent> which
    contains another VML, as this code previously just took whatever has been
    read and returned it to writerfilter, and it broke with recursion.
    So now try to mark recursion entry and returns the right shape.
    
    Related to 36c12c246d886b2d96d7a2d4d0c250db9d925c74 and the previous
    commits it reverted.
    
    Change-Id: I949a6b52ec7540aa59b047c7b6e908b10fb3bdc1

diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx
index 20671bb..f6be8e3 100644
--- a/oox/inc/oox/vml/vmlshapecontainer.hxx
+++ b/oox/inc/oox/vml/vmlshapecontainer.hxx
@@ -32,6 +32,7 @@
 #include <com/sun/star/awt/Rectangle.hpp>
 #include "oox/helper/refmap.hxx"
 #include "oox/helper/refvector.hxx"
+#include <stack>
 
 namespace com { namespace sun { namespace star {
     namespace drawing { class XShapes; }
@@ -92,16 +93,29 @@ public:
     template< typename Functor >
     const ShapeBase*    findShape( const Functor& rFunctor ) const;
 
-    /** Returns the first shape in the collection (Word only). */
-    const ShapeBase*    getFirstShape() const;
+    /**
+      (Word only) Returns the last shape in the collection, if it is after the last
+      mark from pushMark(), and removes it.
+    */
+    boost::shared_ptr< ShapeBase > takeLastShape();
+    /**
+      Adds a recursion mark to the stack. It is possible that a shape contains <w:txbxContent>
+      which contains another shape, and writerfilter needs to know which shape is from the inner
+      ooxml context and which from the outer ooxml context, while it is necessary to keep
+      at least shape types across such blocks. Therefore this function marks beginning
+      of each shape xml block, and takeLastShape() returns only shapes from this block.
+    */
+    void pushMark();
+    /**
+      Removes a recursion mark.
+    */
+    void popMark();
 
     /** Creates and inserts all UNO shapes into the passed container. */
     void                convertAndInsert(
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                             const ShapeParentAnchor* pParentAnchor = 0 ) const;
 
-    inline void                clearShapes( ) { maShapes.clear( ); }
-
 private:
     typedef RefVector< ShapeType >                  ShapeTypeVector;
     typedef RefVector< ShapeBase >                  ShapeVector;
@@ -113,6 +127,7 @@ private:
     ShapeVector         maShapes;           ///< All shape definitions.
     ShapeTypeMap        maTypesById;        ///< All shape templates mapped by identifier.
     ShapeMap            maShapesById;       ///< All shape definitions mapped by identifier.
+    std::stack< size_t > markStack;         ///< Recursion marks from pushMark()/popMark().
 };
 
 // ----------------------------------------------------------------------------
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
index 04e2330..418ca7c 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -190,6 +190,11 @@ void SAL_CALL ShapeContextHandler::startFastElement
         createFastChildContext(Element, Attribs);
     }
 
+    // Entering VML block (startFastElement() is called for the outermost tag),
+    // handle possible recursion.
+    if ( getContextHandler() == getDrawingShapeContext() )
+        mpDrawing->getShapes().pushMark();
+
     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
 
     if (xContextHandler.is())
@@ -201,6 +206,9 @@ void SAL_CALL ShapeContextHandler::startUnknownElement
  const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
+    if ( getContextHandler() == getDrawingShapeContext() )
+        mpDrawing->getShapes().pushMark();
+
     uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
 
     if (xContextHandler.is())
@@ -280,11 +288,11 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException)
         if ( getContextHandler() == getDrawingShapeContext() )
         {
             mpDrawing->finalizeFragmentImport();
-            if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().getFirstShape() )
-            {
+            if( boost::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() )
                 xResult = pShape->convertAndInsert( xShapes );
-                mpDrawing->getShapes( ).clearShapes( );
-            }
+            // Only now remove the recursion mark, because getShape() is called in writerfilter
+            // after endFastElement().
+            mpDrawing->getShapes().popMark();
         }
         else if (mxDiagramShapeContext.is())
         {
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
index 0309839..c30994c 100644
--- a/oox/source/vml/vmlshapecontainer.cxx
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -118,11 +118,26 @@ const ShapeBase* ShapeContainer::getShapeById( const OUString& rShapeId, bool bD
    return 0;
 }
 
-const ShapeBase* ShapeContainer::getFirstShape() const
+boost::shared_ptr< ShapeBase > ShapeContainer::takeLastShape()
 {
-    OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::getFirstShape - illegal call, Word filter only" );
-    OSL_ENSURE( maShapes.size() == 1, "ShapeContainer::getFirstShape - single shape expected" );
-    return maShapes.get( 0 ).get();
+    OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::takeLastShape - illegal call, Word filter only" );
+    assert( !markStack.empty());
+    if( markStack.top() >= maShapes.size())
+        return boost::shared_ptr< ShapeBase >();
+    boost::shared_ptr< ShapeBase > ret = maShapes.back();
+    maShapes.pop_back();
+    return ret;
+}
+
+void ShapeContainer::pushMark()
+{
+    markStack.push( maShapes.size());
+}
+
+void ShapeContainer::popMark()
+{
+    assert( !markStack.empty());
+    markStack.pop();
 }
 
 void ShapeContainer::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
commit b122c9381ae1d589dc097790b1b5cf1fda853c22
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Jun 19 10:07:32 2012 +0200

    oox: fix all vmlshapecontainer doxygen errors
    
    Change-Id: Ieccd1f5e89c550095cd83a3f11939eec210f789e

diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx
index 2880625..20671bb 100644
--- a/oox/inc/oox/vml/vmlshapecontainer.hxx
+++ b/oox/inc/oox/vml/vmlshapecontainer.hxx
@@ -108,11 +108,11 @@ private:
     typedef RefMap< ::rtl::OUString, ShapeType >    ShapeTypeMap;
     typedef RefMap< ::rtl::OUString, ShapeBase >    ShapeMap;
 
-    Drawing&            mrDrawing;          /// The VML drawing page that contains this shape.
-    ShapeTypeVector     maTypes;            /// All shape templates.
-    ShapeVector         maShapes;           /// All shape definitions.
-    ShapeTypeMap        maTypesById;        /// All shape templates mapped by identifier.
-    ShapeMap            maShapesById;       /// All shape definitions mapped by identifier.
+    Drawing&            mrDrawing;          ///< The VML drawing page that contains this shape.
+    ShapeTypeVector     maTypes;            ///< All shape templates.
+    ShapeVector         maShapes;           ///< All shape definitions.
+    ShapeTypeMap        maTypesById;        ///< All shape templates mapped by identifier.
+    ShapeMap            maShapesById;       ///< All shape definitions mapped by identifier.
 };
 
 // ----------------------------------------------------------------------------
commit 798aef37ac80ceaeeed75adebb53992bdf57bb0d
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Jun 12 17:11:10 2012 +0200

    Revert "rework getting shape for the .docx import filter"
    
    Stupid containers with shared_ptr. Trying to remove the object
    from it gets it deleted because it's owned by the shared_ptr
    and there's no sensible way to wrestle it out of it. This will
    need to be redone somehow.
    
    This reverts commit 04d600d4be7c50db4b3b505039eb8bc96856f593.

diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx
index 9b11c6c..2880625 100644
--- a/oox/inc/oox/vml/vmlshapecontainer.hxx
+++ b/oox/inc/oox/vml/vmlshapecontainer.hxx
@@ -92,14 +92,16 @@ public:
     template< typename Functor >
     const ShapeBase*    findShape( const Functor& rFunctor ) const;
 
-    /** Returns and removes the last shape in the collection (Word only). */
-    const ShapeBase*    takeLastShape();
+    /** Returns the first shape in the collection (Word only). */
+    const ShapeBase*    getFirstShape() const;
 
     /** Creates and inserts all UNO shapes into the passed container. */
     void                convertAndInsert(
                             const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
                             const ShapeParentAnchor* pParentAnchor = 0 ) const;
 
+    inline void                clearShapes( ) { maShapes.clear( ); }
+
 private:
     typedef RefVector< ShapeType >                  ShapeTypeVector;
     typedef RefVector< ShapeBase >                  ShapeVector;
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
index 241ae86..04e2330 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -280,8 +280,11 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException)
         if ( getContextHandler() == getDrawingShapeContext() )
         {
             mpDrawing->finalizeFragmentImport();
-            if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().takeLastShape() )
+            if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().getFirstShape() )
+            {
                 xResult = pShape->convertAndInsert( xShapes );
+                mpDrawing->getShapes( ).clearShapes( );
+            }
         }
         else if (mxDiagramShapeContext.is())
         {
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
index 144aa78..0309839 100644
--- a/oox/source/vml/vmlshapecontainer.cxx
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -118,14 +118,11 @@ const ShapeBase* ShapeContainer::getShapeById( const OUString& rShapeId, bool bD
    return 0;
 }
 
-const ShapeBase* ShapeContainer::takeLastShape()
+const ShapeBase* ShapeContainer::getFirstShape() const
 {
-    assert( mrDrawing.getType() == VMLDRAWING_WORD );
-    if( maShapes.empty())
-        return NULL;
-    const ShapeBase* ret = maShapes.back().get();
-    maShapes.pop_back();
-    return ret;
+    OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::getFirstShape - illegal call, Word filter only" );
+    OSL_ENSURE( maShapes.size() == 1, "ShapeContainer::getFirstShape - single shape expected" );
+    return maShapes.get( 0 ).get();
 }
 
 void ShapeContainer::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const


More information about the Libreoffice-commits mailing list