a11y: Report QWidget locale

Implement support for QAccessible::Attribute::Locale
(newly introduced in a previous commit) for QWidget
by introducing QAccessibleWidgetV2 which subclasses
QAccessibleWidget and implements the
QAccessibleAttributesInterface to report the QWidget::locale
property for QAccessible::Attribute::Locale.
(Leave QAccessibleWidget unchanged for ABI compatibility.)

Switch QAccessibleWidget subclasses to subclass the
newly introduced QAccessibleWidgetV2.

Add a corresponding unit test.

Task-number: QTBUG-137144
Change-Id: I61385b17ee1272801ad769da5a807ca4e068cfb2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Michael Weghorn 2025-05-27 11:31:27 +02:00 committed by Volker Hilsheimer
parent e9e025a085
commit bb2121551c
15 changed files with 202 additions and 105 deletions

View File

@ -172,7 +172,7 @@ private:
Constructs a QAccessibleTabBar object for \a w.
*/
QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
: QAccessibleWidget(w, QAccessible::PageTabList)
: QAccessibleWidgetV2(w, QAccessible::PageTabList)
{
Q_ASSERT(tabBar());
}
@ -188,7 +188,7 @@ void *QAccessibleTabBar::interface_cast(QAccessible::InterfaceType t)
if (t == QAccessible::SelectionInterface) {
return static_cast<QAccessibleSelectionInterface*>(this);
}
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
/*! Returns the QTabBar. */
@ -337,7 +337,7 @@ bool QAccessibleTabBar::clear()
Constructs a QAccessibleComboBox object for \a w.
*/
QAccessibleComboBox::QAccessibleComboBox(QWidget *w)
: QAccessibleWidget(w, QAccessible::ComboBox)
: QAccessibleWidgetV2(w, QAccessible::ComboBox)
{
Q_ASSERT(comboBox());
}
@ -412,7 +412,7 @@ QString QAccessibleComboBox::text(QAccessible::Text t) const
switch (t) {
case QAccessible::Name:
#ifndef Q_OS_UNIX // on Linux we use relations for this, name is text (fall through to Value)
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
break;
#endif
case QAccessible::Value:
@ -430,14 +430,14 @@ QString QAccessibleComboBox::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
}
return str;
}
QAccessible::State QAccessibleComboBox::state() const
{
QAccessible::State s = QAccessibleWidget::state();
QAccessible::State s = QAccessibleWidgetV2::state();
if (QComboBox *cBox = comboBox()) {
s.expandable = true;
@ -497,7 +497,7 @@ QStringList QAccessibleComboBox::keyBindingsForAction(const QString &/*actionNam
#if QT_CONFIG(scrollarea)
// ======================= QAccessibleAbstractScrollArea =======================
QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Client)
: QAccessibleWidgetV2(widget, QAccessible::Client)
{
Q_ASSERT(qobject_cast<QAbstractScrollArea *>(widget));
}
@ -521,7 +521,7 @@ int QAccessibleAbstractScrollArea::indexOfChild(const QAccessibleInterface *chil
bool QAccessibleAbstractScrollArea::isValid() const
{
return (QAccessibleWidget::isValid() && abstractScrollArea() && abstractScrollArea()->viewport());
return (QAccessibleWidgetV2::isValid() && abstractScrollArea() && abstractScrollArea()->viewport());
}
QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(int x, int y) const

View File

@ -35,7 +35,7 @@ class QAbstractScrollArea;
class QScrollArea;
#if QT_CONFIG(scrollarea)
class QAccessibleAbstractScrollArea : public QAccessibleWidget
class QAccessibleAbstractScrollArea : public QAccessibleWidgetV2
{
public:
explicit QAccessibleAbstractScrollArea(QWidget *widget);
@ -70,7 +70,7 @@ public:
#endif // QT_CONFIG(scrollarea)
#if QT_CONFIG(tabbar)
class QAccessibleTabBar : public QAccessibleWidget, public QAccessibleSelectionInterface
class QAccessibleTabBar : public QAccessibleWidgetV2, public QAccessibleSelectionInterface
{
public:
explicit QAccessibleTabBar(QWidget *w);
@ -102,7 +102,7 @@ protected:
#endif // QT_CONFIG(tabbar)
#if QT_CONFIG(combobox)
class QAccessibleComboBox : public QAccessibleWidget
class QAccessibleComboBox : public QAccessibleWidgetV2
{
public:
explicit QAccessibleComboBox(QWidget *w);

View File

@ -32,7 +32,7 @@ QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
}
QAccessibleMenu::QAccessibleMenu(QWidget *w)
: QAccessibleWidget(w)
: QAccessibleWidgetV2(w)
{
Q_ASSERT(menu());
}
@ -57,7 +57,7 @@ QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const
QString QAccessibleMenu::text(QAccessible::Text t) const
{
QString tx = QAccessibleWidget::text(t);
QString tx = QAccessibleWidgetV2::text(t);
if (!tx.isEmpty())
return tx;
@ -97,7 +97,7 @@ QAccessibleInterface *QAccessibleMenu::parent() const
}
}
}
return QAccessibleWidget::parent();
return QAccessibleWidgetV2::parent();
}
int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const
@ -111,7 +111,7 @@ int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const
#if QT_CONFIG(menubar)
QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
: QAccessibleWidget(w, QAccessible::MenuBar)
: QAccessibleWidgetV2(w, QAccessible::MenuBar)
{
Q_ASSERT(menuBar());
}

View File

@ -28,7 +28,7 @@ class QMenu;
class QMenuBar;
class QAction;
class QAccessibleMenu : public QAccessibleWidget
class QAccessibleMenu : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMenu(QWidget *w);
@ -47,7 +47,7 @@ protected:
};
#if QT_CONFIG(menubar)
class QAccessibleMenuBar : public QAccessibleWidget
class QAccessibleMenuBar : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMenuBar(QWidget *w);

View File

@ -481,6 +481,33 @@ void *QAccessibleWidget::interface_cast(QAccessible::InterfaceType t)
return nullptr;
}
// QAccessibleWidgetV2 implementation
QAccessibleWidgetV2::~QAccessibleWidgetV2() = default;
/*! \reimp */
void *QAccessibleWidgetV2::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::AttributesInterface)
return static_cast<QAccessibleAttributesInterface *>(this);
return QAccessibleWidget::interface_cast(t);
}
/*! \reimp */
QList<QAccessible::Attribute> QAccessibleWidgetV2::attributeKeys() const
{
return { QAccessible::Attribute::Locale };
}
/*! \reimp */
QVariant QAccessibleWidgetV2::attributeValue(QAccessible::Attribute key) const
{
if (key == QAccessible::Attribute::Locale)
return QVariant::fromValue(widget()->locale());
return QVariant();
}
QT_END_NAMESPACE
#endif // QT_CONFIG(accessibility)

View File

@ -6,6 +6,7 @@
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtGui/qaccessibleobject.h>
#include <QtCore/qlist.h>
QT_BEGIN_NAMESPACE
@ -14,7 +15,8 @@ QT_BEGIN_NAMESPACE
class QAccessibleWidgetPrivate;
class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject, public QAccessibleActionInterface
class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject,
public QAccessibleActionInterface
{
public:
explicit QAccessibleWidget(QWidget *o, QAccessible::Role r = QAccessible::Client, const QString& name = QString());
@ -57,6 +59,29 @@ private:
Q_DISABLE_COPY(QAccessibleWidget)
};
class Q_WIDGETS_EXPORT QAccessibleWidgetV2 : public QAccessibleWidget,
public QAccessibleAttributesInterface
{
#ifdef Q_OS_INTEGRITY
// force instantiation to avoid error #2045
struct error2045 : QList<QAccessible::Attribute> {};
#endif
public:
explicit QAccessibleWidgetV2(QWidget *object, QAccessible::Role role = QAccessible::Client,
const QString& name = QString())
: QAccessibleWidget(object, role, name)
{}
~QAccessibleWidgetV2() override;
void *interface_cast(QAccessible::InterfaceType t) override;
// QAccessibleAttributesInterface
QList<QAccessible::Attribute> attributeKeys() const override;
QVariant attributeValue(QAccessible::Attribute key) const override;
private:
Q_DISABLE_COPY(QAccessibleWidgetV2)
};
#endif // QT_CONFIG(accessibility)

View File

@ -83,7 +83,7 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
iface = new QAccessibleButton(widget);
#endif
} else if (classname == "QDialog"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Dialog);
iface = new QAccessibleWidgetV2(widget, QAccessible::Dialog);
#if QT_CONFIG(messagebox)
} else if (classname == "QMessageBox"_L1) {
iface = new QAccessibleMessageBox(widget);
@ -105,7 +105,7 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
iface = new QAccessibleProgressBar(widget);
#endif
} else if (classname == "QToolBar"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::ToolBar, widget->windowTitle());
iface = new QAccessibleWidgetV2(widget, QAccessible::ToolBar, widget->windowTitle());
#if QT_CONFIG(menubar)
} else if (classname == "QMenuBar"_L1) {
iface = new QAccessibleMenuBar(widget);
@ -131,12 +131,12 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
iface = new QAccessibleTabBar(widget);
#endif
} else if (classname == "QSizeGrip"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Grip);
iface = new QAccessibleWidgetV2(widget, QAccessible::Grip);
#if QT_CONFIG(splitter)
} else if (classname == "QSplitter"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Splitter);
iface = new QAccessibleWidgetV2(widget, QAccessible::Splitter);
} else if (classname == "QSplitterHandle"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Grip);
iface = new QAccessibleWidgetV2(widget, QAccessible::Grip);
#endif
#if QT_CONFIG(textedit) && !defined(QT_NO_CURSOR)
} else if (classname == "QTextEdit"_L1) {
@ -147,7 +147,7 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
} else if (classname == "QTipLabel"_L1) {
iface = new QAccessibleDisplay(widget, QAccessible::ToolTip);
} else if (classname == "QFrame"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Border);
iface = new QAccessibleWidgetV2(widget, QAccessible::Border);
#if QT_CONFIG(stackedwidget)
} else if (classname == "QStackedWidget"_L1) {
iface = new QAccessibleStackedWidget(widget);
@ -172,7 +172,7 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
#endif
#if QT_CONFIG(rubberband)
} else if (classname == "QRubberBand"_L1) {
iface = new QAccessibleWidget(widget, QAccessible::Border);
iface = new QAccessibleWidgetV2(widget, QAccessible::Border);
#endif
#if QT_CONFIG(textbrowser) && !defined(QT_NO_CURSOR)
} else if (classname == "QTextBrowser"_L1) {
@ -194,7 +194,7 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
#endif
} else if (classname == "QWidget"_L1) {
iface = new QAccessibleWidget(widget);
iface = new QAccessibleWidgetV2(widget);
} else if (classname == "QWindowContainer"_L1) {
iface = new QAccessibleWindowContainer(widget);
}

