qaccessiblewidget.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/accessible/qaccessiblewidget.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qaccessiblewidget.h"-
41-
42#ifndef QT_NO_ACCESSIBILITY-
43-
44#include "qaction.h"-
45#include "qapplication.h"-
46#include "qgroupbox.h"-
47#include "qlabel.h"-
48#include "qtooltip.h"-
49#include "qwhatsthis.h"-
50#include "qwidget.h"-
51#include "qdebug.h"-
52#include <qmath.h>-
53#include <QRubberBand>-
54#include <QFocusFrame>-
55#include <QMenu>-
56#include <QtWidgets/private/qwidget_p.h>-
57-
58QT_BEGIN_NAMESPACE-
59-
60static QList<QWidget*> childWidgets(const QWidget *widget)-
61{-
62 QList<QObject*> list = widget->children();QList<QWidget*> widgets;-
63 for (int i = 0; i < list.size(); ++i)QObject *o : widget->children()) {-
64 QWidget *w = qobject_cast<QWidget *>(list.at(i));o);-
65 if (w && !w->isWindow()
wDescription
TRUEnever evaluated
FALSEnever evaluated
!w->isWindow()Description
TRUEnever evaluated
FALSEnever evaluated
0
66 && !qobject_cast<QFocusFrame*>(w)
!qobject_cast<QFocusFrame*>(w)Description
TRUEnever evaluated
FALSEnever evaluated
0
67#if !defined(QT_NO_MENU)-
68 && !qobject_cast<QMenu*>(w)
!qobject_cast<QMenu*>(w)Description
TRUEnever evaluated
FALSEnever evaluated
0
69#endif-
70 && w->objectName() != QLatin1String("qt_rubberband")
w->objectName(...t_rubberband")Description
TRUEnever evaluated
FALSEnever evaluated
0
71 && w->objectName() != QLatin1String("qt_spinbox_lineedit"))
w->objectName(...box_lineedit")Description
TRUEnever evaluated
FALSEnever evaluated
0
72 widgets.append(w);
never executed: widgets.append(w);
0
73 }
never executed: end of block
0
74 return widgets;
never executed: return widgets;
0
75}-
76-
77static QString buddyString(const QWidget *widget)-
78{-
79 if (!widget)
!widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
80 return QString();
never executed: return QString();
0
81 QWidget *parent = widget->parentWidget();-
82 if (!parent)
!parentDescription
TRUEnever evaluated
FALSEnever evaluated
0
83 return QString();
never executed: return QString();
0
84#ifndef QT_NO_SHORTCUT-
85 QObjectList ol =for (QObject *o : parent->children();-
for (int i = 0; i < ol.size(); ++i)()) {
86 QLabel *label = qobject_cast<QLabel*>(ol.at(i));o);-
87 if (label && label->buddy() == widget)
labelDescription
TRUEnever evaluated
FALSEnever evaluated
label->buddy() == widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
88 return label->text();
never executed: return label->text();
0
89 }
never executed: end of block
0
90#endif-
91-
92#ifndef QT_NO_GROUPBOX-
93 QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);-
94 if (groupbox)
groupboxDescription
TRUEnever evaluated
FALSEnever evaluated
0
95 return groupbox->title();
never executed: return groupbox->title();
0
96#endif-
97-
98 return QString();
never executed: return QString();
0
99}-
100-
101/* This function will return the offset of the '&' in the text that would be-
102 preceding the accelerator character.-
103 If this text does not have an accelerator, -1 will be returned. */-
104static int qt_accAmpIndex(const QString &text)-
105{-
106#ifndef QT_NO_SHORTCUT-
107 if (text.isEmpty())-
108 return -1;-
109-
110 int fa = 0;-
111 while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) {-
112 ++fa;-
113 if (fa < text.length()) {-
114 // ignore "&&"-
115 if (text.at(fa) == QLatin1Char('&')) {-
116-
117 ++fa;-
118 continue;-
119 } else {-
120 return fa - 1;-
121 break;
dead code: break;
-
122 }-
123 }-
124 }-
125-
126 return -1;-
127#else-
128 Q_UNUSED(text);-
129 return -1;-
130#endif-
131}-
132-
133QString qt_accStripAmp(const QString &text)-
134{-
135 QString newText(text);-
136 int ampIndex = qt_accAmpIndex(newText);-
137 if (ampIndex != -1)-
138 newText.remove(ampIndex, 1);-
139-
140 return newText.replace(QLatin1String("&&"), QLatin1String("&"));-
141}-
142-
143QString qt_accHotKey(const QString &text)-
144{-
145 int ampIndex = qt_accAmpIndex(text);-
146 if (ampIndex != -1)-
147 return QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + text.at(ampIndex + 1);-
148-
149 return QString();-
150}-
151-
152// ### inherit QAccessibleObjectPrivate-
153class QAccessibleWidgetPrivate-
154{-
155public:-
156 QAccessibleWidgetPrivate()-
157 :role(QAccessible::Client)-
158 {}-
159-
160 QAccessible::Role role;-
161 QString name;-
162 QStringList primarySignals;-
163};-
164-
165/*!-
166 \class QAccessibleWidget-
167 \brief The QAccessibleWidget class implements the QAccessibleInterface for QWidgets.-
168-
169 \ingroup accessibility-
170 \inmodule QtWidgets-
171-
172 This class is part of \l {Accessibility for QWidget Applications}.-
173-
174 This class is convenient to use as a base class for custom-
175 implementations of QAccessibleInterfaces that provide information-
176 about widget objects.-
177-
178 The class provides functions to retrieve the parentObject() (the-
179 widget's parent widget), and the associated widget(). Controlling-
180 signals can be added with addControllingSignal(), and setters are-
181 provided for various aspects of the interface implementation, for-
182 example setValue(), setDescription(), setAccelerator(), and-
183 setHelp().-
184-
185 \sa QAccessible, QAccessibleObject-
186*/-
187-
188/*!-
189 Creates a QAccessibleWidget object for widget \a w.-
190 \a role and \a name are optional parameters that set the object's-
191 role and name properties.-
192*/-
193QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role, const QString &name)-
194: QAccessibleObject(w)-
195{-
196 Q_ASSERT(widget());-
197 d = new QAccessibleWidgetPrivate();-
198 d->role = role;-
199 d->name = name;-
200}-
201-
202/*! \reimp */-
203bool QAccessibleWidget::isValid() const-
204{-
205 if (!object() || static_cast<QWidget *>(object())->d_func()->data.in_destructor)-
206 return false;-
207 return QAccessibleObject::isValid();-
208}-
209-
210/*! \reimp */-
211QWindow *QAccessibleWidget::window() const-
212{-
213 const QWidget *w = widget();-
214 Q_ASSERT(w);-
215 QWindow *result = w->windowHandle();-
216 if (!result) {-
217 if (const QWidget *nativeParent = w->nativeParentWidget())-
218 result = nativeParent->windowHandle();-
219 }-
220 return result;-
221}-
222-
223/*!-
224 Destroys this object.-
225*/-
226QAccessibleWidget::~QAccessibleWidget()-
227{-
228 delete d;-
229}-
230-
231/*!-
232 Returns the associated widget.-
233*/-
234QWidget *QAccessibleWidget::widget() const-
235{-
236 return qobject_cast<QWidget*>(object());-
237}-
238-
239/*!-
240 Returns the associated widget's parent object, which is either the-
241 parent widget, or qApp for top-level widgets.-
242*/-
243QObject *QAccessibleWidget::parentObject() const-
244{-
245 QWidget *w = widget();-
246 if (!w || w->isWindow() || !w->parentWidget())-
247 return qApp;-
248 return w->parent();-
249}-
250-
251/*! \reimp */-
252QRect QAccessibleWidget::rect() const-
253{-
254 QWidget *w = widget();-
255 if (!w->isVisible())-
256 return QRect();-
257 QPoint wpos = w->mapToGlobal(QPoint(0, 0));-
258-
259 return QRect(wpos.x(), wpos.y(), w->width(), w->height());-
260}-
261-
262QT_BEGIN_INCLUDE_NAMESPACE-
263#include <private/qobject_p.h>-
264QT_END_INCLUDE_NAMESPACE-
265-
266class QACConnectionObject : public QObject-
267{-
268 Q_DECLARE_PRIVATE(QObject)-
269public:-
270 inline bool isSender(const QObject *receiver, const char *signal) const-
271 { return d_func()->isSender(receiver, signal); }-
272 inline QObjectList receiverList(const char *signal) const-
273 { return d_func()->receiverList(signal); }-
274 inline QObjectList senderList() const-
275 { return d_func()->senderList(); }-
276};-
277-
278/*!-
279 Registers \a signal as a controlling signal.-
280-
281 An object is a Controller to any other object connected to a-
282 controlling signal.-
283*/-
284void QAccessibleWidget::addControllingSignal(const QString &signal)-
285{-
286 QByteArray s = QMetaObject::normalizedSignature(signal.toLatin1());-
287 if (Q_UNLIKELY(object()->metaObject()->indexOfSignal(s) < 0)))
__builtin_expe...) < 0), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
288 qWarning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
never executed: QMessageLogger(__FILE__, 288, __PRETTY_FUNCTION__).warning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
0
289 d->primarySignals << QLatin1String(s);-
290}
never executed: end of block
0
291-
292static inline bool isAncestor(const QObject *obj, const QObject *child)-
293{-
294 while (child) {-
295 if (child == obj)-
296 return true;-
297 child = child->parent();-
298 }-
299 return false;-
300}-
301-
302/*! \reimp */-
303QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >-
304QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const-
305{-
306 QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels;-
307 if (match & QAccessible::Label) {
match & QAccessible::LabelDescription
TRUEnever evaluated
FALSEnever evaluated
0
308 const QAccessible::Relation rel = QAccessible::Label;-
309 if (QWidget *parent = widget()->parentWidget()) {
QWidget *paren...parentWidget()Description
TRUEnever evaluated
FALSEnever evaluated
0
310#ifndef QT_NO_SHORTCUT-
311 // first check for all siblings that are labels to us-
312 // ideally we would go through all objects and check, but that-
313 // will be too expensive-
314 const QList<QWidget*> kids = childWidgets(parent);-
315 for (int i = 0; i <QWidget *kid : kids.count(); ++i) {-
316 if (QLabel *labelSibling = qobject_cast<QLabel*>(kids.at(i)))kid)) {
QLabel *labelS...<QLabel*>(kid)Description
TRUEnever evaluated
FALSEnever evaluated
0
317 if (labelSibling->buddy() == widget()) {
labelSibling->...() == widget()Description
TRUEnever evaluated
FALSEnever evaluated
0
318 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(labelSibling);-
319 rels.append(qMakePair(iface, rel));-
320 }
never executed: end of block
0
321 }
never executed: end of block
0
322 }
never executed: end of block
0
323#endif-
324#ifndef QT_NO_GROUPBOX-
325 QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);-
326 if (groupbox && !groupbox->title().isEmpty()) {
groupboxDescription
TRUEnever evaluated
FALSEnever evaluated
!groupbox->title().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
327 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupbox);-
328 rels.append(qMakePair(iface, rel));-
329 }
never executed: end of block
0
330#endif-
331 }
never executed: end of block
0
332 }
never executed: end of block
0
333-
334 if (match & QAccessible::Controlled) {
match & QAcces...le::ControlledDescription
TRUEnever evaluated
FALSEnever evaluated
0
335 QObjectList allReceivers;-
336 QACConnectionObject *connectionObject = (QACConnectionObject*)object();-
337 for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
sig < d->prima...ignals.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
338 const QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toLatin1());-
339 allReceivers += receivers;-
340 }
never executed: end of block
0
341-
342 allReceivers.removeAll(object()); //### The object might connect to itself internally-
343-
344 for (int i = 0; i < allReceivers.count(); ++i) {
i < allReceivers.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
345 const QAccessible::Relation rel = QAccessible::Controlled;-
346 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(allReceivers.at(i));-
347 if (iface)
ifaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
348 rels.append(qMakePair(iface, rel));
never executed: rels.append(qMakePair(iface, rel));
0
349 }
never executed: end of block
0
350 }
never executed: end of block
0
351-
352 return rels;
never executed: return rels;
0
353}-
354-
355/*! \reimp */-
356QAccessibleInterface *QAccessibleWidget::parent() const-
357{-
358 return QAccessible::queryAccessibleInterface(parentObject());-
359}-
360-
361/*! \reimp */-
362QAccessibleInterface *QAccessibleWidget::child(int index) const-
363{-
364 Q_ASSERT(widget());-
365 QWidgetList childList = childWidgets(widget());-
366 if (index >= 0 && index < childList.size())-
367 return QAccessible::queryAccessibleInterface(childList.at(index));-
368 return 0;-
369}-
370-
371/*! \reimp */-
372QAccessibleInterface *QAccessibleWidget::focusChild() const-
373{-
374 if (widget()->hasFocus())-
375 return QAccessible::queryAccessibleInterface(object());-
376-
377 QWidget *fw = widget()->focusWidget();-
378 if (!fw)-
379 return 0;-
380-
381 if (isAncestor(widget(), fw) || fw == widget())-
382 return QAccessible::queryAccessibleInterface(fw);-
383 return 0;-
384}-
385-
386/*! \reimp */-
387int QAccessibleWidget::childCount() const-
388{-
389 QWidgetList cl = childWidgets(widget());-
390 return cl.size();-
391}-
392-
393/*! \reimp */-
394int QAccessibleWidget::indexOfChild(const QAccessibleInterface *child) const-
395{-
396 if (!child)-
397 return -1;-
398 QWidgetList cl = childWidgets(widget());-
399 return cl.indexOf(qobject_cast<QWidget *>(child->object()));-
400}-
401-
402// from qwidget.cpp-
403extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);-
404-
405/*! \reimp */-
406QString QAccessibleWidget::text(QAccessible::Text t) const-
407{-
408 QString str;-
409-
410 switch (t) {-
411 case QAccessible::Name:-
412 if (!d->name.isEmpty()) {-
413 str = d->name;-
414 } else if (!widget()->accessibleName().isEmpty()) {-
415 str = widget()->accessibleName();-
416 } else if (widget()->isWindow()) {-
417 if (widget()->isMinimized())-
418 str = qt_setWindowTitle_helperHelper(widget()->windowIconText(), widget());-
419 else-
420 str = qt_setWindowTitle_helperHelper(widget()->windowTitle(), widget());-
421 } else {-
422 str = qt_accStripAmp(buddyString(widget()));-
423 }-
424 break;-
425 case QAccessible::Description:-
426 str = widget()->accessibleDescription();-
427#ifndef QT_NO_TOOLTIP-
428 if (str.isEmpty())-
429 str = widget()->toolTip();-
430#endif-
431 break;-
432 case QAccessible::Help:-
433#ifndef QT_NO_WHATSTHIS-
434 str = widget()->whatsThis();-
435#endif-
436 break;-
437 case QAccessible::Accelerator:-
438 str = qt_accHotKey(buddyString(widget()));-
439 break;-
440 case QAccessible::Value:-
441 break;-
442 default:-
443 break;-
444 }-
445 return str;-
446}-
447-
448/*! \reimp */-
449QStringList QAccessibleWidget::actionNames() const-
450{-
451 QStringList names;-
452 if (widget()->isEnabled()) {-
453 if (widget()->focusPolicy() != Qt::NoFocus)-
454 names << setFocusAction();-
455 }-
456 return names;-
457}-
458-
459/*! \reimp */-
460void QAccessibleWidget::doAction(const QString &actionName)-
461{-
462 if (!widget()->isEnabled())-
463 return;-
464-
465 if (actionName == setFocusAction()) {-
466 if (widget()->isWindow())-
467 widget()->activateWindow();-
468 widget()->setFocus();-
469 }-
470}-
471-
472/*! \reimp */-
473QStringList QAccessibleWidget::keyBindingsForAction(const QString & /* actionName */) const-
474{-
475 return QStringList();-
476}-
477-
478/*! \reimp */-
479QAccessible::Role QAccessibleWidget::role() const-
480{-
481 return d->role;-
482}-
483-
484/*! \reimp */-
485QAccessible::State QAccessibleWidget::state() const-
486{-
487 QAccessible::State state;-
488-
489 QWidget *w = widget();-
490 if (w->testAttribute(Qt::WA_WState_Visible) == false)-
491 state.invisible = true;-
492 if (w->focusPolicy() != Qt::NoFocus)-
493 state.focusable = true;-
494 if (w->hasFocus())-
495 state.focused = true;-
496 if (!w->isEnabled())-
497 state.disabled = true;-
498 if (w->isWindow()) {-
499 if (w->windowFlags() & Qt::WindowSystemMenuHint)-
500 state.movable = true;-
501 if (w->minimumSize() != w->maximumSize())-
502 state.sizeable = true;-
503 if (w->isActiveWindow())-
504 state.active = true;-
505 }-
506-
507 return state;-
508}-
509-
510/*! \reimp */-
511QColor QAccessibleWidget::foregroundColor() const-
512{-
513 return widget()->palette().color(widget()->foregroundRole());-
514}-
515-
516/*! \reimp */-
517QColor QAccessibleWidget::backgroundColor() const-
518{-
519 return widget()->palette().color(widget()->backgroundRole());-
520}-
521-
522/*! \reimp */-
523void *QAccessibleWidget::interface_cast(QAccessible::InterfaceType t)-
524{-
525 if (t == QAccessible::ActionInterface)-
526 return static_cast<QAccessibleActionInterface*>(this);-
527 return 0;-
528}-
529-
530QT_END_NAMESPACE-
531-
532#endif //QT_NO_ACCESSIBILITY-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9