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 {
TagAttributeTagAttribute76 TagAttribute(){}
TagAttributeTagAttribute77 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 {
AttributeListImpl_implAttributeListImpl_impl91 AttributeListImpl_impl()
92 {
93 // performance improvement during adding
94 vecAttribute.reserve(20);
95 }
96 ::std::vector<struct TagAttribute> vecAttribute;
97 };
98
99
100
getLength(void)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
AttributeListImpl(const AttributeListImpl & r)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
getNameByIndex(sal_Int16 i)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
getTypeByIndex(sal_Int16 i)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
getValueByIndex(sal_Int16 i)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
getTypeByName(const OUString & sName)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
getValueByName(const OUString & sName)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
AttributeListImpl()165 AttributeListImpl::AttributeListImpl()
166 {
167 m_pImpl = new AttributeListImpl_impl;
168 }
169
170
171
~AttributeListImpl()172 AttributeListImpl::~AttributeListImpl()
173 {
174 delete m_pImpl;
175 }
176
177
addAttribute(const OUString & sName,const OUString & sType,const OUString & sValue)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
clear()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
queryInterface(const Type & rType)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
ignorableWhitespace(const OUString &)204 void SAL_CALL OReadAccelatorDocumentHandler::ignorableWhitespace(
205 const OUString& )
206 throw( SAXException, RuntimeException )
207 {
208 }
209
processingInstruction(const OUString &,const OUString &)210 void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction(
211 const OUString&, const OUString& )
212 throw( SAXException, RuntimeException )
213 {
214 }
215
setDocumentLocator(const Reference<XLocator> & xLocator)216 void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator(
217 const Reference< XLocator > &xLocator)
218 throw( SAXException, RuntimeException )
219 {
220 m_xLocator = xLocator;
221 }
222
getErrorLineString()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
startDocument(void)235 void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void)
236 throw ( SAXException, RuntimeException )
237 {
238 }
239
endDocument(void)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
startElement(const OUString & aElementName,const Reference<XAttributeList> & xAttrList)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
characters(const rtl::OUString &)312 void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&)
313 throw( SAXException, RuntimeException )
314 {
315 }
316
317
endElement(const OUString & aName)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
OWriteAccelatorDocumentHandler(const SvtAcceleratorItemList & aWriteAcceleratorList,Reference<XDocumentHandler> xDocumentHandler)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
~OWriteAccelatorDocumentHandler()360 OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler()
361 {
362 }
363
WriteAcceleratorDocument()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
WriteAcceleratorItem(const SvtAcceleratorConfigItem & aAcceleratorItem)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