source: trunk/src/gui/accessible/qaccessibleobject.cpp@ 143

Last change on this file since 143 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qaccessibleobject.h"
43
44#ifndef QT_NO_ACCESSIBILITY
45
46#include "qapplication.h"
47#include "qwidget.h"
48#include "qpointer.h"
49#include "qmetaobject.h"
50#include "qvarlengtharray.h"
51
52QT_BEGIN_NAMESPACE
53
54class QAccessibleObjectPrivate
55{
56public:
57 QPointer<QObject> object;
58
59 QList<QByteArray> actionList() const;
60};
61
62QList<QByteArray> QAccessibleObjectPrivate::actionList() const
63{
64 QList<QByteArray> actionList;
65
66 if (!object)
67 return actionList;
68
69 const QMetaObject *mo = object->metaObject();
70 Q_ASSERT(mo);
71
72 QByteArray defaultAction = QMetaObject::normalizedSignature(
73 mo->classInfo(mo->indexOfClassInfo("DefaultSlot")).value());
74
75 for (int i = 0; i < mo->methodCount(); ++i) {
76 const QMetaMethod member = mo->method(i);
77 if (member.methodType() != QMetaMethod::Slot && member.access() != QMetaMethod::Public)
78 continue;
79
80 if (!qstrcmp(member.tag(), "QACCESSIBLE_SLOT")) {
81 if (member.signature() == defaultAction)
82 actionList.prepend(defaultAction);
83 else
84 actionList << member.signature();
85 }
86 }
87
88 return actionList;
89}
90
91/*!
92 \class QAccessibleObject
93 \brief The QAccessibleObject class implements parts of the
94 QAccessibleInterface for QObjects.
95
96 \ingroup accessibility
97
98 This class is mainly provided for convenience. All subclasses of
99 the QAccessibleInterface that provide implementations of non-widget objects
100 should use this class as their base class.
101
102 \sa QAccessible, QAccessibleWidget
103*/
104
105/*!
106 Creates a QAccessibleObject for \a object.
107*/
108QAccessibleObject::QAccessibleObject(QObject *object)
109{
110 d = new QAccessibleObjectPrivate;
111 d->object = object;
112}
113
114/*!
115 Destroys the QAccessibleObject.
116
117 This only happens when a call to release() decrements the internal
118 reference counter to zero.
119*/
120QAccessibleObject::~QAccessibleObject()
121{
122 delete d;
123}
124
125/*!
126 \reimp
127*/
128QObject *QAccessibleObject::object() const
129{
130#ifndef QT_NO_DEBUG
131 if (!d->object)
132 qWarning("QAccessibleInterface is invalid. Crash pending...");
133#endif
134 return d->object;
135}
136
137/*!
138 \reimp
139*/
140bool QAccessibleObject::isValid() const
141{
142 return !d->object.isNull();
143}
144
145/*! \reimp */
146QRect QAccessibleObject::rect(int) const
147{
148 return QRect();
149}
150
151/*! \reimp */
152void QAccessibleObject::setText(Text, int, const QString &)
153{
154}
155
156/*! \reimp */
157int QAccessibleObject::userActionCount(int) const
158{
159 return 0;
160}
161
162/*! \reimp */
163bool QAccessibleObject::doAction(int, int, const QVariantList &)
164{
165 return false;
166}
167
168static const char * const action_text[][5] =
169{
170 // Name, Description, Value, Help, Accelerator
171 { "Press", "", "", "", "Space" },
172 { "SetFocus", "Passes focus to this widget", "", "", "" },
173 { "Increase", "", "", "", "" },
174 { "Decrease", "", "", "", "" },
175 { "Accept", "", "", "", "" },
176 { "Cancel", "", "", "", "" },
177 { "Select", "", "", "", "" },
178 { "ClearSelection", "", "", "", "" },
179 { "RemoveSelection", "", "", "", "" },
180 { "ExtendSelection", "", "", "", "" },
181 { "AddToSelection", "", "", "", "" }
182};
183
184/*! \reimp */
185QString QAccessibleObject::actionText(int action, Text t, int child) const
186{
187 if (child || action > FirstStandardAction || action < LastStandardAction || t > Accelerator)
188 return QString();
189
190 return QString::fromLatin1(action_text[-(action - FirstStandardAction)][t]);
191}
192
193
194/*!
195 \class QAccessibleApplication
196 \brief The QAccessibleApplication class implements the QAccessibleInterface for QApplication.
197
198 \internal
199
200 \ingroup accessibility
201*/
202
203/*!
204 Creates a QAccessibleApplication for the QApplication object referenced by qApp.
205*/
206QAccessibleApplication::QAccessibleApplication()
207: QAccessibleObject(qApp)
208{
209}
210
211// all toplevel widgets except popups and the desktop
212static QWidgetList topLevelWidgets()
213{
214 QWidgetList list;
215 const QWidgetList tlw(qApp->topLevelWidgets());
216 for (int i = 0; i < tlw.count(); ++i) {
217 QWidget *w = tlw.at(i);
218 if (!(w->windowType() == Qt::Popup) && !(w->windowType() == Qt::Desktop))
219 list.append(w);
220 }
221
222 return list;
223}
224
225/*! \reimp */
226int QAccessibleApplication::childCount() const
227{
228 return topLevelWidgets().count();
229}
230
231/*! \reimp */
232int QAccessibleApplication::indexOfChild(const QAccessibleInterface *child) const
233{
234 if (!child->object()->isWidgetType())
235 return -1;
236
237 const QWidgetList tlw(topLevelWidgets());
238 int index = tlw.indexOf(static_cast<QWidget*>(child->object()));
239 if (index != -1)
240 ++index;
241 return index;
242}
243
244/*! \reimp */
245int QAccessibleApplication::childAt(int x, int y) const
246{
247 const QWidgetList tlw(topLevelWidgets());
248 for (int i = 0; i < tlw.count(); ++i) {
249 QWidget *w = tlw.at(i);
250 if (w->frameGeometry().contains(x,y))
251 return i+1;
252 }
253 return -1;
254}
255
256/*! \reimp */
257QAccessible::Relation QAccessibleApplication::relationTo(int child, const
258 QAccessibleInterface *other, int otherChild) const
259{
260 QObject *o = other ? other->object() : 0;
261 if (!o)
262 return Unrelated;
263
264 if(o == object()) {
265 if (child && !otherChild)
266 return Child;
267 if (!child && otherChild)
268 return Ancestor;
269 if (!child && !otherChild)
270 return Self;
271 }
272
273 QWidgetList tlw(topLevelWidgets());
274 if (tlw.contains(qobject_cast<QWidget*>(o)))
275 return Ancestor;
276
277 for (int i = 0; i < tlw.count(); ++i) {
278 QWidget *w = tlw.at(i);
279 QObjectList cl = qFindChildren<QObject *>(w, QString());
280 if (cl.contains(o))
281 return Ancestor;
282 }
283
284 return Unrelated;
285}
286
287/*! \reimp */
288int QAccessibleApplication::navigate(RelationFlag relation, int entry,
289 QAccessibleInterface **target) const
290{
291 if (!target)
292 return -1;
293
294 *target = 0;
295 QObject *targetObject = 0;
296
297 switch (relation) {
298 case Self:
299 targetObject = object();
300 break;
301 case Child:
302 if (entry > 0 && entry <= childCount()) {
303 const QWidgetList tlw(topLevelWidgets());
304 if (tlw.count() >= entry)
305 targetObject = tlw.at(entry-1);
306 } else {
307 return -1;
308 }
309 break;
310 case FocusChild:
311 targetObject = qApp->activeWindow();
312 break;
313 default:
314 break;
315 }
316 *target = QAccessible::queryAccessibleInterface(targetObject);
317 return *target ? 0 : -1;
318}
319
320/*! \reimp */
321QString QAccessibleApplication::text(Text t, int) const
322{
323 switch (t) {
324 case Name:
325 if (qApp->activeWindow())
326 return qApp->activeWindow()->windowTitle();
327 break;
328 case Description:
329 return qApp->applicationFilePath();
330 default:
331 break;
332 }
333 return QString();
334}
335
336/*! \reimp */
337QAccessible::Role QAccessibleApplication::role(int) const
338{
339 return Application;
340}
341
342/*! \reimp */
343QAccessible::State QAccessibleApplication::state(int) const
344{
345 return qApp->activeWindow() ? Focused : Normal;
346}
347
348/*! \reimp */
349int QAccessibleApplication::userActionCount(int) const
350{
351 return 1;
352}
353
354/*! \reimp */
355bool QAccessibleApplication::doAction(int action, int child, const QVariantList &param)
356{
357 if (action == 0 || action == 1) {
358 QWidget *w = 0;
359 w = qApp->activeWindow();
360 if (!w)
361 w = topLevelWidgets().at(0);
362 if (!w)
363 return false;
364 w->activateWindow();
365 return true;
366 }
367 return QAccessibleObject::doAction(action, child, param);
368}
369
370/*! \reimp */
371QString QAccessibleApplication::actionText(int action, Text text, int child) const
372{
373 QString str;
374 if ((action == 0 || action == 1) && !child) switch (text) {
375 case Name:
376 return QApplication::tr("Activate");
377 case Description:
378 return QApplication::tr("Activates the program's main window");
379 default:
380 break;
381 }
382 return QAccessibleObject::actionText(action, text, child);
383}
384
385// ### Qt 5: remove me - binary compatibility hack
386QAccessibleObjectEx::QAccessibleObjectEx(QObject *object)
387{
388 d = new QAccessibleObjectPrivate;
389 d->object = object;
390}
391bool QAccessibleObjectEx::isValid() const
392{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::isValid(); }
393QObject *QAccessibleObjectEx::object() const
394{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::object(); }
395QRect QAccessibleObjectEx::rect(int child) const
396{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::rect(child); }
397void QAccessibleObjectEx::setText(Text t, int child, const QString &text)
398{ reinterpret_cast<QAccessibleObject *>(this)->QAccessibleObject::setText(t, child, text); }
399int QAccessibleObjectEx::userActionCount(int child) const
400{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::userActionCount(child); }
401bool QAccessibleObjectEx::doAction(int action, int child, const QVariantList &params)
402{ return reinterpret_cast<QAccessibleObject *>(this)->QAccessibleObject::doAction(action, child, params); }
403QString QAccessibleObjectEx::actionText(int action, Text t, int child) const
404{ return reinterpret_cast<const QAccessibleObject *>(this)->QAccessibleObject::actionText(action, t, child); }
405QAccessibleObjectEx::~QAccessibleObjectEx()
406{ delete d; }
407
408QT_END_NAMESPACE
409
410#endif //QT_NO_ACCESSIBILITY
Note: See TracBrowser for help on using the repository browser.