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