Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <xml/acceleratorconfigurationreader.hxx>
30 : :
31 : : #include <acceleratorconst.h>
32 : :
33 : : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
34 : : #include <com/sun/star/awt/KeyModifier.hpp>
35 : : #include <com/sun/star/awt/KeyEvent.hpp>
36 : : #include <com/sun/star/awt/Key.hpp>
37 : : #include <com/sun/star/container/ElementExistException.hpp>
38 : :
39 : : #include <vcl/svapp.hxx>
40 : : #include <rtl/ustrbuf.hxx>
41 : :
42 : :
43 : : namespace framework{
44 : :
45 : : //-----------------------------------------------
46 : : /* Throws a SaxException in case a wrong formated XML
47 : : structure was detected.
48 : :
49 : : This macro combined the given comment with a generic
50 : : way to find out the XML line (where the error occurred)
51 : : to format a suitable message.
52 : :
53 : : @param COMMENT
54 : : an ascii string, which describe the problem.
55 : : */
56 : : #define THROW_PARSEEXCEPTION(COMMENT) \
57 : : { \
58 : : ::rtl::OUStringBuffer sMessage(256); \
59 : : sMessage.append (implts_getErrorLineString()); \
60 : : sMessage.appendAscii(COMMENT ); \
61 : : \
62 : : throw css::xml::sax::SAXException( \
63 : : sMessage.makeStringAndClear(), \
64 : : static_cast< css::xml::sax::XDocumentHandler* >(this), \
65 : : css::uno::Any()); \
66 : : }
67 : :
68 : : //-----------------------------------------------
69 : : // XInterface
70 [ - + ][ # # ]: 5705 : DEFINE_XINTERFACE_1(AcceleratorConfigurationReader ,
71 : : OWeakObject ,
72 : : DIRECT_INTERFACE(css::xml::sax::XDocumentHandler))
73 : :
74 : : //-----------------------------------------------
75 : 1141 : AcceleratorConfigurationReader::AcceleratorConfigurationReader(AcceleratorCache& rContainer)
76 [ + - ]: 1141 : : ThreadHelpBase (&Application::GetSolarMutex())
77 : : , OWeakObject ( )
78 : : , m_rContainer (rContainer )
79 : : , m_bInsideAcceleratorList(sal_False )
80 [ + - ][ + - ]: 2282 : , m_bInsideAcceleratorItem(sal_False )
81 : : {
82 : 1141 : }
83 : :
84 : : //-----------------------------------------------
85 [ + - ][ + - ]: 1141 : AcceleratorConfigurationReader::~AcceleratorConfigurationReader()
[ + - ]
86 : : {
87 [ - + ]: 2282 : }
88 : :
89 : : //-----------------------------------------------
90 : 0 : void SAL_CALL AcceleratorConfigurationReader::startDocument()
91 : : throw(css::xml::sax::SAXException,
92 : : css::uno::RuntimeException )
93 : : {
94 : 0 : }
95 : :
96 : : //-----------------------------------------------
97 : 0 : void SAL_CALL AcceleratorConfigurationReader::endDocument()
98 : : throw(css::xml::sax::SAXException,
99 : : css::uno::RuntimeException )
100 : : {
101 : : // The xml file seems to be corrupted.
102 : : // Because we found no end-tags ... at least for
103 : : // one list or item.
104 [ # # ][ # # ]: 0 : if (
105 : : (m_bInsideAcceleratorList) ||
106 : : (m_bInsideAcceleratorItem)
107 : : )
108 : : {
109 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("No matching start or end element 'acceleratorlist' found!")
[ # # ][ # # ]
[ # # ][ # # ]
110 : : }
111 : 0 : }
112 : :
113 : : //-----------------------------------------------
114 : 0 : void SAL_CALL AcceleratorConfigurationReader::startElement(const ::rtl::OUString& sElement ,
115 : : const css::uno::Reference< css::xml::sax::XAttributeList >& xAttributeList)
116 : : throw(css::xml::sax::SAXException,
117 : : css::uno::RuntimeException )
118 : : {
119 : 0 : EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement);
120 : :
121 : : // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
122 : : // Because an item occures very often ... a list should occure one times only!
123 [ # # ]: 0 : if (eElement == E_ELEMENT_ITEM)
124 : : {
125 [ # # ]: 0 : if (!m_bInsideAcceleratorList)
126 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("An element \"accel:item\" must be embeded into 'accel:acceleratorlist'.")
[ # # ][ # # ]
[ # # ][ # # ]
127 [ # # ]: 0 : if (m_bInsideAcceleratorItem)
128 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("An element \"accel:item\" is not a container.")
[ # # ][ # # ]
[ # # ][ # # ]
129 : 0 : m_bInsideAcceleratorItem = sal_True;
130 : :
131 : 0 : ::rtl::OUString sCommand;
132 [ # # ]: 0 : css::awt::KeyEvent aEvent ;
133 : :
134 [ # # ][ # # ]: 0 : sal_Int16 c = xAttributeList->getLength();
135 : 0 : sal_Int16 i = 0;
136 [ # # ]: 0 : for (i=0; i<c; ++i)
137 : : {
138 [ # # ][ # # ]: 0 : ::rtl::OUString sAttribute = xAttributeList->getNameByIndex(i);
139 [ # # ][ # # ]: 0 : ::rtl::OUString sValue = xAttributeList->getValueByIndex(i);
140 [ # # ]: 0 : EXMLAttribute eAttribute = AcceleratorConfigurationReader::implst_classifyAttribute(sAttribute);
141 [ # # # # : 0 : switch(eAttribute)
# # # ]
142 : : {
143 : : case E_ATTRIBUTE_URL :
144 [ # # ]: 0 : sCommand = sValue.intern();
145 : 0 : break;
146 : :
147 : : case E_ATTRIBUTE_KEYCODE :
148 [ # # ][ # # ]: 0 : aEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sValue);
149 : 0 : break;
150 : :
151 : : case E_ATTRIBUTE_MOD_SHIFT :
152 : 0 : aEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
153 : 0 : break;
154 : :
155 : : case E_ATTRIBUTE_MOD_MOD1 :
156 : 0 : aEvent.Modifiers |= css::awt::KeyModifier::MOD1;
157 : 0 : break;
158 : :
159 : : case E_ATTRIBUTE_MOD_MOD2 :
160 : 0 : aEvent.Modifiers |= css::awt::KeyModifier::MOD2;
161 : 0 : break;
162 : :
163 : : case E_ATTRIBUTE_MOD_MOD3 :
164 : 0 : aEvent.Modifiers |= css::awt::KeyModifier::MOD3;
165 : : }
166 : 0 : }
167 : :
168 : : // validate command and key event.
169 [ # # ][ # # ]: 0 : if (
[ # # ]
170 : 0 : sCommand.isEmpty() ||
171 : : (aEvent.KeyCode == 0 )
172 : : )
173 : : {
174 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("XML element does not describe a valid accelerator nor a valid command.")
[ # # ][ # # ]
[ # # ][ # # ]
175 : : }
176 : :
177 : : // register key event + command inside cache ...
178 : : // Check for already existing items there.
179 [ # # ][ # # ]: 0 : if (!m_rContainer.hasKey(aEvent))
180 [ # # ][ # # ]: 0 : m_rContainer.setKeyCommandPair(aEvent, sCommand);
181 : : #ifdef ENABLE_WARNINGS
182 : : else
183 : : {
184 : : // Attention: Its not realy a reason to throw an exception and kill the office, if the configuration contains
185 : : // multiple registrations for the same key :-) Show a warning ... and ignore the second item.
186 : : // THROW_PARSEEXCEPTION("Command is registered for the same key more then once.")
187 : : ::rtl::OUStringBuffer sMsg(256);
188 : : sMsg.appendAscii("Double registration detected.\nCommand = \"");
189 : : sMsg.append (sCommand );
190 : : sMsg.appendAscii("\"\nKeyCode = " );
191 : : sMsg.append ((sal_Int32)aEvent.KeyCode );
192 : : sMsg.appendAscii("\nModifiers = " );
193 : : sMsg.append ((sal_Int32)aEvent.Modifiers );
194 : : sMsg.appendAscii("\nIgnore this item!" );
195 : : LOG_WARNING("AcceleratorConfigurationReader::startElement()", U2B(sMsg.makeStringAndClear()))
196 : : }
197 : : #endif // ENABLE_WARNINGS
198 : : }
199 : :
200 [ # # ]: 0 : if (eElement == E_ELEMENT_ACCELERATORLIST)
201 : : {
202 [ # # ]: 0 : if (m_bInsideAcceleratorList)
203 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("An element \"accel:acceleratorlist\" cannot be used recursive.")
[ # # ][ # # ]
[ # # ][ # # ]
204 : 0 : m_bInsideAcceleratorList = sal_True;
205 : 0 : return;
206 : : }
207 : : }
208 : :
209 : : //-----------------------------------------------
210 : 0 : void SAL_CALL AcceleratorConfigurationReader::endElement(const ::rtl::OUString& sElement)
211 : : throw(css::xml::sax::SAXException,
212 : : css::uno::RuntimeException )
213 : : {
214 : 0 : EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement);
215 : :
216 : : // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
217 : : // Because an item occures very often ... a list should occure one times only!
218 [ # # ]: 0 : if (eElement == E_ELEMENT_ITEM)
219 : : {
220 [ # # ]: 0 : if (!m_bInsideAcceleratorItem)
221 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("Found end element 'accel:item', but no start element.")
[ # # ][ # # ]
[ # # ][ # # ]
222 : 0 : m_bInsideAcceleratorItem = sal_False;
223 : : }
224 : :
225 [ # # ]: 0 : if (eElement == E_ELEMENT_ACCELERATORLIST)
226 : : {
227 [ # # ]: 0 : if (!m_bInsideAcceleratorList)
228 [ # # ][ # # ]: 0 : THROW_PARSEEXCEPTION("Found end element 'accel:acceleratorlist', but no start element.")
[ # # ][ # # ]
[ # # ][ # # ]
229 : 0 : m_bInsideAcceleratorList = sal_False;
230 : : }
231 : 0 : }
232 : :
233 : : //-----------------------------------------------
234 : 0 : void SAL_CALL AcceleratorConfigurationReader::characters(const ::rtl::OUString&)
235 : : throw(css::xml::sax::SAXException,
236 : : css::uno::RuntimeException )
237 : : {
238 : 0 : }
239 : :
240 : : //-----------------------------------------------
241 : 0 : void SAL_CALL AcceleratorConfigurationReader::ignorableWhitespace(const ::rtl::OUString&)
242 : : throw(css::xml::sax::SAXException,
243 : : css::uno::RuntimeException )
244 : : {
245 : 0 : }
246 : :
247 : : //-----------------------------------------------
248 : 0 : void SAL_CALL AcceleratorConfigurationReader::processingInstruction(const ::rtl::OUString& /*sTarget*/,
249 : : const ::rtl::OUString& /*sData*/ )
250 : : throw(css::xml::sax::SAXException,
251 : : css::uno::RuntimeException )
252 : : {
253 : 0 : }
254 : :
255 : : //-----------------------------------------------
256 : 1141 : void SAL_CALL AcceleratorConfigurationReader::setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator >& xLocator)
257 : : throw(css::xml::sax::SAXException,
258 : : css::uno::RuntimeException )
259 : : {
260 : 1141 : m_xLocator = xLocator;
261 : 1141 : }
262 : :
263 : : //-----------------------------------------------
264 : 0 : AcceleratorConfigurationReader::EXMLElement AcceleratorConfigurationReader::implst_classifyElement(const ::rtl::OUString& sElement)
265 : : {
266 : : AcceleratorConfigurationReader::EXMLElement eElement;
267 : :
268 [ # # ]: 0 : if (sElement.equals(NS_ELEMENT_ACCELERATORLIST))
269 : 0 : eElement = E_ELEMENT_ACCELERATORLIST;
270 : : else
271 [ # # ]: 0 : if (sElement.equals(NS_ELEMENT_ITEM))
272 : 0 : eElement = E_ELEMENT_ITEM;
273 : : else
274 : : throw css::uno::RuntimeException(
275 : : DECLARE_ASCII("Unknown XML element detected!"),
276 [ # # ][ # # ]: 0 : css::uno::Reference< css::xml::sax::XDocumentHandler >());
277 : :
278 : 0 : return eElement;
279 : : }
280 : :
281 : : //-----------------------------------------------
282 : 0 : AcceleratorConfigurationReader::EXMLAttribute AcceleratorConfigurationReader::implst_classifyAttribute(const ::rtl::OUString& sAttribute)
283 : : {
284 : : AcceleratorConfigurationReader::EXMLAttribute eAttribute;
285 : :
286 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_KEYCODE))
287 : 0 : eAttribute = E_ATTRIBUTE_KEYCODE;
288 : : else
289 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_MOD_SHIFT))
290 : 0 : eAttribute = E_ATTRIBUTE_MOD_SHIFT;
291 : : else
292 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD1))
293 : 0 : eAttribute = E_ATTRIBUTE_MOD_MOD1;
294 : : else
295 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD2))
296 : 0 : eAttribute = E_ATTRIBUTE_MOD_MOD2;
297 : : else
298 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD3))
299 : 0 : eAttribute = E_ATTRIBUTE_MOD_MOD3;
300 : : else
301 [ # # ]: 0 : if (sAttribute.equals(NS_ATTRIBUTE_URL))
302 : 0 : eAttribute = E_ATTRIBUTE_URL;
303 : : else
304 : : throw css::uno::RuntimeException(
305 : : DECLARE_ASCII("Unknown XML attribute detected!"),
306 [ # # ][ # # ]: 0 : css::uno::Reference< css::xml::sax::XDocumentHandler >());
307 : :
308 : 0 : return eAttribute;
309 : : }
310 : :
311 : : //-----------------------------------------------
312 : 0 : ::rtl::OUString AcceleratorConfigurationReader::implts_getErrorLineString()
313 : : {
314 [ # # ]: 0 : if (!m_xLocator.is())
315 [ # # ]: 0 : return DECLARE_ASCII("Error during parsing XML. (No further info available ...)");
316 : :
317 : 0 : ::rtl::OUStringBuffer sMsg(256);
318 [ # # ]: 0 : sMsg.appendAscii("Error during parsing XML in\nline = ");
319 [ # # ][ # # ]: 0 : sMsg.append (m_xLocator->getLineNumber() );
[ # # ]
320 [ # # ]: 0 : sMsg.appendAscii("\ncolumn = " );
321 [ # # ][ # # ]: 0 : sMsg.append (m_xLocator->getColumnNumber() );
[ # # ]
322 [ # # ]: 0 : sMsg.appendAscii("." );
323 [ # # ]: 0 : return sMsg.makeStringAndClear();
324 : : }
325 : :
326 : : } // namespace framework
327 : :
328 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|