xref: /trunk/main/unotools/source/config/xmlaccelcfg.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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