View File

@ -108,13 +108,13 @@ QString QAccessiblePlainTextEdit::text(QAccessible::Text t) const
if (t == QAccessible::Value)
return plainTextEdit()->toPlainText();
return QAccessibleWidget::text(t);
return QAccessibleWidgetV2::text(t);
}
void QAccessiblePlainTextEdit::setText(QAccessible::Text t, const QString &text)
{
if (t != QAccessible::Value) {
QAccessibleWidget::setText(t, text);
QAccessibleWidgetV2::setText(t, text);
return;
}
if (plainTextEdit()->isReadOnly())
@ -139,7 +139,7 @@ void *QAccessiblePlainTextEdit::interface_cast(QAccessible::InterfaceType t)
return static_cast<QAccessibleTextInterface*>(this);
else if (t == QAccessible::EditableTextInterface)
return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
QPoint QAccessiblePlainTextEdit::scrollBarPosition() const
@ -234,13 +234,13 @@ QString QAccessibleTextEdit::text(QAccessible::Text t) const
if (t == QAccessible::Value)
return textEdit()->toPlainText();
return QAccessibleWidget::text(t);
return QAccessibleWidgetV2::text(t);
}
void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text)
{
if (t != QAccessible::Value) {
QAccessibleWidget::setText(t, text);
QAccessibleWidgetV2::setText(t, text);
return;
}
if (textEdit()->isReadOnly())
@ -265,7 +265,7 @@ void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t)
return static_cast<QAccessibleTextInterface*>(this);
else if (t == QAccessible::EditableTextInterface)
return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
@ -292,7 +292,7 @@ void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
#if QT_CONFIG(stackedwidget)
// ======================= QAccessibleStackedWidget ======================
QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::LayeredPane)
: QAccessibleWidgetV2(widget, QAccessible::LayeredPane)
{
Q_ASSERT(qobject_cast<QStackedWidget *>(widget));
}
@ -340,7 +340,7 @@ QStackedWidget *QAccessibleStackedWidget::stackedWidget() const
#if QT_CONFIG(toolbox)
// ======================= QAccessibleToolBox ======================
QAccessibleToolBox::QAccessibleToolBox(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::LayeredPane)
: QAccessibleWidgetV2(widget, QAccessible::LayeredPane)
{
Q_ASSERT(qobject_cast<QToolBox *>(widget));
}
@ -354,7 +354,7 @@ QToolBox * QAccessibleToolBox::toolBox() const
// ======================= QAccessibleMdiArea ======================
#if QT_CONFIG(mdiarea)
QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::LayeredPane)
: QAccessibleWidgetV2(widget, QAccessible::LayeredPane)
{
Q_ASSERT(qobject_cast<QMdiArea *>(widget));
}
@ -391,7 +391,7 @@ QMdiArea *QAccessibleMdiArea::mdiArea() const
// ======================= QAccessibleMdiSubWindow ======================
QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window)
: QAccessibleWidgetV2(widget, QAccessible::Window)
{
Q_ASSERT(qobject_cast<QMdiSubWindow *>(widget));
}
@ -403,7 +403,7 @@ QString QAccessibleMdiSubWindow::text(QAccessible::Text textType) const
title.remove("[*]"_L1);
return title;
}
return QAccessibleWidget::text(textType);
return QAccessibleWidgetV2::text(textType);
}
void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString &text)
@ -411,7 +411,7 @@ void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString
if (textType == QAccessible::Name)
mdiSubWindow()->setWindowTitle(text);
else
QAccessibleWidget::setText(textType, text);
QAccessibleWidgetV2::setText(textType, text);
}
QAccessible::State QAccessibleMdiSubWindow::state() const
@ -463,7 +463,7 @@ QRect QAccessibleMdiSubWindow::rect() const
if (mdiSubWindow()->isHidden())
return QRect();
if (!mdiSubWindow()->parent())
return QAccessibleWidget::rect();
return QAccessibleWidgetV2::rect();
const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0));
return QRect(pos, mdiSubWindow()->size());
}
@ -477,7 +477,7 @@ QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const
#if QT_CONFIG(dialogbuttonbox)
// ======================= QAccessibleDialogButtonBox ======================
QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Grouping)
: QAccessibleWidgetV2(widget, QAccessible::Grouping)
{
Q_ASSERT(qobject_cast<QDialogButtonBox*>(widget));
}
@ -500,7 +500,7 @@ QAccessible::Role QAccessibleTextBrowser::role() const
#if QT_CONFIG(calendarwidget)
// ===================== QAccessibleCalendarWidget ========================
QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Table)
: QAccessibleWidgetV2(widget, QAccessible::Table)
{
Q_ASSERT(qobject_cast<QCalendarWidget *>(widget));
}
@ -563,7 +563,7 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const
// If there is a custom title bar widget, that one becomes child 1, after the content 0
// (in that case the buttons are ignored)
QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window)
: QAccessibleWidgetV2(widget, QAccessible::Window)
{
}
@ -639,15 +639,15 @@ QString QAccessibleDockWidget::text(QAccessible::Text t) const
#ifndef QT_NO_CURSOR
QAccessibleTextWidget::QAccessibleTextWidget(QWidget *o, QAccessible::Role r, const QString &name):
QAccessibleWidget(o, r, name)
QAccessibleTextWidget::QAccessibleTextWidget(QWidget *o, QAccessible::Role r, const QString &name)
: QAccessibleWidgetV2(o, r, name)
{
}
QAccessible::State QAccessibleTextWidget::state() const
{
QAccessible::State s = QAccessibleWidget::state();
QAccessible::State s = QAccessibleWidgetV2::state();
s.selectableText = true;
s.multiLine = true;
return s;
@ -1071,7 +1071,7 @@ void QAccessibleTextWidget::replaceText(int startOffset, int endOffset, const QS
#if QT_CONFIG(mainwindow)
QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window) { }
: QAccessibleWidgetV2(widget, QAccessible::Window) { }
QAccessibleInterface *QAccessibleMainWindow::child(int index) const
{

View File

@ -41,7 +41,7 @@ class QTextCursor;
class QTextDocument;
#ifndef QT_NO_CURSOR
class QAccessibleTextWidget : public QAccessibleWidget,
class QAccessibleTextWidget : public QAccessibleWidgetV2,
public QAccessibleTextInterface,
public QAccessibleEditableTextInterface
{
@ -83,7 +83,7 @@ public:
void insertText(int offset, const QString &text) override;
void replaceText(int startOffset, int endOffset, const QString &text) override;
using QAccessibleWidget::text;
using QAccessibleWidgetV2::text;
protected:
QTextCursor textCursorForRange(int startOffset, int endOffset) const;
@ -150,7 +150,7 @@ protected:
#endif // QT_CONFIG(textedit)
#endif //QT_NO_CURSOR
class QAccessibleStackedWidget : public QAccessibleWidget
class QAccessibleStackedWidget : public QAccessibleWidgetV2
{
public:
explicit QAccessibleStackedWidget(QWidget *widget);
@ -164,7 +164,7 @@ protected:
QStackedWidget *stackedWidget() const;
};
class QAccessibleToolBox : public QAccessibleWidget
class QAccessibleToolBox : public QAccessibleWidgetV2
{
public:
explicit QAccessibleToolBox(QWidget *widget);
@ -180,7 +180,7 @@ protected:
};
#if QT_CONFIG(mdiarea)
class QAccessibleMdiArea : public QAccessibleWidget
class QAccessibleMdiArea : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMdiArea(QWidget *widget);
@ -193,7 +193,7 @@ protected:
QMdiArea *mdiArea() const;
};
class QAccessibleMdiSubWindow : public QAccessibleWidget
class QAccessibleMdiSubWindow : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMdiSubWindow(QWidget *widget);
@ -212,7 +212,7 @@ protected:
#endif // QT_CONFIG(mdiarea)
#if QT_CONFIG(dialogbuttonbox)
class QAccessibleDialogButtonBox : public QAccessibleWidget
class QAccessibleDialogButtonBox : public QAccessibleWidgetV2
{
public:
explicit QAccessibleDialogButtonBox(QWidget *widget);
@ -230,7 +230,7 @@ public:
#endif // QT_CONFIG(textbrowser) && QT_NO_CURSOR
#if QT_CONFIG(calendarwidget)
class QAccessibleCalendarWidget : public QAccessibleWidget
class QAccessibleCalendarWidget : public QAccessibleWidgetV2
{
public:
explicit QAccessibleCalendarWidget(QWidget *widget);
@ -250,7 +250,7 @@ private:
#endif // QT_CONFIG(calendarwidget)
#if QT_CONFIG(dockwidget)
class QAccessibleDockWidget: public QAccessibleWidget
class QAccessibleDockWidget: public QAccessibleWidgetV2
{
public:
explicit QAccessibleDockWidget(QWidget *widget);
@ -268,7 +268,7 @@ protected:
#endif // QT_CONFIG(dockwidget)
#if QT_CONFIG(mainwindow)
class QAccessibleMainWindow : public QAccessibleWidget
class QAccessibleMainWindow : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMainWindow(QWidget *widget);

View File

@ -35,7 +35,7 @@ using namespace Qt::StringLiterals;
#if QT_CONFIG(spinbox)
QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
: QAccessibleWidget(w, QAccessible::SpinBox), lineEdit(nullptr)
: QAccessibleWidgetV2(w, QAccessible::SpinBox), lineEdit(nullptr)
{
Q_ASSERT(abstractSpinBox());
}
@ -69,7 +69,7 @@ QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const
{
if (t == QAccessible::Value)
return abstractSpinBox()->text();
return QAccessibleWidget::text(t);
return QAccessibleWidgetV2::text(t);
}
void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t)
@ -80,7 +80,7 @@ void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t)
return static_cast<QAccessibleTextInterface*>(this);
if (t == QAccessible::EditableTextInterface)
return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
QVariant QAccessibleAbstractSpinBox::currentValue() const
@ -251,7 +251,7 @@ QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const
{
if (textType == QAccessible::Value)
return doubleSpinBox()->textFromValue(doubleSpinBox()->value());
return QAccessibleWidget::text(textType);
return QAccessibleWidgetV2::text(textType);
}
#endif // QT_CONFIG(spinbox)
@ -326,7 +326,7 @@ QString QAccessibleSlider::text(QAccessible::Text t) const
}
QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r)
: QAccessibleWidget(w, r)
: QAccessibleWidgetV2(w, r)
{
Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
}
@ -335,7 +335,7 @@ void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::ValueInterface)
return static_cast<QAccessibleValueInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
QVariant QAccessibleAbstractSlider::currentValue() const

