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.zol...@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 <c...@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zol...@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.zol...@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 <c...@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zol...@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 );
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits