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 "ChartPlotAreaOASISTContext.hxx"
27 #include "TransformerBase.hxx"
28 #include <xmloff/nmspmap.hxx>
29 #include "xmloff/xmlnmspe.hxx"
30 #include <xmloff/xmltoken.hxx>
31 #include "DeepTContext.hxx"
32 #include "ActionMapTypesOASIS.hxx"
33 #include "MutableAttrList.hxx"
34 
35 using namespace ::com::sun::star;
36 using namespace ::xmloff::token;
37 
38 using ::com::sun::star::uno::Reference;
39 using ::rtl::OUString;
40 
41 class XMLAxisOASISContext : public XMLPersElemContentTContext
42 {
43 public:
44 	TYPEINFO();
45 
46 	XMLAxisOASISContext( XMLTransformerBase& rTransformer,
47                          const ::rtl::OUString& rQName,
48                          ::rtl::Reference< XMLPersAttrListTContext > & rOutCategoriesContext );
49     ~XMLAxisOASISContext();
50 
51 	virtual XMLTransformerContext *CreateChildContext(
52         sal_uInt16 nPrefix,
53         const ::rtl::OUString& rLocalName,
54         const ::rtl::OUString& rQName,
55         const Reference< xml::sax::XAttributeList >& xAttrList );
56 
57     virtual void StartElement( const Reference< xml::sax::XAttributeList >& rAttrList );
58 	virtual void EndElement();
59 
60     bool IsCategoryAxis() const;
61 
62 private:
63     ::rtl::Reference< XMLPersAttrListTContext > &   m_rCategoriesContext;
64     bool                                            m_bHasCategories;
65 };
66 
67 TYPEINIT1( XMLAxisOASISContext, XMLPersElemContentTContext );
68 
XMLAxisOASISContext(XMLTransformerBase & rTransformer,const::rtl::OUString & rQName,::rtl::Reference<XMLPersAttrListTContext> & rOutCategoriesContext)69 XMLAxisOASISContext::XMLAxisOASISContext(
70     XMLTransformerBase& rTransformer,
71     const ::rtl::OUString& rQName,
72     ::rtl::Reference< XMLPersAttrListTContext > & rOutCategoriesContext ) :
73         XMLPersElemContentTContext( rTransformer, rQName ),
74         m_rCategoriesContext( rOutCategoriesContext ),
75         m_bHasCategories( false )
76 {}
77 
~XMLAxisOASISContext()78 XMLAxisOASISContext::~XMLAxisOASISContext()
79 {}
80 
CreateChildContext(sal_uInt16 nPrefix,const::rtl::OUString & rLocalName,const::rtl::OUString & rQName,const Reference<xml::sax::XAttributeList> & xAttrList)81 XMLTransformerContext * XMLAxisOASISContext::CreateChildContext(
82     sal_uInt16 nPrefix,
83     const ::rtl::OUString& rLocalName,
84     const ::rtl::OUString& rQName,
85     const Reference< xml::sax::XAttributeList >& xAttrList )
86 {
87 	XMLTransformerContext * pContext = 0;
88 
89 	if( XML_NAMESPACE_CHART == nPrefix &&
90         IsXMLToken( rLocalName, XML_CATEGORIES ) )
91     {
92         // store categories element at parent
93         m_rCategoriesContext.set( new XMLPersAttrListTContext( GetTransformer(), rQName ));
94         m_bHasCategories = true;
95         pContext = m_rCategoriesContext.get();
96     }
97     else
98     {
99         pContext =  XMLPersElemContentTContext::CreateChildContext(
100             nPrefix, rLocalName, rQName, xAttrList );
101     }
102 
103     return pContext;
104 }
105 
StartElement(const Reference<xml::sax::XAttributeList> & rAttrList)106 void XMLAxisOASISContext::StartElement(
107     const Reference< xml::sax::XAttributeList >& rAttrList )
108 {
109 	OUString aLocation, aMacroName;
110 	Reference< xml::sax::XAttributeList > xAttrList( rAttrList );
111 	XMLMutableAttributeList *pMutableAttrList = 0;
112 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
113 	for( sal_Int16 i=0; i < nAttrCount; i++ )
114 	{
115 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
116 		OUString aLocalName;
117 		sal_uInt16 nPrefix =
118 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
119 
120         if( nPrefix == XML_NAMESPACE_CHART &&
121             IsXMLToken( aLocalName, XML_DIMENSION ) )
122         {
123 			if( !pMutableAttrList )
124 			{
125 				pMutableAttrList = new XMLMutableAttributeList( xAttrList );
126 				xAttrList = pMutableAttrList;
127 			}
128 
129 			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
130             XMLTokenEnum eToken = XML_TOKEN_INVALID;
131             if( IsXMLToken( rAttrValue, XML_X ))
132             {
133                 eToken = XML_DOMAIN;
134                 // has to be XML_CATEGORY for axes with a categories
135                 // sub-element.  The attribute is changed later (when it is
136                 // known that there is a categories sub-element) in this case.
137             }
138             else if( IsXMLToken( rAttrValue, XML_Y ))
139             {
140                 eToken = XML_VALUE;
141             }
142             else if( IsXMLToken( rAttrValue, XML_Z ))
143             {
144                 eToken = XML_SERIES;
145             }
146             else
147             {
148                 OSL_ENSURE( false, "ChartAxis: Invalid attribute value" );
149             }
150 
151             if( eToken != XML_TOKEN_INVALID )
152             {
153                 OUString aNewAttrQName(
154                     GetTransformer().GetNamespaceMap().GetQNameByKey(
155                         XML_NAMESPACE_CHART, GetXMLToken( XML_CLASS )));
156                 pMutableAttrList->RenameAttributeByIndex( i, aNewAttrQName );
157 
158 				pMutableAttrList->SetValueByIndex( i, GetXMLToken( eToken ));
159             }
160         }
161     }
162 
163     XMLPersElemContentTContext::StartElement( xAttrList );
164 }
165 
EndElement()166 void XMLAxisOASISContext::EndElement()
167 {
168     // if we have categories, change the "class" attribute
169     if( IsCategoryAxis() &&
170         m_rCategoriesContext.is() )
171     {
172         OSL_ENSURE( GetAttrList().is(), "Invalid attribute list" );
173         XMLMutableAttributeList * pMutableAttrList =
174             new XMLMutableAttributeList( GetAttrList());
175         OUString aAttrQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
176                                  XML_NAMESPACE_CHART, GetXMLToken( XML_CLASS )));
177         sal_Int16 nIndex = pMutableAttrList->GetIndexByName( aAttrQName );
178         if( nIndex != -1 )
179         {
180             OSL_ENSURE( IsXMLToken( pMutableAttrList->getValueByIndex( nIndex ),
181                                     XML_DOMAIN ), "Axis Dimension: invalid former value" );
182             pMutableAttrList->SetValueByIndex( nIndex, GetXMLToken( XML_CATEGORY ));
183             OSL_ENSURE( IsXMLToken( pMutableAttrList->getValueByIndex( nIndex ),
184                                     XML_CATEGORY ), "Axis Dimension: invalid new value" );
185         }
186 
187         GetTransformer().GetDocHandler()->startElement(
188             GetExportQName(),
189             Reference< xml::sax::XAttributeList >( pMutableAttrList ));
190         ExportContent();
191         GetTransformer().GetDocHandler()->endElement( GetExportQName());
192     }
193     else
194         Export();
195 }
196 
IsCategoryAxis() const197 bool XMLAxisOASISContext::IsCategoryAxis() const
198 {
199     return m_bHasCategories;
200 }
201 
202 
203 TYPEINIT1( XMLChartPlotAreaOASISTContext, XMLProcAttrTransformerContext );
204 
XMLChartPlotAreaOASISTContext(XMLTransformerBase & rTransformer,const::rtl::OUString & rQName)205 XMLChartPlotAreaOASISTContext::XMLChartPlotAreaOASISTContext(
206     XMLTransformerBase & rTransformer, const ::rtl::OUString & rQName ) :
207         XMLProcAttrTransformerContext( rTransformer, rQName, OASIS_SHAPE_ACTIONS )
208 {
209 }
210 
~XMLChartPlotAreaOASISTContext()211 XMLChartPlotAreaOASISTContext::~XMLChartPlotAreaOASISTContext()
212 {}
213 
CreateChildContext(sal_uInt16 nPrefix,const::rtl::OUString & rLocalName,const::rtl::OUString & rQName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)214 XMLTransformerContext * XMLChartPlotAreaOASISTContext::CreateChildContext(
215     sal_uInt16 nPrefix,
216     const ::rtl::OUString& rLocalName,
217     const ::rtl::OUString& rQName,
218     const uno::Reference< xml::sax::XAttributeList >& xAttrList )
219 {
220 	XMLTransformerContext *pContext = 0;
221 
222 	if( XML_NAMESPACE_CHART == nPrefix &&
223 		IsXMLToken( rLocalName, XML_AXIS ) )
224 	{
225         pContext = new XMLAxisOASISContext( GetTransformer(), rQName, m_rCategoriesContext );
226     }
227     else
228 	{
229         // export (and forget) categories if found in an axis-element
230         // otherwise export regularly
231         ExportCategories();
232         pContext =  XMLProcAttrTransformerContext::CreateChildContext(
233                 nPrefix, rLocalName, rQName, xAttrList );
234 	}
235 
236 	return pContext;
237 }
238 
EndElement()239 void XMLChartPlotAreaOASISTContext::EndElement()
240 {
241     ExportCategories();
242     XMLProcAttrTransformerContext::EndElement();
243 }
244 
ExportCategories()245 void XMLChartPlotAreaOASISTContext::ExportCategories()
246 {
247     if( m_rCategoriesContext.is())
248     {
249         m_rCategoriesContext->Export();
250         m_rCategoriesContext.clear();
251     }
252 }
253