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