View File

@ -33,7 +33,7 @@ class QAccessibleLineEdit;
#if QT_CONFIG(spinbox)
class QAccessibleAbstractSpinBox:
public QAccessibleWidget,
public QAccessibleWidgetV2,
public QAccessibleValueInterface,
public QAccessibleTextInterface,
public QAccessibleEditableTextInterface
@ -108,7 +108,7 @@ protected:
#endif // QT_CONFIG(spinbox)
#if QT_CONFIG(slider)
class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface
class QAccessibleAbstractSlider: public QAccessibleWidgetV2, public QAccessibleValueInterface
{
public:
explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider);

View File

@ -82,7 +82,7 @@ QString qt_accHotKey(const QString &text);
Creates a QAccessibleButton object for \a w.
*/
QAccessibleButton::QAccessibleButton(QWidget *w)
: QAccessibleWidget(w)
: QAccessibleWidgetV2(w)
{
Q_ASSERT(button());
@ -125,13 +125,13 @@ QString QAccessibleButton::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
return str;
}
QAccessible::State QAccessibleButton::state() const
{
QAccessible::State state = QAccessibleWidget::state();
QAccessible::State state = QAccessibleWidgetV2::state();
QAbstractButton *b = button();
#if QT_CONFIG(checkbox)
@ -184,7 +184,7 @@ QRect QAccessibleButton::rect() const
return rb->style()->subElementRect(QStyle::SE_RadioButtonClickRect, &opt, rb).translated(wpos);
}
#endif
return QAccessibleWidget::rect();
return QAccessibleWidgetV2::rect();
}
QAccessible::Role QAccessibleButton::role() const
@ -222,7 +222,7 @@ QStringList QAccessibleButton::actionNames() const
break;
}
}
names << QAccessibleWidget::actionNames();
names << QAccessibleWidgetV2::actionNames();
return names;
}
@ -242,7 +242,7 @@ void QAccessibleButton::doAction(const QString &actionName)
} else if (actionName == toggleAction()) {
button()->toggle();
} else {
QAccessibleWidget::doAction(actionName);
QAccessibleWidgetV2::doAction(actionName);
}
}
@ -392,7 +392,7 @@ void QAccessibleToolButton::doAction(const QString &actionName)
\a role is propagated to the QAccessibleWidget constructor.
*/
QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role)
: QAccessibleWidget(w, role)
: QAccessibleWidgetV2(w, role)
{
}
@ -421,12 +421,12 @@ QAccessible::Role QAccessibleDisplay::role() const
#endif
}
#endif
return QAccessibleWidget::role();
return QAccessibleWidgetV2::role();
}
QAccessible::State QAccessibleDisplay::state() const
{
QAccessible::State s = QAccessibleWidget::state();
QAccessible::State s = QAccessibleWidgetV2::state();
s.readOnly = true;
return s;
}
@ -481,7 +481,7 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
return str;
}
@ -490,7 +490,7 @@ QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
{
QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels =
QAccessibleWidget::relations(match);
QAccessibleWidgetV2::relations(match);
# if QT_CONFIG(shortcut) && QT_CONFIG(label)
if (match & QAccessible::Labelled) {
if (QLabel *label = qobject_cast<QLabel*>(object())) {
@ -507,7 +507,7 @@ void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::ImageInterface)
return static_cast<QAccessibleImageInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
/*! \internal */
@ -551,7 +551,7 @@ QPoint QAccessibleDisplay::imagePosition() const
#if QT_CONFIG(groupbox)
QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w)
: QAccessibleWidget(w)
: QAccessibleWidgetV2(w)
{
}
@ -562,7 +562,7 @@ QGroupBox* QAccessibleGroupBox::groupBox() const
QString QAccessibleGroupBox::text(QAccessible::Text t) const
{
QString txt = QAccessibleWidget::text(t);
QString txt = QAccessibleWidgetV2::text(t);
if (txt.isEmpty()) {
switch (t) {
@ -587,7 +587,7 @@ QString QAccessibleGroupBox::text(QAccessible::Text t) const
QAccessible::State QAccessibleGroupBox::state() const
{
QAccessible::State st = QAccessibleWidget::state();
QAccessible::State st = QAccessibleWidgetV2::state();
st.checkable = groupBox()->isCheckable();
st.checked = groupBox()->isChecked();
return st;
@ -602,7 +602,7 @@ QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
{
QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels =
QAccessibleWidget::relations(match);
QAccessibleWidgetV2::relations(match);
if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
const QList<QWidget*> kids = _q_ac_childWidgets(widget());
@ -617,7 +617,7 @@ QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::All
QStringList QAccessibleGroupBox::actionNames() const
{
QStringList actions = QAccessibleWidget::actionNames();
QStringList actions = QAccessibleWidgetV2::actionNames();
if (groupBox()->isCheckable()) {
actions.prepend(QAccessibleActionInterface::toggleAction());
@ -652,7 +652,7 @@ QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
\a name is propagated to the QAccessibleWidget constructor.
*/
QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
: QAccessibleWidget(w, QAccessible::EditableText, name)
: QAccessibleWidgetV2(w, QAccessible::EditableText, name)
{
addControllingSignal("textChanged(const QString&)"_L1);
addControllingSignal("returnPressed()"_L1);
@ -678,7 +678,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
if (str.isEmpty() && t == QAccessible::Description)
str = lineEdit()->placeholderText();
return str;
@ -687,7 +687,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const
void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text)
{
if (t != QAccessible::Value) {
QAccessibleWidget::setText(t, text);
QAccessibleWidgetV2::setText(t, text);
return;
}
@ -704,7 +704,7 @@ void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text)
QAccessible::State QAccessibleLineEdit::state() const
{
QAccessible::State state = QAccessibleWidget::state();
QAccessible::State state = QAccessibleWidgetV2::state();
QLineEdit *l = lineEdit();
state.editable = true;
@ -724,7 +724,7 @@ void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
return static_cast<QAccessibleTextInterface*>(this);
if (t == QAccessible::EditableTextInterface)
return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
return QAccessibleWidgetV2::interface_cast(t);
}
void QAccessibleLineEdit::addSelection(int startOffset, int endOffset)
@ -922,7 +922,7 @@ QProgressBar *QAccessibleProgressBar::progressBar() const
QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w)
: QAccessibleWidget(w)
: QAccessibleWidgetV2(w)
{
}
@ -958,7 +958,7 @@ QWindowContainer *QAccessibleWindowContainer::container() const
Implements QAccessibleWidget for QMessageBox
*/
QAccessibleMessageBox::QAccessibleMessageBox(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::AlertMessage)
: QAccessibleWidgetV2(widget, QAccessible::AlertMessage)
{
Q_ASSERT(qobject_cast<QMessageBox *>(widget));
}
@ -974,7 +974,7 @@ QString QAccessibleMessageBox::text(QAccessible::Text t) const
switch (t) {
case QAccessible::Name:
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
if (str.isEmpty()) // implies no title text is set
str = messageBox()->text();
break;
@ -985,7 +985,7 @@ QString QAccessibleMessageBox::text(QAccessible::Text t) const
str = messageBox()->informativeText();
break;
default:
str = QAccessibleWidget::text(t);
str = QAccessibleWidgetV2::text(t);
break;
}

View File

@ -31,7 +31,7 @@ class QMessageBox;
class QProgressBar;
#if QT_CONFIG(abstractbutton)
class QAccessibleButton : public QAccessibleWidget
class QAccessibleButton : public QAccessibleWidgetV2
{
Q_DECLARE_TR_FUNCTIONS(QAccessibleButton)
public:
@ -74,7 +74,7 @@ protected:
};
#endif // QT_CONFIG(toolbutton)
class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface
class QAccessibleDisplay : public QAccessibleWidgetV2, public QAccessibleImageInterface
{
public:
explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText);
@ -94,7 +94,7 @@ public:
};
#if QT_CONFIG(groupbox)
class QAccessibleGroupBox : public QAccessibleWidget
class QAccessibleGroupBox : public QAccessibleWidgetV2
{
public:
explicit QAccessibleGroupBox(QWidget *w);
@ -117,7 +117,7 @@ private:
#endif
#if QT_CONFIG(lineedit)
class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface
class QAccessibleLineEdit : public QAccessibleWidgetV2, public QAccessibleTextInterface, public QAccessibleEditableTextInterface
{
public:
explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString());
@ -178,7 +178,7 @@ protected:
#endif
class QWindowContainer;
class QAccessibleWindowContainer : public QAccessibleWidget
class QAccessibleWindowContainer : public QAccessibleWidgetV2
{
public:
QAccessibleWindowContainer(QWidget *w);
@ -191,7 +191,7 @@ private:
};
#if QT_CONFIG(messagebox)
class QAccessibleMessageBox : public QAccessibleWidget
class QAccessibleMessageBox : public QAccessibleWidgetV2
{
public:
explicit QAccessibleMessageBox(QWidget *widget);

View File

@ -18,15 +18,15 @@ public:
}
};
class QtTestAccessibleWidgetIface: public QAccessibleWidget
class QtTestAccessibleWidgetIface: public QAccessibleWidgetV2
{
public:
QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {}
QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidgetV2(w) {}
QString text(QAccessible::Text t) const override
{
if (t == QAccessible::Help)
return QString::fromLatin1("Help yourself");
return QAccessibleWidget::text(t);
return QAccessibleWidgetV2::text(t);
}
static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
{
@ -63,7 +63,7 @@ public:
QString text;
};
class CustomTextWidgetIface: public QAccessibleWidget, public QAccessibleTextInterface
class CustomTextWidgetIface: public QAccessibleWidgetV2, public QAccessibleTextInterface
{
public:
static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
@ -72,7 +72,7 @@ public:
return new CustomTextWidgetIface(static_cast<CustomTextWidget*>(o));
return 0;
}
CustomTextWidgetIface(CustomTextWidget *w): QAccessibleWidget(w) {}
CustomTextWidgetIface(CustomTextWidget *w): QAccessibleWidgetV2(w) {}
void *interface_cast(QAccessible::InterfaceType t) override
{
if (t == QAccessible::TextInterface)
@ -85,7 +85,7 @@ public:
{
if (t == QAccessible::Value)
return textWidget()->text;
return QAccessibleWidget::text(t);
return QAccessibleWidgetV2::text(t);
}
QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const override

View File

@ -234,6 +234,8 @@ private slots:
void messageBoxTest_data();
void messageBoxTest();
void widgetLocaleTest();
protected slots:
void onClicked();
private:
@ -4360,7 +4362,7 @@ private:
bool m_focus;
};
class FocusChildTestAccessibleWidget : public QAccessibleWidget
class FocusChildTestAccessibleWidget : public QAccessibleWidgetV2
{
public:
static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
@ -4371,7 +4373,7 @@ public:
}
FocusChildTestAccessibleWidget(QtTestAccessibleWidget *w)
: QAccessibleWidget(w)
: QAccessibleWidgetV2(w)
{
m_children.push_back(new FocusChildTestAccessibleInterface(0, false, this));
m_children.push_back(new FocusChildTestAccessibleInterface(1, true, this));
@ -4380,7 +4382,7 @@ public:
QAccessible::State state() const override
{
QAccessible::State s = QAccessibleWidget::state();
QAccessible::State s = QAccessibleWidgetV2::state();
s.focused = false;
return s;
}
@ -4734,5 +4736,48 @@ void tst_QAccessibility::messageBoxTest()
QTestAccessibility::clearEvents();
}
void tst_QAccessibility::widgetLocaleTest()
{
QMainWindow mainWindow;
QWidget w(&mainWindow);
QHBoxLayout *box = new QHBoxLayout(&w);
QLabel *label = new QLabel("Hello world");
box->addWidget(label);
// "你好世界" is "Hello world" in Chinese
QLabel *chineseLabel = new QLabel(QString::fromUtf16(u"你好世界"));
const QLocale chinese(QLocale::Chinese, QLocale::China);
chineseLabel->setLocale(chinese);
box->addWidget(chineseLabel);
mainWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
// verify that locale is the default locale if none was set explicitly
QAccessibleInterface *labelAcc = QAccessible::queryAccessibleInterface(label);
QVERIFY(labelAcc);
QVERIFY(labelAcc->attributesInterface());
QVERIFY(labelAcc->attributesInterface()->attributeKeys().contains(
QAccessible::Attribute::Locale));
const QVariant localeVariant =
labelAcc->attributesInterface()->attributeValue(QAccessible::Attribute::Locale);
QVERIFY(localeVariant.isValid() && localeVariant.canConvert<QLocale>());
QCOMPARE(localeVariant.toLocale(), QLocale());
// verify that locale matches the one explicitly set for the widget
QAccessibleInterface *chineseLabelAcc = QAccessible::queryAccessibleInterface(chineseLabel);
QVERIFY(chineseLabelAcc);
QVERIFY(chineseLabelAcc->attributesInterface());
QVERIFY(chineseLabelAcc->attributesInterface()->attributeKeys().contains(
QAccessible::Attribute::Locale));
const QVariant chineseLocaleVariant =
chineseLabelAcc->attributesInterface()->attributeValue(QAccessible::Attribute::Locale);
QVERIFY(chineseLocaleVariant.isValid() && chineseLocaleVariant.canConvert<QLocale>());
QCOMPARE(chineseLocaleVariant.toLocale(), chinese);
QTestAccessibility::clearEvents();
}
QTEST_MAIN(tst_QAccessibility)
#include "tst_qaccessibility.moc"