[Libreoffice-commits] core.git: 2 commits - include/oox oox/source sc/source sw/CppunitTest_sw_ooxmlimport.mk sw/qa writerfilter/source

Tamás Zolnai tamas.zolnai at collabora.com
Wed Aug 9 17:08:13 UTC 2017


 include/oox/vml/vmldrawing.hxx                      |    5 +++
 include/oox/vml/vmlshapecontext.hxx                 |    9 ++++++
 oox/source/core/fragmenthandler2.cxx                |    1 
 oox/source/ppt/slidefragmenthandler.cxx             |    1 
 oox/source/vml/vmldrawing.cxx                       |   11 ++++++-
 oox/source/vml/vmldrawingfragment.cxx               |    3 +-
 oox/source/vml/vmlshape.cxx                         |   13 +++++---
 oox/source/vml/vmlshapecontext.cxx                  |   18 +++++++++++-
 sc/source/filter/oox/worksheetfragment.cxx          |    2 +
 sw/CppunitTest_sw_ooxmlimport.mk                    |    3 +-
 sw/qa/extras/ooxmlimport/data/activex_checkbox.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx            |   29 ++++++++++++++++++++
 writerfilter/source/ooxml/model.xml                 |   24 ----------------
 13 files changed, 85 insertions(+), 34 deletions(-)

New commits:
commit 4a764319cbad4e2589cc105145ac27defbf49ff6
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Wed Aug 9 16:06:17 2017 +0200

    tdf#91384: DOCX: import ActiveX controls
    
    Change-Id: Iebf2ff65fcec3231acfc962fb2f1abc2ed2dc67a
    Reviewed-on: https://gerrit.libreoffice.org/40930
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/oox/vml/vmldrawing.hxx b/include/oox/vml/vmldrawing.hxx
index e9309f6c8497..e75fd480b82f 100644
--- a/include/oox/vml/vmldrawing.hxx
+++ b/include/oox/vml/vmldrawing.hxx
@@ -81,6 +81,7 @@ struct OOX_DLLPUBLIC ControlInfo
     OUString     maShapeId;          ///< Shape identifier for shape lookup.
     OUString     maFragmentPath;     ///< Path to the fragment describing the form control properties.
     OUString     maName;             ///< Programmatical name of the form control.
+    bool         mbTextContentShape; ///< Whether this control shape will be imported to Writer or not (has AnchorType poperty or not).
 
     explicit            ControlInfo();
 
diff --git a/include/oox/vml/vmlshapecontext.hxx b/include/oox/vml/vmlshapecontext.hxx
index fe7afb417b52..f73055b3355f 100644
--- a/include/oox/vml/vmlshapecontext.hxx
+++ b/include/oox/vml/vmlshapecontext.hxx
@@ -178,6 +178,15 @@ public:
                         onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
 };
 
+class ControlShapeContext : public ShapeContextBase
+{
+public:
+    explicit            ControlShapeContext(
+                            ::oox::core::ContextHandler2Helper const & rParent,
+                            ShapeContainer& rShapes,
+                            const AttributeList& rAttribs );
+};
+
 
 } // namespace vml
 } // namespace oox
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index 85d6febc73c5..a222af59443c 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -79,6 +79,7 @@ void OleObjectInfo::setShapeId( sal_Int32 nShapeId )
 }
 
 ControlInfo::ControlInfo()
+    : mbTextContentShape(false)
 {
 }
 
diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx
index c1bed09b73fd..5f7c91f24934 100644
--- a/oox/source/vml/vmldrawingfragment.cxx
+++ b/oox/source/vml/vmldrawingfragment.cxx
@@ -51,7 +51,8 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At
     {
         // DOCX filter handles plain shape elements with this fragment handler
         case VMLDRAWING_WORD:
-            if ( getNamespace( nElement ) == NMSP_vml )
+            if ( getNamespace( nElement ) == NMSP_vml
+                 || nElement == W_TOKEN(control) ) // Control shape also defined as a vml shape
                 return ShapeContextBase::createShapeContext( *this, mrDrawing.getShapes(), nElement, rAttribs );
         break;
 
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 2d03cb7e38e0..b51a9020393f 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -1185,18 +1185,21 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes
     const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
     if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
     {
-        OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
-        OUString aShapeName = getShapeName();
-        if( !aShapeName.isEmpty() )
+        if( !pControlInfo->maName.isEmpty() )
         {
-            OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
             // load the control properties from fragment
-            ::oox::ole::EmbeddedControl aControl( aShapeName );
+            ::oox::ole::EmbeddedControl aControl(pControlInfo->maName);
             if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
             {
                 // create and return the control shape (including control model)
                 sal_Int32 nCtrlIndex = -1;
                 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
+
+                if (pControlInfo->mbTextContentShape)
+                {
+                    PropertySet aPropertySet(xShape);
+                    lcl_SetAnchorType(aPropertySet, maTypeModel, mrDrawing.getFilter().getGraphicHelper());
+                }
                 // on error, proceed and try to create picture from replacement image
                 if( xShape.is() )
                     return xShape;
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index eed6154768a1..f49d0ddfae04 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -262,6 +262,9 @@ ContextHandlerRef ShapeContextBase::createShapeContext( ContextHandler2Helper co
         case VML_TOKEN( diagram ):
         case VML_TOKEN( image ):
             return new ShapeContext( rParent, rShapes.createShape< ComplexShape >(), rAttribs );
+
+        case W_TOKEN(control):
+            return new ControlShapeContext( rParent, rShapes, rAttribs );
     }
     return nullptr;
 }
@@ -556,6 +559,17 @@ ContextHandlerRef RectangleShapeContext::onCreateContext( sal_Int32 nElement, co
     return ShapeContext::onCreateContext( nElement, rAttribs );
 }
 
+ControlShapeContext::ControlShapeContext( ::oox::core::ContextHandler2Helper const & rParent, ShapeContainer& rShapes, const AttributeList& rAttribs )
+    : ShapeContextBase (rParent)
+{
+    ::oox::vml::ControlInfo aInfo;
+    aInfo.maShapeId = rAttribs.getXString( W_TOKEN( shapeid ), OUString() );
+    aInfo.maFragmentPath = getFragmentPathFromRelId(rAttribs.getString( R_TOKEN(id), OUString() ));
+    aInfo.maName = rAttribs.getString( W_TOKEN( name ), OUString() );
+    aInfo.mbTextContentShape = true;
+    rShapes.getDrawing().registerControl(aInfo);
+}
+
 } // namespace vml
 } // namespace oox
 
diff --git a/sw/CppunitTest_sw_ooxmlimport.mk b/sw/CppunitTest_sw_ooxmlimport.mk
index 112231f62a04..4638a3d32c61 100644
--- a/sw/CppunitTest_sw_ooxmlimport.mk
+++ b/sw/CppunitTest_sw_ooxmlimport.mk
@@ -83,7 +83,8 @@ $(eval $(call gb_CppunitTest_use_components,sw_ooxmlimport,\
     sw/util/swd \
     sw/util/msword \
     sfx2/util/sfx \
-	starmath/util/sm \
+    sot/util/sot \
+    starmath/util/sm \
     svl/source/fsstor/fsstorage \
     svl/util/svl \
     svtools/util/svt \
diff --git a/sw/qa/extras/ooxmlimport/data/activex_checkbox.docx b/sw/qa/extras/ooxmlimport/data/activex_checkbox.docx
new file mode 100755
index 000000000000..d7415ef5a5c6
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/activex_checkbox.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index bbbf1e65e740..bea70605fdae 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -60,7 +60,9 @@
 #include <unotools/streamwrap.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
 #include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
 #include <test/mtfxmldump.hxx>
 
 class Test : public SwModelTestBase
@@ -1441,6 +1443,33 @@ DECLARE_OOXMLIMPORT_TEST(testGroupShapeFontName, "groupshape-fontname.docx")
     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(getRun(getParagraphOfText(1, xText), 1), "CharFontNameAsian"));
 }
 
+DECLARE_OOXMLIMPORT_TEST( testActiveXCheckbox, "activex_checkbox.docx" )
+{
+    uno::Reference<drawing::XControlShape> xControlShape( getShape(1), uno::UNO_QUERY );
+    CPPUNIT_ASSERT( xControlShape.is() );
+
+    // Check control type
+    uno::Reference<beans::XPropertySet> xPropertySet( xControlShape->getControl(), uno::UNO_QUERY );
+    uno::Reference<lang::XServiceInfo> xServiceInfo( xPropertySet, uno::UNO_QUERY );
+    CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox" ) ) );
+
+    // Check custom label
+    CPPUNIT_ASSERT_EQUAL( OUString( "Custom Caption" ), getProperty<OUString>(xPropertySet, "Label") );
+
+    // Check background color (highlight system color)
+    CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x316AC5 ), getProperty<sal_Int32>(xPropertySet, "BackgroundColor") );
+
+    // Check Text color (active border system color)
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
+
+    // Check state of the checkbox
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPropertySet, "State"));
+
+    // Check anchor type
+    uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
+}
+
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 49fe6f8f44ad..386d51d7c364 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -12455,17 +12455,6 @@
           <ref name="CT_PPrChange"/>
         </element>
       </define>
