Qt Accessibility Client

accessibleobject.cpp
1/*
2 SPDX-FileCopyrightText: 2012 Frederik Gladhorn <gladhorn@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7#include "accessibleobject.h"
8#include "qaccessibilityclient_debug.h"
9
10#include <QString>
11#include <QDebug>
12
13#include "accessibleobject_p.h"
14#include "registry_p.h"
15
16#include <atspi/atspi-constants.h>
17
18using namespace QAccessibleClient;
19
21 :d(nullptr)
22{
23}
24
25AccessibleObject::AccessibleObject(RegistryPrivate *registryPrivate, const QString &service, const QString &path)
26 :d(nullptr)
27{
28 Q_ASSERT(registryPrivate);
29 Q_ASSERT(!service.isEmpty());
30 Q_ASSERT(!path.isEmpty());
31 if (registryPrivate->m_cache) {
32 const QString id = path + service;
33 d = registryPrivate->m_cache->get(id);
34 if (!d) {
35 d = QSharedPointer<AccessibleObjectPrivate>(new AccessibleObjectPrivate(registryPrivate, service, path));
36 registryPrivate->m_cache->add(id, d);
37 }
38 } else {
39 d = QSharedPointer<AccessibleObjectPrivate>(new AccessibleObjectPrivate(registryPrivate, service, path));
40 }
41}
42
44 :d(dd)
45{
46}
47
49 : d(other.d)
50{
51}
52
56
58{
59 if (!d || !d->registryPrivate)
60 return QString();
61 return d->path + d->service;
62}
63
65{
66 if (!d || !d->registryPrivate)
67 return QUrl();
68 QUrl u;
69 u.setScheme(d->registryPrivate->ACCESSIBLE_OBJECT_SCHEME_STRING);
70 u.setPath(d->path);
71 u.setFragment(d->service);
72 return u;
73}
74
76{
77 return d && d->registryPrivate
78 && (!d->service.isEmpty())
79 && (!d->path.isEmpty())
80 && (d->path != QLatin1String("/org/a11y/atspi/null"));
81}
82
84{
85 d = other.d;
86 return *this;
87}
88
90{
91 return (d == other.d) || (d && other.d && *d == *other.d);
92}
93
95{
96 return d->registryPrivate->parentAccessible(*this);
97}
98
100{
101 return d->registryPrivate->children(*this);
102}
103
105{
106 QVector< QList<AccessibleObject> > result(roles.count());
107 const QList<AccessibleObject> all = children();
108 for(int i = 0; i < all.count(); ++i) {
109 const AccessibleObject &child = all[i];
110 int index = roles.indexOf(child.role());
111 if (index < 0) continue;
112 result[index].append(child);
113 }
114 return result;
115}
116
118{
119 return d->registryPrivate->childCount(*this);
120}
121
123{
124 return d->registryPrivate->child(*this, index);
125}
126
128{
129 return d->registryPrivate->indexInParent(*this);
130}
131
133{
134 return d->registryPrivate->accessibleId(*this);
135}
136
138{
139 return d->registryPrivate->name(*this);
140}
141
143{
144 return d->registryPrivate->description(*this);
145}
146
148{
149 return d->registryPrivate->role(*this);
150}
151
153{
154 return d->registryPrivate->roleName(*this);
155}
156
158{
159 return d->registryPrivate->localizedRoleName(*this);
160}
161
163{
164 return d->registryPrivate->layer(*this);
165}
166
168{
169 return d->registryPrivate->mdiZOrder(*this);
170}
171
173{
174 return d->registryPrivate->alpha(*this);
175}
176
178{
179 if( supportedInterfaces() & AccessibleObject::ComponentInterface ){
180 return d->registryPrivate->boundingRect(*this);
181 } else {
182 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "boundingRect called on accessible that does not implement component";
183 return QRect();
184 }
185}
186
188{
189 if( supportedInterfaces() & AccessibleObject::TextInterface ){
190 return d->registryPrivate->characterRect(*this, offset);
191 } else {
192 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "characterRect called on accessible that does not implement text";
193 return QRect();
194 }
195}
196
198{
199 return d->registryPrivate->supportedInterfaces(*this);
200}
201
203{
204 if( supportedInterfaces() & AccessibleObject::TextInterface ){
205 return d->registryPrivate->caretOffset(*this);
206 } else {
207 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "caretOffset called on accessible that does not implement text";
208 return 0;
209 }
210}
211
213{
214 if( supportedInterfaces() & AccessibleObject::TextInterface ){
215 return d->registryPrivate->characterCount(*this);
216 } else {
217 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "characterCount called on accessible that does not implement text";
218 return 0;
219 }
220}
221
222QString AccessibleObject::text(int startOffset, int endOffset) const
223{
224 if( supportedInterfaces() & AccessibleObject::TextInterface )
225 return d->registryPrivate->text(*this, startOffset, endOffset);
226 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "text called on accessible that does not implement text";
227 return QString();
228}
229
230QString AccessibleObject::textWithBoundary(int offset, TextBoundary boundary, int *startOffset, int *endOffset) const
231{
232 if (supportedInterfaces() & AccessibleObject::TextInterface)
233 return d->registryPrivate->textWithBoundary(*this, offset, boundary, startOffset, endOffset);
234 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "text called on accessible that does not implement text";
235 return QString();
236}
237
239{
240 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
241 return d->registryPrivate->setText(*this, text);
242 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "setText called on accessible that does not implement editableText";
243 return false;
244}
245
246bool AccessibleObject::insertText(const QString &text, int position, int length)
247{
248 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
249 return d->registryPrivate->insertText(*this, text, position, length);
250 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "insertText called on accessible that does not implement editableText";
251 return false;
252}
253
254bool AccessibleObject::copyText(int startPos, int endPos)
255{
256 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
257 return d->registryPrivate->copyText(*this, startPos, endPos);
258 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "copyText called on accessible that does not implement editableText";
259 return false;
260}
261
262bool AccessibleObject::cutText(int startPos, int endPos)
263{
264 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
265 return d->registryPrivate->cutText(*this, startPos, endPos);
266 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "cutText called on accessible that does not implement editableText";
267 return false;
268}
269
270bool AccessibleObject::deleteText(int startPos, int endPos)
271{
272 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
273 return d->registryPrivate->deleteText(*this, startPos, endPos);
274 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "deleteText called on accessible that does not implement editableText";
275 return false;
276}
277
279{
280 if( supportedInterfaces() & AccessibleObject::EditableTextInterface )
281 return d->registryPrivate->pasteText(*this, position);
282 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "pasteText called on accessible that does not implement editableText";
283 return false;
284}
285
287{
288 if(supportedInterfaces() & AccessibleObject::Text)
289 return d->registryPrivate->textSelections(*this);
290 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "textSelections called on accessible that does not implement text";
291 return QList< QPair<int,int> >();
292}
293
294void AccessibleObject::setTextSelections(const QList< QPair<int,int> > &selections)
295{
296 if(supportedInterfaces() & AccessibleObject::Text)
297 return d->registryPrivate->setTextSelections(*this, selections);
298 qCWarning(LIBQACCESSIBILITYCLIENT_LOG) << "setTextSelections called on accessible that does not implement text";
299}
300
302{
304 if (ifaces & TextInterface) {
305 const int offset = caretOffset();
306 const QRect r = characterRect(offset);
307 if (r.x() != 0 || r.y() != 0)
308 return r.center();
309 }
310 if (ifaces & ComponentInterface) {
311 const QRect r = boundingRect();
312 if (!r.isNull())
313 return r.center();
314 }
316 if (p.isValid())
317 return p.focusPoint(); // recursive
318 return QPoint();
319}
320
322{
323 return d->registryPrivate->application(*this);
324}
325
327{
328 return d->registryPrivate->appToolkitName(*this);
329}
330
332{
333 return d->registryPrivate->appVersion(*this);
334}
335
337{
338 return d->registryPrivate->appId(*this);
339}
340
342{
343 return d->registryPrivate->appLocale(*this, lctype);
344}
345
347{
348 return d->registryPrivate->appBusAddress(*this);
349}
350
352{
353 return d->registryPrivate->minimumValue(*this);
354}
355
357{
358 return d->registryPrivate->maximumValue(*this);
359}
360
362{
363 return d->registryPrivate->minimumValueIncrement(*this);
364}
365
367{
368 return d->registryPrivate->currentValue(*this);
369}
370
372{
373 return d->registryPrivate->setCurrentValue(*this, value);
374}
375
377{
378 return d->registryPrivate->selection(*this);
379}
380
382{
383 return d->registryPrivate->imageDescription(*this);
384}
385
387{
388 return d->registryPrivate->imageLocale(*this);
389}
390
392{
393 return d->registryPrivate->imageRect(*this);
394}
395
397{
398 // Actions in atspi are supposed to be static what means they cannot change in
399 // between (e.g. actions removed or added or edited) so we can safely just
400 // fetch them only once and store the result for the life-time of the object,
401 if (!d->actionsFetched) {
402 d->actionsFetched = true;
403 d->actions = d->registryPrivate->actions(*this);
404 }
405 return d->actions;
406}
407
409{
410 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SELECTABLE_TEXT);
411}
412
414{
415 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_HAS_TOOLTIP);
416}
417
419{
420 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_ACTIVE);
421}
422
424{
425 //FIXME: Find better AccessibleObject::isCheckable
426 //return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_);
427
428 Role role = d->registryPrivate->role(*this);
429 if (role == AccessibleObject::CheckBox ||
430 role == AccessibleObject::CheckableMenuItem ||
431 role == AccessibleObject::RadioButton ||
432 role == AccessibleObject::RadioMenuItem ||
433 role == AccessibleObject::ToggleButton)
434 return true;
435 return false;
436}
437
439{
440 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_CHECKED);
441}
442
444{
445 return d->defunct;
446}
447
449{
450 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_IS_DEFAULT);
451}
452
454{
455 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_EDITABLE);
456}
457
459{
460 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_ENABLED);
461}
462
464{
465 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_EXPANDABLE);
466}
467
469{
470 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_EXPANDED);
471}
472
474{
475 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_FOCUSABLE);
476}
477
479{
480 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_FOCUSED);
481}
482
484{
485 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_MULTI_LINE);
486}
487
489{
490 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SELECTABLE);
491}
492
494{
495 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SELECTED);
496}
497
499{
500 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SENSITIVE);
501}
502
504{
505 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SINGLE_LINE);
506}
507
509{
510 QStringList s;
511 if (isActive()) s << QStringLiteral("Active");
512 if (isCheckable()) s << QStringLiteral("Checkable");
513 if (isChecked()) s << QStringLiteral("Checked");
514 if (isEditable()) s << QStringLiteral("Editable");
515 if (isExpandable()) s << QStringLiteral("Expandable");
516 if (isExpanded()) s << QStringLiteral("Expanded");
517 if (isFocusable()) s << QStringLiteral("Focusable");
518 if (isFocused()) s << QStringLiteral("Focused");
519 if (isMultiLine()) s << QStringLiteral("MultiLine");
520 if (isSelectable()) s << QStringLiteral("Selectable");
521 if (isSelected()) s << QStringLiteral("Selected");
522 if (isSensitive()) s << QStringLiteral("Sensitive");
523 if (isSingleLine()) s << QStringLiteral("SingleLine");
524 if (isEnabled()) s << QStringLiteral("Enabled");
525 return s.join(QLatin1String(", "));
526}
527
529{
530 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_VISIBLE);
531}
532
534{
535 return d->registryPrivate->state(*this) & (quint64(1) << ATSPI_STATE_SUPPORTS_AUTOCOMPLETION);
536}
537
538#ifndef QT_NO_DEBUG_STREAM
539QACCESSIBILITYCLIENT_EXPORT QDebug QAccessibleClient::operator<<(QDebug d, const AccessibleObject &object)
540{
541 d.nospace();
542 d << "AccessibleObject(";
543 if (object.d) {
544 d << "service=" << object.d->service;
545 d << " path=" << object.d->path;
546 d << " name=" << object.name();
547 } else {
548 d << "invalid";
549 }
550 d << ")";
551 return d.space();
552}
553#endif
This class represents an accessible object.
bool setText(const QString &text)
Set the text of the EditableTextInterface.
QString stateString() const
Return a string representing states of this object.
bool isDefault() const
Returns if the AccessibleObject is the default widget (e.g. a button in a dialog)
bool isSelectable() const
Returns if the AccessibleObject is selectable.
double currentValue() const
The current value of the valuator.
QString accessibleId() const
Returns the accessible id of this accessible.
AccessibleObject & operator=(const AccessibleObject &other)
Assignment operator.
bool isEnabled() const
Returns if the AccessibleObject is currently enabled.
Interfaces supportedInterfaces() const
Returns List of interfaces supported by the accessible.
bool isChecked() const
Returns if the AccessibleObject is currently checked.
bool isValid() const
Returns true if this object is valid.
bool isDefunct() const
Returns if the AccessibleObject is defunct - that means it does not properly respont to requests and ...
bool operator==(const AccessibleObject &other) const
Comparison operator.
AccessibleObject child(int index) const
Returns a specific child at position index.
QString id() const
Returns a unique identifier for the object.
bool isVisible() const
Returns if the AccessibleObject is currently visible (it can still be off the screen,...
double alpha() const
Obtain the alpha value of the component.
bool deleteText(int startPos, int endPos)
Delete the text from the EditableTextInterface.
AccessibleObject()
Construct an invalid AccessibleObject.
bool isSensitive() const
Returns if the AccessibleObject reacts to input events.
QString textWithBoundary(int offset, TextBoundary boundary, int *startOffset=nullptr, int *endOffset=nullptr) const
Returns the text of the TextInterface by boundary.
Role role() const
Returns the role as integer value of this accessible.
QString description() const
Returns the description for this accessible.
bool isFocusable() const
Returns if the AccessibleObject is focusable.
bool isExpandable() const
Returns if the AccessibleObject can be expanded to show more information.
double minimumValue() const
The minimum value allowed by this valuator.
QRect boundingRect() const
Returns a bounding rectangle for the accessible.
bool isFocused() const
Returns if the AccessibleObject is currently focused.
int mdiZOrder() const
Obtain the relative stacking order (i.e.
bool isCheckable() const
Returns if the AccessibleObject is checkable (often indicates a check action)
QList< AccessibleObject > children() const
Returns this accessible's children in a list.
int characterCount() const
Returns the number of characters.
TextBoundary
The TextBoundaries enum represents the different boundaries when asking for text at a certain offset.
QPoint focusPoint() const
Returns focus-point of the object.
QRect characterRect(int offset) const
Returns a bounding rectangle for the character at position offset.
bool isMultiLine() const
Returns if the AccessibleObject is a multi line text edit.
int caretOffset() const
Returns the offset of the caret from the beginning of the text.
QString appToolkitName() const
Returns the toolkit name.
QList< AccessibleObject > selection() const
Returns the selection of accessible objects.
bool isEditable() const
Returns if the AccessibleObject is an editable text.
double maximumValue() const
The maximum value allowed by this valuator.
bool supportsAutocompletion() const
Returns if the AccessibleObject supports automatic text completion.
AccessibleObject application() const
Returns the application object.
double minimumValueIncrement() const
The smallest incremental change which this valuator allows.
QRect imageRect() const
The image boundaries.
int appId() const
Returns the unique application identifier.
QString text(int startOffset=0, int endOffset=-1) const
Returns the text of the TextInterface.
QString imageLocale() const
The locale of the image.
bool insertText(const QString &text, int position=0, int length=-1)
Insert the text into the EditableTextInterface.
bool isSingleLine() const
Returns if the AccessibleObject is a single line text edit.
~AccessibleObject()
Destroys the AccessibleObject.
int childCount() const
Returns the number of children for this accessible.
bool pasteText(int position)
Paste the text from the clipboard into the EditableTextInterface.
QString appVersion() const
Returns the toolkit version.
int indexInParent() const
Returns this accessible's index in it's parent's list of children.
QString imageDescription() const
A description text of the image.
bool copyText(int startPos, int endPos)
Copy the text from the EditableTextInterface into the clipboard.
QString appLocale(LocaleType lctype=LocaleTypeMessages) const
The application locale.
void setTextSelections(const QList< QPair< int, int > > &selections)
Set text selections, usually only one selection will be set, use a list containing one QPair with the...
bool setCurrentValue(const double value)
Set the value of the valuator.
AccessibleObject parent() const
Returns this object's parent.
QString roleName() const
Returns the name of the role of this accessible.
QString localizedRoleName() const
Returns the name of the role of this accessible.
Role
The role indicates the type of UI element that an AccessibleObject represents.
bool hasToolTip() const
Returns if the AccessibleObject has a tool tip.
QString appBusAddress() const
The application dbus address.
bool hasSelectableText() const
Returns if the AccessibleObject allows text selections.
bool isExpanded() const
Returns if the AccessibleObject is currently expanded.
QVector< QSharedPointer< QAction > > actions() const
Returns a list of actions supported by this accessible.
bool cutText(int startPos, int endPos)
Cut the text from the EditableTextInterface into the clipboard.
bool isSelected() const
Returns if the AccessibleObject is currently selected.
QList< QPair< int, int > > textSelections() const
Returns a list of selections the text has.
QUrl url() const
Returns a QUrl that references the AccessibleObject.
int layer() const
The ComponentLayer in which this object resides.
QString name() const
Returns the name of this accessible.
bool isActive() const
Returns if the AccessibleObject is currently active.
QDebug & nospace()
QDebug & space()
void append(QList< T > &&value)
qsizetype count() const const
qsizetype indexOf(const AT &value, qsizetype from) const const
QPoint center() const const
bool isNull() const const
int x() const const
int y() const const
bool isEmpty() const const
QString join(QChar separator) const const
void setFragment(const QString &fragment, ParsingMode mode)
void setPath(const QString &path, ParsingMode mode)
void setScheme(const QString &scheme)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:15:32 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.