From 15e01d90b92a84cba538940614ea30df401a9976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= Date: Tue, 14 Jan 2014 18:43:06 +0100 Subject: [PATCH] ooxml: Preserve shape style attribute fillRef Shape style attributes contain the default format for the shape in case that no direct format is specified for it. This is an example of the attribute we want to preserve with this patch: ... ... The relevant values in these tags are stored at the maShapeStyleRefs member in the Shape object. The storage happens at ShapeStyleContext::onCreateContext which is run when the tag is opened. The ShapeStyleRef object contains the idx value and a Color object which will contain the inner tag . The Color object has been modified to store the string value of schemeClr. The storage happens at ColorValueContext::onStartElement which is run when the tag is opened. Later, Shape::createAndInsert is called by the ShapeContextHandler to create the actual XShape, this happens when the tag is closed. createAndInsert puts idx and schemeClr values into the InteropGrabBag property of the XShape with the name StyleFillRef. On export time, when the shape data is written at ShapeExport::WriteCustomShape, we added a call to DrawingML::WriteShapeStyle. This method will check the existence of the InteropGrabBag property in the shape, read the StyleFillRef prop inside it and output the proper XML to the style definition. DrawingML::WriteShapeStyle also writes some mock tags into the because we found that they are compulsory. We will replace them with the proper data in further patches. The method putPropertyToGrabBag was added to the Shape object for convenience. The data files for some /sd/qa/ unit tests were updated to reflect the new property StyleFillRef inside the InteropGrabBag. Change-Id: I5ffa5242852461a1a709a8f169d40f0d7a2c9aa3 --- include/oox/drawingml/color.hxx | 7 + include/oox/drawingml/shape.hxx | 3 + include/oox/export/drawingml.hxx | 1 + oox/source/drawingml/colorchoicecontext.cxx | 5 + oox/source/drawingml/shape.cxx | 33 ++ oox/source/export/drawingml.cxx | 46 +++ oox/source/export/shapes.cxx | 4 + sd/qa/unit/data/xml/fdo47434_0.xml | 36 +- sd/qa/unit/data/xml/n762695_0.xml | 9 +- sd/qa/unit/data/xml/n820786_0.xml | 432 +++++++++++++++++--- 10 files changed, 523 insertions(+), 53 deletions(-) diff --git a/include/oox/drawingml/color.hxx b/include/oox/drawingml/color.hxx index 2b01e643c91c..481113b364d5 100644 --- a/include/oox/drawingml/color.hxx +++ b/include/oox/drawingml/color.hxx @@ -58,6 +58,8 @@ public: void setPrstClr( sal_Int32 nToken ); /** Sets a scheme color from the a:schemeClr element. */ void setSchemeClr( sal_Int32 nToken ); + /** Sets the scheme name from the a:schemeClr element for interoperability purposes */ + void setSchemeName( OUString sSchemeName ) { msSchemeName = sSchemeName; } /** Sets a system color from the a:sysClr element. */ void setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb ); /** Sets a palette color index. */ @@ -90,6 +92,9 @@ public: /** Returns the transparency of the color (0 = opaque, 100 = full transparent). */ sal_Int16 getTransparency() const; + /** Returns the scheme name from the a:schemeClr element for interoperability purposes */ + OUString getSchemeName() const { return msSchemeName; } + private: /** Internal helper for getColor(). */ void setResolvedRgb( sal_Int32 nRgb ) const; @@ -130,6 +135,8 @@ private: mutable sal_Int32 mnC2; /// Green, green%, saturation, or system default RGB. mutable sal_Int32 mnC3; /// Blue, blue%, or luminance. sal_Int32 mnAlpha; /// Alpha value (color opacity). + + OUString msSchemeName; /// Scheme name from the a:schemeClr element for interoperability purposes }; typedef boost::shared_ptr< Color > ColorPtr; diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx index f39f75d03c82..01cc1e97710b 100644 --- a/include/oox/drawingml/shape.hxx +++ b/include/oox/drawingml/shape.hxx @@ -217,6 +217,9 @@ protected: ::oox::core::XmlFilterBase& rFilter, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ); + void putPropertyToGrabBag( + const ::com::sun::star::beans::PropertyValue& pProperty ); + std::vector< ShapePtr > maChildren; // only used for group shapes com::sun::star::awt::Size maChSize; // only used for group shapes com::sun::star::awt::Point maChPosition; // only used for group shapes diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 00ec32ed7028..2de1ba0187ee 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -147,6 +147,7 @@ public: void WritePresetShape( const char* pShape, MSO_SPT eShapeType, sal_Bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const ::com::sun::star::beans::PropertyValue& rProp ); void WritePolyPolygon( const PolyPolygon& rPolyPolygon ); void WriteFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); + void WriteShapeStyle( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); static void ResetCounters(); diff --git a/oox/source/drawingml/colorchoicecontext.cxx b/oox/source/drawingml/colorchoicecontext.cxx index 951033d8bb47..076b245034e0 100644 --- a/oox/source/drawingml/colorchoicecontext.cxx +++ b/oox/source/drawingml/colorchoicecontext.cxx @@ -69,7 +69,12 @@ void ColorValueContext::onStartElement( const AttributeList& rAttribs ) break; case A_TOKEN( schemeClr ): + { mrColor.setSchemeClr( rAttribs.getToken( XML_val, XML_TOKEN_INVALID ) ); + oox::OptValue sSchemeName = rAttribs.getString( XML_val ); + if( sSchemeName.has() ) + mrColor.setSchemeName( sSchemeName.use() ); + } break; case A_TOKEN( prstClr ): diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index c368363fc9ce..09d74bf2ded1 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -564,6 +564,21 @@ Reference< XShape > Shape::createAndInsert( if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) ) aFillProperties.assignUsed( *pFillProps ); nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper ); + + OUString sColorScheme = pFillRef->maPhClr.getSchemeName(); + if( !sColorScheme.isEmpty() ) + { + Sequence< PropertyValue > aProperties(2); + aProperties[0].Name = "SchemeClr"; + aProperties[0].Value = Any( sColorScheme ); + aProperties[1].Name = "Idx"; + aProperties[1].Value = Any( pFillRef->mnThemedIdx ); + + PropertyValue pStyleFillRef; + pStyleFillRef.Name = "StyleFillRef"; + pStyleFillRef.Value = Any( aProperties ); + putPropertyToGrabBag( pStyleFillRef ); + } } if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) ) { @@ -1037,6 +1052,24 @@ void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& } } +void Shape::putPropertyToGrabBag( const PropertyValue& pProperty ) +{ + Reference< XPropertySet > xSet( mxShape, UNO_QUERY ); + Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); + const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ); + if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) ) + { + Sequence< PropertyValue > aGrabBag; + xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; + + sal_Int32 length = aGrabBag.getLength(); + aGrabBag.realloc( length + 1 ); + aGrabBag[length] = pProperty; + + xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) ); + } +} + // ============================================================================ } } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index b533d747371b..e98a3260837a 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -1620,6 +1620,52 @@ void DrawingML::WriteFill( Reference< XPropertySet > xPropSet ) return; } +void DrawingML::WriteShapeStyle( Reference< XPropertySet > xPropSet ) +{ + // check existence of the grab bag + if ( !GetProperty( xPropSet, "InteropGrabBag" ) ) + return; + + // extract the relevant properties from the grab bag + Sequence< PropertyValue > aGrabBag; + Sequence< PropertyValue > aFillRefProperties; + mAny >>= aGrabBag; + for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i) + if( aGrabBag[i].Name == "StyleFillRef" ) + { + aGrabBag[i].Value >>= aFillRefProperties; + break; + } + + // write mock + mpFS->singleElementNS( XML_a, XML_lnRef, XML_idx, I32S( 0 ), FSEND ); + + // write + if( aFillRefProperties.getLength() > 0 ) + { + OUString sSchemeClr; + sal_uInt32 nIdx; + for( sal_Int32 i=0; i < aFillRefProperties.getLength(); ++i) + if( aFillRefProperties[i].Name == "SchemeClr" ) + aFillRefProperties[i].Value >>= sSchemeClr; + else if( aFillRefProperties[i].Name == "Idx" ) + aFillRefProperties[i].Value >>= nIdx; + mpFS->startElementNS( XML_a, XML_fillRef, XML_idx, I32S( nIdx ), FSEND ); + mpFS->singleElementNS( XML_a, XML_schemeClr, XML_val, + OUStringToOString( sSchemeClr, RTL_TEXTENCODING_ASCII_US ).getStr(), + FSEND ); + mpFS->endElementNS( XML_a, XML_fillRef ); + } + else + // write mock + mpFS->singleElementNS( XML_a, XML_fillRef, XML_idx, I32S( 0 ), FSEND ); + + // write mock + mpFS->singleElementNS( XML_a, XML_effectRef, XML_idx, I32S( 0 ), FSEND ); + // write mock + mpFS->singleElementNS( XML_a, XML_fontRef, XML_idx, "minor", FSEND ); +} + } } diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 76dd7431ced0..cdbe0d68f468 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -369,6 +369,10 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape ) pFS->endElementNS( mnXmlNamespace, XML_spPr ); + pFS->startElementNS( mnXmlNamespace, XML_style, FSEND ); + WriteShapeStyle( rXPropSet ); + pFS->endElementNS( mnXmlNamespace, XML_style ); + // write text WriteTextBox( xShape, mnXmlNamespace ); diff --git a/sd/qa/unit/data/xml/fdo47434_0.xml b/sd/qa/unit/data/xml/fdo47434_0.xml index 50b275376910..21b0a2931e08 100644 --- a/sd/qa/unit/data/xml/fdo47434_0.xml +++ b/sd/qa/unit/data/xml/fdo47434_0.xml @@ -23,7 +23,14 @@ - + + + + + + + + @@ -84,7 +91,14 @@ - + + + + + + + + @@ -145,7 +159,14 @@ - + + + + + + + + @@ -206,7 +227,14 @@ - + + + + + + + + diff --git a/sd/qa/unit/data/xml/n762695_0.xml b/sd/qa/unit/data/xml/n762695_0.xml index d55c97976c3f..1d1e35f1581c 100644 --- a/sd/qa/unit/data/xml/n762695_0.xml +++ b/sd/qa/unit/data/xml/n762695_0.xml @@ -13,7 +13,14 @@ - + + + + + + + + diff --git a/sd/qa/unit/data/xml/n820786_0.xml b/sd/qa/unit/data/xml/n820786_0.xml index 5983782fe892..335b6150e512 100644 --- a/sd/qa/unit/data/xml/n820786_0.xml +++ b/sd/qa/unit/data/xml/n820786_0.xml @@ -258,7 +258,14 @@ - + + + + + + + + @@ -323,7 +330,14 @@ - + + + + + + + + @@ -388,7 +402,14 @@ - + + + + + + + + @@ -453,7 +474,14 @@ - + + + + + + + + @@ -518,7 +546,14 @@ - + + + + + + + + @@ -583,7 +618,14 @@ - + + + + + + + + @@ -648,7 +690,14 @@ - + + + + + + + + @@ -713,7 +762,14 @@ - + + + + + + + + @@ -778,7 +834,14 @@ - + + + + + + + + @@ -843,7 +906,14 @@ - + + + + + + + + @@ -908,7 +978,14 @@ - + + + + + + + + @@ -973,7 +1050,14 @@ - + + + + + + + + @@ -1038,7 +1122,14 @@ - + + + + + + + + @@ -1103,7 +1194,14 @@ - + + + + + + + + @@ -1168,7 +1266,14 @@ - + + + + + + + + @@ -1233,7 +1338,14 @@ - + + + + + + + + @@ -1298,7 +1410,14 @@ - + + + + + + + + @@ -1363,7 +1482,14 @@ - + + + + + + + + @@ -1428,7 +1554,14 @@ - + + + + + + + + @@ -1493,7 +1626,14 @@ - + + + + + + + + @@ -1558,7 +1698,14 @@ - + + + + + + + + @@ -1623,7 +1770,14 @@ - + + + + + + + + @@ -1688,7 +1842,14 @@ - + + + + + + + + @@ -1753,7 +1914,14 @@ - + + + + + + + + @@ -1818,7 +1986,14 @@ - + + + + + + + + @@ -1883,7 +2058,14 @@ - + + + + + + + + @@ -1948,7 +2130,14 @@ - + + + + + + + + @@ -2013,7 +2202,14 @@ - + + + + + + + + @@ -2078,7 +2274,14 @@ - + + + + + + + + @@ -2143,7 +2346,14 @@ - + + + + + + + + @@ -2208,7 +2418,14 @@ - + + + + + + + + @@ -2273,7 +2490,14 @@ - + + + + + + + + @@ -2338,7 +2562,14 @@ - + + + + + + + + @@ -2403,7 +2634,14 @@ - + + + + + + + + @@ -2468,7 +2706,14 @@ - + + + + + + + + @@ -2533,7 +2778,14 @@ - + + + + + + + + @@ -2598,7 +2850,14 @@ - + + + + + + + + @@ -2663,7 +2922,14 @@ - + + + + + + + + @@ -2728,7 +2994,14 @@ - + + + + + + + + @@ -2793,7 +3066,14 @@ - + + + + + + + + @@ -2858,7 +3138,14 @@ - + + + + + + + + @@ -2923,7 +3210,14 @@ - + + + + + + + + @@ -2988,7 +3282,14 @@ - + + + + + + + + @@ -3053,7 +3354,14 @@ - + + + + + + + + @@ -3118,7 +3426,14 @@ - + + + + + + + + @@ -3183,7 +3498,14 @@ - + + + + + + + + @@ -3248,7 +3570,14 @@ - + + + + + + + + @@ -3313,7 +3642,14 @@ - + + + + + + + +