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); 60 virtual ::rtl::OUString SAL_CALL getNameByIndex(sal_Int16 i); 61 virtual ::rtl::OUString SAL_CALL getTypeByIndex(sal_Int16 i); 62 virtual ::rtl::OUString SAL_CALL getTypeByName(const ::rtl::OUString& aName); 63 virtual ::rtl::OUString SAL_CALL getValueByIndex(sal_Int16 i); 64 virtual ::rtl::OUString SAL_CALL getValueByName(const ::rtl::OUString& aName); 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) 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) 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) 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) 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 ) 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) 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 ) 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 { 207 } 208 209 void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction( 210 const OUString&, const OUString& ) 211 { 212 } 213 214 void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator( 215 const Reference< XLocator > &xLocator) 216 { 217 m_xLocator = xLocator; 218 } 219 220 ::rtl::OUString OReadAccelatorDocumentHandler::getErrorLineString() 221 { 222 char buffer[32]; 223 224 if ( m_xLocator.is() ) 225 { 226 return OUString::createFromAscii( buffer ); 227 } 228 else 229 return OUString(); 230 } 231 232 void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void) 233 { 234 } 235 236 void SAL_CALL OReadAccelatorDocumentHandler::endDocument(void) 237 { 238 if ( m_nElementDepth > 0 ) 239 { 240 OUString aErrorMessage = getErrorLineString(); 241 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" )); 242 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 243 } 244 } 245 246 247 void SAL_CALL OReadAccelatorDocumentHandler::startElement( 248 const OUString& aElementName, const Reference< XAttributeList > &xAttrList ) 249 { 250 m_nElementDepth++; 251 252 if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) 253 { 254 // acceleratorlist 255 if ( m_bAcceleratorMode ) 256 { 257 OUString aErrorMessage = getErrorLineString(); 258 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); 259 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 260 } 261 else 262 m_bAcceleratorMode = sal_True; 263 } 264 else if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) 265 { 266 // accelerator item 267 if ( !m_bAcceleratorMode ) 268 { 269 OUString aErrorMessage = getErrorLineString(); 270 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list element has to be used before!" )); 271 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 272 } 273 else 274 { 275 // read accelerator item 276 m_bItemCloseExpected = sal_True; 277 278 SvtAcceleratorConfigItem aItem; 279 280 // read attributes for accelerator 281 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) 282 { 283 OUString aName = xAttrList->getNameByIndex( i ); 284 OUString aValue = xAttrList->getValueByIndex( i ); 285 286 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_URL ))) 287 aItem.aCommand = aValue; 288 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_MODIFIER ))) 289 aItem.nModifier = (sal_uInt16)aValue.toInt32(); 290 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_KEYCODE ))) 291 aItem.nCode = (sal_uInt16)aValue.toInt32(); 292 } 293 294 m_aReadAcceleratorList.push_back( aItem ); 295 } 296 } 297 else 298 { 299 OUString aErrorMessage = getErrorLineString(); 300 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown element found!" )); 301 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 302 } 303 } 304 305 306 void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&) 307 { 308 } 309 310 311 void SAL_CALL OReadAccelatorDocumentHandler::endElement( const OUString& aName ) 312 { 313 m_nElementDepth--; 314 315 if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST ))) 316 { 317 // acceleratorlist 318 if ( !m_bAcceleratorMode ) 319 { 320 OUString aErrorMessage = getErrorLineString(); 321 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" )); 322 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 323 } 324 } 325 else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM ))) 326 { 327 if ( !m_bItemCloseExpected ) 328 { 329 OUString aErrorMessage = getErrorLineString(); 330 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Closing accelerator item element expected!" )); 331 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 332 } 333 } 334 else 335 { 336 OUString aErrorMessage = getErrorLineString(); 337 aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown closing element found!" )); 338 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); 339 } 340 } 341 342 // ------------------------------------------------------------------ 343 344 OWriteAccelatorDocumentHandler::OWriteAccelatorDocumentHandler( 345 const SvtAcceleratorItemList& aWriteAcceleratorList, Reference< XDocumentHandler > xDocumentHandler ) : 346 m_xWriteDocumentHandler( xDocumentHandler ), 347 m_aWriteAcceleratorList( aWriteAcceleratorList ) 348 { 349 m_aAttributeType = OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); 350 } 351 352 OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler() 353 { 354 } 355 356 void OWriteAccelatorDocumentHandler::WriteAcceleratorDocument() 357 { 358 AttributeListImpl* pList = new AttributeListImpl; 359 Reference< XAttributeList > rList( (XAttributeList *)pList , UNO_QUERY ); 360 361 m_xWriteDocumentHandler->startDocument(); 362 m_xWriteDocumentHandler->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )), rList ); 363 m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); 364 365 std::list< SvtAcceleratorConfigItem>::const_iterator p; 366 for ( p = m_aWriteAcceleratorList.begin(); p != m_aWriteAcceleratorList.end(); p++ ) 367 WriteAcceleratorItem( *p ); 368 369 m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )) ); 370 m_xWriteDocumentHandler->endDocument(); 371 } 372 373 void OWriteAccelatorDocumentHandler::WriteAcceleratorItem( 374 const SvtAcceleratorConfigItem& aAcceleratorItem ) 375 { 376 AttributeListImpl* pAcceleratorAttributes = new AttributeListImpl; 377 Reference< XAttributeList > xAcceleratorAttrList( (XAttributeList *)pAcceleratorAttributes , UNO_QUERY ); 378 379 // set attributes 380 pAcceleratorAttributes->addAttribute( 381 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_KEYCODE )), 382 m_aAttributeType, 383 OUString::valueOf( aAcceleratorItem.nCode )); 384 385 pAcceleratorAttributes->addAttribute( 386 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MODIFIER )), 387 m_aAttributeType, 388 OUString::valueOf( aAcceleratorItem.nModifier )); 389 390 pAcceleratorAttributes->addAttribute( 391 OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )), 392 m_aAttributeType, 393 aAcceleratorItem.aCommand ); 394 395 // write start element 396 m_xWriteDocumentHandler->startElement( 397 OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )), 398 xAcceleratorAttrList ); 399 m_xWriteDocumentHandler->ignorableWhitespace( OUString() ); 400 m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )) ); 401 } 402