summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorJacobo Aragunde Pérez <jaragunde@igalia.com>2014-01-16 10:27:46 +0100
committerJacobo Aragunde Pérez <jaragunde@igalia.com>2014-01-18 14:51:43 +0100
commitbc0a9076aa43a0782bcf81e55d3f84f6af0f68e8 (patch)
tree909a71cd59e868368d6e6ae8277823aee75b2685 /oox
parent15e01d90b92a84cba538940614ea30df401a9976 (diff)
ooxml: Preserve shape theme attribute for solid fill
Users can select the fill color for a shape among the theme-defined colors. This results in the following XML: <wps:spPr> ... <a:solidFill> <a:schemeClr val="accent2"/> </a:solidFill> ... </wps:spPr> Now we store both the original fill color and the name of the theme-defined color, if it exists, on the import phase. They are put into the InteropGrabBag of the shape with the names OriginalSolidFillClr and SpPrSolidFillSchemeClr. Additionally, we needed to to store the decoded theme color inside StyleFillRef. On the export phase we have to take into account several combinations of factors: * If the final color for the shape fill is different from the original color, we must ignore any theme attributes and write the new color. * If the fill color is unchanged and some theme color exists, we must write the theme color. * If the fill color is unchanged and no theme color exists, we must check if the original color matches the style-defined color. If it does, we must not write any <a:solidFill> tag. * Otherwise we must write the <a:solidFill> tag with the RGB color. The method putPropertiesToGrabBag was added to the Shape object for convenience. The data files for some /sd/qa/ unit tests were updated to reflect the new properties inside the Shape InteropGrabBag. Change-Id: If0915c5442872a8acab0a8a081f60c89c97277bd
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/shape.cxx43
-rw-r--r--oox/source/export/drawingml.cxx59
2 files changed, 99 insertions, 3 deletions
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 09d74bf2ded1..c9889db608d0 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -568,11 +568,13 @@ Reference< XShape > Shape::createAndInsert(
OUString sColorScheme = pFillRef->maPhClr.getSchemeName();
if( !sColorScheme.isEmpty() )
{
- Sequence< PropertyValue > aProperties(2);
+ Sequence< PropertyValue > aProperties(3);
aProperties[0].Name = "SchemeClr";
aProperties[0].Value = Any( sColorScheme );
aProperties[1].Name = "Idx";
aProperties[1].Value = Any( pFillRef->mnThemedIdx );
+ aProperties[2].Name = "Color";
+ aProperties[2].Value = Any( nFillPhClr );
PropertyValue pStyleFillRef;
pStyleFillRef.Name = "StyleFillRef";
@@ -764,6 +766,18 @@ Reference< XShape > Shape::createAndInsert(
mxShape->setPosition(awt::Point(aShapeRectHmm.X, aShapeRectHmm.Y));
mxShape->setSize(awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
}
+
+ Sequence< PropertyValue > aProperties( 1 );
+ aProperties[0].Name = "OriginalSolidFillClr";
+ aProperties[0].Value = aShapeProps[PROP_FillColor];
+ OUString sColorFillScheme = aFillProperties.maFillColor.getSchemeName();
+ if( !aFillProperties.maFillColor.isPlaceHolder() && !sColorFillScheme.isEmpty() )
+ {
+ aProperties.realloc( 2 );
+ aProperties[1].Name = "SpPrSolidFillSchemeClr";
+ aProperties[1].Value = Any( sColorFillScheme );
+ }
+ putPropertiesToGrabBag( aProperties );
}
// These can have a custom geometry, so position should be set here,
@@ -1070,6 +1084,33 @@ void Shape::putPropertyToGrabBag( const PropertyValue& pProperty )
}
}
+void Shape::putPropertiesToGrabBag( const Sequence< PropertyValue >& aProperties )
+{
+ 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 ) )
+ {
+ // get existing grab bag
+ Sequence< PropertyValue > aGrabBag;
+ xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
+ sal_Int32 length = aGrabBag.getLength();
+
+ // update grab bag size to contain the new items
+ aGrabBag.realloc( length + aProperties.getLength() );
+
+ // put the new items
+ for( sal_Int32 i=0; i < aProperties.getLength(); ++i )
+ {
+ aGrabBag[length + i].Name = aProperties[i].Name;
+ aGrabBag[length + i].Value = aProperties[i].Value;
+ }
+
+ // put it back to the shape
+ xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
+ }
+}
+
// ============================================================================
} }
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index e98a3260837a..ebcfb165cb54 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -174,10 +174,65 @@ void DrawingML::WriteSolidFill( sal_uInt32 nColor )
mpFS->endElementNS( XML_a, XML_solidFill );
}
+void DrawingML::WriteSolidFill( OUString sSchemeName )
+{
+ mpFS->startElementNS( XML_a, XML_solidFill, FSEND );
+ mpFS->singleElementNS( XML_a, XML_schemeClr, XML_val,
+ OUStringToOString( sSchemeName, RTL_TEXTENCODING_ASCII_US ).getStr(),
+ FSEND );
+ mpFS->endElementNS( XML_a, XML_solidFill );
+}
+
void DrawingML::WriteSolidFill( Reference< XPropertySet > rXPropSet )
{
- if ( GetProperty( rXPropSet, "FillColor" ) )
- WriteSolidFill( *((sal_uInt32*) mAny.getValue()) & 0xffffff );
+ // get fill color
+ sal_uInt32 nFillColor;
+ if ( !GetProperty( rXPropSet, "FillColor" ) )
+ return;
+ mAny >>= nFillColor;
+
+ // get InteropGrabBag and search the relevant attributes
+ OUString sColorFillScheme;
+ sal_uInt32 nOriginalColor;
+ Sequence< PropertyValue > aStyleProperties;
+ if ( GetProperty( rXPropSet, "InteropGrabBag" ) )
+ {
+ Sequence< PropertyValue > aGrabBag;
+ mAny >>= aGrabBag;
+ for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
+ if( aGrabBag[i].Name == "SpPrSolidFillSchemeClr" )
+ aGrabBag[i].Value >>= sColorFillScheme;
+ else if( aGrabBag[i].Name == "OriginalSolidFillClr" )
+ aGrabBag[i].Value >>= nOriginalColor;
+ else if( aGrabBag[i].Name == "StyleFillRef" )
+ aGrabBag[i].Value >>= aStyleProperties;
+ }
+
+ // write XML
+ if ( nFillColor != nOriginalColor )
+ // the user has set a different color for the shape
+ WriteSolidFill( nFillColor & 0xffffff );
+ else if ( !sColorFillScheme.isEmpty() )
+ // the shape had a scheme color and the user didn't change it
+ WriteSolidFill( sColorFillScheme );
+ else if ( aStyleProperties.hasElements() )
+ {
+ sal_uInt32 nThemeColor;
+ for( sal_Int32 i=0; i < aStyleProperties.getLength(); ++i )
+ if( aStyleProperties[i].Name == "Color" )
+ {
+ aStyleProperties[i].Value >>= nThemeColor;
+ break;
+ }
+ if ( nFillColor != nThemeColor )
+ // the shape contains a theme but it wasn't being used
+ WriteSolidFill( nFillColor & 0xffffff );
+ // in case the shape used the style color and the user didn't change it,
+ // we must not write a <a: solidFill> tag.
+ }
+ else
+ // the shape had a custom color and the user didn't change it
+ WriteSolidFill( nFillColor & 0xffffff );
}
void DrawingML::WriteGradientStop( sal_uInt16 nStop, sal_uInt32 nColor )