LibreOffice Module xmloff (master)  1
SchXMLLegendContext.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "SchXMLLegendContext.hxx"
21 #include "SchXMLEnumConverter.hxx"
22 
23 #include <xmloff/xmlimp.hxx>
24 #include <xmloff/xmlnamespace.hxx>
25 #include <xmloff/namespacemap.hxx>
26 #include <xmloff/xmluconv.hxx>
27 
28 #include <sal/log.hxx>
29 
30 #include <com/sun/star/chart/ChartLegendExpansion.hpp>
31 #include <com/sun/star/chart/XChartDocument.hpp>
32 #include <com/sun/star/drawing/FillStyle.hpp>
33 
34 using namespace ::xmloff::token;
35 using namespace com::sun::star;
36 
37 namespace
38 {
39 
41 {
42  XML_TOK_LEGEND_POSITION,
43  XML_TOK_LEGEND_OVERLAY,
44  XML_TOK_LEGEND_X,
45  XML_TOK_LEGEND_Y,
46  XML_TOK_LEGEND_STYLE_NAME,
47  XML_TOK_LEGEND_EXPANSION,
48  XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO,
49  XML_TOK_LEGEND_WIDTH,
50  XML_TOK_LEGEND_WIDTH_EXT,
51  XML_TOK_LEGEND_HEIGHT,
52  XML_TOK_LEGEND_HEIGHT_EXT
53 };
54 
55 const SvXMLTokenMapEntry aLegendAttributeTokenMap[] =
56 {
57  { XML_NAMESPACE_CHART, XML_LEGEND_POSITION, XML_TOK_LEGEND_POSITION },
58  { XML_NAMESPACE_LO_EXT, XML_OVERLAY, XML_TOK_LEGEND_OVERLAY },
59  { XML_NAMESPACE_SVG, XML_X, XML_TOK_LEGEND_X },
60  { XML_NAMESPACE_SVG, XML_Y, XML_TOK_LEGEND_Y },
61  { XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_LEGEND_STYLE_NAME },
62  { XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION, XML_TOK_LEGEND_EXPANSION },
63  { XML_NAMESPACE_STYLE, XML_LEGEND_EXPANSION_ASPECT_RATIO, XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO },
64  { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_LEGEND_WIDTH },
65  { XML_NAMESPACE_CHART_EXT, XML_WIDTH, XML_TOK_LEGEND_WIDTH_EXT },
66  { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_LEGEND_HEIGHT },
67  { XML_NAMESPACE_CHART_EXT, XML_HEIGHT, XML_TOK_LEGEND_HEIGHT_EXT },
69 };
70 
71 class LegendAttributeTokenMap : public SvXMLTokenMap
72 {
73 public:
74  LegendAttributeTokenMap(): SvXMLTokenMap( aLegendAttributeTokenMap ) {}
75  virtual ~LegendAttributeTokenMap() {}
76 };
77 
78 //a LegendAttributeTokenMap Singleton
79 struct theLegendAttributeTokenMap : public rtl::Static< LegendAttributeTokenMap, theLegendAttributeTokenMap > {};
80 
81 }//end anonymous namespace
82 
83 SchXMLLegendContext::SchXMLLegendContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, const OUString& rLocalName ) :
84  SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
85  mrImportHelper( rImpHelper )
86 {
87 }
88 
89 void SchXMLLegendContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
90 {
91  uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
92  if( !xDoc.is() )
93  return;
94 
95  // turn on legend
96  uno::Reference< beans::XPropertySet > xDocProp( xDoc, uno::UNO_QUERY );
97  if( xDocProp.is() )
98  {
99  try
100  {
101  xDocProp->setPropertyValue("HasLegend", uno::makeAny( true ) );
102  }
103  catch(const beans::UnknownPropertyException&)
104  {
105  SAL_INFO("xmloff.chart", "Property HasLegend not found" );
106  }
107  }
108 
109  uno::Reference< drawing::XShape > xLegendShape = xDoc->getLegend();
110  uno::Reference< beans::XPropertySet > xLegendProps( xLegendShape, uno::UNO_QUERY );
111  if( !xLegendShape.is() || !xLegendProps.is() )
112  {
113  SAL_INFO("xmloff.chart", "legend could not be created" );
114  return;
115  }
116 
117  // parse attributes
118  sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
119  const SvXMLTokenMap& rAttrTokenMap = theLegendAttributeTokenMap::get();
120 
121  awt::Point aLegendPos;
122  bool bOverlay = false;
123  bool bHasXPosition=false;
124  bool bHasYPosition=false;
125  awt::Size aLegendSize;
126  bool bHasWidth=false;
127  bool bHasHeight=false;
128  chart::ChartLegendExpansion nLegendExpansion = chart::ChartLegendExpansion_HIGH;
129  bool bHasExpansion=false;
130 
131  OUString sAutoStyleName;
132  uno::Any aAny;
133 
134  for( sal_Int16 i = 0; i < nAttrCount; i++ )
135  {
136  OUString sAttrName = xAttrList->getNameByIndex( i );
137  OUString aLocalName;
138  OUString aValue = xAttrList->getValueByIndex( i );
139  sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
140 
141  switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
142  {
143  case XML_TOK_LEGEND_POSITION:
144  try
145  {
146  if( SchXMLEnumConverter::getLegendPositionConverter().importXML( aValue, aAny, GetImport().GetMM100UnitConverter() ) )
147  xLegendProps->setPropertyValue("Alignment", aAny );
148  }
149  catch(const beans::UnknownPropertyException&)
150  {
151  SAL_INFO("xmloff.chart", "Property Alignment (legend) not found" );
152  }
153  break;
154  case XML_TOK_LEGEND_OVERLAY:
155  try
156  {
157  bOverlay = xAttrList->getValueByIndex(i).toBoolean();
158  xLegendProps->setPropertyValue("Overlay", uno::makeAny(bOverlay));
159  }
160  catch(const beans::UnknownPropertyException&)
161  {
162  SAL_INFO("xmloff.chart", "Property Overlay (legend) not found" );
163  }
164  break;
165  case XML_TOK_LEGEND_X:
167  aLegendPos.X, aValue );
168  bHasXPosition = true;
169  break;
170  case XML_TOK_LEGEND_Y:
172  aLegendPos.Y, aValue );
173  bHasYPosition = true;
174  break;
175  case XML_TOK_LEGEND_STYLE_NAME:
176  sAutoStyleName = aValue;
177  break;
178  case XML_TOK_LEGEND_EXPANSION:
179  SchXMLEnumConverter::getLegendPositionConverter().importXML( aValue, aAny, GetImport().GetMM100UnitConverter() );
180  bHasExpansion = (aAny>>=nLegendExpansion);
181  break;
182  case XML_TOK_LEGEND_EXPANSION_ASPECT_RATIO:
183  break;
184  case XML_TOK_LEGEND_WIDTH:
185  case XML_TOK_LEGEND_WIDTH_EXT:
187  aLegendSize.Width, aValue );
188  bHasWidth = true;
189  break;
190  case XML_TOK_LEGEND_HEIGHT:
191  case XML_TOK_LEGEND_HEIGHT_EXT:
193  aLegendSize.Height, aValue );
194  bHasHeight = true;
195  break;
196  default:
197  break;
198  }
199  }
200 
201  if( bHasExpansion && nLegendExpansion!= chart::ChartLegendExpansion_CUSTOM )
202  xLegendProps->setPropertyValue("Expansion", uno::makeAny(nLegendExpansion) );
203  else if( bHasHeight && bHasWidth )
204  xLegendShape->setSize( aLegendSize );
205 
206  if( bHasXPosition && bHasYPosition )
207  xLegendShape->setPosition( aLegendPos );
208 
209  // the fill style has the default "none" in XML, but "solid" in the model.
210  xLegendProps->setPropertyValue("FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
211 
212  // set auto-styles for Legend
213  mrImportHelper.FillAutoStyle(sAutoStyleName, xLegendProps);
214 }
215 
217 {
218 }
219 
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_uInt16 XML_NAMESPACE_CHART
LegendAttributeTokens
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:394
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
void FillAutoStyle(const OUString &rAutoStyleName, const css::uno::Reference< css::beans::XPropertySet > &rProp)
Fill in the autostyle.
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
#define XML_TOKEN_MAP_END
Definition: xmltkmap.hxx:33
bool convertMeasureToCore(sal_Int32 &rValue, const OUString &rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
convert string to measure with meCoreMeasureUnit, using optional min and max values ...
Definition: xmluconv.cxx:171
constexpr sal_uInt16 XML_NAMESPACE_SVG
int i
constexpr sal_uInt16 XML_NAMESPACE_CHART_EXT
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Definition: xmltkmap.cxx:99
static XMLEnumPropertyHdl & getLegendPositionConverter()
SchXMLImportHelper & mrImportHelper
With this class you can import a element containing its data as element o...
virtual void StartElement(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
StartElement is called after a context has been constructed and before an elements context is parsed...
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:44
const css::uno::Reference< css::chart::XChartDocument > & GetChartDocument() const
Handling of tokens in XML:
#define SAL_INFO(area, stream)
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:396
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Imports the given value according to the XML-data-type corresponding to the derived class...
SchXMLLegendContext(SchXMLImportHelper &rImpHelper, SvXMLImport &rImport, const OUString &rLocalName)
constexpr sal_uInt16 XML_NAMESPACE_STYLE
virtual ~SchXMLLegendContext() override