Fix updateAccessibility for QGraphicsObjects

If updateAccessibility is called on a QGraphicsObject, walk up and find
the closest ancestor widget with a HWND.
(cherry picked from commit d4291591dfb6a7b1f5c7d00879e8162e84d9ab1b)

Reviewed-by: Frederik Gladhorn
(cherry picked from commit 96406a7dd609e75340f7b4a05726c60c197786b8)
This commit is contained in:
Jan-Arve Sæther 2011-05-05 16:19:16 +02:00
parent 068545f2cd
commit 5e8b377cb7

View File

@ -49,6 +49,9 @@
#include "qsettings.h"
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
#include <QtGui/qgraphicsitem.h>
#include <QtGui/qgraphicsscene.h>
#include <QtGui/qgraphicsview.h>
#include <winuser.h>
#if !defined(WINABLEAPI)
@ -150,6 +153,106 @@ static const char *roleString(QAccessible::Role role)
return roles[int(role)];
}
static const char *eventString(QAccessible::Event ev)
{
static const char *events[] = {
"null", // 0
"SoundPlayed" /*= 0x0001*/,
"Alert" /*= 0x0002*/,
"ForegroundChanged" /*= 0x0003*/,
"MenuStart" /*= 0x0004*/,
"MenuEnd" /*= 0x0005*/,
"PopupMenuStart" /*= 0x0006*/,
"PopupMenuEnd" /*= 0x0007*/,
"ContextHelpStart" /*= 0x000C*/, // 8
"ContextHelpEnd" /*= 0x000D*/,
"DragDropStart" /*= 0x000E*/,
"DragDropEnd" /*= 0x000F*/,
"DialogStart" /*= 0x0010*/,
"DialogEnd" /*= 0x0011*/,
"ScrollingStart" /*= 0x0012*/,
"ScrollingEnd" /*= 0x0013*/,
"MenuCommand" /*= 0x0018*/, // 16
// Values from IAccessible2
"ActionChanged" /*= 0x0101*/, // 17
"ActiveDescendantChanged",
"AttributeChanged",
"DocumentContentChanged",
"DocumentLoadComplete",
"DocumentLoadStopped",
"DocumentReload",
"HyperlinkEndIndexChanged",
"HyperlinkNumberOfAnchorsChanged",
"HyperlinkSelectedLinkChanged",
"HypertextLinkActivated",
"HypertextLinkSelected",
"HyperlinkStartIndexChanged",
"HypertextChanged",
"HypertextNLinksChanged",
"ObjectAttributeChanged",
"PageChanged",
"SectionChanged",
"TableCaptionChanged",
"TableColumnDescriptionChanged",
"TableColumnHeaderChanged",
"TableModelChanged",
"TableRowDescriptionChanged",
"TableRowHeaderChanged",
"TableSummaryChanged",
"TextAttributeChanged",
"TextCaretMoved",
// TextChanged, deprecated, use TextUpdated
//TextColumnChanged = TextCaretMoved + 2,
"TextInserted",
"TextRemoved",
"TextUpdated",
"TextSelectionChanged",
"VisibleDataChanged", /*= 0x0101+32*/
"ObjectCreated" /*= 0x8000*/, // 49
"ObjectDestroyed" /*= 0x8001*/,
"ObjectShow" /*= 0x8002*/,
"ObjectHide" /*= 0x8003*/,
"ObjectReorder" /*= 0x8004*/,
"Focus" /*= 0x8005*/,
"Selection" /*= 0x8006*/,
"SelectionAdd" /*= 0x8007*/,
"SelectionRemove" /*= 0x8008*/,
"SelectionWithin" /*= 0x8009*/,
"StateChanged" /*= 0x800A*/,
"LocationChanged" /*= 0x800B*/,
"NameChanged" /*= 0x800C*/,
"DescriptionChanged" /*= 0x800D*/,
"ValueChanged" /*= 0x800E*/,
"ParentChanged" /*= 0x800F*/,
"HelpChanged" /*= 0x80A0*/,
"DefaultActionChanged" /*= 0x80B0*/,
"AcceleratorChanged" /*= 0x80C0*/
};
int e = int(ev);
if (e <= 0x80c0) {
const int last = sizeof(events)/sizeof(char*) - 1;
if (e <= 0x07)
return events[e];
else if (e <= 0x13)
return events[e - 0x0c + 8];
else if (e == 0x18)
return events[16];
else if (e <= 0x0101 + 32)
return events[e - 0x101 + 17];
else if (e <= 0x800f)
return events[e - 0x8000 + 49];
else if (e == 0x80a0)
return events[last - 2];
else if (e == 0x80b0)
return events[last - 1];
else if (e == 0x80c0)
return events[last];
}
return "unknown";
};
void showDebug(const char* funcName, const QAccessibleInterface *iface)
{
qDebug() << "Role:" << roleString(iface->role(0))
@ -266,9 +369,28 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
if (w->internalWinId())
break;
}
p = p->parent();
if (QGraphicsObject *gfxObj = qobject_cast<QGraphicsObject*>(p)) {
QGraphicsItem *parentItem = gfxObj->parentItem();
if (parentItem) {
p = parentItem->toGraphicsObject();
} else {
QGraphicsView *view = 0;
if (QGraphicsScene *scene = gfxObj->scene()) {
QWidget *fw = QApplication::focusWidget();
const QList<QGraphicsView*> views = scene->views();
for (int i = 0 ; i < views.count() && view != fw; ++i) {
view = views.at(i);
}
}
p = view;
}
} else {
p = p->parent();
}
} while (p);
//qDebug() << "updateAccessibility(), hwnd:" << w << ", object:" << o << "," << eventString(reason);
if (!w) {
if (reason != QAccessible::ContextHelpStart &&
reason != QAccessible::ContextHelpEnd)