1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: acceleratorconfigurationreader.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <xml/acceleratorconfigurationreader.hxx>
35 //_______________________________________________
38 #ifndef __FRAMEWORK_ACCELERATORCONST_H_
39 #include <acceleratorconst.h>
42 //_______________________________________________
44 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
45 #include <com/sun/star/awt/KeyModifier.hpp>
46 #include <com/sun/star/awt/KeyEvent.hpp>
47 #include <com/sun/star/awt/Key.hpp>
48 #include <com/sun/star/container/ElementExistException.hpp>
50 //_______________________________________________
52 #include <vcl/svapp.hxx>
53 #include <rtl/ustrbuf.hxx>
55 //_______________________________________________
60 //-----------------------------------------------
61 /* Throws a SaxException in case a wrong formated XML
62 structure was detected.
64 This macro combined the given comment with a generic
65 way to find out the XML line (where the error occured)
66 to format a suitable message.
69 an ascii string, which describe the problem.
71 #define THROW_PARSEEXCEPTION(COMMENT) \
73 ::rtl::OUStringBuffer sMessage(256); \
74 sMessage.append (implts_getErrorLineString()); \
75 sMessage.appendAscii(COMMENT ); \
77 throw css::xml::sax::SAXException( \
78 sMessage.makeStringAndClear(), \
79 static_cast< css::xml::sax::XDocumentHandler* >(this), \
83 //-----------------------------------------------
85 DEFINE_XINTERFACE_1(AcceleratorConfigurationReader
,
87 DIRECT_INTERFACE(css::xml::sax::XDocumentHandler
))
89 //-----------------------------------------------
90 AcceleratorConfigurationReader::AcceleratorConfigurationReader(AcceleratorCache
& rContainer
)
91 : ThreadHelpBase (&Application::GetSolarMutex())
93 , m_rContainer (rContainer
)
94 , m_bInsideAcceleratorList(sal_False
)
95 , m_bInsideAcceleratorItem(sal_False
)
99 //-----------------------------------------------
100 AcceleratorConfigurationReader::~AcceleratorConfigurationReader()
104 //-----------------------------------------------
105 void SAL_CALL
AcceleratorConfigurationReader::startDocument()
106 throw(css::xml::sax::SAXException
,
107 css::uno::RuntimeException
)
111 //-----------------------------------------------
112 void SAL_CALL
AcceleratorConfigurationReader::endDocument()
113 throw(css::xml::sax::SAXException
,
114 css::uno::RuntimeException
)
116 // The xml file seems to be corrupted.
117 // Because we found no end-tags ... at least for
120 (m_bInsideAcceleratorList
) ||
121 (m_bInsideAcceleratorItem
)
124 THROW_PARSEEXCEPTION("No matching start or end element 'acceleratorlist' found!")
128 //-----------------------------------------------
129 void SAL_CALL
AcceleratorConfigurationReader::startElement(const ::rtl::OUString
& sElement
,
130 const css::uno::Reference
< css::xml::sax::XAttributeList
>& xAttributeList
)
131 throw(css::xml::sax::SAXException
,
132 css::uno::RuntimeException
)
134 EXMLElement eElement
= AcceleratorConfigurationReader::implst_classifyElement(sElement
);
136 // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
137 // Because an item occures very often ... a list should occure one times only!
138 if (eElement
== E_ELEMENT_ITEM
)
140 if (!m_bInsideAcceleratorList
)
141 THROW_PARSEEXCEPTION("An element \"accel:item\" must be embeded into 'accel:acceleratorlist'.")
142 if (m_bInsideAcceleratorItem
)
143 THROW_PARSEEXCEPTION("An element \"accel:item\" is not a container.")
144 m_bInsideAcceleratorItem
= sal_True
;
146 ::rtl::OUString sCommand
;
147 css::awt::KeyEvent aEvent
;
149 sal_Int16 c
= xAttributeList
->getLength();
153 ::rtl::OUString sAttribute
= xAttributeList
->getNameByIndex(i
);
154 ::rtl::OUString sValue
= xAttributeList
->getValueByIndex(i
);
155 EXMLAttribute eAttribute
= AcceleratorConfigurationReader::implst_classifyAttribute(sAttribute
);
158 case E_ATTRIBUTE_URL
:
159 sCommand
= sValue
.intern();
162 case E_ATTRIBUTE_KEYCODE
:
163 aEvent
.KeyCode
= m_rKeyMapping
->mapIdentifierToCode(sValue
);
166 case E_ATTRIBUTE_MOD_SHIFT
:
167 aEvent
.Modifiers
|= css::awt::KeyModifier::SHIFT
;
170 case E_ATTRIBUTE_MOD_MOD1
:
171 aEvent
.Modifiers
|= css::awt::KeyModifier::MOD1
;
174 case E_ATTRIBUTE_MOD_MOD2
:
175 aEvent
.Modifiers
|= css::awt::KeyModifier::MOD2
;
178 case E_ATTRIBUTE_MOD_MOD3
:
179 aEvent
.Modifiers
|= css::awt::KeyModifier::MOD3
;
183 // validate command and key event.
185 (!sCommand
.getLength()) ||
186 (aEvent
.KeyCode
== 0 )
189 THROW_PARSEEXCEPTION("XML element does not describe a valid accelerator nor a valid command.")
192 // register key event + command inside cache ...
193 // Check for already existing items there.
194 if (!m_rContainer
.hasKey(aEvent
))
195 m_rContainer
.setKeyCommandPair(aEvent
, sCommand
);
196 #ifdef ENABLE_WARNINGS
199 // Attention: Its not realy a reason to throw an exception and kill the office, if the configuration contains
200 // multiple registrations for the same key :-) Show a warning ... and ignore the second item.
201 // THROW_PARSEEXCEPTION("Command is registered for the same key more then once.")
202 ::rtl::OUStringBuffer
sMsg(256);
203 sMsg
.appendAscii("Double registration detected.\nCommand = \"");
204 sMsg
.append (sCommand
);
205 sMsg
.appendAscii("\"\nKeyCode = " );
206 sMsg
.append ((sal_Int32
)aEvent
.KeyCode
);
207 sMsg
.appendAscii("\nModifiers = " );
208 sMsg
.append ((sal_Int32
)aEvent
.Modifiers
);
209 sMsg
.appendAscii("\nIgnore this item!" );
210 LOG_WARNING("AcceleratorConfigurationReader::startElement()", U2B(sMsg
.makeStringAndClear()))
212 #endif // ENABLE_WARNINGS
215 if (eElement
== E_ELEMENT_ACCELERATORLIST
)
217 if (m_bInsideAcceleratorList
)
218 THROW_PARSEEXCEPTION("An element \"accel:acceleratorlist\" cannot be used recursive.")
219 m_bInsideAcceleratorList
= sal_True
;
224 //-----------------------------------------------
225 void SAL_CALL
AcceleratorConfigurationReader::endElement(const ::rtl::OUString
& sElement
)
226 throw(css::xml::sax::SAXException
,
227 css::uno::RuntimeException
)
229 EXMLElement eElement
= AcceleratorConfigurationReader::implst_classifyElement(sElement
);
231 // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
232 // Because an item occures very often ... a list should occure one times only!
233 if (eElement
== E_ELEMENT_ITEM
)
235 if (!m_bInsideAcceleratorItem
)
236 THROW_PARSEEXCEPTION("Found end element 'accel:item', but no start element.")
237 m_bInsideAcceleratorItem
= sal_False
;
240 if (eElement
== E_ELEMENT_ACCELERATORLIST
)
242 if (!m_bInsideAcceleratorList
)
243 THROW_PARSEEXCEPTION("Found end element 'accel:acceleratorlist', but no start element.")
244 m_bInsideAcceleratorList
= sal_False
;
248 //-----------------------------------------------
249 void SAL_CALL
AcceleratorConfigurationReader::characters(const ::rtl::OUString
&)
250 throw(css::xml::sax::SAXException
,
251 css::uno::RuntimeException
)
255 //-----------------------------------------------
256 void SAL_CALL
AcceleratorConfigurationReader::ignorableWhitespace(const ::rtl::OUString
&)
257 throw(css::xml::sax::SAXException
,
258 css::uno::RuntimeException
)
262 //-----------------------------------------------
263 void SAL_CALL
AcceleratorConfigurationReader::processingInstruction(const ::rtl::OUString
& /*sTarget*/,
264 const ::rtl::OUString
& /*sData*/ )
265 throw(css::xml::sax::SAXException
,
266 css::uno::RuntimeException
)
270 //-----------------------------------------------
271 void SAL_CALL
AcceleratorConfigurationReader::setDocumentLocator(const css::uno::Reference
< css::xml::sax::XLocator
>& xLocator
)
272 throw(css::xml::sax::SAXException
,
273 css::uno::RuntimeException
)
275 m_xLocator
= xLocator
;
278 //-----------------------------------------------
279 AcceleratorConfigurationReader::EXMLElement
AcceleratorConfigurationReader::implst_classifyElement(const ::rtl::OUString
& sElement
)
281 AcceleratorConfigurationReader::EXMLElement eElement
;
283 if (sElement
.equals(NS_ELEMENT_ACCELERATORLIST
))
284 eElement
= E_ELEMENT_ACCELERATORLIST
;
286 if (sElement
.equals(NS_ELEMENT_ITEM
))
287 eElement
= E_ELEMENT_ITEM
;
289 throw css::uno::RuntimeException(
290 DECLARE_ASCII("Unknown XML element detected!"),
291 css::uno::Reference
< css::xml::sax::XDocumentHandler
>());
296 //-----------------------------------------------
297 AcceleratorConfigurationReader::EXMLAttribute
AcceleratorConfigurationReader::implst_classifyAttribute(const ::rtl::OUString
& sAttribute
)
299 AcceleratorConfigurationReader::EXMLAttribute eAttribute
;
301 if (sAttribute
.equals(NS_ATTRIBUTE_KEYCODE
))
302 eAttribute
= E_ATTRIBUTE_KEYCODE
;
304 if (sAttribute
.equals(NS_ATTRIBUTE_MOD_SHIFT
))
305 eAttribute
= E_ATTRIBUTE_MOD_SHIFT
;
307 if (sAttribute
.equals(NS_ATTRIBUTE_MOD_MOD1
))
308 eAttribute
= E_ATTRIBUTE_MOD_MOD1
;
310 if (sAttribute
.equals(NS_ATTRIBUTE_MOD_MOD2
))
311 eAttribute
= E_ATTRIBUTE_MOD_MOD2
;
313 if (sAttribute
.equals(NS_ATTRIBUTE_MOD_MOD3
))
314 eAttribute
= E_ATTRIBUTE_MOD_MOD3
;
316 if (sAttribute
.equals(NS_ATTRIBUTE_URL
))
317 eAttribute
= E_ATTRIBUTE_URL
;
319 throw css::uno::RuntimeException(
320 DECLARE_ASCII("Unknown XML attribute detected!"),
321 css::uno::Reference
< css::xml::sax::XDocumentHandler
>());
326 //-----------------------------------------------
327 ::rtl::OUString
AcceleratorConfigurationReader::implts_getErrorLineString()
329 if (!m_xLocator
.is())
330 return DECLARE_ASCII("Error during parsing XML. (No further info available ...)");
332 ::rtl::OUStringBuffer
sMsg(256);
333 sMsg
.appendAscii("Error during parsing XML in\nline = ");
334 sMsg
.append (m_xLocator
->getLineNumber() );
335 sMsg
.appendAscii("\ncolumn = " );
336 sMsg
.append (m_xLocator
->getColumnNumber() );
337 sMsg
.appendAscii("." );
338 return sMsg
.makeStringAndClear();
341 } // namespace framework