10#include <QtCore/qtextboundaryfinder.h>
11#include <QtGui/qclipboard.h>
12#include <QtGui/qguiapplication.h>
13#include <QtGui/qtextcursor.h>
14#include <private/qguiapplication_p.h>
15#include <qpa/qplatformaccessibility.h>
16#include <qpa/qplatformintegration.h>
18#include <QtCore/qdebug.h>
19#include <QtCore/qloggingcategory.h>
20#include <QtCore/qmetaobject.h>
21#include <QtCore/private/qmetaobject_p.h>
22#include <QtCore/qhash.h>
23#include <private/qfactoryloader_p.h>
438#if QT_CONFIG(accessibility)
443QAccessibleInterface::~QAccessibleInterface()
456 (QAccessibleFactoryInterface_iid,
"/accessible"_L1))
464QAccessible::UpdateHandler QAccessible::updateHandler =
nullptr;
465QAccessible::RootObjectHandler QAccessible::rootObjectHandler =
nullptr;
467static bool cleanupAdded =
false;
469static QPlatformAccessibility *platformAccessibility()
472 return pfIntegration ? pfIntegration->accessibility() :
nullptr;
487void QAccessible::cleanup()
489 if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
490 pfAccessibility->cleanup();
493static void qAccessibleCleanup()
495 qAccessibleActivationObservers()->clear();
496 qAccessibleFactories()->clear();
546void QAccessible::installFactory(InterfaceFactory
factory)
557 qAccessibleFactories()->append(
factory);
563void QAccessible::removeFactory(InterfaceFactory
factory)
565 qAccessibleFactories()->removeAll(
factory);
575QAccessible::UpdateHandler QAccessible::installUpdateHandler(UpdateHandler handler)
577 UpdateHandler old = updateHandler;
578 updateHandler = handler;
588QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectHandler handler)
590 RootObjectHandler old = rootObjectHandler;
591 rootObjectHandler = handler;
603QAccessible::ActivationObserver::~ActivationObserver()
612void QAccessible::installActivationObserver(QAccessible::ActivationObserver *observer)
621 if (qAccessibleActivationObservers()->
contains(observer))
623 qAccessibleActivationObservers()->append(observer);
632void QAccessible::removeActivationObserver(ActivationObserver *observer)
634 qAccessibleActivationObservers()->removeAll(observer);
655QAccessibleInterface *QAccessible::queryAccessibleInterface(
QObject *
object)
660 if (Id
id = QAccessibleCache::instance()->idForObject(
object))
661 return QAccessibleCache::instance()->interfaceForId(
id);
676 const bool qmlRelated = !objectPriv->isDeletingChildren &&
677 objectPriv->declarativeData;
678 while (qmlRelated &&
mo) {
683 mo =
mo->superClass();
689 for (
int i = qAccessibleFactories()->
size();
i > 0; --
i) {
690 InterfaceFactory
factory = qAccessibleFactories()->at(
i - 1);
691 if (QAccessibleInterface *iface =
factory(cn,
object)) {
692 QAccessibleCache::instance()->insert(
object, iface);
693 Q_ASSERT(QAccessibleCache::instance()->containsObject(
object));
699 if (!qAccessiblePlugins()->
contains(cn)) {
700 QAccessiblePlugin *
factory =
nullptr;
701 const int index = acLoader()->indexOf(cn);
703 factory = qobject_cast<QAccessiblePlugin *>(acLoader()->instance(
index));
704 qAccessiblePlugins()->insert(cn,
factory);
709 QAccessiblePlugin *
factory = qAccessiblePlugins()->value(cn);
713 QAccessibleCache::instance()->insert(
object,
result);
714 Q_ASSERT(QAccessibleCache::instance()->containsObject(
object));
718 mo =
mo->superClass();
721 if (
object ==
qApp) {
722 QAccessibleInterface *appInterface =
new QAccessibleApplication;
723 QAccessibleCache::instance()->insert(
object, appInterface);
724 Q_ASSERT(QAccessibleCache::instance()->containsObject(
qApp));
745QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *iface)
748 return QAccessibleCache::instance()->insert(
iface->object(), iface);
756void QAccessible::deleteAccessibleInterface(Id
id)
758 QAccessibleCache::instance()->deleteInterface(
id);
764QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface)
766 Id id = QAccessibleCache::instance()->idForInterface(iface);
768 id = registerAccessibleInterface(iface);
777QAccessibleInterface *QAccessible::accessibleInterface(Id
id)
779 return QAccessibleCache::instance()->interfaceForId(
id);
794bool QAccessible::isActive()
796 if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
797 return pfAccessibility->isActive();
804void QAccessible::setActive(
bool active)
806 for (
int i = 0;
i < qAccessibleActivationObservers()->size() ;++
i)
807 qAccessibleActivationObservers()->at(
i)->accessibilityActiveChanged(active);
825void QAccessible::setRootObject(
QObject *
object)
827 if (rootObjectHandler) {
828 rootObjectHandler(
object);
832 if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
833 pfAccessibility->setRootObject(
object);
855void QAccessible::updateAccessibility(QAccessibleEvent *
event)
863 QAccessibleInterface *
iface =
event->accessibleInterface();
865 if (
event->type() == QAccessible::TableModelChanged) {
866 if (
iface->tableInterface())
867 iface->tableInterface()->modelChange(
static_cast<QAccessibleTableModelChangeEvent*
>(
event));
872 updateHandler(
event);
876 if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
877 pfAccessibility->notifyAccessibilityUpdate(
event);
893 int characterCount = endCursor.
position();
897 switch (boundaryType) {
909 case SentenceBoundary: {
918 const int offsetWithinBlockText = offsetCursor.
position() -
result.first;
920 sentenceFinder.setPosition(offsetWithinBlockText);
921 int prevBoundary = offsetWithinBlockText;
922 int nextBoundary = offsetWithinBlockText;
924 prevBoundary = sentenceFinder.toPreviousBoundary();
925 nextBoundary = sentenceFinder.toNextBoundary();
926 if (nextBoundary != -1)
928 if (prevBoundary != -1)
929 result.first += prevBoundary;
937 case ParagraphBoundary:
945 result.second = characterCount;
1096QAccessibleInterface::relations(QAccessible::Relation
match)
const
1107QAccessibleInterface *QAccessibleInterface::focusChild()
const
1246QColor QAccessibleInterface::foregroundColor()
const
1256QColor QAccessibleInterface::backgroundColor()
const
1333QAccessibleEvent::~QAccessibleEvent()
1360QAccessible::Id QAccessibleEvent::uniqueId()
const
1364 QAccessibleInterface *
iface = QAccessible::queryAccessibleInterface(m_object);
1367 if (m_child != -1) {
1370 qCWarning(lcAccessibilityCore) <<
"Invalid child in QAccessibleEvent:" << m_object <<
"child:" << m_child;
1374 return QAccessible::uniqueId(iface);
1412QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent()
1455QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent()
1534QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent()
1562QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent()
1602QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent()
1644QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent()
1705QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
1739QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent()
1748QAccessibleInterface *QAccessibleEvent::accessibleInterface()
const
1750 if (m_object ==
nullptr)
1751 return QAccessible::accessibleInterface(m_uniqueId);
1753 QAccessibleInterface *
iface = QAccessible::queryAccessibleInterface(m_object);
1754 if (!iface || !
iface->isValid())
1758 QAccessibleInterface *
child =
iface->child(m_child);
1762 qCWarning(lcAccessibilityCore) <<
"Cannot create accessible child interface for object: " << m_object <<
" index: " << m_child;
1781QWindow *QAccessibleInterface::window()
const
1794void QAccessibleInterface::virtual_hook(
int ,
void * )
1815const char *qAccessibleRoleString(QAccessible::Role role)
1817 if (role >= QAccessible::UserRole)
1818 role = QAccessible::UserRole;
1819 static int roleEnum = QAccessible::staticMetaObject.indexOfEnumerator(
"Role");
1820 return QAccessible::staticMetaObject.enumerator(roleEnum).valueToKey(role);
1824const char *qAccessibleEventString(QAccessible::Event
event)
1826 static int eventEnum = QAccessible::staticMetaObject.indexOfEnumerator(
"Event");
1827 return QAccessible::staticMetaObject.enumerator(eventEnum).valueToKey(
event);
1830#ifndef QT_NO_DEBUG_STREAM
1836 d <<
"QAccessibleInterface(null)";
1840 d <<
"QAccessibleInterface(" <<
Qt::hex << (
const void *) iface <<
Qt::dec;
1841 if (
iface->isValid()) {
1842 d <<
" name=" <<
iface->text(QAccessible::Name) <<
' ';
1843 d <<
"role=" << qAccessibleRoleString(
iface->role()) <<
' ';
1844 if (
iface->childCount())
1845 d <<
"childc=" <<
iface->childCount() <<
' ';
1846 if (
iface->object()) {
1847 d <<
"obj=" <<
iface->object();
1852 stateStrings << u
"focusable"_s;
1854 stateStrings << u
"focused"_s;
1856 stateStrings << u
"selected"_s;
1858 stateStrings << u
"invisible"_s;
1860 if (!stateStrings.isEmpty())
1861 d << stateStrings.join(u
'|');
1864 d <<
"rect=" <<
iface->rect();
1877 d.nospace() <<
"QAccessibleEvent(";
1880 d.nospace() <<
"child=" << ev.child();
1882 d.nospace() <<
"no object, uniqueId=" << ev.uniqueId();
1884 d <<
" event=" << qAccessibleEventString(ev.type());
1885 if (ev.type() == QAccessible::StateChanged) {
1886 QAccessible::State changed =
static_cast<const QAccessibleStateChangeEvent*
>(&ev)->changedStates();
1887 d <<
"State changed:";
1888 if (changed.disabled)
d <<
"disabled";
1889 if (changed.selected)
d <<
"selected";
1890 if (changed.focusable)
d <<
"focusable";
1891 if (changed.focused)
d <<
"focused";
1892 if (changed.pressed)
d <<
"pressed";
1893 if (changed.checkable)
d <<
"checkable";
1894 if (changed.checked)
d <<
"checked";
1895 if (changed.checkStateMixed)
d <<
"checkStateMixed";
1896 if (changed.readOnly)
d <<
"readOnly";
1897 if (changed.hotTracked)
d <<
"hotTracked";
1898 if (changed.defaultButton)
d <<
"defaultButton";
1899 if (changed.expanded)
d <<
"expanded";
1900 if (changed.collapsed)
d <<
"collapsed";
1901 if (changed.busy)
d <<
"busy";
1902 if (changed.expandable)
d <<
"expandable";
1903 if (changed.marqueed)
d <<
"marqueed";
1904 if (changed.animated)
d <<
"animated";
1905 if (changed.invisible)
d <<
"invisible";
1906 if (changed.offscreen)
d <<
"offscreen";
1907 if (changed.sizeable)
d <<
"sizeable";
1908 if (changed.movable)
d <<
"movable";
1909 if (changed.selfVoicing)
d <<
"selfVoicing";
1910 if (changed.selectable)
d <<
"selectable";
1911 if (changed.linked)
d <<
"linked";
1912 if (changed.traversed)
d <<
"traversed";
1913 if (changed.multiSelectable)
d <<
"multiSelectable";
1914 if (changed.extSelectable)
d <<
"extSelectable";
1915 if (changed.passwordEdit)
d <<
"passwordEdit";
1916 if (changed.hasPopup)
d <<
"hasPopup";
1917 if (changed.modal)
d <<
"modal";
1921 if (changed.active)
d <<
"active";
1922 if (changed.invalid)
d <<
"invalid";
1923 if (changed.editable)
d <<
"editable";
1924 if (changed.multiLine)
d <<
"multiLine";
1925 if (changed.selectableText)
d <<
"selectableText";
1926 if (changed.supportsAutoCompletion)
d <<
"supportsAutoCompletion";
1957QAccessibleTextInterface::~QAccessibleTextInterface()
2028static QString textLineBoundary(
int beforeAtAfter,
const QString &
text,
int offset,
int *startOffset,
int *endOffset)
2030 Q_ASSERT(beforeAtAfter >= -1 && beforeAtAfter <= 1);
2031 Q_ASSERT(*startOffset == -1 && *endOffset == -1);
2036 if (beforeAtAfter == 1) {
2041 }
else if (beforeAtAfter == -1) {
2052 if (*endOffset <= 0 || *endOffset >
length)
2055 return text.
mid(*startOffset, *endOffset - *startOffset);
2075QString QAccessibleTextInterface::textBeforeOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
2076 int *startOffset,
int *endOffset)
const
2083 *startOffset = *endOffset = -1;
2084 if (
txt.isEmpty() || offset <= 0 || offset >
txt.size())
2089 switch (boundaryType) {
2090 case QAccessible::CharBoundary:
2093 case QAccessible::WordBoundary:
2096 case QAccessible::SentenceBoundary:
2099 case QAccessible::LineBoundary:
2100 case QAccessible::ParagraphBoundary:
2102 return textLineBoundary(-1,
txt,
offset, startOffset, endOffset);
2103 case QAccessible::NoBoundary:
2113 boundary.setPosition(
offset);
2118 }
while (boundary.toPreviousBoundary() > 0);
2119 Q_ASSERT(boundary.position() >= 0);
2120 *endOffset = boundary.position();
2122 while (boundary.toPreviousBoundary() > 0) {
2126 Q_ASSERT(boundary.position() >= 0);
2127 *startOffset = boundary.position();
2129 return txt.mid(*startOffset, *endOffset - *startOffset);
2149QString QAccessibleTextInterface::textAfterOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
2150 int *startOffset,
int *endOffset)
const
2157 *startOffset = *endOffset = -1;
2158 if (
txt.isEmpty() || offset < 0 || offset >=
txt.size())
2163 switch (boundaryType) {
2164 case QAccessible::CharBoundary:
2167 case QAccessible::WordBoundary:
2170 case QAccessible::SentenceBoundary:
2173 case QAccessible::LineBoundary:
2174 case QAccessible::ParagraphBoundary:
2176 return textLineBoundary(1,
txt,
offset, startOffset, endOffset);
2177 case QAccessible::NoBoundary:
2187 boundary.setPosition(
offset);
2190 int toNext = boundary.toNextBoundary();
2193 if (toNext < 0 || toNext >=
txt.size())
2197 *startOffset = boundary.position();
2200 int toNext = boundary.toNextBoundary();
2203 if (toNext < 0 || toNext >=
txt.size())
2207 *endOffset = boundary.position();
2209 if ((*startOffset == -1) || (*endOffset == -1) || (*startOffset == *endOffset)) {
2214 return txt.mid(*startOffset, *endOffset - *startOffset);
2234QString QAccessibleTextInterface::textAtOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
2235 int *startOffset,
int *endOffset)
const
2242 *startOffset = *endOffset = -1;
2243 if (
txt.isEmpty() || offset < 0 || offset >
txt.size())
2246 if (
offset ==
txt.size() && boundaryType == QAccessible::CharBoundary)
2251 switch (boundaryType) {
2252 case QAccessible::CharBoundary:
2255 case QAccessible::WordBoundary:
2258 case QAccessible::SentenceBoundary:
2261 case QAccessible::LineBoundary:
2262 case QAccessible::ParagraphBoundary:
2264 return textLineBoundary(0,
txt,
offset, startOffset, endOffset);
2265 case QAccessible::NoBoundary:
2267 *endOffset =
txt.size();
2276 boundary.setPosition(
offset);
2281 }
while (boundary.toPreviousBoundary() > 0);
2282 Q_ASSERT(boundary.position() >= 0);
2283 *startOffset = boundary.position();
2285 while (boundary.toNextBoundary() <
txt.size()) {
2290 *endOffset = boundary.position();
2292 return txt.mid(*startOffset, *endOffset - *startOffset);
2345QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
2389QAccessibleValueInterface::~QAccessibleValueInterface()
2452QAccessibleImageInterface::~QAccessibleImageInterface()
2471QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
2539QAccessibleTableInterface::~QAccessibleTableInterface()
2715QAccessibleActionInterface::~QAccessibleActionInterface()
2783struct QAccessibleActionStrings
2785 QAccessibleActionStrings() :
2806 const QString scrollLeftAction;
2807 const QString scrollRightAction;
2809 const QString scrollDownAction;
2810 const QString previousPageAction;
2815 if (actionName == pressAction)
2816 return QAccessibleActionInterface::tr(
"Triggers the action");
2817 else if (actionName == increaseAction)
2818 return QAccessibleActionInterface::tr(
"Increase the value");
2819 else if (actionName == decreaseAction)
2820 return QAccessibleActionInterface::tr(
"Decrease the value");
2821 else if (actionName == showMenuAction)
2822 return QAccessibleActionInterface::tr(
"Shows the menu");
2823 else if (actionName == setFocusAction)
2824 return QAccessibleActionInterface::tr(
"Sets the focus");
2825 else if (actionName == toggleAction)
2826 return QAccessibleActionInterface::tr(
"Toggles the state");
2827 else if (actionName == scrollLeftAction)
2828 return QAccessibleActionInterface::tr(
"Scrolls to the left");
2829 else if (actionName == scrollRightAction)
2830 return QAccessibleActionInterface::tr(
"Scrolls to the right");
2831 else if (actionName == scrollUpAction)
2832 return QAccessibleActionInterface::tr(
"Scrolls up");
2833 else if (actionName == scrollDownAction)
2834 return QAccessibleActionInterface::tr(
"Scrolls down");
2835 else if (actionName == previousPageAction)
2836 return QAccessibleActionInterface::tr(
"Goes back a page");
2837 else if (actionName == nextPageAction)
2838 return QAccessibleActionInterface::tr(
"Goes to the next page");
2847QString QAccessibleActionInterface::localizedActionName(
const QString &actionName)
const
2849 return QAccessibleActionInterface::tr(
qPrintable(actionName));
2852QString QAccessibleActionInterface::localizedActionDescription(
const QString &actionName)
const
2854 return accessibleActionStrings()->localizedDescription(actionName);
2861const QString &QAccessibleActionInterface::pressAction()
2863 return accessibleActionStrings()->pressAction;
2870const QString &QAccessibleActionInterface::increaseAction()
2872 return accessibleActionStrings()->increaseAction;
2879const QString &QAccessibleActionInterface::decreaseAction()
2881 return accessibleActionStrings()->decreaseAction;
2888const QString &QAccessibleActionInterface::showMenuAction()
2890 return accessibleActionStrings()->showMenuAction;
2897const QString &QAccessibleActionInterface::setFocusAction()
2899 return accessibleActionStrings()->setFocusAction;
2906const QString &QAccessibleActionInterface::toggleAction()
2908 return accessibleActionStrings()->toggleAction;
2915QString QAccessibleActionInterface::scrollLeftAction()
2917 return accessibleActionStrings()->scrollLeftAction;
2924QString QAccessibleActionInterface::scrollRightAction()
2926 return accessibleActionStrings()->scrollRightAction;
2933QString QAccessibleActionInterface::scrollUpAction()
2935 return accessibleActionStrings()->scrollUpAction;
2942QString QAccessibleActionInterface::scrollDownAction()
2944 return accessibleActionStrings()->scrollDownAction;
2951QString QAccessibleActionInterface::previousPageAction()
2953 return accessibleActionStrings()->previousPageAction;
2960QString QAccessibleActionInterface::nextPageAction()
2962 return accessibleActionStrings()->nextPageAction;
2986QAccessibleSelectionInterface::~QAccessibleSelectionInterface()
3015QAccessibleInterface* QAccessibleSelectionInterface::selectedItem(
int selectionIndex)
const
3018 if (selectionIndex < 0 || selectionIndex >
items.
length() -1) {
3019 qCWarning(lcAccessibilityCore) <<
"Selection index" << selectionIndex <<
"out of range.";
3023 return items.
at(selectionIndex);
3032bool QAccessibleSelectionInterface::isSelected(QAccessibleInterface *childItem)
const
3034 return selectedItems().contains(childItem);
3074QString qAccessibleLocalizedActionDescription(
const QString &actionName)
3076 return accessibleActionStrings()->localizedDescription(actionName);
3112QAccessibleHyperlinkInterface::~QAccessibleHyperlinkInterface()
3121#include "moc_qaccessible_base.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
static QPlatformIntegration * platformIntegration()
qsizetype length() const noexcept
const_reference at(qsizetype i) const noexcept
static QObjectPrivate * get(QObject *o)
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
BoundaryType
\value Grapheme Finds a grapheme which is the smallest boundary.
\reentrant \inmodule QtGui
bool movePosition(MoveOperation op, MoveMode=MoveAnchor, int n=1)
Moves the cursor by performing the given operation n times, using the specified mode,...
bool isNull() const
Returns true if the cursor is null; otherwise returns false.
int position() const
Returns the absolute position of the cursor within the document.
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & dec(QTextStream &stream)
Calls QTextStream::setIntegerBase(10) on stream and returns stream.
std::pair< T1, T2 > QPair
void qAddPostRoutine(QtCleanUpFunction p)
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLuint GLintptr offset
#define qPrintable(string)
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
#define QT_TRANSLATE_NOOP(scope, x)
QItemEditorFactory * factory