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 {
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)
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)
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)
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)
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 )
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)
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 )
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 {
207 }
208
processingInstruction(const OUString &,const OUString &)209 void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction(
210 const OUString&, const OUString& )
211 {
212 }
213
setDocumentLocator(const Reference<XLocator> & xLocator)214 void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator(
215 const Reference< XLocator > &xLocator)
216 {
217 m_xLocator = xLocator;
218 }
219
getErrorLineString()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
startDocument(void)232 void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void)
233 {
234 }
235
endDocument(void)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
startElement(const OUString & aElementName,const Reference<XAttributeList> & xAttrList)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
characters(const rtl::OUString &)306 void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&)
307 {
308 }
309
310
endElement(const OUString & aName)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
OWriteAccelatorDocumentHandler(const SvtAcceleratorItemList & aWriteAcceleratorList,Reference<XDocumentHandler> xDocumentHandler)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
~OWriteAccelatorDocumentHandler()352 OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler()
353 {
354 }
355
WriteAcceleratorDocument()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
WriteAcceleratorItem(const SvtAcceleratorConfigItem & aAcceleratorItem)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