Qt Accessibility Client

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

KDE's Doxygen guidelines are available online.