1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "SchXMLLegendContext.hxx"
27 #include "SchXMLEnumConverter.hxx"
28
29 #include <xmloff/xmlnmspe.hxx>
30 #include <xmloff/xmlement.hxx>
31 #include <xmloff/prstylei.hxx>
32 #include <xmloff/nmspmap.hxx>
33 #include <xmloff/xmluconv.hxx>
34
35 #include <tools/debug.hxx>
36
37 #include <com/sun/star/chart/ChartLegendPosition.hpp>
38 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
39 #include <com/sun/star/drawing/FillStyle.hpp>
40
41 using namespace ::xmloff::token;
42 using namespace com::sun::star;
43
44 using rtl::OUString;
45 using com::sun::star::uno::Reference;
46
47 //----------------------------------------
48
49 namespace
50 {
51
52 enum LegendAttributeTokens
53 {
54 XML_TOK_LEGEND_POSITION,
55 XML_TOK_LEGEND_X,
56 XML_TOK_LEGEND_Y,
57 XML_TOK_LEGEND_STYLE_NAME,
58 XML_TOK_LEGEND_EXPANSION,
59 XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO,
60 XML_TOK_LEGEND_WIDTH,
61 XML_TOK_LEGEND_WIDTH_EXT,
62 XML_TOK_LEGEND_HEIGHT,
63 XML_TOK_LEGEND_HEIGHT_EXT
64 };
65
66 SvXMLTokenMapEntry aLegendAttributeTokenMap[] =
67 {
68 { XML_NAMESPACE_CHART, XML_LEGEND_POSITION, XML_TOK_LEGEND_POSITION },
69 { XML_NAMESPACE_SVG, XML_X, XML_TOK_LEGEND_X },
70 { XML_NAMESPACE_SVG, XML_Y, XML_TOK_LEGEND_Y },
71 { XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_LEGEND_STYLE_NAME },
72 { XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION, XML_TOK_LEGEND_EXPANSION },
73 { XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION_ASPECT_RATIO, XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO },
74 { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_LEGEND_WIDTH },
75 { XML_NAMESPACE_CHART_EXT, XML_WIDTH, XML_TOK_LEGEND_WIDTH_EXT },
76 { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_LEGEND_HEIGHT },
77 { XML_NAMESPACE_CHART_EXT, XML_HEIGHT, XML_TOK_LEGEND_HEIGHT_EXT },
78 XML_TOKEN_MAP_END
79 };
80
81 class LegendAttributeTokenMap : public SvXMLTokenMap
82 {
83 public:
LegendAttributeTokenMap()84 LegendAttributeTokenMap(): SvXMLTokenMap( aLegendAttributeTokenMap ) {}
~LegendAttributeTokenMap()85 virtual ~LegendAttributeTokenMap() {}
86 };
87
88 //a LegendAttributeTokenMap Singleton
89 struct theLegendAttributeTokenMap : public rtl::Static< LegendAttributeTokenMap, theLegendAttributeTokenMap > {};
90
91 }//end anonymous namespace
92
93 //----------------------------------------
94
SchXMLLegendContext(SchXMLImportHelper & rImpHelper,SvXMLImport & rImport,const rtl::OUString & rLocalName)95 SchXMLLegendContext::SchXMLLegendContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, const rtl::OUString& rLocalName ) :
96 SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
97 mrImportHelper( rImpHelper )
98 {
99 }
100
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)101 void SchXMLLegendContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
102 {
103 uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
104 if( !xDoc.is() )
105 return;
106
107 // turn on legend
108 uno::Reference< beans::XPropertySet > xDocProp( xDoc, uno::UNO_QUERY );
109 if( xDocProp.is() )
110 {
111 try
112 {
113 xDocProp->setPropertyValue( rtl::OUString::createFromAscii( "HasLegend" ), uno::makeAny( sal_True ) );
114 }
115 catch( beans::UnknownPropertyException )
116 {
117 DBG_ERROR( "Property HasLegend not found" );
118 }
119 }
120
121 uno::Reference< drawing::XShape > xLegendShape( xDoc->getLegend(), uno::UNO_QUERY );
122 uno::Reference< beans::XPropertySet > xLegendProps( xLegendShape, uno::UNO_QUERY );
123 if( !xLegendShape.is() || !xLegendProps.is() )
124 {
125 DBG_ERROR( "legend could not be created" );
126 return;
127 }
128
129 // parse attributes
130 sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
131 const SvXMLTokenMap& rAttrTokenMap = theLegendAttributeTokenMap::get();
132
133 awt::Point aLegendPos;
134 bool bHasXPosition=false;
135 bool bHasYPosition=false;
136 awt::Size aLegendSize;
137 bool bHasWidth=false;
138 bool bHasHeight=false;
139 chart::ChartLegendExpansion nLegendExpansion = chart::ChartLegendExpansion_HIGH;
140 bool bHasExpansion=false;
141
142 rtl::OUString sAutoStyleName;
143 uno::Any aAny;
144
145 for( sal_Int16 i = 0; i < nAttrCount; i++ )
146 {
147 rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
148 rtl::OUString aLocalName;
149 rtl::OUString aValue = xAttrList->getValueByIndex( i );
150 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
151
152 switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
153 {
154 case XML_TOK_LEGEND_POSITION:
155 {
156 try
157 {
158 if( SchXMLEnumConverter::getLegendPositionConverter().importXML( aValue, aAny, GetImport().GetMM100UnitConverter() ) )
159 xLegendProps->setPropertyValue( rtl::OUString::createFromAscii( "Alignment" ), aAny );
160 }
161 catch( beans::UnknownPropertyException )
162 {
163 DBG_ERROR( "Property Alignment (legend) not found" );
164 }
165 }
166 break;
167
168 case XML_TOK_LEGEND_X:
169 GetImport().GetMM100UnitConverter().convertMeasure( aLegendPos.X, aValue );
170 bHasXPosition = true;
171 break;
172 case XML_TOK_LEGEND_Y:
173 GetImport().GetMM100UnitConverter().convertMeasure( aLegendPos.Y, aValue );
174 bHasYPosition = true;
175 break;
176 case XML_TOK_LEGEND_STYLE_NAME:
177 sAutoStyleName = aValue;
178 break;
179 case XML_TOK_LEGEND_EXPANSION:
180 SchXMLEnumConverter::getLegendPositionConverter().importXML( aValue, aAny, GetImport().GetMM100UnitConverter() );
181 bHasExpansion = (aAny>>=nLegendExpansion);
182 break;
183 case XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO:
184 break;
185 case XML_TOK_LEGEND_WIDTH:
186 case XML_TOK_LEGEND_WIDTH_EXT:
187 GetImport().GetMM100UnitConverter().convertMeasure( aLegendSize.Width, aValue );
188 bHasWidth = true;
189 break;
190 case XML_TOK_LEGEND_HEIGHT:
191 case XML_TOK_LEGEND_HEIGHT_EXT:
192 GetImport().GetMM100UnitConverter().convertMeasure( aLegendSize.Height, aValue );
193 bHasHeight = true;
194 break;
195 default:
196 break;
197 }
198 }
199
200 if( bHasXPosition && bHasYPosition )
201 xLegendShape->setPosition( aLegendPos );
202
203 if( bHasExpansion && nLegendExpansion!= chart::ChartLegendExpansion_CUSTOM )
204 xLegendProps->setPropertyValue( rtl::OUString::createFromAscii( "Expansion" ), uno::makeAny(nLegendExpansion) );
205 else if( bHasHeight && bHasWidth )
206 xLegendShape->setSize( aLegendSize );
207
208 // the fill style has the default "none" in XML, but "solid" in the model.
209 xLegendProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" )), uno::makeAny( drawing::FillStyle_NONE ));
210
211 // set auto-styles for Legend
212 const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
213 if( pStylesCtxt )
214 {
215 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
216 mrImportHelper.GetChartFamilyID(), sAutoStyleName );
217
218 if( pStyle && pStyle->ISA( XMLPropStyleContext ))
219 (( XMLPropStyleContext* )pStyle )->FillPropertySet( xLegendProps );
220 }
221 }
222
~SchXMLLegendContext()223 SchXMLLegendContext::~SchXMLLegendContext()
224 {
225 }
226