-      <define name="CT_Control">
-        <attribute name="name">
-          <data type="string"/>
-        </attribute>
-        <attribute name="shapeid">
-          <data type="string"/>
-        </attribute>
-        <attribute name="r:id">
-          <ref name="ST_String"/>
-        </attribute>
-      </define>
       <define name="CT_Background">
         <ref name="CT_PictureBase"/>
         <attribute name="color">
@@ -12496,9 +12485,6 @@
       </define>
       <define name="CT_Object">
         <ref name="CT_PictureBase"/>
-        <element name="control">
-          <ref name="CT_Control"/>
-        </element>
         <attribute name="dxaOrig">
           <data type="string"/>
         </attribute>
@@ -12511,9 +12497,6 @@
         <element name="movie">
           <ref name="CT_Rel"/>
         </element>
-        <element name="control">
-          <ref name="CT_Control"/>
-        </element>
       </define>
       <define name="CT_Drawing">
         <choice>
@@ -17503,11 +17486,6 @@
       <element name="sectPr" tokenid="ooxml:CT_PPr_sectPr"/>
       <element name="pPrChange" tokenid="ooxml:CT_PPr_pPrChange"/>
     </resource>
-    <resource name="CT_Control" resource="Properties">
-      <attribute name="name" tokenid="ooxml:CT_Control_name"/>
-      <attribute name="shapeid" tokenid="ooxml:CT_Control_shapeid"/>
-      <attribute name="r:id" tokenid="ooxml:CT_Control_r_id"/>
-    </resource>
     <resource name="CT_Background" resource="Properties">
       <attribute name="color" tokenid="ooxml:CT_Background_color"/>
       <attribute name="themeColor" tokenid="ooxml:CT_Background_themeColor"/>
@@ -17520,7 +17498,6 @@
     </resource>
     <resource name="CT_PictureBase" resource="Properties"/>
     <resource name="CT_Object" resource="Shape">
-      <element name="control" tokenid="ooxml:CT_Object_control"/>
       <attribute name="dxaOrig" tokenid="ooxml:CT_Object_dxaOrig"/>
       <attribute name="dyaOrig" tokenid="ooxml:CT_Object_dyaOrig"/>
       <action name="end" action="sendPropertiesWithId" sendtokenid="ooxml:object"/>
@@ -17528,7 +17505,6 @@
     </resource>
     <resource name="CT_Picture" resource="Shape">
       <element name="movie" tokenid="ooxml:CT_Picture_movie"/>
-      <element name="control" tokenid="ooxml:CT_Picture_control"/>
       <action name="end" action="sendPropertiesWithId" sendtokenid="ooxml:object"/>
       <action name="end" action="clearProps"/>
     </resource>
commit 286c27e805c4501451857abff19c23b3719146a3
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Wed Aug 9 05:59:44 2017 +0200

    tdf#111548: Better fix for PPTX / XLSX import of ActiveX controls
    
    Follow up fix for:
    c8e3633a352c2fda3aebb9781288a926e7a88c42
    
    Revert part of it and fix the real issue: shapid was
    messed up.
    
    Change-Id: I1fb87a7eae4d9054fe19c203af4aeead7db35898
    Reviewed-on: https://gerrit.libreoffice.org/40929
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/oox/vml/vmldrawing.hxx b/include/oox/vml/vmldrawing.hxx
index 032d29494a44..e9309f6c8497 100644
--- a/include/oox/vml/vmldrawing.hxx
+++ b/include/oox/vml/vmldrawing.hxx
@@ -78,10 +78,14 @@ struct OOX_DLLPUBLIC OleObjectInfo : public ::oox::ole::OleObjectInfo
 /** Contains information about a form control embedded in a draw page. */
 struct OOX_DLLPUBLIC ControlInfo
 {
+    OUString     maShapeId;          ///< Shape identifier for shape lookup.
     OUString     maFragmentPath;     ///< Path to the fragment describing the form control properties.
     OUString     maName;             ///< Programmatical name of the form control.
 
     explicit            ControlInfo();
+
+    /** Sets the string representation of the passed numeric shape identifier. */
+    void                setShapeId( sal_Int32 nShapeId );
 };
 
 
diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx
index 1e4c06ab1cf2..e07bd74bc6ab 100644
--- a/oox/source/core/fragmenthandler2.cxx
+++ b/oox/source/core/fragmenthandler2.cxx
@@ -77,6 +77,7 @@ bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeLis
                     "p14",
                     "p15",
                     "x12ac",
+                    "v",
                 };
 
                 if (std::find(aSupportedNS.begin(), aSupportedNS.end(), aRequires) != aSupportedNS.end())
diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx
index 3a967eea14ce..9d6fcf16aa99 100644
--- a/oox/source/ppt/slidefragmenthandler.cxx
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -139,6 +139,7 @@ SlideFragmentHandler::~SlideFragmentHandler()
     case PPT_TOKEN( control ):
         {
             ::oox::vml::ControlInfo aInfo;
+            aInfo.setShapeId( rAttribs.getInteger( XML_spid, 0 ) );
             aInfo.maFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
             aInfo.maName = rAttribs.getXString( XML_name, OUString() );
             mpSlidePersistPtr->getDrawing()->registerControl( aInfo );
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index 6cb8f4dc7ebe..85d6febc73c5 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -82,6 +82,11 @@ ControlInfo::ControlInfo()
 {
 }
 
+void ControlInfo::setShapeId( sal_Int32 nShapeId )
+{
+    maShapeId = lclGetShapeId(nShapeId);
+}
+
 Drawing::Drawing( XmlFilterBase& rFilter, const Reference< XDrawPage >& rxDrawPage, DrawingType eType ) :
     mrFilter( rFilter ),
     mxDrawPage( rxDrawPage ),
@@ -124,9 +129,10 @@ void Drawing::registerOleObject( const OleObjectInfo& rOleObject )
 
 void Drawing::registerControl( const ControlInfo& rControl )
 {
+    OSL_ENSURE( !rControl.maShapeId.isEmpty(), "Drawing::registerControl - missing form control shape id" );
     OSL_ENSURE( !rControl.maName.isEmpty(), "Drawing::registerControl - missing form control name" );
-    OSL_ENSURE( maControls.count( rControl.maName ) == 0, "Drawing::registerControl - form control already registered" );
-    maControls.insert( ControlInfoMap::value_type( rControl.maName, rControl ) );
+    OSL_ENSURE( maControls.count( rControl.maShapeId ) == 0, "Drawing::registerControl - form control already registered" );
+    maControls.insert( ControlInfoMap::value_type( rControl.maShapeId, rControl ) );
 }
 
 void Drawing::finalizeFragmentImport()
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index 29d1f71f8a4d..eed6154768a1 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -282,10 +282,12 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper const & rParent, Shape
     {
         mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() );
         // get ShapeType and ShapeId from name for compatibility
-        mrTypeModel.maShapeId = mrTypeModel.maShapeName;
         static const OUString sShapeTypePrefix = "shapetype_";
         if( mrTypeModel.maShapeName.startsWith( sShapeTypePrefix ) )
+        {
+            mrTypeModel.maShapeId = mrTypeModel.maShapeName;
             mrTypeModel.moShapeType = mrTypeModel.maShapeName.copy(sShapeTypePrefix.getLength()).toInt32();
+        }
     }
 
     // coordinate system position/size, CSS style
diff --git a/sc/source/filter/oox/worksheetfragment.cxx b/sc/source/filter/oox/worksheetfragment.cxx
index b5d593a46ec4..703593747c22 100644
--- a/sc/source/filter/oox/worksheetfragment.cxx
+++ b/sc/source/filter/oox/worksheetfragment.cxx
@@ -752,6 +752,7 @@ void WorksheetFragment::importOleObject( const AttributeList& rAttribs )
 void WorksheetFragment::importControl( const AttributeList& rAttribs )
 {
     ::oox::vml::ControlInfo aInfo;
+    aInfo.setShapeId( rAttribs.getInteger( XML_shapeId, 0 ) );
     aInfo.maFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
     aInfo.maName = rAttribs.getString( XML_name, OUString() );
     getVmlDrawing().registerControl( aInfo );
@@ -888,6 +889,7 @@ void WorksheetFragment::importOleObject( SequenceInputStream& rStrm )
 void WorksheetFragment::importControl( SequenceInputStream& rStrm )
 {
     ::oox::vml::ControlInfo aInfo;
+    aInfo.setShapeId( rStrm.readInt32() );
     aInfo.maFragmentPath = getFragmentPathFromRelId( BiffHelper::readString( rStrm ) );
     rStrm >> aInfo.maName;
     getVmlDrawing().registerControl( aInfo );


More information about the Libreoffice-commits mailing list