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