diff -Nru qt-at-spi-0.1.1/debian/changelog qt-at-spi-0.1.1+20120306/debian/changelog --- qt-at-spi-0.1.1/debian/changelog 2012-01-16 12:20:34.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/debian/changelog 2012-03-07 22:34:32.000000000 +0000 @@ -1,3 +1,13 @@ +qt-at-spi (0.1.1+20120306-0ubuntu1) precise; urgency=low + + * New upstream bugfix snapshot (LP: #947641) + - Fix broken menu accessibility + - Set proper role for password line edits + - Emit selection changed signals + - Implement accessible actions + + -- Luke Yelavich Thu, 08 Mar 2012 09:34:05 +1100 + qt-at-spi (0.1.1-0ubuntu1) precise; urgency=low * New upstream release. diff -Nru qt-at-spi-0.1.1/doc/qatspi.qdocconf qt-at-spi-0.1.1+20120306/doc/qatspi.qdocconf --- qt-at-spi-0.1.1/doc/qatspi.qdocconf 1970-01-01 00:00:00.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/doc/qatspi.qdocconf 2012-03-05 13:34:16.000000000 +0000 @@ -0,0 +1,13 @@ +project = Qt AT-SPI bridge +description = Linux Qt accessibility bridge + +sourcedirs = ../src +headerdirs = ../src +sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" +headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" +examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml" +examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng" + +outputformats = HTML +outputdir = html + diff -Nru qt-at-spi-0.1.1/doc/README qt-at-spi-0.1.1+20120306/doc/README --- qt-at-spi-0.1.1/doc/README 1970-01-01 00:00:00.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/doc/README 2012-03-05 13:34:16.000000000 +0000 @@ -0,0 +1,5 @@ +You can create the API documentation with the following command: + $ qdoc3 qatspi.qdocconf + +The documentation will be generated in doc/html. + diff -Nru qt-at-spi-0.1.1/examples/simple/mainwindow.ui qt-at-spi-0.1.1+20120306/examples/simple/mainwindow.ui --- qt-at-spi-0.1.1/examples/simple/mainwindow.ui 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/examples/simple/mainwindow.ui 2012-03-05 13:34:16.000000000 +0000 @@ -6,7 +6,7 @@ 0 0 - 4095 + 5756 602 @@ -21,14 +21,54 @@ - 4 + 0 Line Edit - - + + + + + Name line edit + + + + + + + Name line edit + + + QLineEdit::Password + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Enter your name: + + + lineEdit + + + + Accessible description for "Some Text" label @@ -38,64 +78,36 @@ - - - - - - Enter your name: - - - lineEdit - - - - - - - Name line edit - - - - - - - - - - - Display greeting - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Test entering a password: + + + lineEdit + + - - + + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 5563 + 20 + + + + Display greeting + + + @@ -530,7 +542,7 @@ 0 0 - 3902 + 5563 70 @@ -744,7 +756,7 @@ 0 0 - 4095 + 5756 21 @@ -892,7 +904,6 @@ hideButton showButton checkBox - greetButton checkBox_2 textEdit lineEdit diff -Nru qt-at-spi-0.1.1/.gitignore qt-at-spi-0.1.1+20120306/.gitignore --- qt-at-spi-0.1.1/.gitignore 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/.gitignore 2012-03-05 13:34:16.000000000 +0000 @@ -6,6 +6,8 @@ examples/simple/simple examples/declarative/declarative +doc/html + callgrind.out.* pcviewer.cfg *~ diff -Nru qt-at-spi-0.1.1/src/accessible.cpp qt-at-spi-0.1.1+20120306/src/accessible.cpp --- qt-at-spi-0.1.1/src/accessible.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/accessible.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,344 +0,0 @@ -/* - * D-Bus AT-SPI, Qt Adaptor - * - * Copyright 2009-2011 Nokia Corporation and/or its subsidiary(-ies). - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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, see . - */ - -#include "accessible.h" - -#include -#include -#include - -#include - -#include "adaptor.h" -#include "bridge.h" -#include "cache.h" -#include "constant_mappings.h" - -#include "generated/accessible_adaptor.h" -#include "generated/action_adaptor.h" -#include "generated/component_adaptor.h" -#include "generated/editable_text_adaptor.h" -#include "generated/event_adaptor.h" -#include "generated/socket_proxy.h" -#include "generated/table_adaptor.h" -#include "generated/text_adaptor.h" -#include "generated/value_adaptor.h" - -#define ACCESSIBLE_CREATION_DEBUG - -#define QSPI_REGISTRY_NAME "org.a11y.atspi.Registry" - - -QString QSpiAccessible::pathForObject(QObject *object) -{ - Q_ASSERT(object); - return QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast(object)); -} - -QString QSpiAccessible::pathForInterface(QAccessibleInterface *interface, int childIndex) -{ - QString path; - QAccessibleInterface* interfaceWithObject = interface; - while(!interfaceWithObject->object()) { - QAccessibleInterface* parentInterface; - interfaceWithObject->navigate(QAccessible::Ancestor, 1, &parentInterface); - Q_ASSERT(parentInterface->isValid()); - int index = parentInterface->indexOfChild(interfaceWithObject); - //Q_ASSERT(index >= 0); - // FIXME: This should never happen! - if (index < 0) { - - index = 999; - path.prepend("/BROKEN_OBJECT_HIERARCHY"); - qWarning() << "Object claims to have child that we cannot navigate to. FIX IT!" << parentInterface->object(); - - qDebug() << "Original interface: " << interface->object() << index; - qDebug() << "Parent interface: " << parentInterface->object() << " childcount:" << parentInterface->childCount(); - QObject* p = parentInterface->object(); - qDebug() << p->children(); - - QAccessibleInterface* tttt; - int id = parentInterface->navigate(QAccessible::Child, 1, &tttt); - qDebug() << "Nav child: " << id << tttt->object(); - } - path.prepend('/' + QString::number(index)); - interfaceWithObject = parentInterface; - } - path.prepend(QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast(interfaceWithObject->object()))); - - if (childIndex > 0) { - path.append('/' + QString::number(childIndex)); - } - return path; -} - -QPair QSpiAccessible::interfaceFromPath(const QString& dbusPath) -{ - QStringList parts = dbusPath.split('/'); - - Q_ASSERT(parts.size() > 5); - - // ignore the first /org/a11y/atspi/accessible/ - QString objectString = parts.at(5); - - quintptr uintptr = objectString.toULongLong(); - - if (!uintptr) - return QPair(0, 0); - - QObject* object = reinterpret_cast(uintptr); - - qDebug() << object; - QAccessibleInterface* inter = QAccessible::queryAccessibleInterface(object); - QAccessibleInterface* childInter; - - int index = 0; - - for (int i = 6; i < parts.size(); ++i) { - index = inter->navigate(QAccessible::Child, parts.at(i).toInt(), &childInter); - if (index == 0) { - delete inter; - inter = childInter; - } - } - - return QPair(inter, index); -} - -QSpiAccessible::QSpiAccessible(QAccessibleInterface *interface, int index) - : QSpiAdaptor(interface, index) -{ - QString path = pathForInterface(interface, index); - QDBusObjectPath dbusPath = QDBusObjectPath(path); - - reference = QSpiObjectReference(spiBridge->dBusConnection(), - dbusPath); -#ifdef ACCESSIBLE_CREATION_DEBUG - qDebug() << "ACCESSIBLE: " << interface->object() << reference.path.path() << interface->text(QAccessible::Name, index) << qSpiRoleMapping[interface->role(index)].name(); -#endif - - new AccessibleAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_ACCESSIBLE; - - if ( (!interface->rect(index).isEmpty()) || - (interface->object() && interface->object()->isWidgetType()) || - (interface->role(index) == QAccessible::ListItem) || - (interface->role(index) == QAccessible::Cell) || - (interface->role(index) == QAccessible::TreeItem) || - (interface->role(index) == QAccessible::Row) || - (interface->role(index) == QAccessible::RowHeader) || - (interface->role(index) == QAccessible::ColumnHeader) || - (interface->object() && interface->object()->inherits("QSGItem")) - ) { - new ComponentAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_COMPONENT; - - if (interface->object() && interface->object()->isWidgetType()) { - QWidget *w = qobject_cast(interface->object()); - if (w->isWindow()) { - new WindowAdaptor(this); -#ifdef ACCESSIBLE_CREATION_DEBUG - qDebug() << " IS a window"; -#endif - } - } - } -#ifdef ACCESSIBLE_CREATION_DEBUG - else { - qDebug() << " IS NOT a component"; - } -#endif - - new ObjectAdaptor(this); - new FocusAdaptor(this); - - if (interface->actionInterface()) - { - new ActionAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_ACTION; - } - if (interface->textInterface()) - { - new TextAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_TEXT; - oldText = interface->textInterface()->text(0, interface->textInterface()->characterCount()); - } - if (interface->editableTextInterface()) - { - new EditableTextAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_EDITABLE_TEXT; - } - if (interface->valueInterface()) - { - new ValueAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_VALUE; - } - if (interface->table2Interface()) - { - new TableAdaptor(this); - supportedInterfaces << QSPI_INTERFACE_TABLE; - } - - spiBridge->dBusConnection().registerObject(reference.path.path(), - this, QDBusConnection::ExportAdaptors); - state = interface->state(childIndex()); -} - -QSpiObjectReference QSpiAccessible::getParentReference() const -{ - Q_ASSERT(interface); - - if (interface->isValid()) { - QAccessibleInterface *parentInterface = 0; - interface->navigate(QAccessible::Ancestor, 1, &parentInterface); - if (parentInterface) { - QSpiAdaptor *parent = spiBridge->objectToAccessible(parentInterface->object()); - delete parentInterface; - if (parent) - return parent->getReference(); - } - } - qWarning() << "Invalid parent: " << interface << interface->object(); - return QSpiObjectReference(); -} - -void QSpiAccessible::accessibleEvent(QAccessible::Event event) -{ - Q_ASSERT(interface); - if (!interface->isValid()) { - spiBridge->removeAdaptor(this); - return; - } - - switch (event) { - case QAccessible::NameChanged: { - QSpiObjectReference r = getReference(); - QDBusVariant data; - data.setVariant(QVariant::fromValue(r)); - emit PropertyChange("accessible-name", 0, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::DescriptionChanged: { - QSpiObjectReference r = getReference(); - QDBusVariant data; - data.setVariant(QVariant::fromValue(r)); - emit PropertyChange("accessible-description", 0, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::Focus: { - - qDebug() << "Focus: " << getReference().path.path() << interface->object() << interface->text(QAccessible::Name, 0); - - QDBusVariant data; - data.setVariant(QVariant::fromValue(getReference())); - emit StateChanged("focused", 1, 0, data, spiBridge->getRootReference()); - emit Focus("", 0, 0, data, spiBridge->getRootReference()); - break; - } -#if (QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)) - case QAccessible::TextUpdated: { - Q_ASSERT(interface->textInterface()); - - // at-spi doesn't have a proper text updated/changed, so remove all and re-add the new text - qDebug() << "Text changed: " << interface->object(); - QDBusVariant data; - data.setVariant(QVariant::fromValue(oldText)); - emit TextChanged("delete", 0, oldText.length(), data, spiBridge->getRootReference()); - - QString text = interface->textInterface()->text(0, interface->textInterface()->characterCount()); - data.setVariant(QVariant::fromValue(text)); - emit TextChanged("insert", 0, text.length(), data, spiBridge->getRootReference()); - oldText = text; - - QDBusVariant cursorData; - int pos = interface->textInterface()->cursorPosition(); - cursorData.setVariant(QVariant::fromValue(pos)); - emit TextCaretMoved(QString(), pos ,0, cursorData, spiBridge->getRootReference()); - break; - } - case QAccessible::TextCaretMoved: { - Q_ASSERT(interface->textInterface()); - qDebug() << "Text caret moved: " << interface->object(); - QDBusVariant data; - int pos = interface->textInterface()->cursorPosition(); - data.setVariant(QVariant::fromValue(pos)); - emit TextCaretMoved(QString(), pos ,0, data, spiBridge->getRootReference()); - break; - } -#endif - case QAccessible::ValueChanged: { - Q_ASSERT(interface->valueInterface()); - QDBusVariant data; - data.setVariant(QVariant::fromValue(getReference())); - emit PropertyChange("accessible-value", 0, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::ObjectShow:{ - QDBusVariant data; - data.setVariant(QVariant::fromValue(getReference())); - emit StateChanged("showing", 1, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::ObjectHide: { - QDBusVariant data; - data.setVariant(QVariant::fromValue(getReference())); - emit StateChanged("showing", 0, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::ObjectDestroyed: - // TODO - maybe send children-changed and cache Removed -// qWarning() << "Object destroyed"; - break; - case QAccessible::StateChanged: { - QAccessible::State newState = interface->state(childIndex()); -// qDebug() << "StateChanged: old: " << state << " new: " << newState << " xor: " << (state^newState); - if ((state^newState) & QAccessible::Checked) { - int checked = (newState & QAccessible::Checked) ? 1 : 0; - QDBusVariant data; - data.setVariant(QVariant::fromValue(getReference())); - emit StateChanged("checked", checked, 0, data, spiBridge->getRootReference()); - } - state = newState; - break; - } - case QAccessible::TableModelChanged: { - // This is rather evil. We don't send data and hope that at-spi fetches the right child. - // This hack fails when a row gets removed and a different one added in its place. - QDBusVariant data; - emit ChildrenChanged("add", 0, 0, data, spiBridge->getRootReference()); - break; - } - case QAccessible::ParentChanged: - // TODO - send parent changed - default: -// qWarning() << "QSpiAccessible::accessibleEvent not handled: " << QString::number(event, 16) -// << " obj: " << interface->object() -// << (interface->isValid() ? interface->object()->objectName() : " invalid interface!"); - break; - } -} - -void QSpiAccessible::windowActivated() -{ - QDBusVariant data; - data.setVariant(QString()); - emit Create("", 0, 0, data, spiBridge->getRootReference()); - emit Restore("", 0, 0, data, spiBridge->getRootReference()); - emit Activate("", 0, 0, data, spiBridge->getRootReference()); -} diff -Nru qt-at-spi-0.1.1/src/accessible.h qt-at-spi-0.1.1+20120306/src/accessible.h --- qt-at-spi-0.1.1/src/accessible.h 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/accessible.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - * D-Bus AT-SPI, Qt Adaptor - * - * Copyright 2009-2011 Nokia Corporation and/or its subsidiary(-ies). - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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, see . - */ - -#ifndef Q_SPI_ACCESSIBLE_H -#define Q_SPI_ACCESSIBLE_H - -#include "adaptor.h" - -#include -#include -#include - -#include - - -/* - * Used for all accessible objects other than the root object. - * - * Assigns its own D-Bus reference and uses the QAccessibleInterface 'navigate' - * method to report its parent. - */ -class QSpiAccessible : public QSpiAdaptor -{ - Q_OBJECT - -public: - QSpiAccessible(QAccessibleInterface *interface, int index = 0); - virtual ~QSpiAccessible() {} - virtual QSpiObjectReference getParentReference() const; - virtual void accessibleEvent(QAccessible::Event event); - void windowActivated(); - - static QString pathForInterface(QAccessibleInterface *interface, int index); - static QString pathForObject(QObject *object); - static QPair interfaceFromPath(const QString& dbusPath); - -Q_SIGNALS: - // window - void Activate(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void Create(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void Restore(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - -private: - static QDBusObjectPath getUnique(); - - // AT-SPI wants updates of what changed, not only the new state. - QAccessible::State state; - // When changing text, we remove the complete old text, but for that we need its length. - QString oldText; - - friend class QSpiAccessibleBridge; -}; - -#endif /* Q_SPI_ACCESSIBLE_H */ diff -Nru qt-at-spi-0.1.1/src/adaptor.cpp qt-at-spi-0.1.1+20120306/src/adaptor.cpp --- qt-at-spi-0.1.1/src/adaptor.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/adaptor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1313 +0,0 @@ -/* - * D-Bus AT-SPI, Qt Adaptor - * - * Copyright 2009-2011 Nokia Corporation and/or its subsidiary(-ies). - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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, see . - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "accessible.h" -#include "adaptor.h" -#include "bridge.h" -#include "constant_mappings.h" - - -QSpiAdaptor::QSpiAdaptor(QAccessibleInterface *interface_, int child) - : interface(interface_), child(child) -{ -} - -QObject* QSpiAdaptor::getObject() const -{ - return interface->object(); -} - -QSpiObjectReference QSpiAdaptor::getReference() const -{ - return reference; -} - -QStringList QSpiAdaptor::getSupportedInterfaces() const -{ - return supportedInterfaces; -} - -bool QSpiAdaptor::checkInterface() const -{ - // The interface can be deleted behind our back with no notification. - if (!interface->isValid()) { - spiBridge->removeAdaptor(const_cast(this)); - return false; - } - return true; -} - -QSpiAccessibleCacheItem QSpiAdaptor::getCacheItem() const -{ - Q_ASSERT(interface); - if (!interface->isValid()) { - qWarning() << "QSpiObject::getCacheItem: invalid interface" << reference.path.path(); - return QSpiAccessibleCacheItem(); - } - - QSpiAccessibleCacheItem item; - item.path = getReference(); - item.parent = getParentReference(); - item.application = spiBridge->getRootReference(); - item.children = GetChildren(); - item.supportedInterfaces = getSupportedInterfaces(); - item.name = interface->text(QAccessible::Name, child); - item.role = qSpiRoleMapping.value(interface->role(child)).spiRole(); - item.description = interface->text(QAccessible::Description, child); - item.state = GetState(); - return item; -} - -void QSpiAdaptor::signalChildrenChanged(const QString &type, int detail1, int detail2, const QDBusVariant &data) -{ - emit ChildrenChanged(type, detail1, detail2, data, spiBridge->getRootReference()); -} - -int QSpiAdaptor::childCount() const -{ - if (!checkInterface()) return 0; - - if (child) - return 0; - return interface->childCount(); -} - -QString QSpiAdaptor::description() const -{ - if (!checkInterface()) return QString(); - return interface->text(QAccessible::Description, child); -} - -QString QSpiAdaptor::name() const -{ - if (!checkInterface()) return QString(); - QString name = interface->text(QAccessible::Name, child); - if (!name.isEmpty()) { - return name; - } - return interface->text(QAccessible::Value, child); -} - -QSpiObjectReference QSpiAdaptor::parent() const -{ - if (!checkInterface()) return QSpiObjectReference(); - return getParentReference(); -} - -QSpiObjectReference QSpiAdaptor::GetApplication() const -{ - if (!checkInterface()) return QSpiObjectReference(); - return spiBridge->getRootReference(); -} - -QSpiAttributeSet QSpiAdaptor::GetAttributes() const -{ - if (!checkInterface()) return QSpiAttributeSet(); - // No attributes interface in QAccessible so a blank list seems the sensible option. - QSpiAttributeSet out0; - return out0; -} - -QSpiObjectReference QSpiAdaptor::GetChildAtIndex(int index) const -{ - if (!checkInterface()) return QSpiObjectReference(); - // if we are the child of a complex widget, we cannot have any children - Q_ASSERT(child == 0); - Q_ASSERT(index < interface->childCount()); - QSpiAdaptor* child = getChild(index+1); - if (!child) { - qWarning() << "WARNING:QSpiAdaptor::GetChildAtIndex no child: " << index << getReference().path.path() << interface->object(); - return QSpiObjectReference(); - } - return child->getReference(); -} - -QSpiObjectReferenceArray QSpiAdaptor::GetChildren() const -{ - QList children; - if (!checkInterface()) return children; - - // TODO: become independent of caching the interfaces... - // QPair pair = QSpiAccessible::interfaceFromPath(getReference().path.path()); - qDebug() << "CHILDREN: " << getReference().path.path(); - - // when we are a child that means that we cannot have children of our own - if (child) { - QAccessibleInterface *iface; - interface->navigate(QAccessible::Ancestor, 1, &iface); - qWarning() << "WARNING:QSpiAdaptor::GetChildren Request child of virtual child: " - << getReference().path.path() << interface->object() << "child: " << childIndex() << " parent: " << iface->object(); - delete iface; - return children; - } - - for (int i = 1; i <= interface->childCount(); ++i) { - QSpiAdaptor* child = getChild(i); - if (child) { - children << child->getReference(); - qDebug() << " CHILD: " << child->getReference().path.path(); - } - -// // use navigate and return refernces -// QAccessibleInterface* childInterface; -// int childIndex = interface->navigate(QAccessible::Child, i, &childInterface); -// QString path; -// if (childIndex) { -// path = QSpiAccessible::pathForInterface(interface, childIndex); -// } else { -// Q_ASSERT(childInterface); -// path = QSpiAccessible::pathForInterface(childInterface, childIndex); -// } -// children.append(QSpiObjectReference(spiBridge->dBusConnection(), QDBusObjectPath(path))); - } - -// Q_ASSERT(interface->childCount() == children.count()); - if (interface->childCount() != children.count()) { - qWarning() << "WARNING: Widget reports more children than it has. This will lead to inconsistent behavior." - << interface->object() << qSpiRoleMapping[interface->role(child)].name() << getReference().path.path(); - } - - - return children; -} - -QSpiAdaptor* QSpiAdaptor::getChild(int index) const -{ - Q_ASSERT(index > 0 && index <= interface->childCount()); - QAccessibleInterface *child = 0; - int ret = interface->navigate(QAccessible::Child, index, &child); - if (ret == 0) { - return spiBridge->interfaceToAccessible(child, 0, true); - } else if (ret > 0){ - Q_ASSERT(ret <= interface->childCount()); - return spiBridge->interfaceToAccessible(interface, ret, true); - } - qWarning() << "QSpiAdaptor::getChild INVALID CHILD: " << interface->object() << index; - return 0; -} - -int QSpiAdaptor::GetIndexInParent() const -{ - if (!checkInterface()) return -1; - - if (child) - return child; - - QAccessibleInterface* parent; - interface->navigate(QAccessible::Ancestor, 1, &parent); - if (parent) { - int index = parent->indexOfChild(interface); - Q_ASSERT(index != 0); - delete parent; - return index; - } - return -1; -} - -QString QSpiAdaptor::GetLocalizedRoleName() const -{ - if (!checkInterface()) return QString(); - - QString out0; - out0 = qSpiRoleMapping.value(interface->role(child)).localizedName(); - return out0; -} - -QSpiRelationArray QSpiAdaptor::GetRelationSet() const -{ - if (!checkInterface()) return QSpiRelationArray(); - - const QAccessible::RelationFlag relationsToCheck[] = {QAccessible::Label, QAccessible::Labelled, QAccessible::Controller, QAccessible::Controlled, static_cast(-1)}; - const AtspiRelationType relationTypes[] = {ATSPI_RELATION_LABELLED_BY, ATSPI_RELATION_LABEL_FOR, ATSPI_RELATION_CONTROLLED_BY, ATSPI_RELATION_CONTROLLER_FOR}; - - QSpiRelationArray relations; - - QAccessibleInterface *target; - - for (int i = 0; relationsToCheck[i] >= 0; i++) { - QList related; - int navigateResult = 1; - - for (int j = 1; navigateResult >= 0; j++) { - navigateResult = interface->navigate(relationsToCheck[i], j, &target); - if (navigateResult == 0) { - QSpiAdaptor *targetAdaptor = spiBridge->interfaceToAccessible(target, 0, false); - related.append(targetAdaptor->getReference()); - delete target; - } else if (navigateResult > 0) { - //Then it's a child of the object - related.append(this->GetChildAtIndex(navigateResult)); - } - } - if (!related.isEmpty()) - relations.append(QSpiRelationArrayEntry(relationTypes[i], related)); - } - - return relations; -} - -uint QSpiAdaptor::GetRole() const -{ - if (!checkInterface()) return QAccessible::NoRole; - - QAccessible::Role role = interface->role(child); - return qSpiRoleMapping[role].spiRole(); -} - -QString QSpiAdaptor::GetRoleName() const -{ - if (!checkInterface()) return QString(); - return qSpiRoleMapping[interface->role(child)].name(); -} - -QSpiUIntList QSpiAdaptor::GetState() const -{ - if (!checkInterface()) return QSpiUIntList(); - - quint64 spiState = spiStatesFromQState(interface->state(child)); - if (interface->table2Interface()) { - setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS); - } else if (interface->role(child) == QAccessible::TreeItem - && static_cast(interface)->isExpandable()) { - setSpiStateBit(&spiState, ATSPI_STATE_EXPANDABLE); - } - return spiStateSetFromSpiStates(spiState); -} - -int QSpiAdaptor::nActions() const -{ - if (!checkInterface()) return 0; - - return interface->actionInterface()->actionCount(); -} - -bool QSpiAdaptor::DoAction(int index) -{ - if (!checkInterface()) return false; - - interface->actionInterface()->doAction(index); - return TRUE; -} - -/* AT-SPI Action interface --------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -QSpiActionArray QSpiAdaptor::GetActions() -{ - QSpiActionArray index; - if (!checkInterface()) return index; - - for (int i = 0; i < interface->actionInterface()->actionCount(); i++) - { - QSpiAction action; - QStringList keyBindings; - - action.name = interface->actionInterface()->name(i); - action.description = interface->actionInterface()->description(i); - - keyBindings = interface->actionInterface()->keyBindings(i); - - if (keyBindings.length() > 0) - action.keyBinding = keyBindings[0]; - else - action.keyBinding = ""; - - index << action; - } - return index; -} - -QString QSpiAdaptor::GetDescription(int index) -{ - if (!checkInterface()) return QString(); - - return interface->actionInterface()->description(index); -} - -QString QSpiAdaptor::GetKeyBinding(int index) -{ - if (!checkInterface()) return QString(); - QStringList keyBindings; - - keyBindings = interface->actionInterface()->keyBindings(index); - /* Might as well return the first key binding, what are the other options? */ - if (keyBindings.length() > 0) - return keyBindings[0]; - else - return QString(); -} - -QString QSpiAdaptor::GetName(int index) -{ - if (!checkInterface()) return QString(); - return interface->actionInterface()->name(index); -} - -/* AT-SPI Application interface ---------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -int QSpiAdaptor::id() const -{ - if (!checkInterface()) return -1; - return property("Id").toInt(); -} - -QString QSpiAdaptor::toolkitName() const -{ - if (!checkInterface()) return QString(); -// qWarning() << "QSpiAdaptor::toolkitName FIXME: We pretend to be GAIL as toolkit. This is evil and needs fixing."; - return QLatin1String("Qt"); -// return QLatin1String("GAIL"); -} - -QString QSpiAdaptor::version() const -{ - if (!checkInterface()) return QString(); - return QLatin1String(QT_VERSION_STR); -} - -/// The bus address for direct (p2p) connections. -/// Not supported atm. -QString QSpiAdaptor::GetApplicationBusAddress() const -{ - qDebug() << "QSpiAdaptor::GetApplicationBusAddress implement me!"; - return QString(); -} - -QString QSpiAdaptor::GetLocale(uint lctype) -{ - if (!checkInterface()) return QString(); - Q_UNUSED(lctype) - QLocale currentLocale; - return currentLocale.languageToString(currentLocale.language()); -} - -/* AT-SPI Component interface -----------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -static QAccessibleInterface *getWindow(QAccessibleInterface* interface) -{ - QAccessibleInterface *current=NULL, *tmp=NULL; - - interface->navigate(QAccessible::Ancestor, 0, ¤t); - - while (current && - current->role(0) != QAccessible::Window && - current->role(0) != QAccessible::Application) - { - tmp = NULL; - current->navigate (QAccessible::Ancestor, 1, &tmp); - current = tmp; - } - - if (current) { - return current; - } else { - return NULL; - } -} - -static QRect getRelativeRect(QAccessibleInterface* interface, int child) -{ - QAccessibleInterface *window; - QRect wr, cr; - - cr = interface->rect(child); - - window = getWindow(interface); - if (window) - { - wr = window->rect(child); - - cr.setX(cr.x() - wr.x()); - cr.setY(cr.x() - wr.y()); - } - return cr; -} - -bool QSpiAdaptor::Contains(int x, int y, uint coord_type) -{ - if (!checkInterface()) return false; - if (coord_type == 0) - return interface->rect(child).contains(x, y); - else - return getRelativeRect(interface, child).contains(x, y); -} - -QSpiObjectReference QSpiAdaptor::GetAccessibleAtPoint(int x, int y, uint coord_type) -{ - if (!checkInterface()) return QSpiObjectReference(); - Q_UNUSED (coord_type) - - - // Grab the top level widget. For complex widgets we want to return a child - // at the right position instead. - QWidget* w = qApp->widgetAt(x,y); -// qDebug() << "QSpiAdaptor::GetAccessibleAtPoint " << x << ", " << y << " Coord: " << coord_type << w; - - if (w) { - QSpiAdaptor* adaptor = spiBridge->objectToAccessible(w); - - int i = adaptor->associatedInterface()->childAt(x, y); - if (i > 0) { - QSpiAdaptor* child = adaptor->getChild(i); - return child->getReference(); - } - return adaptor->getReference(); - } else { - return QSpiObjectReference(spiBridge->dBusConnection(), QDBusObjectPath(QSPI_OBJECT_PATH_NULL)); - } -} - -double QSpiAdaptor::GetAlpha() -{ - if (!checkInterface()) return 0.0; - // TODO Find out if the QAccessible iterface needs extending to provide an alpha value. - return 1.0; -} - -QSpiRect QSpiAdaptor::GetExtents(uint coord_type) -{ - QSpiRect val; - if (!checkInterface()) return val; - - QRect rect; - if (coord_type == 0) - rect = interface->rect(child); - else - rect = getRelativeRect(interface, child); - - val.x = rect.x (); - val.y = rect.y (); - val.width = rect.width (); - val.height = rect.height (); - return val; -} - -uint QSpiAdaptor::GetLayer() -{ - if (!checkInterface()) return 0; - // TODO Find out if QT has any concept of 'Layers' - return 1; // Corresponds to LAYER_WINDOW. -} - -short QSpiAdaptor::GetMDIZOrder() -{ - if (!checkInterface()) return 0; - // TODO Does Qt have any concept of Layers? - return 0; -} - -int QSpiAdaptor::GetPosition(uint coord_type, int &y) -{ - if (!checkInterface()) return 0; - QRect rect; - if (coord_type == 0) - rect = interface->rect(child); - else - rect = getRelativeRect(interface, child); - y = rect.y (); - return rect.x (); -} - -int QSpiAdaptor::GetSize(int &height) -{ - if (!checkInterface()) return 0; - QRect rect = interface->rect(child); - height = rect.height(); - return rect.width(); -} - -bool QSpiAdaptor::GrabFocus() -{ - if (!checkInterface()) return false; - // TODO This does not seem to be supported by QAccessibleInterface. - // FIXME: raise the window to make it active also? - // FIXME: graphics/qml items - - if (interface->object()->isWidgetType()) { - QWidget* w = static_cast(interface->object()); - w->setFocus(Qt::OtherFocusReason); - return true; - } - - return false; -} - -/* AT-SPI EditableText interface --------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void QSpiAdaptor::CopyText(int startPos, int endPos) -{ - if (!checkInterface()) return; - interface->editableTextInterface()->copyText(startPos, endPos); -} - -bool QSpiAdaptor::CutText(int startPos, int endPos) -{ - if (!checkInterface()) return false; - interface->editableTextInterface()->cutText(startPos, endPos); - return TRUE; -} - -bool QSpiAdaptor::DeleteText(int startPos, int endPos) -{ - if (!checkInterface()) return false; - interface->editableTextInterface()->deleteText(startPos, endPos); - return TRUE; -} - -bool QSpiAdaptor::InsertText(int position, const QString &text, int length) -{ - if (!checkInterface()) return false; - ; - return TRUE; -} - -bool QSpiAdaptor::PasteText(int position) -{ - if (!checkInterface()) return false; - interface->editableTextInterface()->pasteText(position); - return TRUE; -} - -bool QSpiAdaptor::SetTextContents(const QString &newContents) -{ - if (!checkInterface()) return false; - interface->editableTextInterface()->replaceText(0, interface->textInterface()->characterCount(), newContents); - return TRUE; -} - -/* AT-SPI Table interface ---------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -QSpiObjectReference QSpiAdaptor::caption() const -{ - if (!checkInterface()) return QSpiObjectReference(); - - QAccessibleInterface* captionObject = interface->table2Interface()->caption(); - if (captionObject) - return spiBridge->interfaceToAccessible(captionObject, 0, true)->getReference(); - - return QSpiObjectReference(); -} - -int QSpiAdaptor::nColumns() const -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->columnCount(); -} - -int QSpiAdaptor::nRows() const -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->rowCount(); -} - -int QSpiAdaptor::nSelectedColumns() const -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->selectedColumnCount(); -} - -int QSpiAdaptor::nSelectedRows() const -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->selectedRowCount(); -} - -QSpiObjectReference QSpiAdaptor::summary() const -{ - if (!checkInterface()) return QSpiObjectReference(); - QAccessibleInterface* summaryObject = interface->table2Interface()->summary(); - if (summaryObject) - return spiBridge->interfaceToAccessible(summaryObject, 0, true)->getReference(); - return QSpiObjectReference(); -} - -QSpiObjectReference QSpiAdaptor::GetAccessibleAt(int row, int column) -{ - if (!checkInterface()) return QSpiObjectReference(); - - qDebug() << "QSpiAdaptor::GetAccessibleAt" << row << column; - - Q_ASSERT(interface->table2Interface()); - Q_ASSERT(row >= 0); - Q_ASSERT(column >= 0); - Q_ASSERT(row < interface->table2Interface()->rowCount()); - Q_ASSERT(column < interface->table2Interface()->columnCount()); - - QAccessibleInterface* cell = interface->table2Interface()->cellAt(row, column); - if (!cell) { - qWarning() << "WARNING: no cell interface returned for " << interface->object() << row << column; - return QSpiObjectReference(); - } - return spiBridge->interfaceToAccessible(cell, 0, true)->getReference(); -} - -int QSpiAdaptor::GetIndexAt(int row, int column) -{ - if (!checkInterface()) return 0; - - QAccessibleInterface *cell = interface->table2Interface()->cellAt(row, column); - int index = interface->indexOfChild(cell); - - qDebug() << "QSpiAdaptor::GetIndexAt" << row << column << index; - - Q_ASSERT(index > 0); - - delete cell; - return index; -} - -int QSpiAdaptor::GetColumnAtIndex(int index) -{ - if (!checkInterface()) return 0; - - qDebug() << "QSpiAdaptor::GetColumnAtIndex" << index; - if (index < 2) - return -1; - - QAccessibleInterface *iface; - interface->navigate(QAccessible::Child, index, &iface); - if (iface) { - qDebug() << "iface: " << iface->text(QAccessible::Name, 0); - - QAccessibleTable2CellInterface *cell = static_cast(iface); - int i = cell->columnIndex(); - delete cell; - return i; - } - return 0; -} - -int QSpiAdaptor::GetRowAtIndex(int index) -{ - if (!checkInterface()) return 0; - - if (index < 2) // 0 is self, 1 the corner button - return -1; - - qDebug() << "QSpiAdaptor::GetRowAtIndex" << index; - QAccessibleInterface *iface; - interface->navigate(QAccessible::Child, index, &iface); - if (iface) { - qDebug() << "iface: " << iface->text(QAccessible::Name, 0); - - QAccessibleTable2CellInterface *cell = static_cast(iface); - int i = cell->rowIndex(); - delete cell; - return i; - } - return 0; -} - -QString QSpiAdaptor::GetColumnDescription(int column) -{ - if (!checkInterface()) return QString(); - return interface->table2Interface()->columnDescription(column); -} - -QString QSpiAdaptor::GetRowDescription(int row) -{ - if (!checkInterface()) return QString(); - return interface->table2Interface()->rowDescription(row); -} - -bool QSpiAdaptor::GetRowColumnExtentsAtIndex(int index, - int &row, - int &col, - int &row_extents, - int &col_extents, - bool &is_selected) -{ - if (!checkInterface()) return false; - - int cols = interface->table2Interface()->columnCount(); - row = index/cols; - col = index%cols; - QAccessibleTable2CellInterface *cell = interface->table2Interface()->cellAt(row, col); - if (cell) { - cell->rowColumnExtents(&row, &col, &row_extents, &col_extents, &is_selected); - return true; - } - - return false; -} - -int QSpiAdaptor::GetColumnExtentAt(int row, int column) -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->cellAt(row, column)->columnExtent(); -} - -int QSpiAdaptor::GetRowExtentAt(int row, int column) -{ - if (!checkInterface()) return 0; - return interface->table2Interface()->cellAt(row, column)->rowExtent(); -} - -QSpiObjectReference QSpiAdaptor::GetColumnHeader(int column) -{ - if (!checkInterface()) return QSpiObjectReference(); - - QAccessibleTable2CellInterface *cell = interface->table2Interface()->cellAt(0, column); - if (cell) { - QList header = cell->columnHeaderCells(); - delete cell; - if (header.size() > 0) - return spiBridge->interfaceToAccessible(header.at(0), 0, true)->getReference(); - } - return QSpiObjectReference(); -} - -QSpiObjectReference QSpiAdaptor::GetRowHeader(int row) -{ - if (!checkInterface()) return QSpiObjectReference(); - Q_UNUSED (row); - qWarning() << "Implement: QSpiAdaptor::GetRowHeader"; - return QSpiObjectReference(); - - // TODO There should be a row param here right? -// return spiBridge->objectToAccessible(interface->tableInterface()->rowHeader()->object())->getReference(); -} - -QSpiIntList QSpiAdaptor::GetSelectedColumns() -{ - QSpiIntList columns; - if (!checkInterface()) return columns; - columns = interface->table2Interface()->selectedColumns(); - return columns; -} - -QSpiIntList QSpiAdaptor::GetSelectedRows() -{ - QSpiIntList rows; - if (!checkInterface()) return rows; - rows = interface->table2Interface()->selectedRows(); - return rows; -} - -bool QSpiAdaptor::IsColumnSelected(int column) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->isColumnSelected(column); -} - -bool QSpiAdaptor::IsRowSelected(int row) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->isRowSelected(row); -} - -bool QSpiAdaptor::IsSelected(int row, int column) -{ - if (!checkInterface()) return false; - QAccessibleTable2CellInterface* cell = interface->table2Interface()->cellAt(row, column); - bool selected = cell->isSelected(); - delete cell; - return selected; -} - -bool QSpiAdaptor::AddColumnSelection(int column) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->selectColumn(column); -} - -bool QSpiAdaptor::AddRowSelection(int row) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->selectRow(row); -} - -bool QSpiAdaptor::RemoveColumnSelection(int column) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->unselectColumn(column); -} - -bool QSpiAdaptor::RemoveRowSelection(int row) -{ - if (!checkInterface()) return false; - return interface->table2Interface()->unselectRow(row); -} - -/* AT-SPI Text interface ----------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -int QSpiAdaptor::caretOffset() const -{ - if (!checkInterface()) return 0; - return interface->textInterface()->cursorPosition(); -} - -int QSpiAdaptor::characterCount() const -{ - if (!checkInterface()) return 0; - return interface->textInterface()->characterCount(); -} - -bool QSpiAdaptor::AddSelection(int startOffset, int endOffset) -{ - if (!checkInterface()) return false; - int lastSelection = interface->textInterface()->selectionCount (); - interface->textInterface()->setSelection (lastSelection, startOffset, endOffset); - return interface->textInterface()->selectionCount() > lastSelection; -} - -QSpiAttributeSet QSpiAdaptor::GetAttributeRun(int offset, - bool includeDefaults, - int &startOffset, - int &endOffset) -{ - if (!checkInterface()) return QSpiAttributeSet(); - Q_UNUSED (includeDefaults); - return GetAttributes (offset, startOffset, endOffset); -} - -QString QSpiAdaptor::GetAttributeValue(int offset, - const QString &attributeName, - int &startOffset, - int &endOffset, - bool &defined) -{ - if (!checkInterface()) return QString(); - QString mapped; - QString joined; - QStringList attributes; - QSpiAttributeSet map; - - joined = interface->textInterface()->attributes(offset, &startOffset, &endOffset); - attributes = joined.split (';', QString::SkipEmptyParts, Qt::CaseSensitive); - foreach (QString attr, attributes) - { - QStringList items; - items = attr.split(':', QString::SkipEmptyParts, Qt::CaseSensitive); - map[items[0]] = items[1]; - } - mapped = map[attributeName]; - if (mapped == "") - defined = TRUE; - else - defined = FALSE; - return mapped; -} - -QSpiAttributeSet QSpiAdaptor::GetAttributes(int offset, int &startOffset, int &endOffset) -{ - QSpiAttributeSet set; - if (!checkInterface()) return set; - - QString joined; - QStringList attributes; - - joined = interface->textInterface()->attributes(offset, &startOffset, &endOffset); - attributes = joined.split (';', QString::SkipEmptyParts, Qt::CaseSensitive); - foreach (const QString &attr, attributes) - { - QStringList items; - items = attr.split(':', QString::SkipEmptyParts, Qt::CaseSensitive); - set[items[0]] = items[1]; - } - return set; -} - -QSpiTextRangeList QSpiAdaptor::GetBoundedRanges(int x, - int y, - int width, - int height, - uint coordType, - uint xClipType, - uint yClipType) -{ - if (!checkInterface()) return QSpiTextRangeList(); - qWarning("Not implemented: QSpiAdaptor::GetBoundedRanges"); - Q_UNUSED(x) Q_UNUSED (y) Q_UNUSED(width) - Q_UNUSED(height) Q_UNUSED(coordType) - Q_UNUSED(xClipType) Q_UNUSED(yClipType) - QSpiTextRangeList out0; - return out0; -} - -int QSpiAdaptor::GetCharacterAtOffset(int offset) -{ - if (!checkInterface()) return 0; - int start=offset, end=offset+1; - QString result; - result = interface->textInterface()->textAtOffset(offset, QAccessible2::CharBoundary, &start, &end); - return *(qPrintable (result)); -} - -int QSpiAdaptor::GetCharacterExtents(int offset, uint coordType, int &y, int &width, int &height) -{ - if (!checkInterface()) return 0; - int x; - - // QAccessible2 has RelativeToParent as a coordinate type instead of relative - // to top-level window, which is an AT-SPI coordinate type. - if (static_cast(coordType) != QAccessible2::RelativeToScreen) { - const QWidget *widget = qobject_cast(interface->object()); - if (!widget) { - y = 0; - width = 0; - height = 0; - return 0; - } - const QWidget *parent = widget->parentWidget(); - while (parent) { - widget = parent; - parent = widget->parentWidget(); - } - x = -widget->x(); - y = -widget->y(); - } else { - x = 0; - y = 0; - } - - QRect rect = interface->textInterface()->characterRect(offset, QAccessible2::RelativeToScreen); - width = rect.width(); - height = rect.height(); - y += rect.y(); - return x+rect.x(); -} - -QSpiAttributeSet QSpiAdaptor::GetDefaultAttributeSet() -{ - // Empty set seems reasonable. There is no default attribute set. - QSpiAttributeSet attributes; - if (!checkInterface()) return attributes; - return attributes; -} - -QSpiAttributeSet QSpiAdaptor::GetDefaultAttributes() -{ - // Deprecated in favour of default attribute set. - return GetDefaultAttributeSet(); -} - -int QSpiAdaptor::GetNSelections() -{ - if (!checkInterface()) return 0; - return interface->textInterface()->selectionCount(); -} - -int QSpiAdaptor::GetOffsetAtPoint(int x, int y, uint coordType) -{ - if (!checkInterface()) return -1; - return interface->textInterface()->offsetAtPoint (QPoint (x, y), static_cast (coordType)); -} - -int QSpiAdaptor::GetRangeExtents(int startOffset, int endOffset, uint coordType, int &y, int &width, int &height) -{ - if (!checkInterface()) return -1; - - if (endOffset == -1) - endOffset = interface->textInterface()->characterCount(); - - if (endOffset <= startOffset) { - y=0; - width = 0; - height = 0; - return 0; - } - - int xOffset = 0, yOffset = 0; - QAccessibleTextInterface *textInterface = interface->textInterface(); - - // QAccessible2 has RelativeToParent as a coordinate type instead of relative - // to top-level window, which is an AT-SPI coordinate type. - if (static_cast(coordType) != QAccessible2::RelativeToScreen) { - const QWidget *widget = qobject_cast(interface->object()); - if (!widget) { - y = 0; - width = 0; - height = 0; - return 0; - } - const QWidget *parent = widget->parentWidget(); - while (parent) { - widget = parent; - parent = widget->parentWidget(); - } - xOffset = -widget->x(); - yOffset = -widget->y(); - } - - int minX=INT_MAX, minY=INT_MAX, maxX=0, maxY=0; - - for (int i=startOffset; icharacterRect(i, QAccessible2::RelativeToScreen); - if (rect.x() < minX) { - minX = rect.x(); - } - if (rect.y() < minY) { - minY = rect.y(); - } - if ((rect.x() + rect.width()) > maxX) { - maxX = (rect.x() + rect.width()); - } - if ((rect.y() + rect.height()) > maxY) { - maxY = (rect.y() + rect.height()); - } - } - - width = maxX - minX; - height = maxY - minY; - y = minY + yOffset; - return minX + xOffset; -} - -int QSpiAdaptor::GetSelection(int selectionNum, int &endOffset) -{ - if (!checkInterface()) return -1; - int start, end; - interface->textInterface()->selection(selectionNum, &start, &end); - - if (start<0) { - endOffset = interface->textInterface()->cursorPosition(); - return endOffset; - } - - endOffset = end; - return start; -} - -QString QSpiAdaptor::GetText(int startOffset, int endOffset) -{ - if (!checkInterface()) return QString(); - if (endOffset == -1) - endOffset = interface->textInterface()->characterCount(); - return interface->textInterface()->text(startOffset, endOffset); -} - -QString QSpiAdaptor::GetTextAfterOffset(int offset, uint type, int &startOffset, int &endOffset) -{ - if (!checkInterface()) return QString(); - // FIXME find out if IA2 types are the same as the ones in at-spi - return interface->textInterface()->textAfterOffset(offset, (QAccessible2::BoundaryType)type, &startOffset, &endOffset); -} - -QString QSpiAdaptor::GetTextAtOffset(int offset, uint type, int &startOffset, int &endOffset) -{ - if (!checkInterface()) return QString(); - QAccessibleTextInterface * t = interface->textInterface(); - QAccessible2::BoundaryType rType; - switch (type) { - case ATSPI_TEXT_BOUNDARY_CHAR: - rType = QAccessible2::CharBoundary; - break; - case ATSPI_TEXT_BOUNDARY_WORD_START: { - QString text = t->textAtOffset(offset, QAccessible2::WordBoundary, &startOffset, &endOffset); - - if ((startOffset < 0) || (endOffset < 0)) - return text; - - int limit = t->characterCount(); - for (int i=endOffset + 1; i < limit; i++) { - int j; - int k; - t->textAtOffset(i, QAccessible2::WordBoundary, &j, &k); - if (j <= i) { - endOffset = j; - break; - } - } - return t->text(startOffset, endOffset); } - case ATSPI_TEXT_BOUNDARY_WORD_END: { - QString text = t->textAtOffset(offset, QAccessible2::WordBoundary, &startOffset, &endOffset); - - if ((startOffset < 0) || (endOffset < 0)) - return text; - - for (int i=startOffset - 1; i >= 0; i--) { - int j; - int k; - t->textAtOffset(i, QAccessible2::WordBoundary, &j, &k); - if (k >= i) { - startOffset = k; - break; - } - } - return t->text(startOffset, endOffset); } - case ATSPI_TEXT_BOUNDARY_SENTENCE_END: - case ATSPI_TEXT_BOUNDARY_SENTENCE_START: - rType = QAccessible2::SentenceBoundary; - break; - case ATSPI_TEXT_BOUNDARY_LINE_START: { - QString text = t->textAtOffset(offset, QAccessible2::LineBoundary, &startOffset, &endOffset); - - if ((startOffset < 0) || (endOffset < 0)) - return text; - - int limit = t->characterCount(); - for (int i=endOffset + 1; i < limit; i++) { - int j; - int k; - t->textAtOffset(i, QAccessible2::LineBoundary, &j, &k); - if (j <= i) { - endOffset = j; - break; - } - } - return t->text(startOffset, endOffset); } - case ATSPI_TEXT_BOUNDARY_LINE_END: { - QString text = t->textAtOffset(offset, QAccessible2::LineBoundary, &startOffset, &endOffset); - - if ((startOffset < 0) || (endOffset < 0)) - return text; - - if (startOffset <= offset) - text = t->textAtOffset(offset + 1, QAccessible2::LineBoundary, &startOffset, &endOffset); - - for (int i=startOffset - 1; i >= 0; i--) { - int j; - int k; - t->textAtOffset(i, QAccessible2::LineBoundary, &j, &k); - if (k >= i) { - startOffset = k; - break; - } - } - return t->text(startOffset, endOffset); } - default: - startOffset = -1; - endOffset = -1; - return QString(); - } - - return t->textAtOffset(offset, rType, &startOffset, &endOffset); -} - -QString QSpiAdaptor::GetTextBeforeOffset(int offset, uint type, int &startOffset, int &endOffset) -{ - if (!checkInterface()) return QString(); - // FIXME find out if IA2 types are the same as the ones in at-spi - return interface->textInterface()->textBeforeOffset(offset, (QAccessible2::BoundaryType)type, &startOffset, &endOffset); -} - -bool QSpiAdaptor::RemoveSelection(int selectionNum) -{ - if (!checkInterface()) return false; - interface->textInterface()->removeSelection(selectionNum); - return true; -} - -bool QSpiAdaptor::SetCaretOffset(int offset) -{ - if (!checkInterface()) return false; - interface->textInterface()->setCursorPosition(offset); - return true; -} - -bool QSpiAdaptor::SetSelection(int selectionNum, int startOffset, int endOffset) -{ - if (!checkInterface()) return false; - interface->textInterface()->setSelection(selectionNum, startOffset, endOffset); - return true; -} - -/* AT-SPI Value interface ---------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -double QSpiAdaptor::currentValue() const -{ - if (!checkInterface()) return 0.0; - double val; - bool success; - val = interface->valueInterface()->currentValue().toDouble (&success); - if (success) - { - return val; - } - else - { - qDebug ("QSpiAccessibleBridge: Could not convert current value to double"); - return 0.0; - } -} - -void QSpiAdaptor::SetCurrentValue(double value) -{ - if (!checkInterface()) return; - interface->valueInterface()->setCurrentValue(QVariant (value)); -} - -double QSpiAdaptor::maximumValue() const -{ - if (!checkInterface()) return 0.0; - double val; - bool success; - val = interface->valueInterface()->maximumValue().toDouble (&success); - if (success) - { - return val; - } - else - { - qDebug ("QSpiAccessibleBridge: Could not convert maximum value to double"); - return 0.0; - } -} - -double QSpiAdaptor::minimumIncrement() const -{ - if (!checkInterface()) return 0.0; - // FIXME: should be in value interface - return 0.0; -} - -double QSpiAdaptor::minimumValue() const -{ - if (!checkInterface()) return 0.0; - double val; - bool success; - val = interface->valueInterface()->minimumValue().toDouble (&success); - if (success) - { - return val; - } - else - { - qDebug ("QSpiAccessibleBridge: Could not convert minimum value to double"); - return 0.0; - } -} - -/*END------------------------------------------------------------------------*/ diff -Nru qt-at-spi-0.1.1/src/adaptor.h qt-at-spi-0.1.1+20120306/src/adaptor.h --- qt-at-spi-0.1.1/src/adaptor.h 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/adaptor.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,254 +0,0 @@ -/* - * D-Bus AT-SPI, Qt Adaptor - * - * Copyright 2009-2011 Nokia Corporation and/or its subsidiary(-ies). - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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, see . - */ - -#ifndef Q_SPI_ADAPTOR_H -#define Q_SPI_ADAPTOR_H - -#include -#include - -#include "struct_marshallers.h" - -#define QSPI_INTERFACE_PREFIX "org.a11y.atspi" - -#define QSPI_INTERFACE_ACCESSIBLE QSPI_INTERFACE_PREFIX ".Accessible" -#define QSPI_INTERFACE_ACTION QSPI_INTERFACE_PREFIX ".Action" -#define QSPI_INTERFACE_APPLICATION QSPI_INTERFACE_PREFIX ".Application" -#define QSPI_INTERFACE_COLLECTION QSPI_INTERFACE_PREFIX ".Collection" -#define QSPI_INTERFACE_COMPONENT QSPI_INTERFACE_PREFIX ".Component" -#define QSPI_INTERFACE_DOCUMENT QSPI_INTERFACE_PREFIX ".Document" -#define QSPI_INTERFACE_EDITABLE_TEXT QSPI_INTERFACE_PREFIX ".EditableText" -#define QSPI_INTERFACE_HYPERLINK QSPI_INTERFACE_PREFIX ".Hyperlink" -#define QSPI_INTERFACE_HYPERTEXT QSPI_INTERFACE_PREFIX ".Hypertext" -#define QSPI_INTERFACE_IMAGE QSPI_INTERFACE_PREFIX ".Image" -#define QSPI_INTERFACE_REGISTRY QSPI_INTERFACE_PREFIX ".Registry" -#define QSPI_INTERFACE_SELECTION QSPI_INTERFACE_PREFIX ".Selection" -#define QSPI_INTERFACE_TABLE QSPI_INTERFACE_PREFIX ".Table" -#define QSPI_INTERFACE_TEXT QSPI_INTERFACE_PREFIX ".Text" -#define QSPI_INTERFACE_TREE QSPI_INTERFACE_PREFIX ".Tree" -#define QSPI_INTERFACE_VALUE QSPI_INTERFACE_PREFIX ".Value" - -#define QSPI_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/" -#define QSPI_OBJECT_PATH_NULL QSPI_OBJECT_PATH_PREFIX "null" -#define QSPI_OBJECT_PATH_ROOT QSPI_OBJECT_PATH_PREFIX "root" - -// FIXME lots of const missing for all the getters... - -/* - * Implements all methods neccessary to adapt calls from AT-SPI to the - * QAccessibleInterface. - * - */ -class QSpiAdaptor :public QObject -{ - Q_OBJECT - -public: - QSpiAdaptor(QAccessibleInterface *interface, int index); - virtual ~QSpiAdaptor() {} - - QStringList getSupportedInterfaces() const; - QSpiAccessibleCacheItem getCacheItem() const; - - virtual QSpiObjectReference getReference() const; - virtual QSpiObjectReference getParentReference() const = 0; - - virtual void accessibleEvent(QAccessible::Event event) = 0; - inline QAccessibleInterface* associatedInterface() const { return interface; } - inline int childIndex() const { return child; } - - QObject* getObject() const; - -public: - // event stuff - void signalChildrenChanged(const QString &type, int detail1, int detail2, const QDBusVariant &data); -Q_SIGNALS: - void ChildrenChanged(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void StateChanged(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void PropertyChange(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void Focus(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void TextChanged(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - void TextCaretMoved(const QString &type, int detail1, int detail2, const QDBusVariant &data, const QSpiObjectReference &parent); - -/* AT-SPI Accessible interface */ -public: - Q_PROPERTY(int ChildCount READ childCount) - int childCount() const; - Q_PROPERTY(QString Description READ description) - QString description() const; - Q_PROPERTY(QString Name READ name) - QString name() const; - Q_PROPERTY(QSpiObjectReference Parent READ parent) - QSpiObjectReference parent() const; - -public Q_SLOTS: - QSpiObjectReference GetApplication() const; - QSpiAttributeSet GetAttributes() const; - QSpiObjectReference GetChildAtIndex(int index) const; - QSpiObjectReferenceArray GetChildren() const; - int GetIndexInParent() const; - QString GetLocalizedRoleName() const; - QSpiRelationArray GetRelationSet() const; - uint GetRole() const; - QString GetRoleName() const; - QSpiUIntList GetState() const; - -/* AT-SPI Action interface */ -public: - Q_PROPERTY(int NActions READ nActions) - int nActions() const; - -public Q_SLOTS: - bool DoAction(int index); - QSpiActionArray GetActions(); - QString GetDescription(int index); - QString GetKeyBinding(int index); - QString GetName(int index); - -/* AT-SPI Application interface */ -public: - Q_PROPERTY(int Id READ id) - int id() const; - Q_PROPERTY(QString ToolkitName READ toolkitName) - QString toolkitName() const; - Q_PROPERTY(QString Version READ version) - QString version() const; - QString GetApplicationBusAddress() const; - -public Q_SLOTS: // METHODS - QString GetLocale(uint lctype); - -/* AT-SPI Component interface */ -public Q_SLOTS: - bool Contains(int x, int y, uint coord_type); - QSpiObjectReference GetAccessibleAtPoint(int x, int y, uint coord_type); - double GetAlpha(); - QSpiRect GetExtents(uint coord_type); - uint GetLayer(); - short GetMDIZOrder(); - int GetPosition(uint coord_type, int &y); - int GetSize(int &height); - bool GrabFocus(); - -/* AT-SPI EditableText interface */ -public Q_SLOTS: - void CopyText(int startPos, int endPos); - bool CutText(int startPos, int endPos); - bool DeleteText(int startPos, int endPos); - bool InsertText(int position, const QString &text, int length); - bool PasteText(int position); - bool SetTextContents(const QString &newContents); - -/* AT-SPI Table interface */ -public: - Q_PROPERTY(QSpiObjectReference Caption READ caption) - QSpiObjectReference caption() const; - Q_PROPERTY(int NColumns READ nColumns) - int nColumns() const; - Q_PROPERTY(int NRows READ nRows) - int nRows() const; - Q_PROPERTY(int NSelectedColumns READ nSelectedColumns) - int nSelectedColumns() const; - Q_PROPERTY(int NSelectedRows READ nSelectedRows) - int nSelectedRows() const; - Q_PROPERTY(QSpiObjectReference Summary READ summary) - QSpiObjectReference summary() const; - -public Q_SLOTS: - QSpiObjectReference GetAccessibleAt(int row, int column); - int GetIndexAt(int row, int column); - int GetColumnAtIndex(int index); - int GetRowAtIndex(int index); - - QSpiObjectReference GetColumnHeader(int column); - QSpiObjectReference GetRowHeader(int row); - QString GetColumnDescription(int column); - QString GetRowDescription(int row); - - int GetColumnExtentAt(int row, int column); - int GetRowExtentAt(int row, int column); - bool GetRowColumnExtentsAtIndex(int index, int &row, int &col, int &row_extents, int &col_extents, bool &is_selected); - - bool IsSelected(int row, int column); - bool IsColumnSelected(int column); - bool IsRowSelected(int row); - QSpiIntList GetSelectedColumns(); - QSpiIntList GetSelectedRows(); - - bool AddColumnSelection(int column); - bool AddRowSelection(int row); - bool RemoveColumnSelection(int column); - bool RemoveRowSelection(int row); - -/* AT-SPI Text interface */ -public: - Q_PROPERTY(int CaretOffset READ caretOffset) - int caretOffset() const; - Q_PROPERTY(int CharacterCount READ characterCount) - int characterCount() const; - -public Q_SLOTS: - bool AddSelection(int startOffset, int endOffset); - QSpiAttributeSet GetAttributeRun(int offset, bool includeDefaults, int &startOffset, int &endOffset); - QString GetAttributeValue(int offset, const QString &attributeName, int &startOffset, int &endOffset, bool &defined); - QSpiAttributeSet GetAttributes(int offset, int &startOffset, int &endOffset); - QSpiTextRangeList GetBoundedRanges(int x, int y, int width, int height, uint coordType, uint xClipType, uint yClipType); - int GetCharacterAtOffset(int offset); - int GetCharacterExtents(int offset, uint coordType, int &y, int &width, int &height); - QSpiAttributeSet GetDefaultAttributeSet(); - QSpiAttributeSet GetDefaultAttributes(); - int GetNSelections(); - int GetOffsetAtPoint(int x, int y, uint coordType); - int GetRangeExtents(int startOffset, int endOffset, uint coordType, int &y, int &width, int &height); - int GetSelection(int selectionNum, int &endOffset); - QString GetText(int startOffset, int endOffset); - QString GetTextAfterOffset(int offset, uint type, int &startOffset, int &endOffset); - QString GetTextAtOffset(int offset, uint type, int &startOffset, int &endOffset); - QString GetTextBeforeOffset(int offset, uint type, int &startOffset, int &endOffset); - bool RemoveSelection(int selectionNum); - bool SetCaretOffset(int offset); - bool SetSelection(int selectionNum, int startOffset, int endOffset); - -/* AT-SPI Text interface */ -public: - Q_PROPERTY(double CurrentValue READ currentValue WRITE SetCurrentValue) - double currentValue() const; - void SetCurrentValue(double value); - Q_PROPERTY(double MaximumValue READ maximumValue) - double maximumValue() const; - Q_PROPERTY(double MinimumIncrement READ minimumIncrement) - double minimumIncrement() const; - Q_PROPERTY(double MinimumValue READ minimumValue) - double minimumValue() const; - - - -public: - QSpiAdaptor* getChild(int child) const; -protected: - QAccessibleInterface *interface; - QSpiObjectReference reference; - QStringList supportedInterfaces; - -private: - bool checkInterface() const; - int child; -}; - -#endif /* Q_SPI_ADAPTOR_H */ diff -Nru qt-at-spi-0.1.1/src/application.cpp qt-at-spi-0.1.1+20120306/src/application.cpp --- qt-at-spi-0.1.1/src/application.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/application.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -27,6 +27,15 @@ //#define KEYBOARD_DEBUG + +/*! + \class QSpiApplicationAdaptor + + \brief QSpiApplicationAdaptor + + QSpiApplicationAdaptor +*/ + QSpiApplicationAdaptor::QSpiApplicationAdaptor(const QDBusConnection &connection, QObject *parent) : QObject(parent), dbusConnection(connection) { diff -Nru qt-at-spi-0.1.1/src/atspiadaptor.cpp qt-at-spi-0.1.1+20120306/src/atspiadaptor.cpp --- qt-at-spi-0.1.1/src/atspiadaptor.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/atspiadaptor.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -28,18 +28,20 @@ #include "generated/socket_proxy.h" +#include "standardactionwrapper.h" #include "constant_mappings.h" #define ACCESSIBLE_LAST_TEXT "QIA2_LAST_TEXT" #define ACCESSIBLE_LAST_STATE "QIA2_LAST_STATE" +/*! + \class AtSpiAdaptor -void getArgs(const QDBusArgument &) -{ - qDebug() << "Hihi: "; // << arg; - + \brief AtSpiAdaptor is the main class to forward between QAccessibleInterface and AT-SPI DBus -} + AtSpiAdaptor implements the functions specified in all at-spi interfaces. + It sends notifications comming from Qt via dbus and listens to incoming dbus requests. +*/ AtSpiAdaptor::AtSpiAdaptor(DBusConnection *connection, QObject *parent) : QDBusVirtualObject(parent), m_dbus(connection), initialized(false) @@ -106,6 +108,9 @@ { } +/*! + Provide DBus introspection. + */ QString AtSpiAdaptor::introspect(const QString &path) const { QLatin1String accessibleIntrospection( @@ -552,7 +557,7 @@ QPair pair; if (path != QSPI_OBJECT_PATH_ROOT) { - QPair pair = interfaceFromPath(path); + QPair pair = interfaceFromPath(path); if (!pair.first) { qWarning() << "WARNING Qt AtSpiAdaptor: Could not find accessible on path: " << path; return QString(); @@ -582,6 +587,11 @@ return xml; } +/*! + When initialized we will send updates, not before this. + + This function also checks which event listeners are registered in the at-spi registry. + */ void AtSpiAdaptor::setInitialized(bool init) { initialized = init; @@ -750,6 +760,9 @@ } } +/*! + Checks via dbus which events should be sent. + */ void AtSpiAdaptor::updateEventListeners() { // QStringList watchedExpressions; @@ -791,6 +804,10 @@ updateEventListeners(); } +/*! + This slot needs to get called when a \a window has be activated or deactivated (become focused). + When \a active is true, the window just received focus, otherwise it lost the focus. + */ void AtSpiAdaptor::windowActivated(QObject* window, bool active) { if (!(sendWindow || sendWindow_activate)) @@ -836,19 +853,19 @@ return m_dbus->connection().send(message); } -QPair AtSpiAdaptor::interfaceFromPath(const QString& dbusPath) const +QPair AtSpiAdaptor::interfaceFromPath(const QString& dbusPath) const { int index = 0; if (dbusPath == QSPI_OBJECT_PATH_ROOT) { - QAccessibleInterfacePointer interface = QAccessibleInterfacePointer(QAccessible::queryAccessibleInterface(qApp)); - return QPair(interface, index); + QAIPointer interface = QAIPointer(QAccessible::queryAccessibleInterface(qApp)); + return QPair(interface, index); } QStringList parts = dbusPath.split('/'); if (parts.size() <= 5) { qWarning() << "invalid path: " << dbusPath; - return QPair(QAccessibleInterfacePointer(), 0); + return QPair(QAIPointer(), 0); } QString objectString = parts.at(5); @@ -859,25 +876,29 @@ if (m_handledObjects[uintptr].data() != 0) { QObject* object = reinterpret_cast(uintptr); - QAccessibleInterfacePointer interface = QAccessibleInterfacePointer(QAccessible::queryAccessibleInterface(object)); - QAccessibleInterfacePointer child; + QAIPointer interface = QAIPointer(QAccessible::queryAccessibleInterface(object)); + QAIPointer child; for (int i = 6; i < parts.size(); ++i) { QAccessibleInterface *childInterface; index = interface->navigate(QAccessible::Child, parts.at(i).toInt(), &childInterface); - child = QAccessibleInterfacePointer(childInterface); + child = QAIPointer(childInterface); if (index == 0) interface = child; } - return QPair(interface, index); + return QPair(interface, index); } else { m_handledObjects.remove(uintptr); } } - return QPair(QAccessibleInterfacePointer(), 0); + return QPair(QAIPointer(), 0); } + +/*! + This function gets called when Qt notifies about accessibility updates. +*/ void AtSpiAdaptor::notify(int reason, QAccessibleInterface *interface, int child) { Q_ASSERT(interface); @@ -994,6 +1015,16 @@ } break; } + case QAccessible::TextSelectionChanged: { + if (sendObject || sendObject_text_selection_changed) { + QString path = pathForInterface(interface, child); + QVariantList args = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(QString())))); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("TextSelectionChanged"), args); + + } + break; + } case QAccessible::ValueChanged: { if (sendObject || sendObject_value_changed) { Q_ASSERT(interface->valueInterface()); @@ -1005,8 +1036,21 @@ break; } + case QAccessible::Selection: { + QString path = pathForInterface(interface, child); + int selected = (interface->state(child) & QAccessible::Selected) ? 1 : 0; + QVariantList stateArgs = packDBusSignalArguments(QLatin1String("selected"), selected, 0, variantForPath(path)); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("StateChanged"), stateArgs); + break; + } + case QAccessible::StateChanged: { if (sendObject || sendObject_state_changed) { + if (!interface->object()) { + qWarning() << "Interface has no object"; + return; + } if (child != 0) { qWarning() << "State for child changed: " << interface->object() << child; return; @@ -1132,10 +1176,14 @@ delete parent; } +/*! + Handle incoming DBus message. + This function dispatches the dbus message to the right interface handler. + */ bool AtSpiAdaptor::handleMessage(const QDBusMessage &message, const QDBusConnection &connection) { // get accessible interface - QPair accessible = interfaceFromPath(message.path()); + QPair accessible = interfaceFromPath(message.path()); if (!(accessible.first)) { qWarning() << "WARNING Qt AtSpiAdaptor: Could not find accessible on path: " << message.path(); return false; @@ -1209,6 +1257,9 @@ return false; } +/*! + Register this application as accessible on the accessibility DBus. + */ void AtSpiAdaptor::registerApplication() { SocketProxy *registry; @@ -1239,7 +1290,7 @@ } if (function == "GetRole") { - sendReply(connection, message, (uint) qSpiRoleMapping[interface->role(child)].spiRole()); + sendReply(connection, message, (uint) getRole(interface, child)); } else if (function == "GetName") { sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->text(QAccessible::Name, child)))); } else if (function == "GetRoleName") { @@ -1317,6 +1368,13 @@ return true; } +AtspiRole AtSpiAdaptor::getRole(QAccessibleInterface *interface, int child) const +{ + if (interface->role(child) == QAccessible::EditableText && interface->state(child) | QAccessible::Protected) + return ATSPI_ROLE_PASSWORD_TEXT; + return qSpiRoleMapping[interface->role(child)].spiRole(); +} + QStringList AtSpiAdaptor::accessibleInterfaces(QAccessibleInterface *interface, int index) const { QStringList ifaces; @@ -1341,10 +1399,9 @@ } #endif - if (!index) { - if (interface->actionInterface()) - ifaces << ATSPI_DBUS_INTERFACE_ACTION; + ifaces << ATSPI_DBUS_INTERFACE_ACTION; + if (!index) { if (interface->textInterface()) { ifaces << ATSPI_DBUS_INTERFACE_TEXT; // Cache the last text? @@ -1407,8 +1464,9 @@ QAccessibleInterface *AtSpiAdaptor::accessibleParent(QAccessibleInterface *iface, int child) const { - if (child) - return iface; + if (child) //It's necessary to return a new instance as it might be deleted + return QAccessible::queryAccessibleInterface(iface->object()); + QAccessibleInterface *parent = 0; iface->navigate(QAccessible::Ancestor, 1, &parent); return parent; @@ -1429,44 +1487,40 @@ QString AtSpiAdaptor::pathForInterface(QAccessibleInterface *interface, int childIndex, bool inDestructor) const { - // Try to navigate to the child. If we get a proper interface, use it since it might have an object associated. + if (!interface) + return ATSPI_DBUS_PATH_NULL; + + // Try to navigate to the child. + // If we get a proper interface, use it since it might have an object associated. QAccessibleInterface* childInterface = 0; if (childIndex) { int ret = interface->navigate(QAccessible::Child, childIndex, &childInterface); if (ret == 0 && childInterface) { - // This is an ugly hack for QAction. It cannot create adaptors from the QObject. - QAccessibleInterface *tmp = QAccessible::queryAccessibleInterface(childInterface->object()); - if (tmp) { - interface = childInterface; - childIndex = 0; - delete tmp; - } + interface = childInterface; + childIndex = 0; } } - QString path; QAccessibleInterface* interfaceWithObject = interface; + + + if (interface->role(0) == QAccessible::MenuItem && interface->object() && + inheritsQAction(interface->object())) { + qDebug() << "Role: " << interface->role(0); + interface->navigate(QAccessible::Ancestor, 1, &interfaceWithObject); + childIndex = interfaceWithObject->indexOfChild(interface); + } + + QString path; while(!interfaceWithObject->object()) { QAccessibleInterface* parentInterface; interfaceWithObject->navigate(QAccessible::Ancestor, 1, &parentInterface); Q_ASSERT(parentInterface->isValid()); int index = parentInterface->indexOfChild(interfaceWithObject); - //Q_ASSERT(index >= 0); - // FIXME: This should never happen! - if (index < 0) { - index = 999; - path.prepend("/BROKEN_OBJECT_HIERARCHY"); + if (index < 0) { qWarning() << "Object claims to have child that we cannot navigate to. FIX IT!" << parentInterface->object(); - - qDebug() << "Original interface: " << interface->object() << index; - qDebug() << "Parent interface: " << parentInterface->object() << " childcount:" << parentInterface->childCount(); - QObject* p = parentInterface->object(); - qDebug() << p->children(); - - QAccessibleInterface* tttt; - int id = parentInterface->navigate(QAccessible::Child, 1, &tttt); - qDebug() << "Nav child: " << id << tttt->object(); + return ATSPI_DBUS_PATH_NULL; } path.prepend('/' + QString::number(index)); interfaceWithObject = parentInterface; @@ -1483,6 +1537,18 @@ return path; } +bool AtSpiAdaptor::inheritsQAction(QObject *object) +{ + const QMetaObject *mo = object->metaObject(); + while (mo) { + const QLatin1String cn(mo->className()); + if (cn == "QAction") + return true; + mo = mo->superClass(); + } + return false; +} + // Component static QAccessibleInterface *getWindow(QAccessibleInterface* interface) { @@ -1636,33 +1702,36 @@ // Action interface bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, int child, const QString &function, const QDBusMessage &message, const QDBusConnection &connection) { - if (!interface->actionInterface()) { - qWarning() << "WARNING Qt AtSpiAdaptor: Could not find action interface for: " << message.path() << interface; - return false; + QAccessibleActionInterface *actionIface = interface->actionInterface(); + bool deleteActionInterface = false; + if (!actionIface) { + actionIface = new StandardActionWrapper(interface, child); + deleteActionInterface = true; + child = 0; } if (function == "GetNActions") { - sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(interface->actionInterface()->actionCount())))); + sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(actionIface->actionCount())))); } else if (function == "DoAction") { int index = message.arguments().at(0).toInt(); - interface->actionInterface()->doAction(index); + actionIface->doAction(index); sendReply(connection, message, true); } else if (function == "GetActions") { if (child) { qWarning() << "AtSpiAdaptor::actionInterface: Requesting action interface for child"; return false; } - sendReply(connection, message, QVariant::fromValue(getActions(interface))); + sendReply(connection, message, QVariant::fromValue(getActions(actionIface))); } else if (function == "GetName") { int index = message.arguments().at(0).toInt(); - sendReply(connection, message, interface->actionInterface()->name(index)); + sendReply(connection, message, actionIface->name(index)); } else if (function == "GetDescription") { int index = message.arguments().at(0).toInt(); - sendReply(connection, message, interface->actionInterface()->description(index)); + sendReply(connection, message, actionIface->description(index)); } else if (function == "GetKeyBinding") { int index = message.arguments().at(0).toInt(); QStringList keyBindings; - keyBindings = interface->actionInterface()->keyBindings(index); + keyBindings = actionIface->keyBindings(index); /* Might as well return the first key binding, what are the other options? */ if (keyBindings.length() > 0) sendReply(connection, message, keyBindings.at(0)); @@ -1670,23 +1739,30 @@ sendReply(connection, message, QString()); } else { qWarning() << "WARNING: AtSpiAdaptor::handleMessage does not implement " << function << message.path(); + if (deleteActionInterface) + delete actionIface; + return false; } + + if (deleteActionInterface) + delete actionIface; + return true; } -QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const +QSpiActionArray AtSpiAdaptor::getActions(QAccessibleActionInterface *actionInterface) const { QSpiActionArray actions; - for (int i = 0; i < interface->actionInterface()->actionCount(); i++) + for (int i = 0; i < actionInterface->actionCount(); i++) { QSpiAction action; QStringList keyBindings; - action.name = interface->actionInterface()->name(i); - action.description = interface->actionInterface()->description(i); + action.name = actionInterface->name(i); + action.description = actionInterface->description(i); - keyBindings = interface->actionInterface()->keyBindings(i); + keyBindings = actionInterface->keyBindings(i); if (keyBindings.length() > 0) action.keyBinding = keyBindings[0]; @@ -2111,7 +2187,7 @@ bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, int child, const QString &function, const QDBusMessage &message, const QDBusConnection &connection) { Q_ASSERT(child == 0); - if (!interface->tableInterface()) { + if (!interface->table2Interface()) { qWarning() << "WARNING Qt AtSpiAdaptor: Could not find table interface for: " << message.path() << interface; return false; } @@ -2120,7 +2196,11 @@ // properties } else if (function == "GetCaption") { // fixme: leak of QAI - QObject *object = interface->tableInterface()->caption()->object(); + QAccessibleInterface *caption = interface->table2Interface()->caption(); + if (!caption) + caption = interface->tableInterface() ? interface->tableInterface()->caption() : 0; + + QObject *object = caption ? caption->object() : 0; if (!object) { connection.send(message.createReply(QVariant::fromValue(QDBusVariant(QVariant::fromValue(QSpiObjectReference()))))); } else { @@ -2142,9 +2222,15 @@ QVariant::fromValue(interface->table2Interface()->selectedRowCount()))))); } else if (function == "GetSummary") { // fixme: leak of QAI - QObject *object = interface->tableInterface()->summary()->object(); + QAccessibleInterface *summary = interface->table2Interface()->summary(); + if (!summary) + summary = interface->tableInterface() ? interface->tableInterface()->summary() : 0; + + QObject *object = summary ? summary->object() : 0; if (!object) { - connection.send(message.createReply(QVariant::fromValue(QDBusVariant(QVariant::fromValue(QSpiObjectReference()))))); + QDBusMessage reply = message.createReply(QVariant::fromValue(QDBusVariant(QVariant::fromValue(QSpiObjectReference())))); + qDebug() << "signature: " << reply.signature(); + connection.send(reply); } else { QDBusObjectPath path(pathForObject(object)); QSpiObjectReference ref(connection, path); diff -Nru qt-at-spi-0.1.1/src/atspiadaptor.h qt-at-spi-0.1.1+20120306/src/atspiadaptor.h --- qt-at-spi-0.1.1/src/atspiadaptor.h 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/atspiadaptor.h 2012-03-05 13:34:16.000000000 +0000 @@ -18,6 +18,8 @@ #ifndef ATSPIADAPTOR_H #define ATSPIADAPTOR_H +#include + #include #include #include @@ -28,7 +30,7 @@ class QAccessibleInterface; class QSpiAccessibleInterface; -typedef QSharedPointer QAccessibleInterfacePointer; +typedef QSharedPointer QAIPointer; class AtSpiAdaptor :public QDBusVirtualObject { @@ -36,31 +38,13 @@ public: explicit AtSpiAdaptor(DBusConnection *connection, QObject *parent = 0); - virtual ~AtSpiAdaptor(); + ~AtSpiAdaptor(); - /** - Register this application as accessible on the accessibility DBus. - */ void registerApplication(); - - /** - Provide DBus introspection. - */ - virtual QString introspect(const QString &path) const; - - /** - Handle incoming DBus messages. - */ - virtual bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection); - - /** - Updates from Qt. - */ + QString introspect(const QString &path) const; + bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection); void notify(int reason, QAccessibleInterface *interface, int child); - /** - When initialized we will send updates, not before this. - */ void setInitialized(bool init); public Q_SLOTS: @@ -69,11 +53,9 @@ void windowActivated(QObject* window, bool active); private: - void updateEventListeners(); void setBitFlag(const QString &flag); - // sending messages QVariantList packDBusSignalArguments(const QString &type, int data1, int data2, const QVariant &variantData) const; bool sendDBusSignal(const QString &path, const QString &interface, const QString &name, const QVariantList &arguments) const; @@ -96,11 +78,12 @@ void sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument) const; QAccessibleInterface *accessibleParent(QAccessibleInterface *iface, int child) const; - QPair interfaceFromPath(const QString& dbusPath) const; + QPair interfaceFromPath(const QString& dbusPath) const; QString pathForInterface(QAccessibleInterface *interface, int index, bool inDestructor = false) const; QString pathForObject(QObject *object) const; // accessible helper functions + AtspiRole getRole(QAccessibleInterface *interface, int child) const; QSpiRelationArray relationSet(QAccessibleInterface *interface, int child, const QDBusConnection &connection) const; QStringList accessibleInterfaces(QAccessibleInterface *interface, int child) const; @@ -108,7 +91,7 @@ static QSpiRect getExtents(QAccessibleInterface *interface, int child, uint coordType); // action helper functions - QSpiActionArray getActions(QAccessibleInterface *interface) const; + QSpiActionArray getActions(QAccessibleActionInterface* interface) const; // text helper functions QVariantList getAttributes(QAccessibleInterface *interface, int offset, bool includeDefaults) const; @@ -117,6 +100,8 @@ QVariantList getRangeExtents(QAccessibleInterface *interface, int startOffset, int endOffset, uint coordType) const; QAccessible2::BoundaryType qAccessibleBoundaryType(int atspiTextBoundaryType) const; + static bool inheritsQAction(QObject *object); + // private vars QSpiObjectReference accessibilityRegistry; DBusConnection *m_dbus; diff -Nru qt-at-spi-0.1.1/src/bridge.cpp qt-at-spi-0.1.1+20120306/src/bridge.cpp --- qt-at-spi-0.1.1/src/bridge.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/bridge.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -34,6 +34,14 @@ QSpiAccessibleBridge* QSpiAccessibleBridge::self = 0; +/*! + \class QSpiAccessibleBridge + + \brief QSpiAccessibleBridge + + QSpiAccessibleBridge +*/ + QSpiAccessibleBridge::QSpiAccessibleBridge() : cache(0) { diff -Nru qt-at-spi-0.1.1/src/cache.cpp qt-at-spi-0.1.1+20120306/src/cache.cpp --- qt-at-spi-0.1.1/src/cache.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/cache.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -25,6 +25,22 @@ #define QSPI_OBJECT_PATH_CACHE "/org/a11y/atspi/cache" +/*! + \class QSpiDBusCache + + \brief This class is responsible for the AT-SPI cache interface. + + The idea behind the cache is that starting an application would + result in many dbus calls. The way GTK/Gail/ATK work is that + they create accessibles for all objects on startup. + In order to avoid querying all the objects individually via DBus + they get sent by using the GetItems call of the cache. + + Additionally the AddAccessible and RemoveAccessible signals + are responsible for adding/removing objects from the cache. + + Currently the Qt bridge chooses to ignore these. +*/ QSpiDBusCache::QSpiDBusCache(QDBusConnection c, QObject* parent) : QObject(parent) diff -Nru qt-at-spi-0.1.1/src/cache.h qt-at-spi-0.1.1+20120306/src/cache.h --- qt-at-spi-0.1.1/src/cache.h 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/cache.h 2012-03-05 13:34:16.000000000 +0000 @@ -23,17 +23,7 @@ #include #include "struct_marshallers.h" -/** This class is responsible for the AT-SPI cache interface. - * - * The idea behind the cache is that starting an application would - * result in many dbus calls. The way GTK/Gail/ATK work is that - * they create accessibles for all objects on startup. - * In order to avoid querying all the objects individually via DBus - * they get sent by using the GetItems call of the cache. - * - * Additionally the AddAccessible and RemoveAccessible signals - * are responsible for adding/removing objects from the cache. - */ + class QSpiDBusCache : public QObject { Q_OBJECT diff -Nru qt-at-spi-0.1.1/src/dbusconnection.cpp qt-at-spi-0.1.1+20120306/src/dbusconnection.cpp --- qt-at-spi-0.1.1/src/dbusconnection.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/dbusconnection.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -27,6 +27,20 @@ #include #include +/*! + \class DBusConnection + + \brief DBusConnection + + DBusConnection +*/ + + +/*! + Connects to the accessibility dbus. + + This is usually a different bus from the session bus. +*/ DBusConnection::DBusConnection() : dbusConnection(connectDBus()) {} @@ -104,6 +118,9 @@ return busAddress; } +/*! + Returns the DBus connection that got established. +*/ QDBusConnection DBusConnection::connection() const { return dbusConnection; diff -Nru qt-at-spi-0.1.1/src/index.qdoc qt-at-spi-0.1.1+20120306/src/index.qdoc --- qt-at-spi-0.1.1/src/index.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/index.qdoc 2012-03-05 13:34:16.000000000 +0000 @@ -0,0 +1,64 @@ +/*! + \page index.html + \contentspage {Qt AT-SPI Bridge} {Contents} + \nextpage Getting Started + + \indexpage Index + \startpage Qt AT-SPI Bridge + + \title Qt AT-SPI Bridge + + Table of contents: + + \list + \o \l {Getting Started} + \o \l {All Classes} + \endlist + */ + + +/*! + \page gettingstarted.html + \contentspage {Qt AT-SPI Bridge} {Contents} + \nextpage All Classes + \previouspage Qt AT-SPI Bridge + + \indexpage Index + \startpage Qt AT-SPI Bridge + + \title Getting Started + + Here could be instructions... + + \l {All Classes} +*/ + + +/*! + \page classes.html + \contentspage {Qt AT-SPI Bridge} {Contents} + \previouspage Getting Started + + \indexpage Index + \startpage Qt AT-SPI Bridge + + \title All Classes + + List of classes in Qt AT-SPI + + \generatelist classes + + +*/ + + +/*! + \page allmodules.html + \contentspage {Qt AT-SPI Bridge} {Contents} + \previouspage Qt AT-SPI Bridge + + \indexpage Index + \startpage Qt AT-SPI Bridge + + \title All Modules + */ \ No newline at end of file diff -Nru qt-at-spi-0.1.1/src/main.cpp qt-at-spi-0.1.1+20120306/src/main.cpp --- qt-at-spi-0.1.1/src/main.cpp 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/main.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -22,6 +22,14 @@ QT_BEGIN_NAMESPACE +/*! + \class QSpiAccessibleBridgePlugin + + \brief QSpiAccessibleBridgePlugin + + QSpiAccessibleBridgePlugin +*/ + class QSpiAccessibleBridgePlugin: public QAccessibleBridgePlugin { public: @@ -32,11 +40,17 @@ virtual QStringList keys() const; }; +/*! + The contructor of the plugin. + */ QSpiAccessibleBridgePlugin::QSpiAccessibleBridgePlugin(QObject *parent) : QAccessibleBridgePlugin(parent) { } +/*! + Creates a new instance of the QAccessibleBridge plugin. + */ QAccessibleBridge* QSpiAccessibleBridgePlugin::create(const QString &key) { if (key == "QSPIACCESSIBLEBRIDGE") @@ -44,6 +58,9 @@ return 0; } +/*! + + */ QStringList QSpiAccessibleBridgePlugin::keys() const { return QStringList() << "QSPIACCESSIBLEBRIDGE"; diff -Nru qt-at-spi-0.1.1/src/src.pro qt-at-spi-0.1.1+20120306/src/src.pro --- qt-at-spi-0.1.1/src/src.pro 2012-01-02 13:47:41.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/src.pro 2012-03-05 13:34:16.000000000 +0000 @@ -10,6 +10,7 @@ struct_marshallers.h \ constant_mappings.h \ dbusconnection.h \ + standardactionwrapper.h \ atspiadaptor.h SOURCES += \ @@ -23,6 +24,7 @@ constant_mappings.cpp \ main.cpp \ dbusconnection.cpp \ + standardactionwrapper.cpp \ atspiadaptor.cpp QMAKE_CFLAGS+=-Werror diff -Nru qt-at-spi-0.1.1/src/standardactionwrapper.cpp qt-at-spi-0.1.1+20120306/src/standardactionwrapper.cpp --- qt-at-spi-0.1.1/src/standardactionwrapper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/standardactionwrapper.cpp 2012-03-05 13:34:16.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012 José Millán Soto + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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, see . + */ + +#include "standardactionwrapper.h" + +#include +#include +#include + +StandardActionWrapper::StandardActionWrapper(QAccessibleInterface* interface, int child) +{ + m_interface = interface; + m_child = child; + QSet actionNames; + QSet toCheck; + + bool focusable = interface->state(child) & QAccessible::Focusable; + + if (focusable) { + toCheck << QAccessible::SetFocus; + toCheck << QAccessible::DefaultAction; + } else { + //There are a lot of widgets which set default action to set focus, even if they are not focusable + QString focusActionName = interface->actionText(QAccessible::SetFocus, QAccessible::Name, child); + QString defaultActionName = interface->actionText(QAccessible::DefaultAction, QAccessible::Name, child); + if (focusActionName != defaultActionName) + toCheck << QAccessible::DefaultAction; + } + + if (interface->role(child) == QAccessible::PushButton) + toCheck << QAccessible::Press; + + for (QSet::const_iterator it = toCheck.constBegin(); it != toCheck.constEnd(); it++) { + QString actionName = interface->actionText(*it, QAccessible::Name, child); + + if (!actionNames.contains(actionName) && !actionName.isEmpty()) { + actionNames << actionName; + m_implementedStandardActions.append(*it); + } + } +} + +int StandardActionWrapper::getAccessibleInterfaceIndex(int actionIndex) +{ + if (actionIndex < m_implementedStandardActions.size()) + return m_implementedStandardActions[actionIndex]; + else + return actionIndex - m_implementedStandardActions.size() + 1; +} + +int StandardActionWrapper::actionCount() +{ + return m_implementedStandardActions.size() + m_interface->userActionCount(m_child); +} + +QString StandardActionWrapper::description(int actionIndex) +{ + return m_interface->actionText(getAccessibleInterfaceIndex(actionIndex), QAccessible::Description, m_child); +} + +void StandardActionWrapper::doAction(int actionIndex) +{ + m_interface->doAction(getAccessibleInterfaceIndex(actionIndex), m_child); +} + +QStringList StandardActionWrapper::keyBindings(int actionIndex) +{ + QStringList result; + result << m_interface->actionText(getAccessibleInterfaceIndex(actionIndex), QAccessible::Accelerator, m_child); + return result; +} + +QString StandardActionWrapper::name(int actionIndex) +{ + return m_interface->actionText(getAccessibleInterfaceIndex(actionIndex), QAccessible::Name, m_child); +} + +QString StandardActionWrapper::localizedName(int actionIndex) +{ + return name(actionIndex); +} diff -Nru qt-at-spi-0.1.1/src/standardactionwrapper.h qt-at-spi-0.1.1+20120306/src/standardactionwrapper.h --- qt-at-spi-0.1.1/src/standardactionwrapper.h 1970-01-01 00:00:00.000000000 +0000 +++ qt-at-spi-0.1.1+20120306/src/standardactionwrapper.h 2012-03-05 13:34:16.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 José Millán Soto + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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, see . + */ + +#ifndef STANDARDACTIONWRAPPER_H +#define STANDARDACTIONWRAPPER_H + +#include +#include + +class StandardActionWrapper: public QAccessibleActionInterface +{ +public: + StandardActionWrapper(QAccessibleInterface *interface, int child); + virtual int actionCount(); + virtual QString description(int actionIndex); + virtual void doAction(int actionIndex); + virtual QStringList keyBindings(int actionIndex); + virtual QString localizedName(int actionIndex); + virtual QString name(int actionIndex); + +private: + int getAccessibleInterfaceIndex(int actionIndex); + + QAccessibleInterface *m_interface; + QList m_implementedStandardActions; + int m_child; +}; + +#endif