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