diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /src/kernel/qaccessible.cpp | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'src/kernel/qaccessible.cpp')
-rw-r--r-- | src/kernel/qaccessible.cpp | 719 |
1 files changed, 719 insertions, 0 deletions
diff --git a/src/kernel/qaccessible.cpp b/src/kernel/qaccessible.cpp new file mode 100644 index 0000000..d037124 --- /dev/null +++ b/src/kernel/qaccessible.cpp @@ -0,0 +1,719 @@ +/**************************************************************************** +** +** Implementation of QAccessible and QAccessibleObject classes +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qaccessible.h" + +#if defined(QT_ACCESSIBILITY_SUPPORT) + +#include "qptrdict.h" +#include "qmetaobject.h" +#include <private/qpluginmanager_p.h> +#include "qapplication.h" +#include <stdlib.h> + +/*! + \class QAccessible qaccessible.h + \brief The QAccessible class provides enums and static functions + relating to accessibility. + + \ingroup misc + + Accessibility clients use implementations of the + QAccessibleInterface to read the information an accessible object + exposes, or to call functions to manipulate the accessible object. + +\omit + Qt provides implementations of the QAccessibleInterface for most + widget classes in a plugin. This plugin is located in the \e + accessibility subdirectory of the plugins installation directory. + The default installation directory for plugins is \c INSTALL/plugins, + where \c INSTALL is the directory where Qt was installed. Calling + queryAccessibleInterface( QObject *object, QAccessibleInterface + **iface ) will ask all plugins located in this directory for an + implementation that exposes the information for objects of the + class of \e object. + + To make a Qt application accessible you have to distribute the + accessibility plugin provded with Qt together with your + application. Simply add the plugins created in + INSTALL/plugins/accessibility to your distribution process. Use \l + QApplication::addLibraryPath() to specify a plugin directory for + your application, and copy the files into an \e accessibility + subdirectory of one of those plugin directories. Qt's + accessibility framework will load the plugins upon request and use + the implementations provided to expose an object's accessibility + information. +\endomit + + See the \link plugins-howto.html plugin documentation \endlink for + more details about how to redistribute Qt plugins. +*/ + +/*! + \enum QAccessible::State + + This enum type defines bitflags that can be combined to indicate + the state of the accessible object. The values are: + + \value Normal + \value Unavailable + \value Selected + \value Focused + \value Pressed + \value Checked + \value Mixed + \value ReadOnly + \value HotTracked + \value Default + \value Expanded + \value Collapsed + \value Busy + \value Floating + \value Marqueed + \value Animated + \value Invisible + \value Offscreen + \value Sizeable + \value Moveable + \value SelfVoicing + \value Focusable + \value Selectable + \value Linked + \value Traversed + \value MultiSelectable + \value ExtSelectable + \value AlertLow + \value AlertMedium + \value AlertHigh + \value Protected + \value Valid +*/ + +/*! + \enum QAccessible::Event + + This enum type defines event types when the state of the + accessible object has changed. The event types are: + + \value SoundPlayed + \value Alert + \value ForegroundChanged + \value MenuStart + \value MenuEnd + \value PopupMenuStart + \value PopupMenuEnd + \value ContextHelpStart + \value ContextHelpEnd + \value DragDropStart + \value DragDropEnd + \value DialogStart + \value DialogEnd + \value ScrollingStart + \value ScrollingEnd + \value ObjectCreated + \value ObjectDestroyed + \value ObjectShow + \value ObjectHide + \value ObjectReorder + \value Focus + \value Selection + \value SelectionAdd + \value SelectionRemove + \value SelectionWithin + \value StateChanged + \value LocationChanged + \value NameChanged + \value DescriptionChanged + \value ValueChanged + \value ParentChanged + \value HelpChanged + \value DefaultActionChanged + \value AcceleratorChanged + \value MenuCommand +*/ + +/*! + \enum QAccessible::Role + + This enum defines a number of roles an accessible object can have. + The roles are: + + \value NoRole + \value TitleBar + \value MenuBar + \value ScrollBar + \value Grip + \value Sound + \value Cursor + \value Caret + \value AlertMessage + \value Window + \value Client + \value PopupMenu + \value MenuItem + \value ToolTip + \value Application + \value Document + \value Pane + \value Chart + \value Dialog + \value Border + \value Grouping + \value Separator + \value ToolBar + \value StatusBar + \value Table + \value ColumnHeader + \value RowHeader + \value Column + \value Row + \value Cell + \value Link + \value HelpBalloon + \value Character + \value List + \value ListItem + \value Outline + \value OutlineItem + \value PageTab + \value PropertyPage + \value Indicator + \value Graphic + \value StaticText + \value EditableText + \value PushButton + \value CheckBox + \value RadioButton + \value ComboBox + \value DropLest + \value ProgressBar + \value Dial + \value HotkeyField + \value Slider + \value SpinBox + \value Diagram + \value Animation + \value Equation + \value ButtonDropDown + \value ButtonMenu + \value ButtonDropGrid + \value Whitespace + \value PageTabList + \value Clock +*/ + +/*! + \enum QAccessible::NavDirection + + This enum specifies which item to move to when navigating. + + \value NavUp sibling above + \value NavDown sibling below + \value NavLeft left sibling + \value NavRight right sibling + \value NavNext next sibling + \value NavPrevious previous sibling + \value NavFirstChild first child + \value NavLastChild last child + \value NavFocusChild child with focus +*/ + +/*! + \enum QAccessible::Text + + This enum specifies string information that an accessible object + returns. + + \value Name The name of the object + \value Description A short text describing the object + \value Value The value of the object + \value Help A longer text giving information about how + to use the object + \value DefaultAction The default method to interact with the object + \value Accelerator The keyboard shortcut that executes the + default action +*/ + +/*! + \fn static void QAccessible::updateAccessibility( QObject *object, int control, Event reason ) + + Notifies accessibility clients about a change in \a object's + accessibility information. + + \a reason specifies the cause of the change, for example, + ValueChange when the position of a slider has been changed. \a + control is the ID of the child element that has changed. When \a + control is 0, the object itself has changed. + + Call this function whenever the state of your accessible object or + one of it's sub-elements has been changed either programmatically + (e.g. by calling QLabel::setText()) or by user interaction. + + If there are no accessibility tools listening to this event, the + performance penalty for calling this function is minor, but if determining + the parameters of the call is expensive you can use isActive() to + avoid unnecessary performance penalties if no client is listening. +*/ + +static QPluginManager<QAccessibleFactoryInterface> *qAccessibleManager = 0; + +class AccessibleCache : public QObject, public QPtrDict<QAccessibleInterface> +{ + Q_OBJECT +public: + AccessibleCache() + : QPtrDict<QAccessibleInterface>(73) + { + } + + void addObject(QObject *object, QAccessibleInterface *iface) + { + insert(object, iface); + connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(removeObject(QObject*))); + } + +public slots: + void removeObject(QObject *object); +}; + +#include "qaccessible.moc" + +static AccessibleCache *qAccessibleInterface = 0; +static bool cleanupAdded = FALSE; + +static void qAccessibleCleanup() +{ + if ( qAccessibleInterface && qAccessibleInterface->count() && qAccessibleManager ) + qAccessibleManager->setAutoUnload( FALSE ); + + delete qAccessibleInterface; + qAccessibleInterface = 0; + delete qAccessibleManager; + qAccessibleManager = 0; +} + +#ifdef Q_WS_MAC +QObject *QAccessible::queryAccessibleObject(QAccessibleInterface *o) +{ + if(qAccessibleInterface) { + for(QPtrDictIterator<QAccessibleInterface> it(*qAccessibleInterface); it.current(); ++it) { + if(it.current() == o) + return (QObject*)it.currentKey(); + } + } + return NULL; +} +#endif + +void AccessibleCache::removeObject(QObject *object) +{ + if (!object) + return; + + remove(object); + if (!count()) { + delete this; + qAccessibleInterface = 0; + } +} + + +/*! + Sets \a iface to point to the implementation of the + QAccessibleInterface for \a object, and returns \c QS_OK if + successfull, or sets \a iface to 0 and returns \c QE_NOCOMPONENT if + no accessibility implementation for \a object exists. + + The function uses the \link QObject::className() classname + \endlink of \a object to find a suitable implementation. If no + implementation for the object's class is available the function + tries to find an implementation for the object's parent class. + + This function is called to answer an accessibility client's + request for object information. You should never need to call this + function yourself. +*/ +QRESULT QAccessible::queryAccessibleInterface( QObject *object, QAccessibleInterface **iface ) +{ + *iface = 0; + if ( !object ) + return QE_INVALIDARG; + + if ( qAccessibleInterface ) { + *iface = qAccessibleInterface->find( object ); + if ( *iface ) { + (*iface)->addRef(); + return QS_OK; + } + } + + if ( !qAccessibleManager ) { + qAccessibleManager = new QPluginManager<QAccessibleFactoryInterface>( IID_QAccessibleFactory, QApplication::libraryPaths(), "/accessible" ); + if ( !cleanupAdded ) { + qAddPostRoutine( qAccessibleCleanup ); + cleanupAdded = TRUE; + } + } + + QInterfacePtr<QAccessibleFactoryInterface> factory = 0; + QMetaObject *mo = object->metaObject(); + while ( mo ) { + qAccessibleManager->queryInterface( mo->className(), &factory ); + if ( factory ) + break; + mo = mo->superClass(); + } + if ( factory ) + return factory->createAccessibleInterface( mo->className(), object, iface ); + + return QE_NOCOMPONENT; +} + +/*! + Returns TRUE if an accessibility implementation has been requested, + during the runtime of the application, otherwise returns FALSE. + + Use this function to prevent potentially expensive notifications via + updateAccessibility(). + + \omit + QListView uses this function to prevent index-lookups for item based + notifications. + \endomit +*/ +bool QAccessible::isActive() +{ + return qAccessibleManager != 0; +} + +/*! + \class QAccessibleInterface qaccessible.h + \brief The QAccessibleInterface class defines an interface that exposes information about accessible objects. + + \ingroup misc +*/ + +/*! + \fn bool QAccessibleInterface::isValid() const + + Returns TRUE if all the data necessary to use this interface + implementation is valid (e.g. all pointers are non-null), + otherwise returns FALSE. +*/ + +/*! + \fn int QAccessibleInterface::childCount() const + + Returns the number of children that belong to this object. A child + can provide accessibility information on it's own (e.g. a child + widget), or be a sub-element of this accessible object. + + All objects provide this information. + + \sa queryChild() +*/ + +/*! + \fn QRESULT QAccessibleInterface::queryChild( int control, QAccessibleInterface **iface ) const + + Sets \a iface to point to the implementation of the + QAccessibleInterface for the child specified with \a control. If + the child doesn't provide accessibility information on it's own, + the value of \a iface is set to 0. For those elements, this + object is responsible for exposing the child's properties. + + All objects provide this information. + + \sa childCount(), queryParent() +*/ + +/*! + \fn QRESULT QAccessibleInterface::queryParent( QAccessibleInterface **iface ) const + + Sets \a iface to point to the implementation of the + QAccessibleInterface for the parent object, or to 0 if there is + no such implementation or object. + + All objects provide this information. + + \sa queryChild() +*/ + +/*! + \fn int QAccessibleInterface::controlAt( int x, int y ) const + + Returns the ID of the child that contains the screen coordinates + (\a x, \a y). This function returns 0 if the point is positioned + on the object itself. If the tested point is outside the + boundaries of the object this function returns -1. + + All visual objects provide this information. +*/ + +/*! + \fn QRect QAccessibleInterface::rect( int control ) const + + Returns the location of the child specified with \a control in + screen coordinates. This function returns the location of the + object itself if \a control is 0. + + All visual objects provide this information. +*/ + +/*! + \fn int QAccessibleInterface::navigate( NavDirection direction, int startControl ) const + + This function traverses to another object, or to a sub-element of + the current object. \a direction specifies in which direction to + navigate, and \a startControl specifies the start point of the + navigation, which is either 0 if the navigation starts at the + object itself, or an ID of one of the object's sub-elements. + + The function returns the ID of the sub-element located in the \a + direction specified. If there is nothing in the navigated \a + direction, this function returns -1. + + All objects support navigation. +*/ + +/*! + \fn QString QAccessibleInterface::text( Text t, int control ) const + + Returns a string property \a t of the child object specified by \a + control, or the string property of the object itself if \a control + is 0. + + The \e Name is a string used by clients to identify, find or + announce an accessible object for the user. All objects must have + a name that is unique within their container. + + An accessible object's \e Description provides textual information + about an object's visual appearance. The description is primarily + used to provide greater context for low-vision or blind users, but + is also used for context searching or other applications. Not all + objects have a description. An "OK" button would not need a + description, but a toolbutton that shows a picture of a smiley + would. + + The \e Value of an accessible object represents visual information + contained by the object, e.g. the text in a line edit. Usually, + the value can be modified by the user. Not all objects have a + value, e.g. static text labels don't, and some objects have a + state that already is the value, e.g. toggle buttons. + + The \e Help text provides information about the function and + usage of an accessible object. Not all objects provide this + information. + + An accessible object's \e DefaultAction describes the object's + primary method of manipulation, and should be a verb or a short + phrase, e.g. "Press" for a button. + + The accelerator is a keyboard shortcut that activates the default + action of the object. A keyboard shortcut is the underlined + character in the text of a menu, menu item or control, and is + either the character itself, or a combination of this character + and a modifier key like ALT, CTRL or SHIFT. Command controls like + tool buttons also have shortcut keys and usually display them in + their tooltip. + + \sa role(), state(), selection() +*/ + +/*! + \fn void QAccessibleInterface::setText( Text t, int control, const QString &text ) + + Sets the text property \a t of the child object \a control to \a + text. If \a control is 0, the text property of the object itself + is set. +*/ + +/*! + \fn QAccessible::Role QAccessibleInterface::role( int control ) const + + Returns the role of the object if \a control is 0, or the role of + the object's sub-element with ID \a control. The role of an object + is usually static. All accessible objects have a role. + + \sa text(), state(), selection() +*/ + +/*! + \fn QAccessible::State QAccessibleInterface::state( int control ) const + + Returns the current state of the object if \a control is 0, or the + state of the object's sub-element element with ID \a control. All + objects have a state. + + \sa text(), role(), selection() +*/ + +/*! + \fn QMemArray<int> QAccessibleInterface::selection() const + + Returns the list of all the element IDs that are selected. + + \sa text(), role(), state() +*/ + +/*! + \fn bool QAccessibleInterface::doDefaultAction( int control ) + + Calling this function performs the default action of the child + object specified by \a control, or the default action of the + object itself if \a control is 0. +*/ + +/*! + \fn bool QAccessibleInterface::setFocus( int control ) + + Gives the focus to the child object specified by \a control, or to + the object itself if \a control is 0. + + Returns TRUE if the focus could be set; otherwise returns FALSE. +*/ + +/*! + \fn bool QAccessibleInterface::setSelected( int control, bool on, bool extend ) + + Sets the selection of the child object with ID \a control to \a + on. If \a extend is TRUE, all child elements between the focused + item and the specified child object have their selection set to \a + on. + + Returns TRUE if the selection could be set; otherwise returns + FALSE. + + \sa setFocus(), clearSelection() +*/ + +/*! + \fn void QAccessibleInterface::clearSelection() + + Removes any selection from the object. + + \sa setSelected() +*/ + + + +/*! + \class QAccessibleObject qaccessible.h + \brief The QAccessibleObject class implements parts of the + QAccessibleInterface for QObjects. + + \ingroup misc + + This class is mainly provided for convenience. All subclasses of + the QAccessibleInterface should use this class as the base class. +*/ + +/*! + Creates a QAccessibleObject for \a object. +*/ +QAccessibleObject::QAccessibleObject( QObject *object ) +: object_(object) +{ + if ( !qAccessibleInterface ) { + qAccessibleInterface = new AccessibleCache; + if ( !cleanupAdded ) { + qAddPostRoutine( qAccessibleCleanup ); + cleanupAdded = TRUE; + } + } + + qAccessibleInterface->addObject(object, this); +} + +/*! + Destroys the QAccessibleObject. + + This only happens when a call to release() decrements the internal + reference counter to zero. +*/ +QAccessibleObject::~QAccessibleObject() +{ + if ( qAccessibleInterface ) { + qAccessibleInterface->removeObject(object_); + if ( !qAccessibleInterface->count() ) { + delete qAccessibleInterface; + qAccessibleInterface = 0; + } + } +} + +/*! + \reimp +*/ +QRESULT QAccessibleObject::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QAccessible ) + *iface = (QAccessibleInterface*)this; + else if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +/*! + Returns the QObject for which this QAccessibleInterface + implementation provides information. Use isValid() to make sure + the object pointer is safe to use. +*/ +QObject *QAccessibleObject::object() const +{ +#if defined(QT_CHECK_RANGE) + if ( !isValid() ) + qWarning( "QAccessibleInterface is invalid. Crash pending..." ); +#endif + return object_; +} + +/*! + \reimp +*/ +bool QAccessibleObject::isValid() const +{ + return !object_.isNull(); +} + +#endif |