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