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_unotools.hxx" 26 27 #include <unotools/xmlaccelcfg.hxx> 28 29 #include <vector> 30 #include <com/sun/star/xml/sax/XAttributeList.hpp> 31 #include <cppuhelper/implbase1.hxx> 32 33 using namespace rtl; 34 using namespace com::sun::star::uno; 35 using namespace com::sun::star::xml::sax; 36 37 #define ELEMENT_ACCELERATORLIST "acceleratorlist" 38 #define ELEMENT_ACCELERATORITEM "item" 39 40 #define ATTRIBUTE_KEYCODE "code" 41 #define ATTRIBUTE_MODIFIER "modifier" 42 #define ATTRIBUTE_URL "url" 43 44 #define ATTRIBUTE_TYPE_CDATA "CDATA" 45 46 // ------------------------------------------------------------------ 47 48 struct AttributeListImpl_impl; 49 class AttributeListImpl : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XAttributeList > 50 { 51 protected: 52 ~AttributeListImpl(); 53 54 public: 55 AttributeListImpl(); 56 AttributeListImpl( const AttributeListImpl & ); 57 58 public: 59 virtual sal_Int16 SAL_CALL getLength(void) throw (::com::sun::star::uno::RuntimeException); 60 virtual ::rtl::OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); 61 virtual ::rtl::OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); 62 virtual ::rtl::OUString SAL_CALL getTypeByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException); 63 virtual ::rtl::OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException); 64 virtual ::rtl::OUString SAL_CALL getValueByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException); 65 66 public: 67 void addAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sType , const ::rtl::OUString &sValue ); 68 void clear(); 69 70 private: 71 struct AttributeListImpl_impl *m_pImpl; 72 }; 73 74 struct TagAttribute 75 { 76 TagAttribute(){} 77 TagAttribute( const OUString &aName, const OUString &aType , const OUString &aValue ) 78 { 79 sName = aName; 80 sType = aType; 81 sValue = aValue; 82 } 83 84 OUString sName; 85 OUString sType; 86 OUString sValue; 87 }; 88 89 struct AttributeListImpl_impl 90 { 91 AttributeListImpl_impl() 92 { 93 // performance improvement during adding 94 vecAttribute.reserve(20); 95 } 96 ::std::vector<struct TagAttribute> vecAttribute; 97 }; 98 99 100 101 sal_Int16 SAL_CALL AttributeListImpl::getLength(void) throw (RuntimeException) 102 { 103 return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size()); 104 } 105 106 107 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r ) : 108 cppu::WeakImplHelper1<com::sun::star::xml::sax::XAttributeList>(r) 109 { 110 m_pImpl = new AttributeListImpl_impl; 111 *m_pImpl = *(r.m_pImpl); 112 } 113 114 OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException) 115 { 116 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { 117 return m_pImpl->vecAttribute[i].sName; 118 } 119 return OUString(); 120 } 121 122 123 OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException) 124 { 125 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { 126 return m_pImpl->vecAttribute[i].sType; 127 } 128 return OUString(); 129 } 130 131 OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException) 132 { 133 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { 134 return m_pImpl->vecAttribute[i].sValue; 135 } 136 return OUString(); 137 138 } 139 140 OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException) 141 { 142 ::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin(); 143 144 for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) { 145 if( (*ii).sName == sName ) { 146 return (*ii).sType; 147 } 148 } 149 return OUString(); 150 } 151 152 OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException) 153 { 154 ::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin(); 155 156 for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) { 157 if( (*ii).sName == sName ) { 158 return (*ii).sValue; 159 } 160 } 161 return OUString(); 162 } 163 164 165 AttributeListImpl::AttributeListImpl() 166 { 167 m_pImpl = new AttributeListImpl_impl; 168 } 169 170 171 172 AttributeListImpl::~AttributeListImpl() 173 { 174 delete m_pImpl; 175 } 176 177 178 void AttributeListImpl::addAttribute( const OUString &sName , 179 const OUString &sType , 180 const OUString &sValue ) 181 { 182 m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) ); 183 } 184 185 void AttributeListImpl::clear() 186 { 187 ::std::vector<struct TagAttribute> dummy; 188 m_pImpl->vecAttribute.swap( dummy ); 189 190 OSL_ASSERT( ! getLength() ); 191 } 192 193 // ------------------------------------------------------------------ 194 195 Any SAL_CALL OReadAccelatorDocumentHandler::queryInterface( const Type & rType ) throw( RuntimeException ) 196 { 197 Any a = ::cppu::queryInterface( rType ,SAL_STATIC_CAST( XDocumentHandler*, this )); 198 if ( a.hasValue() ) 199 return a; 200 else 201 return OWeakObject::queryInterface( rType ); 202 } 203 204 void SAL_CALL OReadAccelatorDocumentHandler::ignorableWhitespace( 205 const OUString& ) 206 throw( SAXException, RuntimeException ) 207 { 208 } 209 210 void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction( 211 const OUString&, const OUString& ) 212 throw( SAXException, RuntimeException ) 213 { 214 } 215 216 void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator( 217 const Reference< XLocator > &xLocator) 218 throw( SAXException, RuntimeException ) 219 { 220 m_xLocator = xLocator; 221 } 222 223 ::rtl::OUString OReadAccelatorDocumentHandler::getErrorLineString() 224 { 225 char buffer[32]; 226 227 if ( m_xLocator.is() ) 228 { 229 return OUString::createFromAscii( buffer ); 230 } 231 else 232 return OUString(); 233 } 234 235 void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void) 236 throw ( SAXException, RuntimeException ) 237 { 238 } 239 240 void SAL_CALL OReadAccelatorDocumentHandler::endDocument(void) 241 throw( SAXException, RuntimeException ) 242 { 243 if ( m_nElementDepth > 0 ) 244 { 245 OUString aErrorMessage = getErrorLineString(); 246 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" )); 247 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 248 } 249 } 250 251 252 void SAL_CALL OReadAccelatorDocumentHandler::startElement( 253 const OUString& aElementName, const Reference< XAttributeList > &xAttrList ) 254 throw( SAXException, RuntimeException ) 255 { 256 m_nElementDepth++; 257 258 if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) 259 { 260 // acceleratorlist 261 if ( m_bAcceleratorMode ) 262 { 263 OUString aErrorMessage = getErrorLineString(); 264 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); 265 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 266 } 267 else 268 m_bAcceleratorMode = sal_True; 269 } 270 else if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) 271 { 272 // accelerator item 273 if ( !m_bAcceleratorMode ) 274 { 275 OUString aErrorMessage = getErrorLineString(); 276 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list element has to be used before!" )); 277 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 278 } 279 else 280 { 281 // read accelerator item 282 m_bItemCloseExpected = sal_True; 283 284 SvtAcceleratorConfigItem aItem; 285 286 // read attributes for accelerator 287 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) 288 { 289 OUString aName = xAttrList->getNameByIndex( i ); 290 OUString aValue = xAttrList->getValueByIndex( i ); 291 292 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_URL ))) 293 aItem.aCommand = aValue; 294 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_MODIFIER ))) 295 aItem.nModifier = (sal_uInt16)aValue.toInt32(); 296 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_KEYCODE ))) 297 aItem.nCode = (sal_uInt16)aValue.toInt32(); 298 } 299 300 m_aReadAcceleratorList.push_back( aItem ); 301 } 302 } 303 else 304 { 305 OUString aErrorMessage = getErrorLineString(); 306 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown element found!" )); 307 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 308 } 309 } 310 311 312 void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&) 313 throw( SAXException, RuntimeException ) 314 { 315 } 316 317 318 void SAL_CALL OReadAccelatorDocumentHandler::endElement( const OUString& aName ) 319 throw( SAXException, RuntimeException ) 320 { 321 m_nElementDepth--; 322 323 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) 324 { 325 // acceleratorlist 326 if ( !m_bAcceleratorMode ) 327 { 328 OUString aErrorMessage = getErrorLineString(); 329 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); 330 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 331 } 332 } 333 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) 334 { 335 if ( !m_bItemCloseExpected ) 336 { 337 OUString aErrorMessage = getErrorLineString(); 338 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Closing accelerator item element expected!" )); 339 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 340 } 341 } 342 else 343 { 344 OUString aErrorMessage = getErrorLineString(); 345 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown closing element found!" )); 346 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 347 } 348 } 349 350 // ------------------------------------------------------------------ 351 352 OWriteAccelatorDocumentHandler::OWriteAccelatorDocumentHandler( 353 const SvtAcceleratorItemList& aWriteAcceleratorList, Reference< XDocumentHandler > xDocumentHandler ) : 354 m_xWriteDocumentHandler( xDocumentHandler ), 355 m_aWriteAcceleratorList( aWriteAcceleratorList ) 356 { 357 m_aAttributeType = OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); 358 } 359 360 OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler() 361 { 362 } 363 364 void OWriteAccelatorDocumentHandler::WriteAcceleratorDocument() 365 throw ( SAXException, RuntimeException ) 366 { 367 AttributeListImpl* pList = new AttributeListImpl; 368 Reference< XAttributeList > rList( (XAttributeList *)pList , UNO_QUERY ); 369 370 m_xWriteDocumentHandler->startDocument(); 371 m_xWriteDocumentHandler->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )), rList ); 372 m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); 373 374 std::list< SvtAcceleratorConfigItem>::const_iterator p; 375 for ( p = m_aWriteAcceleratorList.begin(); p != m_aWriteAcceleratorList.end(); p++ ) 376 WriteAcceleratorItem( *p ); 377 378 m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )) ); 379 m_xWriteDocumentHandler->endDocument(); 380 } 381 382 void OWriteAccelatorDocumentHandler::WriteAcceleratorItem( 383 const SvtAcceleratorConfigItem& aAcceleratorItem ) 384 throw( SAXException, RuntimeException ) 385 { 386 AttributeListImpl* pAcceleratorAttributes = new AttributeListImpl; 387 Reference< XAttributeList > xAcceleratorAttrList( (XAttributeList *)pAcceleratorAttributes , UNO_QUERY ); 388 389 // set attributes 390 pAcceleratorAttributes->addAttribute( 391 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_KEYCODE )), 392 m_aAttributeType, 393 OUString::valueOf( aAcceleratorItem.nCode )); 394 395 pAcceleratorAttributes->addAttribute( 396 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MODIFIER )), 397 m_aAttributeType, 398 OUString::valueOf( aAcceleratorItem.nModifier )); 399 400 pAcceleratorAttributes->addAttribute( 401 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )), 402 m_aAttributeType, 403 aAcceleratorItem.aCommand ); 404 405 // write start element 406 m_xWriteDocumentHandler->startElement( 407 OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )), 408 xAcceleratorAttrList ); 409 m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); 410 m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )) ); 411 } 412