diff options
author | Rüdiger Timm <rt@openoffice.org> | 2004-09-20 09:09:32 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2004-09-20 09:09:32 +0000 |
commit | 00945245311d32444fe9f65d9a7e01a48b7b137e (patch) | |
tree | 3cf1c5fdc39b5cf83f7fe106178f1f27726ce4e9 /framework | |
parent | 81b384b191009dbd598a3f9865a062b7ac510d77 (diff) |
INTEGRATION: CWS keyconfig01 (1.1.2); FILE ADDED
2004/09/09 06:02:05 as 1.1.2.3: #i29441# handle double shortcut registrations more gracefully
2004/06/22 07:57:40 as 1.1.2.2: #i29863# second revision of shortcut configuration
2004/06/04 09:31:08 as 1.1.2.1: #i29863# first revision
Diffstat (limited to 'framework')
-rw-r--r-- | framework/source/xml/acceleratorconfigurationreader.cxx | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/framework/source/xml/acceleratorconfigurationreader.cxx b/framework/source/xml/acceleratorconfigurationreader.cxx new file mode 100644 index 000000000000..f5fda50f0dbd --- /dev/null +++ b/framework/source/xml/acceleratorconfigurationreader.cxx @@ -0,0 +1,387 @@ +/************************************************************************* + * + * $RCSfile: acceleratorconfigurationreader.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2004-09-20 10:09:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _FRAMEWORK_XML_ACCELERATORCONFIGURATIONREADER_HXX_ +#include <xml/acceleratorconfigurationreader.hxx> +#endif + +//_______________________________________________ +// own includes + +#ifndef __FRAMEWORK_ACCELERATORCONST_H_ +#include <acceleratorconst.h> +#endif + +//_______________________________________________ +// interface includes + +#ifndef _COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_KEYMODIFIER_HPP_ +#include <com/sun/star/awt/KeyModifier.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_KEYEVENT_HPP_ +#include <com/sun/star/awt/KeyEvent.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_KEY_HPP_ +#include <com/sun/star/awt/Key.hpp> +#endif + +#ifndef _COM_SUN_STAR_CONTAINER_ELEMENTEXISTEXCEPTION_HPP_ +#include <com/sun/star/container/ElementExistException.hpp> +#endif + +//_______________________________________________ +// other includes + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif + +//_______________________________________________ +// namespace + +namespace framework{ + +//----------------------------------------------- +/* Throws a SaxException in case a wrong formated XML + structure was detected. + + This macro combined the given comment with a generic + way to find out the XML line (where the error occured) + to format a suitable message. + + @param COMMENT + an ascii string, which describe the problem. + */ +#define THROW_PARSEEXCEPTION(COMMENT) \ + { \ + ::rtl::OUStringBuffer sMessage(256); \ + sMessage.append (implts_getErrorLineString()); \ + sMessage.appendAscii(COMMENT ); \ + \ + throw css::xml::sax::SAXException( \ + sMessage.makeStringAndClear(), \ + static_cast< css::xml::sax::XDocumentHandler* >(this), \ + css::uno::Any()); \ + } + +//----------------------------------------------- +// XInterface +DEFINE_XINTERFACE_1(AcceleratorConfigurationReader , + OWeakObject , + DIRECT_INTERFACE(css::xml::sax::XDocumentHandler)) + +//----------------------------------------------- +AcceleratorConfigurationReader::AcceleratorConfigurationReader(AcceleratorCache& rContainer) + : ThreadHelpBase (&Application::GetSolarMutex()) + , OWeakObject ( ) + , m_rContainer (rContainer ) + , m_bInsideAcceleratorList(sal_False ) + , m_bInsideAcceleratorItem(sal_False ) +{ +} + +//----------------------------------------------- +AcceleratorConfigurationReader::~AcceleratorConfigurationReader() +{ +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::startDocument() + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::endDocument() + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ + // The xml file seems to be corrupted. + // Because we found no end-tags ... at least for + // one list or item. + if ( + (m_bInsideAcceleratorList) || + (m_bInsideAcceleratorItem) + ) + { + THROW_PARSEEXCEPTION("No matching start or end element 'acceleratorlist' found!") + } +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::startElement(const ::rtl::OUString& sElement , + const css::uno::Reference< css::xml::sax::XAttributeList >& xAttributeList) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ + EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement); + + // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation. + // Because an item occures very often ... a list should occure one times only! + if (eElement == E_ELEMENT_ITEM) + { + if (!m_bInsideAcceleratorList) + THROW_PARSEEXCEPTION("An element \"accel:item\" must be embeded into 'accel:acceleratorlist'.") + if (m_bInsideAcceleratorItem) + THROW_PARSEEXCEPTION("An element \"accel:item\" is not a container.") + m_bInsideAcceleratorItem = sal_True; + + ::rtl::OUString sCommand; + css::awt::KeyEvent aEvent ; + + sal_Int16 c = xAttributeList->getLength(); + sal_Int16 i = 0; + for (i=0; i<c; ++i) + { + ::rtl::OUString sAttribute = xAttributeList->getNameByIndex(i); + ::rtl::OUString sValue = xAttributeList->getValueByIndex(i); + EXMLAttribute eAttribute = AcceleratorConfigurationReader::implst_classifyAttribute(sAttribute); + switch(eAttribute) + { + case E_ATTRIBUTE_URL : + sCommand = sValue; + break; + + case E_ATTRIBUTE_KEYCODE : + aEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sValue); + break; + + case E_ATTRIBUTE_MOD_SHIFT : + aEvent.Modifiers |= css::awt::KeyModifier::SHIFT; + break; + + case E_ATTRIBUTE_MOD_MOD1 : + aEvent.Modifiers |= css::awt::KeyModifier::MOD1; + break; + + case E_ATTRIBUTE_MOD_MOD2 : + aEvent.Modifiers |= css::awt::KeyModifier::MOD2; + break; + } + } + + // validate command and key event. + if ( + (!sCommand.getLength()) || + (aEvent.KeyCode == 0 ) + ) + { + THROW_PARSEEXCEPTION("XML element does not describe a valid accelerator nor a valid command.") + } + + // register key event + command inside cache ... + // Check for already existing items there. + if (!m_rContainer.hasKey(aEvent)) + m_rContainer.setKeyCommandPair(aEvent, sCommand); + #ifdef ENABLE_WARNINGS + else + { + // Attention: Its not realy a reason to throw an exception and kill the office, if the configuration contains + // multiple registrations for the same key :-) Show a warning ... and ignore the second item. + // THROW_PARSEEXCEPTION("Command is registered for the same key more then once.") + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("Double registration detected.\nCommand = \""); + sMsg.append (sCommand ); + sMsg.appendAscii("\"\nKeyCode = " ); + sMsg.append ((sal_Int32)aEvent.KeyCode ); + sMsg.appendAscii("\nModifiers = " ); + sMsg.append ((sal_Int32)aEvent.Modifiers ); + sMsg.appendAscii("\nIgnore this item!" ); + LOG_WARNING("AcceleratorConfigurationReader::startElement()", U2B(sMsg.makeStringAndClear())) + } + #endif // ENABLE_WARNINGS + } + + if (eElement == E_ELEMENT_ACCELERATORLIST) + { + if (m_bInsideAcceleratorList) + THROW_PARSEEXCEPTION("An element \"accel:acceleratorlist\" cannot be used recursive.") + m_bInsideAcceleratorList = sal_True; + return; + } +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::endElement(const ::rtl::OUString& sElement) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ + EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement); + + // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation. + // Because an item occures very often ... a list should occure one times only! + if (eElement == E_ELEMENT_ITEM) + { + if (!m_bInsideAcceleratorItem) + THROW_PARSEEXCEPTION("Found end element 'accel:item', but no start element.") + m_bInsideAcceleratorItem = sal_False; + } + + if (eElement == E_ELEMENT_ACCELERATORLIST) + { + if (!m_bInsideAcceleratorList) + THROW_PARSEEXCEPTION("Found end element 'accel:acceleratorlist', but no start element.") + m_bInsideAcceleratorList = sal_False; + } +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::characters(const ::rtl::OUString& sChars) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::ignorableWhitespace(const ::rtl::OUString& sWhitespaces) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::processingInstruction(const ::rtl::OUString& sTarget, + const ::rtl::OUString& sData ) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ +} + +//----------------------------------------------- +void SAL_CALL AcceleratorConfigurationReader::setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator >& xLocator) + throw(css::xml::sax::SAXException, + css::uno::RuntimeException ) +{ + m_xLocator = xLocator; +} + +//----------------------------------------------- +AcceleratorConfigurationReader::EXMLElement AcceleratorConfigurationReader::implst_classifyElement(const ::rtl::OUString& sElement) +{ + AcceleratorConfigurationReader::EXMLElement eElement; + + if (sElement.equals(NS_ELEMENT_ACCELERATORLIST)) + eElement = E_ELEMENT_ACCELERATORLIST; + else + if (sElement.equals(NS_ELEMENT_ITEM)) + eElement = E_ELEMENT_ITEM; + else + throw css::uno::RuntimeException( + DECLARE_ASCII("Unknown XML element detected!"), + css::uno::Reference< css::xml::sax::XDocumentHandler >()); + + return eElement; +} + +//----------------------------------------------- +AcceleratorConfigurationReader::EXMLAttribute AcceleratorConfigurationReader::implst_classifyAttribute(const ::rtl::OUString& sAttribute) +{ + AcceleratorConfigurationReader::EXMLAttribute eAttribute; + + if (sAttribute.equals(NS_ATTRIBUTE_KEYCODE)) + eAttribute = E_ATTRIBUTE_KEYCODE; + else + if (sAttribute.equals(NS_ATTRIBUTE_MOD_SHIFT)) + eAttribute = E_ATTRIBUTE_MOD_SHIFT; + else + if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD1)) + eAttribute = E_ATTRIBUTE_MOD_MOD1; + else + if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD2)) + eAttribute = E_ATTRIBUTE_MOD_MOD2; + else + if (sAttribute.equals(NS_ATTRIBUTE_URL)) + eAttribute = E_ATTRIBUTE_URL; + else + throw css::uno::RuntimeException( + DECLARE_ASCII("Unknown XML attribute detected!"), + css::uno::Reference< css::xml::sax::XDocumentHandler >()); + + return eAttribute; +} + +//----------------------------------------------- +::rtl::OUString AcceleratorConfigurationReader::implts_getErrorLineString() +{ + if (!m_xLocator.is()) + return DECLARE_ASCII("Error during parsing XML. (No further info available ...)"); + + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("Error during parsing XML in\nline = "); + sMsg.append (m_xLocator->getLineNumber() ); + sMsg.appendAscii("\ncolumn = " ); + sMsg.append (m_xLocator->getColumnNumber() ); + sMsg.appendAscii("." ); + return sMsg.makeStringAndClear(); +} + +} // namespace framework |