summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/accessible/accessible.pri21
-rw-r--r--src/widgets/accessible/complexwidgets.cpp469
-rw-r--r--src/widgets/accessible/complexwidgets.h145
-rw-r--r--src/widgets/accessible/itemviews.cpp1220
-rw-r--r--src/widgets/accessible/itemviews.h292
-rw-r--r--src/widgets/accessible/qaccessiblemenu.cpp377
-rw-r--r--src/widgets/accessible/qaccessiblemenu.h131
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp4
-rw-r--r--src/widgets/accessible/qaccessiblewidgetfactory.cpp241
-rw-r--r--src/widgets/accessible/qaccessiblewidgetfactory_p.h53
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp1021
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.h314
-rw-r--r--src/widgets/accessible/rangecontrols.cpp316
-rw-r--r--src/widgets/accessible/rangecontrols.h160
-rw-r--r--src/widgets/accessible/simplewidgets.cpp904
-rw-r--r--src/widgets/accessible/simplewidgets.h216
-rw-r--r--src/widgets/accessible/widgets.pro27
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp8
-rw-r--r--src/widgets/dialogs/qwizard.cpp2
-rw-r--r--src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc5
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc20
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp43
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.h3
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h15
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp88
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.h5
-rw-r--r--src/widgets/graphicsview/qgraphicsscene_p.h2
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp24
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.cpp58
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.h6
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex.cpp3
-rw-r--r--src/widgets/graphicsview/qgraphicsscenelinearindex_p.h45
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp8
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp2
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp6
-rw-r--r--src/widgets/itemviews/qtableview.cpp9
-rw-r--r--src/widgets/kernel/kernel.pri7
-rw-r--r--src/widgets/kernel/qapplication.cpp435
-rw-r--r--src/widgets/kernel/qapplication.h1
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp493
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp142
-rw-r--r--src/widgets/kernel/qdesktopwidget_p.h (renamed from src/widgets/kernel/qdesktopwidget_qpa_p.h)4
-rw-r--r--src/widgets/kernel/qdesktopwidget_qpa.cpp193
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp2
-rw-r--r--src/widgets/kernel/qshortcut.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp1079
-rw-r--r--src/widgets/kernel/qwidget.h1
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp1126
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp4
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h (renamed from src/widgets/kernel/qwidgetwindow_qpa_p.h)6
-rw-r--r--src/widgets/statemachine/qguistatemachine.cpp2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp3
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm65
-rw-r--r--src/widgets/styles/qstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.h1
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp21
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp8
-rw-r--r--src/widgets/util/qflickgesture.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp68
-rw-r--r--src/widgets/util/qsystemtrayicon_p.h9
-rw-r--r--src/widgets/util/qsystemtrayicon_qpa.cpp51
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp40
-rw-r--r--src/widgets/widgets.pro3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp2
-rw-r--r--src/widgets/widgets/qcheckbox.h1
-rw-r--r--src/widgets/widgets/qlineedit.cpp3
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp1
-rw-r--r--src/widgets/widgets/qmainwindow.h7
-rw-r--r--src/widgets/widgets/qmdiarea.cpp75
-rw-r--r--src/widgets/widgets/qmdiarea_p.h22
-rw-r--r--src/widgets/widgets/qmenu.cpp4
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp2
-rw-r--r--src/widgets/widgets/qradiobutton.h1
-rw-r--r--src/widgets/widgets/qtextedit.cpp2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp6
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h5
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp4
80 files changed, 8145 insertions, 2031 deletions
diff --git a/src/widgets/accessible/accessible.pri b/src/widgets/accessible/accessible.pri
index 9fb2f18950..bcdfbd639c 100644
--- a/src/widgets/accessible/accessible.pri
+++ b/src/widgets/accessible/accessible.pri
@@ -1,6 +1,23 @@
# Qt accessibility module
contains(QT_CONFIG, accessibility) {
- HEADERS += accessible/qaccessiblewidget.h
- SOURCES += accessible/qaccessiblewidget.cpp
+ HEADERS += \
+ accessible/qaccessiblewidget.h \
+ accessible/qaccessiblewidgetfactory_p.h \
+ accessible/complexwidgets.h \
+ accessible/itemviews.h \
+ accessible/qaccessiblemenu.h \
+ accessible/qaccessiblewidgets.h \
+ accessible/rangecontrols.h \
+ accessible/simplewidgets.h
+
+ SOURCES += \
+ accessible/qaccessiblewidget.cpp \
+ accessible/qaccessiblewidgetfactory.cpp \
+ accessible/complexwidgets.cpp \
+ accessible/itemviews.cpp \
+ accessible/qaccessiblemenu.cpp \
+ accessible/qaccessiblewidgets.cpp \
+ accessible/rangecontrols.cpp \
+ accessible/simplewidgets.cpp
}
diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp
new file mode 100644
index 0000000000..3b7ff2ea26
--- /dev/null
+++ b/src/widgets/accessible/complexwidgets.cpp
@@ -0,0 +1,469 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "complexwidgets.h"
+
+#include <qaccessible.h>
+#include <qapplication.h>
+#include <qabstractbutton.h>
+#include <qevent.h>
+#include <qheaderview.h>
+#include <qtabbar.h>
+#include <qcombobox.h>
+#include <qlistview.h>
+#include <qtableview.h>
+#include <qlineedit.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qtreeview.h>
+#include <private/qtabbar_p.h>
+#include <QAbstractScrollArea>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QDebug>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+QString qt_accStripAmp(const QString &text);
+
+#ifndef QT_NO_TABBAR
+/*!
+ \class QAccessibleTabBar
+ \brief The QAccessibleTabBar class implements the QAccessibleInterface for tab bars.
+ \internal
+
+ \ingroup accessibility
+*/
+
+class QAccessibleTabButton: public QAccessibleInterface, public QAccessibleActionInterface
+{
+public:
+ QAccessibleTabButton(QTabBar *parent, int index)
+ : m_parent(parent), m_index(index)
+ {}
+
+ void *interface_cast(QAccessible::InterfaceType t) {
+ if (t == QAccessible::ActionInterface) {
+ return static_cast<QAccessibleActionInterface*>(this);
+ }
+ return 0;
+ }
+
+ QObject *object() const { return 0; }
+ QAccessible::Role role() const { return QAccessible::PageTab; }
+ QAccessible::State state() const {
+ QAccessibleInterface *parentInterface = parent();
+ QAccessible::State state = parentInterface->state();
+ return state;
+ }
+ QRect rect() const {
+ if (!isValid())
+ return QRect();
+
+ QPoint tp = m_parent->mapToGlobal(QPoint(0,0));
+ QRect rec = m_parent->tabRect(m_index);
+ rec = QRect(tp.x() + rec.x(), tp.y() + rec.y(), rec.width(), rec.height());
+ return rec;
+ }
+
+ bool isValid() const { return true; }// (!m_parent.isNull()) && m_parent->count() > m_index; }
+
+ QAccessibleInterface *childAt(int, int) const { return 0; }
+ int childCount() const { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const { return -1; }
+
+ QString text(QAccessible::Text t) const
+ {
+ if (t == QAccessible::Name)
+ return qt_accStripAmp(m_parent->tabText(m_index));
+ else if (t == QAccessible::Description)
+ return m_parent->tabToolTip(m_index);
+ else if (t == QAccessible::Help)
+ return m_parent->tabWhatsThis(m_index);
+ return QString();
+ }
+
+ void setText(QAccessible::Text, const QString &) {}
+
+ QAccessibleInterface *parent() const {
+ return QAccessible::queryAccessibleInterface(m_parent);
+ }
+ QAccessibleInterface *child(int) const { return 0; }
+ // action interface
+ QStringList actionNames() const
+ {
+ return QStringList(pressAction());
+ }
+
+ void doAction(const QString &actionName)
+ {
+ if (actionName == pressAction())
+ m_parent->setCurrentIndex(m_index);
+ }
+
+ QStringList keyBindingsForAction(const QString &) const
+ {
+ return QStringList();
+ }
+
+ int index() const { return m_index; }
+
+private:
+ QPointer<QTabBar> m_parent;
+ int m_index;
+
+};
+
+/*!
+ Constructs a QAccessibleTabBar object for \a w.
+*/
+QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
+: QAccessibleWidget(w, QAccessible::PageTabList)
+{
+ Q_ASSERT(tabBar());
+}
+
+QAccessibleTabBar::~QAccessibleTabBar()
+{
+ foreach (QAccessible::Id id, m_childInterfaces.values())
+ QAccessible::deleteAccessibleInterface(id);
+}
+
+/*! Returns the QTabBar. */
+QTabBar *QAccessibleTabBar::tabBar() const
+{
+ return qobject_cast<QTabBar*>(object());
+}
+
+QAccessibleInterface* QAccessibleTabBar::child(int index) const
+{
+ if (QAccessible::Id id = m_childInterfaces.value(index))
+ return QAccessible::accessibleInterface(id);
+
+ // first the tabs, then 2 buttons
+ if (index < tabBar()->count()) {
+ QAccessibleTabButton *button = new QAccessibleTabButton(tabBar(), index);
+ QAccessible::registerAccessibleInterface(button);
+ m_childInterfaces.insert(index, QAccessible::uniqueId(button));
+ return button;
+ } else if (index >= tabBar()->count()) {
+ // left button
+ if (index - tabBar()->count() == 0) {
+ return QAccessible::queryAccessibleInterface(tabBar()->d_func()->leftB);
+ }
+ // right button
+ if (index - tabBar()->count() == 1) {
+ return QAccessible::queryAccessibleInterface(tabBar()->d_func()->rightB);
+ }
+ }
+ return 0;
+}
+
+int QAccessibleTabBar::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (child->object() && child->object() == tabBar()->d_func()->leftB)
+ return tabBar()->count();
+ if (child->object() && child->object() == tabBar()->d_func()->rightB)
+ return tabBar()->count() + 1;
+ if (child->role() == QAccessible::PageTab) {
+ QAccessibleInterface *parent = child->parent();
+ if (parent == this) {
+ const QAccessibleTabButton *tabButton = static_cast<const QAccessibleTabButton *>(child);
+ return tabButton->index();
+ }
+ }
+ return -1;
+}
+
+int QAccessibleTabBar::childCount() const
+{
+ // tabs + scroll buttons
+ return tabBar()->count() + 2;
+}
+
+QString QAccessibleTabBar::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Name) {
+ return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex()));
+ }
+ return QString();
+}
+
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_COMBOBOX
+/*!
+ \class QAccessibleComboBox
+ \brief The QAccessibleComboBox class implements the QAccessibleInterface for editable and read-only combo boxes.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleComboBox object for \a w.
+*/
+QAccessibleComboBox::QAccessibleComboBox(QWidget *w)
+: QAccessibleWidget(w, QAccessible::ComboBox)
+{
+ Q_ASSERT(comboBox());
+}
+
+/*!
+ Returns the combobox.
+*/
+QComboBox *QAccessibleComboBox::comboBox() const
+{
+ return qobject_cast<QComboBox*>(object());
+}
+
+QAccessibleInterface *QAccessibleComboBox::child(int index) const
+{
+ if (index == 0) {
+ QAbstractItemView *view = comboBox()->view();
+ //QWidget *parent = view ? view->parentWidget() : 0;
+ return QAccessible::queryAccessibleInterface(view);
+ } else if (index == 1 && comboBox()->isEditable()) {
+ return QAccessible::queryAccessibleInterface(comboBox()->lineEdit());
+ }
+ return 0;
+}
+
+int QAccessibleComboBox::childCount() const
+{
+ // list and text edit
+ return comboBox()->isEditable() ? 2 : 1;
+}
+
+QAccessibleInterface *QAccessibleComboBox::childAt(int x, int y) const
+{
+ if (comboBox()->isEditable() && comboBox()->lineEdit()->rect().contains(x, y))
+ return child(1);
+ return 0;
+}
+
+int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (comboBox()->view() == child->object())
+ return 0;
+ if (comboBox()->isEditable() && comboBox()->lineEdit() == child->object())
+ return 1;
+ return -1;
+}
+
+/*! \reimp */
+QString QAccessibleComboBox::text(QAccessible::Text t) const
+{
+ QString str;
+
+ 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);
+ break;
+#endif
+ case QAccessible::Value:
+ if (comboBox()->isEditable())
+ str = comboBox()->lineEdit()->text();
+ else
+ str = comboBox()->currentText();
+ break;
+#ifndef QT_NO_SHORTCUT
+ case QAccessible::Accelerator:
+ str = QKeySequence(Qt::Key_Down).toString(QKeySequence::NativeText);
+ break;
+#endif
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidget::text(t);
+ return str;
+}
+
+QStringList QAccessibleComboBox::actionNames() const
+{
+ return QStringList() << showMenuAction() << pressAction();
+}
+
+QString QAccessibleComboBox::localizedActionDescription(const QString &actionName) const
+{
+ if (actionName == showMenuAction() || actionName == pressAction())
+ return QComboBox::tr("Open the combo box selection popup");
+ return QString();
+}
+
+void QAccessibleComboBox::doAction(const QString &actionName)
+{
+ if (actionName == showMenuAction() || actionName == pressAction()) {
+ if (comboBox()->view()->isVisible()) {
+ comboBox()->hidePopup();
+ } else {
+ comboBox()->showPopup();
+ }
+ }
+}
+
+QStringList QAccessibleComboBox::keyBindingsForAction(const QString &/*actionName*/) const
+{
+ return QStringList();
+}
+
+#endif // QT_NO_COMBOBOX
+
+#ifndef QT_NO_SCROLLAREA
+// ======================= QAccessibleAbstractScrollArea =======================
+QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::Client)
+{
+ Q_ASSERT(qobject_cast<QAbstractScrollArea *>(widget));
+}
+
+QAccessibleInterface *QAccessibleAbstractScrollArea::child(int index) const
+{
+ return QAccessible::queryAccessibleInterface(accessibleChildren().at(index));
+}
+
+int QAccessibleAbstractScrollArea::childCount() const
+{
+ return accessibleChildren().count();
+}
+
+int QAccessibleAbstractScrollArea::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object())
+ return -1;
+ return accessibleChildren().indexOf(qobject_cast<QWidget *>(child->object()));
+}
+
+bool QAccessibleAbstractScrollArea::isValid() const
+{
+ return (QAccessibleWidget::isValid() && abstractScrollArea() && abstractScrollArea()->viewport());
+}
+
+QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(int x, int y) const
+{
+ if (!abstractScrollArea()->isVisible())
+ return 0;
+
+ for (int i = 0; i < childCount(); ++i) {
+ QPoint wpos = accessibleChildren().at(i)->mapToGlobal(QPoint(0, 0));
+ QRect rect = QRect(wpos, accessibleChildren().at(i)->size());
+ if (rect.contains(x, y))
+ return child(i);
+ }
+ return 0;
+}
+
+QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea() const
+{
+ return static_cast<QAbstractScrollArea *>(object());
+}
+
+QWidgetList QAccessibleAbstractScrollArea::accessibleChildren() const
+{
+ QWidgetList children;
+
+ // Viewport.
+ QWidget * viewport = abstractScrollArea()->viewport();
+ if (viewport)
+ children.append(viewport);
+
+ // Horizontal scrollBar container.
+ QScrollBar *horizontalScrollBar = abstractScrollArea()->horizontalScrollBar();
+ if (horizontalScrollBar && horizontalScrollBar->isVisible()) {
+ children.append(horizontalScrollBar->parentWidget());
+ }
+
+ // Vertical scrollBar container.
+ QScrollBar *verticalScrollBar = abstractScrollArea()->verticalScrollBar();
+ if (verticalScrollBar && verticalScrollBar->isVisible()) {
+ children.append(verticalScrollBar->parentWidget());
+ }
+
+ // CornerWidget.
+ QWidget *cornerWidget = abstractScrollArea()->cornerWidget();
+ if (cornerWidget && cornerWidget->isVisible())
+ children.append(cornerWidget);
+
+ return children;
+}
+
+QAccessibleAbstractScrollArea::AbstractScrollAreaElement
+QAccessibleAbstractScrollArea::elementType(QWidget *widget) const
+{
+ if (!widget)
+ return Undefined;
+
+ if (widget == abstractScrollArea())
+ return Self;
+ if (widget == abstractScrollArea()->viewport())
+ return Viewport;
+ if (widget->objectName() == QLatin1String("qt_scrollarea_hcontainer"))
+ return HorizontalContainer;
+ if (widget->objectName() == QLatin1String("qt_scrollarea_vcontainer"))
+ return VerticalContainer;
+ if (widget == abstractScrollArea()->cornerWidget())
+ return CornerWidget;
+
+ return Undefined;
+}
+
+bool QAccessibleAbstractScrollArea::isLeftToRight() const
+{
+ return abstractScrollArea()->isLeftToRight();
+}
+
+// ======================= QAccessibleScrollArea ===========================
+QAccessibleScrollArea::QAccessibleScrollArea(QWidget *widget)
+ : QAccessibleAbstractScrollArea(widget)
+{
+ Q_ASSERT(qobject_cast<QScrollArea *>(widget));
+}
+#endif // QT_NO_SCROLLAREA
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/complexwidgets.h b/src/widgets/accessible/complexwidgets.h
new file mode 100644
index 0000000000..00186282f3
--- /dev/null
+++ b/src/widgets/accessible/complexwidgets.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPLEXWIDGETS_H
+#define COMPLEXWIDGETS_H
+
+#include <QtCore/qpointer.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractButton;
+class QHeaderView;
+class QTabBar;
+class QComboBox;
+class QTitleBar;
+class QAbstractScrollArea;
+class QScrollArea;
+
+#ifndef QT_NO_SCROLLAREA
+class QAccessibleAbstractScrollArea : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleAbstractScrollArea(QWidget *widget);
+
+ enum AbstractScrollAreaElement {
+ Self = 0,
+ Viewport,
+ HorizontalContainer,
+ VerticalContainer,
+ CornerWidget,
+ Undefined
+ };
+
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+
+//protected:
+ QAbstractScrollArea *abstractScrollArea() const;
+
+private:
+ QWidgetList accessibleChildren() const;
+ AbstractScrollAreaElement elementType(QWidget *widget) const;
+ bool isLeftToRight() const;
+};
+
+class QAccessibleScrollArea : public QAccessibleAbstractScrollArea
+{
+public:
+ explicit QAccessibleScrollArea(QWidget *widget);
+};
+#endif // QT_NO_SCROLLAREA
+
+#ifndef QT_NO_TABBAR
+class QAccessibleTabBar : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleTabBar(QWidget *w);
+ ~QAccessibleTabBar();
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+
+protected:
+ QTabBar *tabBar() const;
+ mutable QHash<int, QAccessible::Id> m_childInterfaces;
+};
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_COMBOBOX
+class QAccessibleComboBox : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleComboBox(QWidget *w);
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE;
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ // QAccessibleActionInterface
+ QStringList actionNames() const Q_DECL_OVERRIDE;
+ QString localizedActionDescription(const QString &actionName) const Q_DECL_OVERRIDE;
+ void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+ QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE;
+
+protected:
+ QComboBox *comboBox() const;
+};
+#endif // QT_NO_COMBOBOX
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // COMPLEXWIDGETS_H
diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp
new file mode 100644
index 0000000000..36b48cfd05
--- /dev/null
+++ b/src/widgets/accessible/itemviews.cpp
@@ -0,0 +1,1220 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemviews.h"
+
+#include <qheaderview.h>
+#include <qtableview.h>
+#include <qlistview.h>
+#include <qtreeview.h>
+#include <private/qtreewidget_p.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ITEMVIEWS
+/*
+Implementation of the IAccessible2 table2 interface. Much simpler than
+the other table interfaces since there is only the main table and cells:
+
+TABLE/LIST/TREE
+ |- HEADER CELL
+ |- CELL
+ |- CELL
+ ...
+*/
+
+
+QAbstractItemView *QAccessibleTable::view() const
+{
+ return qobject_cast<QAbstractItemView*>(object());
+}
+
+int QAccessibleTable::logicalIndex(const QModelIndex &index) const
+{
+ if (!view()->model() || !index.isValid())
+ return -1;
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+ return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader);
+}
+
+QAccessibleTable::QAccessibleTable(QWidget *w)
+ : QAccessibleObject(w)
+{
+ Q_ASSERT(view());
+
+ if (qobject_cast<const QTableView*>(view())) {
+ m_role = QAccessible::Table;
+ } else if (qobject_cast<const QTreeView*>(view())) {
+ m_role = QAccessible::Tree;
+ } else if (qobject_cast<const QListView*>(view())) {
+ m_role = QAccessible::List;
+ } else {
+ // is this our best guess?
+ m_role = QAccessible::Table;
+ }
+}
+
+bool QAccessibleTable::isValid() const
+{
+ return (view() && !qobject_cast<QWidget*>(view())->d_func()->data.in_destructor);
+}
+
+QAccessibleTable::~QAccessibleTable()
+{
+ Q_FOREACH (QAccessible::Id id, childToId.values())
+ QAccessible::deleteAccessibleInterface(id);
+}
+
+QHeaderView *QAccessibleTable::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view())) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view())) {
+ header = tv->header();
+#endif
+ }
+ return header;
+}
+
+QHeaderView *QAccessibleTable::verticalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view())) {
+ header = tv->verticalHeader();
+#endif
+ }
+ return header;
+}
+
+QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const
+{
+ if (!view()->model())
+ return 0;
+ Q_ASSERT(role() != QAccessible::Tree);
+ QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
+ if (!index.isValid()) {
+ qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view();
+ return 0;
+ }
+ return child(logicalIndex(index));
+}
+
+QAccessibleInterface *QAccessibleTable::caption() const
+{
+ return 0;
+}
+
+QString QAccessibleTable::columnDescription(int column) const
+{
+ if (!view()->model())
+ return QString();
+ return view()->model()->headerData(column, Qt::Horizontal).toString();
+}
+
+int QAccessibleTable::columnCount() const
+{
+ if (!view()->model())
+ return 0;
+ return view()->model()->columnCount();
+}
+
+int QAccessibleTable::rowCount() const
+{
+ if (!view()->model())
+ return 0;
+ return view()->model()->rowCount();
+}
+
+int QAccessibleTable::selectedCellCount() const
+{
+ if (!view()->selectionModel())
+ return 0;
+ return view()->selectionModel()->selectedIndexes().count();
+}
+
+int QAccessibleTable::selectedColumnCount() const
+{
+ if (!view()->selectionModel())
+ return 0;
+ return view()->selectionModel()->selectedColumns().count();
+}
+
+int QAccessibleTable::selectedRowCount() const
+{
+ if (!view()->selectionModel())
+ return 0;
+ return view()->selectionModel()->selectedRows().count();
+}
+
+QString QAccessibleTable::rowDescription(int row) const
+{
+ if (!view()->model())
+ return QString();
+ return view()->model()->headerData(row, Qt::Vertical).toString();
+}
+
+QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const
+{
+ QList<QAccessibleInterface*> cells;
+ if (!view()->selectionModel())
+ return cells;
+ Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes())
+ cells.append(child(logicalIndex(index)));
+ return cells;
+}
+
+QList<int> QAccessibleTable::selectedColumns() const
+{
+ if (!view()->selectionModel())
+ return QList<int>();
+ QList<int> columns;
+ Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedColumns()) {
+ columns.append(index.column());
+ }
+ return columns;
+}
+
+QList<int> QAccessibleTable::selectedRows() const
+{
+ if (!view()->selectionModel())
+ return QList<int>();
+ QList<int> rows;
+ Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedRows()) {
+ rows.append(index.row());
+ }
+ return rows;
+}
+
+QAccessibleInterface *QAccessibleTable::summary() const
+{
+ return 0;
+}
+
+bool QAccessibleTable::isColumnSelected(int column) const
+{
+ if (!view()->selectionModel())
+ return false;
+ return view()->selectionModel()->isColumnSelected(column, QModelIndex());
+}
+
+bool QAccessibleTable::isRowSelected(int row) const
+{
+ if (!view()->selectionModel())
+ return false;
+ return view()->selectionModel()->isRowSelected(row, QModelIndex());
+}
+
+bool QAccessibleTable::selectRow(int row)
+{
+ if (!view()->model() || !view()->selectionModel())
+ return false;
+ QModelIndex index = view()->model()->index(row, 0, view()->rootIndex());
+
+ if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns)
+ return false;
+
+ switch (view()->selectionMode()) {
+ case QAbstractItemView::NoSelection:
+ return false;
+ case QAbstractItemView::SingleSelection:
+ if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 )
+ return false;
+ view()->clearSelection();
+ break;
+ case QAbstractItemView::ContiguousSelection:
+ if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))
+ && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex()))
+ view()->clearSelection();
+ break;
+ default:
+ break;
+ }
+
+ view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ return true;
+}
+
+bool QAccessibleTable::selectColumn(int column)
+{
+ if (!view()->model() || !view()->selectionModel())
+ return false;
+ QModelIndex index = view()->model()->index(0, column, view()->rootIndex());
+
+ if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows)
+ return false;
+
+ switch (view()->selectionMode()) {
+ case QAbstractItemView::NoSelection:
+ return false;
+ case QAbstractItemView::SingleSelection:
+ if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1)
+ return false;
+ case QAbstractItemView::ContiguousSelection:
+ if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex()))
+ && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex()))
+ view()->clearSelection();
+ break;
+ default:
+ break;
+ }
+
+ view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns);
+ return true;
+}
+
+bool QAccessibleTable::unselectRow(int row)
+{
+ if (!view()->model() || !view()->selectionModel())
+ return false;
+
+ QModelIndex index = view()->model()->index(row, 0, view()->rootIndex());
+ if (!index.isValid())
+ return false;
+
+ QItemSelection selection(index, index);
+
+ switch (view()->selectionMode()) {
+ case QAbstractItemView::SingleSelection:
+ //In SingleSelection and ContiguousSelection once an item
+ //is selected, there's no way for the user to unselect all items
+ if (selectedRowCount() == 1)
+ return false;
+ break;
+ case QAbstractItemView::ContiguousSelection:
+ if (selectedRowCount() == 1)
+ return false;
+
+ if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))
+ && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) {
+ //If there are rows selected both up the current row and down the current rown,
+ //the ones which are down the current row will be deselected
+ selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex()));
+ }
+ default:
+ break;
+ }
+
+ view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows);
+ return true;
+}
+
+bool QAccessibleTable::unselectColumn(int column)
+{
+ if (!view()->model() || !view()->selectionModel())
+ return false;
+
+ QModelIndex index = view()->model()->index(0, column, view()->rootIndex());
+ if (!index.isValid())
+ return false;
+
+ QItemSelection selection(index, index);
+
+ switch (view()->selectionMode()) {
+ case QAbstractItemView::SingleSelection:
+ //In SingleSelection and ContiguousSelection once an item
+ //is selected, there's no way for the user to unselect all items
+ if (selectedColumnCount() == 1)
+ return false;
+ break;
+ case QAbstractItemView::ContiguousSelection:
+ if (selectedColumnCount() == 1)
+ return false;
+
+ if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex()))
+ && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) {
+ //If there are columns selected both at the left of the current row and at the right
+ //of the current rown, the ones which are at the right will be deselected
+ selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex()));
+ }
+ default:
+ break;
+ }
+
+ view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns);
+ return true;
+}
+
+QAccessible::Role QAccessibleTable::role() const
+{
+ return m_role;
+}
+
+QAccessible::State QAccessibleTable::state() const
+{
+ return QAccessible::State();
+}
+
+QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const
+{
+ QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0));
+ QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset);
+ // FIXME: if indexPosition < 0 in one coordinate, return header
+
+ QModelIndex index = view()->indexAt(indexPosition);
+ if (index.isValid()) {
+ return child(logicalIndex(index));
+ }
+ return 0;
+}
+
+int QAccessibleTable::childCount() const
+{
+ if (!view()->model())
+ return 0;
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+ return (view()->model()->rowCount()+hHeader) * (view()->model()->columnCount()+vHeader);
+}
+
+int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const
+{
+ if (!view()->model())
+ return -1;
+ QAccessibleInterface *parent = iface->parent();
+ if (parent->object() != view())
+ return -1;
+
+ Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class
+ if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
+ const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface);
+ return logicalIndex(cell->m_index);
+ } else if (iface->role() == QAccessible::ColumnHeader){
+ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);
+ return cell->index + (verticalHeader() ? 1 : 0);
+ } else if (iface->role() == QAccessible::RowHeader){
+ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);
+ return (cell->index + 1) * (view()->model()->columnCount() + 1);
+ } else if (iface->role() == QAccessible::Pane) {
+ return 0; // corner button
+ } else {
+ qWarning() << "WARNING QAccessibleTable::indexOfChild Fix my children..."
+ << iface->role() << iface->text(QAccessible::Name);
+ }
+ // FIXME: we are in denial of our children. this should stop.
+ return -1;
+}
+
+QString QAccessibleTable::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Description)
+ return view()->accessibleDescription();
+ return view()->accessibleName();
+}
+
+QRect QAccessibleTable::rect() const
+{
+ if (!view()->isVisible())
+ return QRect();
+ QPoint pos = view()->mapToGlobal(QPoint(0, 0));
+ return QRect(pos.x(), pos.y(), view()->width(), view()->height());
+}
+
+QAccessibleInterface *QAccessibleTable::parent() const
+{
+ if (view() && view()->parent()) {
+ if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) {
+ return QAccessible::queryAccessibleInterface(view()->parent()->parent());
+ }
+ return QAccessible::queryAccessibleInterface(view()->parent());
+ }
+ return 0;
+}
+
+QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const
+{
+ if (!view()->model())
+ return 0;
+
+ if (childToId.contains(logicalIndex)) {
+ QAccessible::Id id = childToId.value(logicalIndex);
+ return QAccessible::accessibleInterface(id);
+ }
+
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+
+ int columns = view()->model()->columnCount() + vHeader;
+
+ int row = logicalIndex / columns;
+ int column = logicalIndex % columns;
+
+ QAccessibleInterface *iface = 0;
+
+ if (vHeader) {
+ if (column == 0) {
+ if (hHeader && row == 0) {
+ iface = new QAccessibleTableCornerButton(view());
+ } else {
+ iface = new QAccessibleTableHeaderCell(view(), row - hHeader, Qt::Vertical);
+ }
+ }
+ --column;
+ }
+ if (!iface && hHeader) {
+ if (row == 0) {
+ iface = new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal);
+ }
+ --row;
+ }
+
+ if (!iface) {
+ QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
+ if (!index.isValid()) {
+ qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column;
+ return 0;
+ }
+ iface = new QAccessibleTableCell(view(), index, cellRole());
+ }
+
+ QAccessible::registerAccessibleInterface(iface);
+ childToId.insert(logicalIndex, QAccessible::uniqueId(iface));
+ return iface;
+}
+
+void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::TableInterface)
+ return static_cast<QAccessibleTableInterface*>(this);
+ return 0;
+}
+
+void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)
+{
+ // if there is no cache yet, we don't update anything
+ if (childToId.isEmpty())
+ return;
+
+ switch (event->modelChangeType()) {
+ case QAccessibleTableModelChangeEvent::ModelReset:
+ Q_FOREACH (QAccessible::Id id, childToId.values())
+ QAccessible::deleteAccessibleInterface(id);
+ childToId.clear();
+ break;
+
+ // rows are inserted: move every row after that
+ case QAccessibleTableModelChangeEvent::RowsInserted:
+ case QAccessibleTableModelChangeEvent::ColumnsInserted: {
+ int newRows = event->lastRow() - event->firstRow() + 1;
+ int newColumns = event->lastColumn() - event->firstColumn() + 1;
+
+ ChildCache newCache;
+ ChildCache::ConstIterator iter = childToId.constBegin();
+
+ while (iter != childToId.constEnd()) {
+ QAccessible::Id id = iter.value();
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
+ Q_ASSERT(iface);
+ if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
+ Q_ASSERT(iface->tableCellInterface());
+ QAccessibleTableCell *cell = static_cast<QAccessibleTableCell*>(iface->tableCellInterface());
+ if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted
+ && cell->m_index.row() >= event->firstRow()) {
+ int newRow = cell->m_index.row() + newRows;
+ cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column());
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted
+ && cell->m_index.column() >= event->firstColumn()) {
+ int newColumn = cell->m_index.column() + newColumns;
+ cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted
+ && iface->role() == QAccessible::RowHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index >= event->firstRow()) {
+ cell->index += newRows;
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted
+ && iface->role() == QAccessible::ColumnHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index >= event->firstColumn()) {
+ cell->index += newColumns;
+ }
+ }
+ if (indexOfChild(iface) >= 0) {
+ newCache.insert(indexOfChild(iface), id);
+ } else {
+ // ### This should really not happen,
+ // but it might if the view has a root index set.
+ // This needs to be fixed.
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ ++iter;
+ }
+ childToId = newCache;
+ break;
+ }
+
+ case QAccessibleTableModelChangeEvent::ColumnsRemoved:
+ case QAccessibleTableModelChangeEvent::RowsRemoved: {
+ int deletedColumns = event->lastColumn() - event->firstColumn() + 1;
+ int deletedRows = event->lastRow() - event->firstRow() + 1;
+ ChildCache newCache;
+ ChildCache::ConstIterator iter = childToId.constBegin();
+ while (iter != childToId.constEnd()) {
+ QAccessible::Id id = iter.value();
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
+ Q_ASSERT(iface);
+ if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
+ Q_ASSERT(iface->tableCellInterface());
+ QAccessibleTableCell *cell = static_cast<QAccessibleTableCell*>(iface->tableCellInterface());
+ if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved) {
+ if (cell->m_index.row() < event->firstRow()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->m_index.row() > event->lastRow()) {
+ int newRow = cell->m_index.row() - deletedRows;
+ cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column());
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved) {
+ if (cell->m_index.column() < event->firstColumn()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->m_index.column() > event->lastColumn()) {
+ int newColumn = cell->m_index.column() - deletedColumns;
+ cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn);
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved
+ && iface->role() == QAccessible::RowHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index < event->firstRow()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->index > event->lastRow()) {
+ cell->index -= deletedRows;
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved
+ && iface->role() == QAccessible::ColumnHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index < event->firstColumn()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->index > event->lastColumn()) {
+ cell->index -= deletedColumns;
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ }
+ ++iter;
+ }
+ childToId = newCache;
+ break;
+ }
+
+ case QAccessibleTableModelChangeEvent::DataChanged:
+ // nothing to do in this case
+ break;
+ }
+}
+
+// TREE VIEW
+
+QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const
+{
+ if (!isValid() || !view()->model())
+ return QModelIndex();
+
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ if ((row < 0) || (column < 0) || (treeView->d_func()->viewItems.count() <= row)) {
+ qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView;
+ return QModelIndex();
+ }
+ QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index;
+
+ if (modelIndex.isValid() && column > 0) {
+ modelIndex = view()->model()->index(modelIndex.row(), column, modelIndex.parent());
+ }
+ return modelIndex;
+}
+
+QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const
+{
+ if (!view()->model())
+ return 0;
+ QPoint viewportOffset = view()->viewport()->mapTo(view(), QPoint(0,0));
+ QPoint indexPosition = view()->mapFromGlobal(QPoint(x, y) - viewportOffset);
+
+ QModelIndex index = view()->indexAt(indexPosition);
+ if (!index.isValid())
+ return 0;
+
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0);
+ int column = index.column();
+
+ int i = row * view()->model()->columnCount() + column;
+ return child(i);
+}
+
+int QAccessibleTree::childCount() const
+{
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ Q_ASSERT(treeView);
+ if (!view()->model())
+ return 0;
+
+ int hHeader = horizontalHeader() ? 1 : 0;
+ return (treeView->d_func()->viewItems.count() + hHeader)* view()->model()->columnCount();
+}
+
+
+QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const
+{
+ if (logicalIndex < 0 || !view()->model() || !view()->model()->columnCount())
+ return 0;
+
+ QAccessibleInterface *iface = 0;
+ int index = logicalIndex;
+
+ if (horizontalHeader()) {
+ if (index < view()->model()->columnCount()) {
+ iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal);
+ } else {
+ index -= view()->model()->columnCount();
+ }
+ }
+
+ if (!iface) {
+ int row = index / view()->model()->columnCount();
+ int column = index % view()->model()->columnCount();
+ QModelIndex modelIndex = indexFromLogical(row, column);
+ if (!modelIndex.isValid())
+ return 0;
+ iface = new QAccessibleTableCell(view(), modelIndex, cellRole());
+ }
+ QAccessible::registerAccessibleInterface(iface);
+ // ### FIXME: get interfaces from the cache instead of re-creating them
+ return iface;
+}
+
+int QAccessibleTree::rowCount() const
+{
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ Q_ASSERT(treeView);
+ return treeView->d_func()->viewItems.count();
+}
+
+int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
+{
+ if (!view()->model())
+ return -1;
+ QAccessibleInterface *parent = iface->parent();
+ if (parent->object() != view())
+ return -1;
+
+ if (iface->role() == QAccessible::TreeItem) {
+ const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface);
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ Q_ASSERT(treeView);
+ int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0);
+ int column = cell->m_index.column();
+
+ int index = row * view()->model()->columnCount() + column;
+ return index;
+ } else if (iface->role() == QAccessible::ColumnHeader){
+ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);
+ return cell->index;
+ } else {
+ qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child"
+ << iface->role() << iface->text(QAccessible::Name);
+ }
+ // FIXME: add scrollbars and don't just ignore them
+ return -1;
+}
+
+QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const
+{
+ QModelIndex index = indexFromLogical(row, column);
+ if (!index.isValid()) {
+ qWarning() << "Requested invalid tree cell: " << row << column;
+ return 0;
+ }
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ Q_ASSERT(treeView);
+ int logicalIndex = treeView->d_func()->accessibleTable2Index(index);
+
+ return child(logicalIndex); // FIXME ### new QAccessibleTableCell(view(), index, cellRole());
+}
+
+QString QAccessibleTree::rowDescription(int) const
+{
+ return QString(); // no headers for rows in trees
+}
+
+bool QAccessibleTree::isRowSelected(int row) const
+{
+ if (!view()->selectionModel())
+ return false;
+ QModelIndex index = indexFromLogical(row);
+ return view()->selectionModel()->isRowSelected(index.row(), index.parent());
+}
+
+bool QAccessibleTree::selectRow(int row)
+{
+ if (!view()->selectionModel())
+ return false;
+ QModelIndex index = indexFromLogical(row);
+
+ if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns)
+ return false;
+
+ switch (view()->selectionMode()) {
+ case QAbstractItemView::NoSelection:
+ return false;
+ case QAbstractItemView::SingleSelection:
+ if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1))
+ return false;
+ view()->clearSelection();
+ break;
+ case QAbstractItemView::ContiguousSelection:
+ if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex()))
+ && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex()))
+ view()->clearSelection();
+ break;
+ default:
+ break;
+ }
+
+ view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ return true;
+}
+
+// TABLE CELL
+
+QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_)
+ : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_)
+{
+ if (!index_.isValid())
+ qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_;
+}
+
+void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::TableCellInterface)
+ return static_cast<QAccessibleTableCellInterface*>(this);
+ if (t == QAccessible::ActionInterface)
+ return static_cast<QAccessibleActionInterface*>(this);
+ return 0;
+}
+
+int QAccessibleTableCell::columnExtent() const { return 1; }
+int QAccessibleTableCell::rowExtent() const { return 1; }
+
+QList<QAccessibleInterface*> QAccessibleTableCell::rowHeaderCells() const
+{
+ QList<QAccessibleInterface*> headerCell;
+ if (verticalHeader()) {
+ // FIXME
+ headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical));
+ }
+ return headerCell;
+}
+
+QList<QAccessibleInterface*> QAccessibleTableCell::columnHeaderCells() const
+{
+ QList<QAccessibleInterface*> headerCell;
+ if (horizontalHeader()) {
+ // FIXME
+ headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal));
+ }
+ return headerCell;
+}
+
+QHeaderView *QAccessibleTableCell::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+
+ return header;
+}
+
+QHeaderView *QAccessibleTableCell::verticalHeader() const
+{
+ QHeaderView *header = 0;
+#ifndef QT_NO_TABLEVIEW
+ if (const QTableView *tv = qobject_cast<const QTableView*>(view))
+ header = tv->verticalHeader();
+#endif
+ return header;
+}
+
+int QAccessibleTableCell::columnIndex() const
+{
+ return m_index.column();
+}
+
+int QAccessibleTableCell::rowIndex() const
+{
+ if (role() == QAccessible::TreeItem) {
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ Q_ASSERT(treeView);
+ int row = treeView->d_func()->viewIndex(m_index);
+ return row;
+ }
+ return m_index.row();
+}
+
+bool QAccessibleTableCell::isSelected() const
+{
+ return view->selectionModel()->isSelected(m_index);
+}
+
+QStringList QAccessibleTableCell::actionNames() const
+{
+ QStringList names;
+ names << toggleAction();
+ return names;
+}
+
+void QAccessibleTableCell::doAction(const QString& actionName)
+{
+ if (actionName == toggleAction()) {
+ if (isSelected())
+ unselectCell();
+ else
+ selectCell();
+ }
+}
+
+QStringList QAccessibleTableCell::keyBindingsForAction(const QString &) const
+{
+ return QStringList();
+}
+
+
+void QAccessibleTableCell::selectCell()
+{
+ QAbstractItemView::SelectionMode selectionMode = view->selectionMode();
+ if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection))
+ return;
+ Q_ASSERT(table());
+ QAccessibleTableInterface *cellTable = table()->tableInterface();
+
+ switch (view->selectionBehavior()) {
+ case QAbstractItemView::SelectItems:
+ break;
+ case QAbstractItemView::SelectColumns:
+ if (cellTable)
+ cellTable->selectColumn(m_index.column());
+ return;
+ case QAbstractItemView::SelectRows:
+ if (cellTable)
+ cellTable->selectRow(m_index.row());
+ return;
+ }
+
+ if (selectionMode == QAbstractItemView::SingleSelection) {
+ view->clearSelection();
+ }
+
+ view->selectionModel()->select(m_index, QItemSelectionModel::Select);
+}
+
+void QAccessibleTableCell::unselectCell()
+{
+
+ QAbstractItemView::SelectionMode selectionMode = view->selectionMode();
+ if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection))
+ return;
+
+ QAccessibleTableInterface *cellTable = table()->tableInterface();
+
+ switch (view->selectionBehavior()) {
+ case QAbstractItemView::SelectItems:
+ break;
+ case QAbstractItemView::SelectColumns:
+ if (cellTable)
+ cellTable->unselectColumn(m_index.column());
+ return;
+ case QAbstractItemView::SelectRows:
+ if (cellTable)
+ cellTable->unselectRow(m_index.row());
+ return;
+ }
+
+ //If the mode is not MultiSelection or ExtendedSelection and only
+ //one cell is selected it cannot be unselected by the user
+ if ((selectionMode != QAbstractItemView::MultiSelection)
+ && (selectionMode != QAbstractItemView::ExtendedSelection)
+ && (view->selectionModel()->selectedIndexes().count() <= 1))
+ return;
+
+ view->selectionModel()->select(m_index, QItemSelectionModel::Deselect);
+}
+
+QAccessibleInterface *QAccessibleTableCell::table() const
+{
+ return QAccessible::queryAccessibleInterface(view);
+}
+
+QAccessible::Role QAccessibleTableCell::role() const
+{
+ return m_role;
+}
+
+QAccessible::State QAccessibleTableCell::state() const
+{
+ QAccessible::State st;
+ QRect globalRect = view->rect();
+ globalRect.translate(view->mapToGlobal(QPoint(0,0)));
+ if (!globalRect.intersects(rect()))
+ st.invisible = true;
+
+ if (view->selectionModel()->isSelected(m_index))
+ st.selected = true;
+ if (view->selectionModel()->currentIndex() == m_index)
+ st.focused = true;
+ if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked)
+ st.checked = true;
+
+ Qt::ItemFlags flags = m_index.flags();
+ if (flags & Qt::ItemIsSelectable) {
+ st.selectable = true;
+ st.focusable = true;
+ if (view->selectionMode() == QAbstractItemView::MultiSelection)
+ st.multiSelectable = true;
+ if (view->selectionMode() == QAbstractItemView::ExtendedSelection)
+ st.extSelectable = true;
+ }
+ if (m_role == QAccessible::TreeItem) {
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ if (treeView->model()->hasChildren(m_index))
+ st.expandable = true;
+ if (treeView->isExpanded(m_index))
+ st.expanded = true;
+ }
+ return st;
+}
+
+
+QRect QAccessibleTableCell::rect() const
+{
+ QRect r;
+ r = view->visualRect(m_index);
+
+ if (!r.isNull()) {
+ r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
+ r.translate(view->mapToGlobal(QPoint(0, 0)));
+ }
+ return r;
+}
+
+QString QAccessibleTableCell::text(QAccessible::Text t) const
+{
+ QAbstractItemModel *model = view->model();
+ QString value;
+ switch (t) {
+ case QAccessible::Name:
+ value = model->data(m_index, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = model->data(m_index, Qt::DisplayRole).toString();
+ break;
+ case QAccessible::Description:
+ value = model->data(m_index, Qt::AccessibleDescriptionRole).toString();
+ break;
+ default:
+ break;
+ }
+ return value;
+}
+
+void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text)
+{
+ if (!(m_index.flags() & Qt::ItemIsEditable))
+ return;
+ view->model()->setData(m_index, text);
+}
+
+bool QAccessibleTableCell::isValid() const
+{
+ return view && view->model() && m_index.isValid();
+}
+
+QAccessibleInterface *QAccessibleTableCell::parent() const
+{
+ return QAccessible::queryAccessibleInterface(view);
+}
+
+QAccessibleInterface *QAccessibleTableCell::child(int) const
+{
+ return 0;
+}
+
+QAccessibleTableHeaderCell::QAccessibleTableHeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_)
+ : view(view_), index(index_), orientation(orientation_)
+{
+ Q_ASSERT(index_ >= 0);
+}
+
+QAccessible::Role QAccessibleTableHeaderCell::role() const
+{
+ if (orientation == Qt::Horizontal)
+ return QAccessible::ColumnHeader;
+ return QAccessible::RowHeader;
+}
+
+QAccessible::State QAccessibleTableHeaderCell::state() const
+{
+ QAccessible::State s;
+ if (QHeaderView *h = headerView()) {
+ s.invisible = !h->testAttribute(Qt::WA_WState_Visible);
+ s.disabled = !h->isEnabled();
+ }
+ return s;
+}
+
+QRect QAccessibleTableHeaderCell::rect() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ if (orientation == Qt::Horizontal) {
+ header = tv->horizontalHeader();
+ } else {
+ header = tv->verticalHeader();
+ }
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+ if (!header)
+ return QRect();
+ QPoint zero = header->mapToGlobal(QPoint(0, 0));
+ int sectionSize = header->sectionSize(index);
+ int sectionPos = header->sectionPosition(index);
+ return orientation == Qt::Horizontal
+ ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height())
+ : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize);
+}
+
+QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const
+{
+ QAbstractItemModel *model = view->model();
+ QString value;
+ switch (t) {
+ case QAccessible::Name:
+ value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = model->headerData(index, orientation, Qt::DisplayRole).toString();
+ break;
+ case QAccessible::Description:
+ value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString();
+ break;
+ default:
+ break;
+ }
+ return value;
+}
+
+void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &)
+{
+ return;
+}
+
+bool QAccessibleTableHeaderCell::isValid() const
+{
+ return view && view->model() && (index >= 0)
+ && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount()));
+}
+
+QAccessibleInterface *QAccessibleTableHeaderCell::parent() const
+{
+ return QAccessible::queryAccessibleInterface(view);
+}
+
+QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const
+{
+ return 0;
+}
+
+QHeaderView *QAccessibleTableHeaderCell::headerView() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ if (orientation == Qt::Horizontal) {
+ header = tv->horizontalHeader();
+ } else {
+ header = tv->verticalHeader();
+ }
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+ return header;
+}
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/itemviews.h b/src/widgets/accessible/itemviews.h
new file mode 100644
index 0000000000..45a07c5972
--- /dev/null
+++ b/src/widgets/accessible/itemviews.h
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACCESSIBLE_ITEMVIEWS_H
+#define ACCESSIBLE_ITEMVIEWS_H
+
+#include "QtCore/qpointer.h"
+#include <QtGui/qaccessible.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qheaderview.h>
+
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QAccessibleTableCell;
+class QAccessibleTableHeaderCell;
+
+class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObject
+{
+public:
+ explicit QAccessibleTable(QWidget *w);
+ bool isValid() const Q_DECL_OVERRIDE;
+
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // table interface
+ virtual QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE;
+ virtual QAccessibleInterface *caption() const Q_DECL_OVERRIDE;
+ virtual QAccessibleInterface *summary() const Q_DECL_OVERRIDE;
+ virtual QString columnDescription(int column) const Q_DECL_OVERRIDE;
+ virtual QString rowDescription(int row) const Q_DECL_OVERRIDE;
+ virtual int columnCount() const Q_DECL_OVERRIDE;
+ virtual int rowCount() const Q_DECL_OVERRIDE;
+
+ // selection
+ virtual int selectedCellCount() const Q_DECL_OVERRIDE;
+ virtual int selectedColumnCount() const Q_DECL_OVERRIDE;
+ virtual int selectedRowCount() const Q_DECL_OVERRIDE;
+ virtual QList<QAccessibleInterface*> selectedCells() const Q_DECL_OVERRIDE;
+ virtual QList<int> selectedColumns() const Q_DECL_OVERRIDE;
+ virtual QList<int> selectedRows() const Q_DECL_OVERRIDE;
+ virtual bool isColumnSelected(int column) const Q_DECL_OVERRIDE;
+ virtual bool isRowSelected(int row) const Q_DECL_OVERRIDE;
+ virtual bool selectRow(int row) Q_DECL_OVERRIDE;
+ virtual bool selectColumn(int column) Q_DECL_OVERRIDE;
+ virtual bool unselectRow(int row) Q_DECL_OVERRIDE;
+ virtual bool unselectColumn(int column) Q_DECL_OVERRIDE;
+
+ QAbstractItemView *view() const;
+
+ void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE;
+
+protected:
+ inline QAccessible::Role cellRole() const {
+ switch (m_role) {
+ case QAccessible::List:
+ return QAccessible::ListItem;
+ case QAccessible::Table:
+ return QAccessible::Cell;
+ case QAccessible::Tree:
+ return QAccessible::TreeItem;
+ default:
+ Q_ASSERT(0);
+ }
+ return QAccessible::NoRole;
+ }
+
+ QHeaderView *horizontalHeader() const;
+ QHeaderView *verticalHeader() const;
+
+ // maybe vector
+ typedef QHash<int, QAccessible::Id> ChildCache;
+ mutable ChildCache childToId;
+
+ virtual ~QAccessibleTable();
+
+private:
+ // the child index for a model index
+ inline int logicalIndex(const QModelIndex &index) const;
+ QAccessible::Role m_role;
+};
+
+class QAccessibleTree :public QAccessibleTable
+{
+public:
+ explicit QAccessibleTree(QWidget *w)
+ : QAccessibleTable(w)
+ {}
+
+
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+ int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE;
+
+ int rowCount() const Q_DECL_OVERRIDE;
+
+ // table interface
+ QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE;
+ QString rowDescription(int row) const Q_DECL_OVERRIDE;
+ bool isRowSelected(int row) const Q_DECL_OVERRIDE;
+ bool selectRow(int row) Q_DECL_OVERRIDE;
+
+private:
+ QModelIndex indexFromLogical(int row, int column = 0) const;
+
+ inline int logicalIndex(const QModelIndex &index) const;
+};
+
+class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface
+{
+public:
+ QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role);
+
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+ QObject *object() const Q_DECL_OVERRIDE { return 0; }
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; }
+ int childCount() const Q_DECL_OVERRIDE { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; }
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int) const Q_DECL_OVERRIDE;
+
+ // cell interface
+ virtual int columnExtent() const Q_DECL_OVERRIDE;
+ virtual QList<QAccessibleInterface*> columnHeaderCells() const Q_DECL_OVERRIDE;
+ virtual int columnIndex() const Q_DECL_OVERRIDE;
+ virtual int rowExtent() const Q_DECL_OVERRIDE;
+ virtual QList<QAccessibleInterface*> rowHeaderCells() const Q_DECL_OVERRIDE;
+ virtual int rowIndex() const Q_DECL_OVERRIDE;
+ virtual bool isSelected() const Q_DECL_OVERRIDE;
+ virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE;
+
+ //action interface
+ virtual QStringList actionNames() const Q_DECL_OVERRIDE;
+ virtual void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+ virtual QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE;
+
+private:
+ QHeaderView *verticalHeader() const;
+ QHeaderView *horizontalHeader() const;
+ QPointer<QAbstractItemView > view;
+ QModelIndex m_index;
+ QAccessible::Role m_role;
+
+ void selectCell();
+ void unselectCell();
+
+friend class QAccessibleTable;
+friend class QAccessibleTree;
+};
+
+
+class QAccessibleTableHeaderCell: public QAccessibleInterface
+{
+public:
+ // For header cells, pass the header view in addition
+ QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation);
+
+ QObject *object() const Q_DECL_OVERRIDE { return 0; }
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; }
+ int childCount() const Q_DECL_OVERRIDE { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; }
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+private:
+ QHeaderView *headerView() const;
+
+ QPointer<QAbstractItemView> view;
+ int index;
+ Qt::Orientation orientation;
+
+friend class QAccessibleTable;
+friend class QAccessibleTree;
+};
+
+// This is the corner button on the top left of a table.
+// It can be used to select all cells or it is not active at all.
+// For now it is ignored.
+class QAccessibleTableCornerButton: public QAccessibleInterface
+{
+public:
+ QAccessibleTableCornerButton(QAbstractItemView *view_)
+ :view(view_)
+ {}
+
+ QObject *object() const Q_DECL_OVERRIDE { return 0; }
+ QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; }
+ QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); }
+ QRect rect() const Q_DECL_OVERRIDE { return QRect(); }
+ bool isValid() const Q_DECL_OVERRIDE { return true; }
+
+ QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; }
+ int childCount() const Q_DECL_OVERRIDE { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; }
+
+ QString text(QAccessible::Text) const Q_DECL_OVERRIDE { return QString(); }
+ void setText(QAccessible::Text, const QString &) Q_DECL_OVERRIDE {}
+
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE {
+ return QAccessible::queryAccessibleInterface(view);
+ }
+ QAccessibleInterface *child(int) const Q_DECL_OVERRIDE {
+ return 0;
+ }
+
+private:
+ QPointer<QAbstractItemView> view;
+};
+
+
+#endif
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // ACCESSIBLE_ITEMVIEWS_H
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp
new file mode 100644
index 0000000000..a6877404eb
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblemenu.cpp
@@ -0,0 +1,377 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblemenu.h"
+
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <QtWidgets/QAction>
+#include <qstyle.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_MENU
+
+QString qt_accStripAmp(const QString &text);
+QString qt_accHotKey(const QString &text);
+
+QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
+{
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action);
+ if (!iface) {
+ iface = new QAccessibleMenuItem(menu, action);
+ QAccessible::registerAccessibleInterface(iface);
+ }
+ return iface;
+}
+
+QAccessibleMenu::QAccessibleMenu(QWidget *w)
+: QAccessibleWidget(w)
+{
+ Q_ASSERT(menu());
+}
+
+QMenu *QAccessibleMenu::menu() const
+{
+ return qobject_cast<QMenu*>(object());
+}
+
+int QAccessibleMenu::childCount() const
+{
+ return menu()->actions().count();
+}
+
+QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const
+{
+ QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
+ if(act && act->isSeparator())
+ act = 0;
+ return act ? getOrCreateMenu(menu(), act) : 0;
+}
+
+QString QAccessibleMenu::text(QAccessible::Text t) const
+{
+ QString tx = QAccessibleWidget::text(t);
+ if (!tx.isEmpty())
+ return tx;
+
+ if (t == QAccessible::Name)
+ return menu()->windowTitle();
+ return tx;
+}
+
+QAccessible::Role QAccessibleMenu::role() const
+{
+ return QAccessible::PopupMenu;
+}
+
+QAccessibleInterface *QAccessibleMenu::child(int index) const
+{
+ if (index < childCount())
+ return getOrCreateMenu(menu(), menu()->actions().at(index));
+ return 0;
+}
+
+QAccessibleInterface *QAccessibleMenu::parent() const
+{
+ if (QAction *menuAction = menu()->menuAction()) {
+ QList<QWidget *> parentCandidates;
+ parentCandidates << menu()->parentWidget();
+ parentCandidates << menuAction->associatedWidgets();
+ foreach (QWidget *w, parentCandidates) {
+ if (qobject_cast<QMenu*>(w) || qobject_cast<QMenuBar*>(w)) {
+ if (w->actions().indexOf(menuAction) != -1)
+ return getOrCreateMenu(w, menuAction);
+ }
+ }
+ }
+ return QAccessibleWidget::parent();
+}
+
+int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const
+{
+ QAccessible::Role r = child->role();
+ if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) {
+ return menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
+ }
+ return -1;
+}
+
+#ifndef QT_NO_MENUBAR
+QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
+ : QAccessibleWidget(w, QAccessible::MenuBar)
+{
+ Q_ASSERT(menuBar());
+}
+
+QMenuBar *QAccessibleMenuBar::menuBar() const
+{
+ return qobject_cast<QMenuBar*>(object());
+}
+
+int QAccessibleMenuBar::childCount() const
+{
+ return menuBar()->actions().count();
+}
+
+QAccessibleInterface *QAccessibleMenuBar::child(int index) const
+{
+ if (index < childCount()) {
+ return getOrCreateMenu(menuBar(), menuBar()->actions().at(index));
+ }
+ return 0;
+}
+
+int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const
+{
+ QAccessible::Role r = child->role();
+ if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) {
+ return menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
+ }
+ return -1;
+}
+
+#endif // QT_NO_MENUBAR
+
+QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action)
+: m_action(action), m_owner(owner)
+{
+}
+
+QAccessibleMenuItem::~QAccessibleMenuItem()
+{}
+
+QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const
+{
+ for (int i = childCount() - 1; i >= 0; --i) {
+ QAccessibleInterface *childInterface = child(i);
+ if (childInterface->rect().contains(x,y)) {
+ return childInterface;
+ }
+ }
+ return 0;
+}
+
+int QAccessibleMenuItem::childCount() const
+{
+ return m_action->menu() ? 1 : 0;
+}
+
+int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const
+{
+ if (child && child->role() == QAccessible::PopupMenu && child->object() == m_action->menu())
+ return 0;
+ return -1;
+}
+
+bool QAccessibleMenuItem::isValid() const
+{
+ return m_action && m_owner ? true : false;
+}
+
+QAccessibleInterface *QAccessibleMenuItem::parent() const
+{
+ return QAccessible::queryAccessibleInterface(owner());
+}
+
+QAccessibleInterface *QAccessibleMenuItem::child(int index) const
+{
+ if (index == 0 && action()->menu())
+ return QAccessible::queryAccessibleInterface(action()->menu());
+ return 0;
+}
+
+void *QAccessibleMenuItem::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ActionInterface)
+ return static_cast<QAccessibleActionInterface*>(this);
+ return 0;
+}
+
+QObject *QAccessibleMenuItem::object() const
+{
+ return m_action;
+}
+
+QRect QAccessibleMenuItem::rect() const
+{
+ QRect rect;
+ QWidget *own = owner();
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
+ rect = menuBar->actionGeometry(m_action);
+ QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
+ rect = rect.translated(globalPos);
+ } else
+#endif // QT_NO_MENUBAR
+ if (QMenu *menu = qobject_cast<QMenu*>(own)) {
+ rect = menu->actionGeometry(m_action);
+ QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
+ rect = rect.translated(globalPos);
+ }
+ return rect;
+}
+
+QAccessible::Role QAccessibleMenuItem::role() const
+{
+ return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem;
+}
+
+void QAccessibleMenuItem::setText(QAccessible::Text /*t*/, const QString & /*text */)
+{
+}
+
+QAccessible::State QAccessibleMenuItem::state() const
+{
+ QAccessible::State s;
+ QWidget *own = owner();
+
+ if (own && (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false)) {
+ s.invisible = true;
+ }
+
+ if (QMenu *menu = qobject_cast<QMenu*>(own)) {
+ if (menu->activeAction() == m_action)
+ s.focused = true;
+#ifndef QT_NO_MENUBAR
+ } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
+ if (menuBar->activeAction() == m_action)
+ s.focused = true;
+#endif
+ }
+ if (own && own->style()->styleHint(QStyle::SH_Menu_MouseTracking))
+ s.hotTracked = true;
+ if (m_action->isSeparator() || !m_action->isEnabled())
+ s.disabled = true;
+ if (m_action->isChecked())
+ s.checked = true;
+
+ return s;
+}
+
+QString QAccessibleMenuItem::text(QAccessible::Text t) const
+{
+ QString str;
+ switch (t) {
+ case QAccessible::Name:
+ str = m_action->text();
+ str = qt_accStripAmp(str);
+ break;
+ case QAccessible::Accelerator: {
+#ifndef QT_NO_SHORTCUT
+ QKeySequence key = m_action->shortcut();
+ if (!key.isEmpty()) {
+ str = key.toString();
+ } else
+#endif
+ {
+ str = qt_accHotKey(m_action->text());
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return str;
+}
+
+QStringList QAccessibleMenuItem::actionNames() const
+{
+ QStringList actions;
+ if (!m_action || m_action->isSeparator())
+ return actions;
+
+ if (m_action->menu()) {
+ actions << showMenuAction();
+ } else {
+ actions << pressAction();
+ }
+ return actions;
+}
+
+void QAccessibleMenuItem::doAction(const QString &actionName)
+{
+ if (!m_action->isEnabled())
+ return;
+
+ if (actionName == pressAction()) {
+ m_action->trigger();
+ } else if (actionName == showMenuAction()) {
+ if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) {
+ if (m_action->menu() && m_action->menu()->isVisible()) {
+ m_action->menu()->hide();
+ } else {
+ bar->setActiveAction(m_action);
+ }
+ } else if (QMenu *menu = qobject_cast<QMenu*>(owner())){
+ if (m_action->menu() && m_action->menu()->isVisible()) {
+ m_action->menu()->hide();
+ } else {
+ menu->setActiveAction(m_action);
+ }
+ }
+ }
+}
+
+QStringList QAccessibleMenuItem::keyBindingsForAction(const QString &) const
+{
+ return QStringList();
+}
+
+
+QAction *QAccessibleMenuItem::action() const
+{
+ return m_action;
+}
+
+QWidget *QAccessibleMenuItem::owner() const
+{
+ return m_owner;
+}
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
+
diff --git a/src/widgets/accessible/qaccessiblemenu.h b/src/widgets/accessible/qaccessiblemenu.h
new file mode 100644
index 0000000000..e8c9f8af3a
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblemenu.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEMENU_H
+#define QACCESSIBLEMENU_H
+
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_MENU
+class QMenu;
+class QMenuBar;
+class QAction;
+
+class QAccessibleMenu : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleMenu(QWidget *w);
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
+ int indexOfChild( const QAccessibleInterface *child ) const Q_DECL_OVERRIDE;
+
+protected:
+ QMenu *menu() const;
+};
+
+#ifndef QT_NO_MENUBAR
+class QAccessibleMenuBar : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleMenuBar(QWidget *w);
+
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+
+protected:
+ QMenuBar *menuBar() const;
+};
+#endif // QT_NO_MENUBAR
+
+
+class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActionInterface
+{
+public:
+ explicit QAccessibleMenuItem(QWidget *owner, QAction *w);
+
+ ~QAccessibleMenuItem();
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface * child) const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ QObject * object() const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ // QAccessibleActionInterface
+ QStringList actionNames() const Q_DECL_OVERRIDE;
+ void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+ QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE;
+
+ QWidget *owner() const;
+protected:
+ QAction *action() const;
+private:
+ QAction *m_action;
+ QPointer<QWidget> m_owner; // can hold either QMenu or the QMenuBar that contains the action
+};
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+#endif // QT_NO_ACCESSIBILITY
+#endif // QACCESSIBLEMENU_H
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
index 4e5fade3f4..8a2e38df7e 100644
--- a/src/widgets/accessible/qaccessiblewidget.cpp
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -134,7 +134,7 @@ static int qt_accAmpIndex(const QString &text)
#endif
}
-QString Q_WIDGETS_EXPORT qt_accStripAmp(const QString &text)
+QString qt_accStripAmp(const QString &text)
{
QString newText(text);
int ampIndex = qt_accAmpIndex(newText);
@@ -144,7 +144,7 @@ QString Q_WIDGETS_EXPORT qt_accStripAmp(const QString &text)
return newText.replace(QLatin1String("&&"), QLatin1String("&"));
}
-QString Q_WIDGETS_EXPORT qt_accHotKey(const QString &text)
+QString qt_accHotKey(const QString &text)
{
int ampIndex = qt_accAmpIndex(text);
if (ampIndex != -1)
diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
new file mode 100644
index 0000000000..a925dd2708
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblewidgets.h"
+#include "qaccessiblemenu.h"
+#include "simplewidgets.h"
+#include "rangecontrols.h"
+#include "complexwidgets.h"
+#include "itemviews.h"
+
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qvariant.h>
+#include <qaccessible.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *object)
+{
+ QAccessibleInterface *iface = 0;
+ if (!object || !object->isWidgetType())
+ return iface;
+ QWidget *widget = static_cast<QWidget*>(object);
+
+ if (false) {
+#ifndef QT_NO_LINEEDIT
+ } else if (classname == QLatin1String("QLineEdit")) {
+ iface = new QAccessibleLineEdit(widget);
+#endif
+#ifndef QT_NO_COMBOBOX
+ } else if (classname == QLatin1String("QComboBox")) {
+ iface = new QAccessibleComboBox(widget);
+#endif
+#ifndef QT_NO_SPINBOX
+ } else if (classname == QLatin1String("QAbstractSpinBox")) {
+ iface = new QAccessibleAbstractSpinBox(widget);
+ } else if (classname == QLatin1String("QSpinBox")) {
+ iface = new QAccessibleSpinBox(widget);
+ } else if (classname == QLatin1String("QDoubleSpinBox")) {
+ iface = new QAccessibleDoubleSpinBox(widget);
+#endif
+#ifndef QT_NO_SCROLLBAR
+ } else if (classname == QLatin1String("QScrollBar")) {
+ iface = new QAccessibleScrollBar(widget);
+#endif
+ } else if (classname == QLatin1String("QAbstractSlider")) {
+ iface = new QAccessibleAbstractSlider(widget);
+#ifndef QT_NO_SLIDER
+ } else if (classname == QLatin1String("QSlider")) {
+ iface = new QAccessibleSlider(widget);
+#endif
+#ifndef QT_NO_TOOLBUTTON
+ } else if (classname == QLatin1String("QToolButton")) {
+ QAccessible::Role role = QAccessible::NoRole;
+#ifndef QT_NO_MENU
+ QToolButton *tb = qobject_cast<QToolButton*>(widget);
+ if (!tb->menu())
+ role = tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton;
+ else if (tb->popupMode() == QToolButton::DelayedPopup)
+ role = QAccessible::ButtonDropDown;
+ else
+#endif
+ role = QAccessible::ButtonMenu;
+ iface = new QAccessibleToolButton(widget, role);
+#endif // QT_NO_TOOLBUTTON
+ } else if (classname == QLatin1String("QCheckBox")) {
+ iface = new QAccessibleButton(widget, QAccessible::CheckBox);
+ } else if (classname == QLatin1String("QRadioButton")) {
+ iface = new QAccessibleButton(widget, QAccessible::RadioButton);
+ } else if (classname == QLatin1String("QPushButton")) {
+ QAccessible::Role role = QAccessible::NoRole;
+ QPushButton *pb = qobject_cast<QPushButton*>(widget);
+#ifndef QT_NO_MENU
+ if (pb->menu())
+ role = QAccessible::ButtonMenu;
+ else
+#endif
+ if (pb->isCheckable())
+ role = QAccessible::CheckBox;
+ else
+ role = QAccessible::PushButton;
+ iface = new QAccessibleButton(widget, role);
+ } else if (classname == QLatin1String("QAbstractButton")) {
+ iface = new QAccessibleButton(widget, QAccessible::PushButton);
+ } else if (classname == QLatin1String("QDialog")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Dialog);
+ } else if (classname == QLatin1String("QMessageBox")) {
+ iface = new QAccessibleWidget(widget, QAccessible::AlertMessage);
+#ifndef QT_NO_MAINWINDOW
+ } else if (classname == QLatin1String("QMainWindow")) {
+ iface = new QAccessibleMainWindow(widget);
+#endif
+ } else if (classname == QLatin1String("QLabel") || classname == QLatin1String("QLCDNumber")) {
+ iface = new QAccessibleDisplay(widget);
+#ifndef QT_NO_GROUPBOX
+ } else if (classname == QLatin1String("QGroupBox")) {
+ iface = new QAccessibleGroupBox(widget);
+#endif
+ } else if (classname == QLatin1String("QStatusBar")) {
+ iface = new QAccessibleDisplay(widget);
+#ifndef QT_NO_PROGRESSBAR
+ } else if (classname == QLatin1String("QProgressBar")) {
+ iface = new QAccessibleProgressBar(widget);
+#endif
+ } else if (classname == QLatin1String("QToolBar")) {
+ iface = new QAccessibleWidget(widget, QAccessible::ToolBar, widget->windowTitle());
+#ifndef QT_NO_MENUBAR
+ } else if (classname == QLatin1String("QMenuBar")) {
+ iface = new QAccessibleMenuBar(widget);
+#endif
+#ifndef QT_NO_MENU
+ } else if (classname == QLatin1String("QMenu")) {
+ iface = new QAccessibleMenu(widget);
+#endif
+#ifndef QT_NO_ITEMVIEWS
+ } else if (classname == QLatin1String("QTreeView")) {
+ iface = new QAccessibleTree(widget);
+ } else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) {
+ iface = new QAccessibleTable(widget);
+ // ### This should be cleaned up. We return the parent for the scrollarea to hide it.
+#endif // QT_NO_ITEMVIEWS
+#ifndef QT_NO_TABBAR
+ } else if (classname == QLatin1String("QTabBar")) {
+ iface = new QAccessibleTabBar(widget);
+#endif
+ } else if (classname == QLatin1String("QSizeGrip")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Grip);
+#ifndef QT_NO_SPLITTER
+ } else if (classname == QLatin1String("QSplitter")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Splitter);
+ } else if (classname == QLatin1String("QSplitterHandle")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Grip);
+#endif
+#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR)
+ } else if (classname == QLatin1String("QTextEdit")) {
+ iface = new QAccessibleTextEdit(widget);
+ } else if (classname == QLatin1String("QPlainTextEdit")) {
+ iface = new QAccessiblePlainTextEdit(widget);
+#endif
+ } else if (classname == QLatin1String("QTipLabel")) {
+ iface = new QAccessibleDisplay(widget, QAccessible::ToolTip);
+ } else if (classname == QLatin1String("QFrame")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Border);
+#ifndef QT_NO_STACKEDWIDGET
+ } else if (classname == QLatin1String("QStackedWidget")) {
+ iface = new QAccessibleStackedWidget(widget);
+#endif
+#ifndef QT_NO_TOOLBOX
+ } else if (classname == QLatin1String("QToolBox")) {
+ iface = new QAccessibleToolBox(widget);
+#endif
+#ifndef QT_NO_MDIAREA
+ } else if (classname == QLatin1String("QMdiArea")) {
+ iface = new QAccessibleMdiArea(widget);
+ } else if (classname == QLatin1String("QMdiSubWindow")) {
+ iface = new QAccessibleMdiSubWindow(widget);
+#endif
+ } else if (classname == QLatin1String("QDialogButtonBox")) {
+ iface = new QAccessibleDialogButtonBox(widget);
+#ifndef QT_NO_DIAL
+ } else if (classname == QLatin1String("QDial")) {
+ iface = new QAccessibleDial(widget);
+#endif
+#ifndef QT_NO_RUBBERBAND
+ } else if (classname == QLatin1String("QRubberBand")) {
+ iface = new QAccessibleWidget(widget, QAccessible::Border);
+#endif
+#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR)
+ } else if (classname == QLatin1String("QTextBrowser")) {
+ iface = new QAccessibleTextBrowser(widget);
+#endif
+#ifndef QT_NO_SCROLLAREA
+ } else if (classname == QLatin1String("QAbstractScrollArea")) {
+ iface = new QAccessibleAbstractScrollArea(widget);
+ } else if (classname == QLatin1String("QScrollArea")) {
+ iface = new QAccessibleScrollArea(widget);
+#endif
+#ifndef QT_NO_CALENDARWIDGET
+ } else if (classname == QLatin1String("QCalendarWidget")) {
+ iface = new QAccessibleCalendarWidget(widget);
+#endif
+#ifndef QT_NO_DOCKWIDGET
+ } else if (classname == QLatin1String("QDockWidget")) {
+ iface = new QAccessibleDockWidget(widget);
+#endif
+
+ } else if (classname == QLatin1String("QDesktopScreenWidget")) {
+ iface = 0;
+ } else if (classname == QLatin1String("QWidget")) {
+ iface = new QAccessibleWidget(widget);
+ } else if (classname == QLatin1String("QWindowContainer")) {
+ iface = new QAccessibleWindowContainer(widget);
+ }
+
+ return iface;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/qaccessiblewidgetfactory_p.h b/src/widgets/accessible/qaccessiblewidgetfactory_p.h
new file mode 100644
index 0000000000..70ac462950
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidgetfactory_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qaccessible.h>
+
+#ifndef QACCESSIBLEWIDGETFACTORY_H
+#define QACCESSIBLEWIDGETFACTORY_H
+
+QT_BEGIN_NAMESPACE
+
+QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *object);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
new file mode 100644
index 0000000000..f0a8ecf608
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -0,0 +1,1021 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblewidgets.h"
+#include "qabstracttextdocumentlayout.h"
+#include "qapplication.h"
+#include "qclipboard.h"
+#include "qtextedit.h"
+#include "private/qtextedit_p.h"
+#include "qtextdocument.h"
+#include "qtextobject.h"
+#include "qplaintextedit.h"
+#include "qtextboundaryfinder.h"
+#include "qscrollbar.h"
+#include "qdebug.h"
+#include <QApplication>
+#include <QStackedWidget>
+#include <QToolBox>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QDialogButtonBox>
+#include <limits.h>
+#include <QRubberBand>
+#include <QTextBrowser>
+#include <QCalendarWidget>
+#include <QAbstractItemView>
+#include <QDockWidget>
+#include <QMainWindow>
+#include <QAbstractButton>
+#include <private/qdockwidget_p.h>
+#include <QFocusFrame>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+QString qt_accStripAmp(const QString &text);
+
+QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
+{
+ if (widget == 0)
+ return QList<QWidget*>();
+ QList<QObject*> list = widget->children();
+ QList<QWidget*> widgets;
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(list.at(i));
+ if (!w)
+ continue;
+ QString objectName = w->objectName();
+ if ((includeTopLevel || !w->isWindow())
+ && !qobject_cast<QFocusFrame*>(w)
+ && !qobject_cast<QMenu*>(w)
+ && objectName != QLatin1String("qt_rubberband")
+ && objectName != QLatin1String("qt_qmainwindow_extended_splitter")) {
+ widgets.append(w);
+ }
+ }
+ return widgets;
+}
+
+#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR)
+
+QAccessiblePlainTextEdit::QAccessiblePlainTextEdit(QWidget* o)
+ :QAccessibleTextWidget(o)
+{
+ Q_ASSERT(widget()->inherits("QPlainTextEdit"));
+}
+
+QPlainTextEdit* QAccessiblePlainTextEdit::plainTextEdit() const
+{
+ return static_cast<QPlainTextEdit *>(widget());
+}
+
+QString QAccessiblePlainTextEdit::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Value)
+ return plainTextEdit()->toPlainText();
+
+ return QAccessibleWidget::text(t);
+}
+
+void QAccessiblePlainTextEdit::setText(QAccessible::Text t, const QString &text)
+{
+ if (t != QAccessible::Value) {
+ QAccessibleWidget::setText(t, text);
+ return;
+ }
+ if (plainTextEdit()->isReadOnly())
+ return;
+
+ plainTextEdit()->setPlainText(text);
+}
+
+QAccessible::State QAccessiblePlainTextEdit::state() const
+{
+ QAccessible::State st = QAccessibleTextWidget::state();
+ if (plainTextEdit()->isReadOnly())
+ st.readOnly = true;
+ else
+ st.editable = true;
+ return st;
+}
+
+void *QAccessiblePlainTextEdit::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::TextInterface)
+ return static_cast<QAccessibleTextInterface*>(this);
+ else if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+QPoint QAccessiblePlainTextEdit::scrollBarPosition() const
+{
+ QPoint result;
+ result.setX(plainTextEdit()->horizontalScrollBar() ? plainTextEdit()->horizontalScrollBar()->sliderPosition() : 0);
+ result.setY(plainTextEdit()->verticalScrollBar() ? plainTextEdit()->verticalScrollBar()->sliderPosition() : 0);
+ return result;
+}
+
+QTextCursor QAccessiblePlainTextEdit::textCursor() const
+{
+ return plainTextEdit()->textCursor();
+}
+
+void QAccessiblePlainTextEdit::setTextCursor(const QTextCursor &textCursor)
+{
+ plainTextEdit()->setTextCursor(textCursor);
+}
+
+QTextDocument* QAccessiblePlainTextEdit::textDocument() const
+{
+ return plainTextEdit()->document();
+}
+
+QWidget* QAccessiblePlainTextEdit::viewport() const
+{
+ return plainTextEdit()->viewport();
+}
+
+void QAccessiblePlainTextEdit::scrollToSubstring(int startIndex, int endIndex)
+{
+ //TODO: Not implemented
+ Q_UNUSED(startIndex);
+ Q_UNUSED(endIndex);
+}
+
+
+/*!
+ \class QAccessibleTextEdit
+ \brief The QAccessibleTextEdit class implements the QAccessibleInterface for richtext editors.
+ \internal
+*/
+
+/*!
+ \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget *widget)
+
+ Constructs a QAccessibleTextEdit object for a \a widget.
+*/
+QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o)
+: QAccessibleTextWidget(o, QAccessible::EditableText)
+{
+ Q_ASSERT(widget()->inherits("QTextEdit"));
+}
+
+/*! Returns the text edit. */
+QTextEdit *QAccessibleTextEdit::textEdit() const
+{
+ return static_cast<QTextEdit *>(widget());
+}
+
+QTextCursor QAccessibleTextEdit::textCursor() const
+{
+ return textEdit()->textCursor();
+}
+
+QTextDocument *QAccessibleTextEdit::textDocument() const
+{
+ return textEdit()->document();
+}
+
+void QAccessibleTextEdit::setTextCursor(const QTextCursor &textCursor)
+{
+ textEdit()->setTextCursor(textCursor);
+}
+
+QWidget *QAccessibleTextEdit::viewport() const
+{
+ return textEdit()->viewport();
+}
+
+QPoint QAccessibleTextEdit::scrollBarPosition() const
+{
+ QPoint result;
+ result.setX(textEdit()->horizontalScrollBar() ? textEdit()->horizontalScrollBar()->sliderPosition() : 0);
+ result.setY(textEdit()->verticalScrollBar() ? textEdit()->verticalScrollBar()->sliderPosition() : 0);
+ return result;
+}
+
+QString QAccessibleTextEdit::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Value)
+ return textEdit()->toPlainText();
+
+ return QAccessibleWidget::text(t);
+}
+
+void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text)
+{
+ if (t != QAccessible::Value) {
+ QAccessibleWidget::setText(t, text);
+ return;
+ }
+ if (textEdit()->isReadOnly())
+ return;
+
+ textEdit()->setText(text);
+}
+
+QAccessible::State QAccessibleTextEdit::state() const
+{
+ QAccessible::State st = QAccessibleTextWidget::state();
+ if (textEdit()->isReadOnly())
+ st.readOnly = true;
+ else
+ st.editable = true;
+ return st;
+}
+
+void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::TextInterface)
+ return static_cast<QAccessibleTextInterface*>(this);
+ else if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
+{
+ QTextEdit *edit = textEdit();
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(startIndex);
+ QRect r = edit->cursorRect(cursor);
+
+ cursor.setPosition(endIndex);
+ r.setBottomRight(edit->cursorRect(cursor).bottomRight());
+
+ r.moveTo(r.x() + edit->horizontalScrollBar()->value(),
+ r.y() + edit->verticalScrollBar()->value());
+
+ // E V I L, but ensureVisible is not public
+ if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
+ qWarning("AccessibleTextEdit::scrollToSubstring failed!");
+}
+
+#endif // QT_NO_TEXTEDIT && QT_NO_CURSOR
+
+#ifndef QT_NO_STACKEDWIDGET
+// ======================= QAccessibleStackedWidget ======================
+QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QStackedWidget *>(widget));
+}
+
+QAccessibleInterface *QAccessibleStackedWidget::childAt(int x, int y) const
+{
+ if (!stackedWidget()->isVisible())
+ return 0;
+ QWidget *currentWidget = stackedWidget()->currentWidget();
+ if (!currentWidget)
+ return 0;
+ QPoint position = currentWidget->mapFromGlobal(QPoint(x, y));
+ if (currentWidget->rect().contains(position))
+ return child(stackedWidget()->currentIndex());
+ return 0;
+}
+
+int QAccessibleStackedWidget::childCount() const
+{
+ return stackedWidget()->count();
+}
+
+int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child)
+ return -1;
+
+ QWidget *widget = qobject_cast<QWidget*>(child->object());
+ return stackedWidget()->indexOf(widget);
+}
+
+QAccessibleInterface *QAccessibleStackedWidget::child(int index) const
+{
+ if (index < 0 || index >= stackedWidget()->count())
+ return 0;
+ return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index));
+}
+
+QStackedWidget *QAccessibleStackedWidget::stackedWidget() const
+{
+ return static_cast<QStackedWidget *>(object());
+}
+#endif // QT_NO_STACKEDWIDGET
+
+#ifndef QT_NO_TOOLBOX
+// ======================= QAccessibleToolBox ======================
+QAccessibleToolBox::QAccessibleToolBox(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QToolBox *>(widget));
+}
+
+QToolBox * QAccessibleToolBox::toolBox() const
+{
+ return static_cast<QToolBox *>(object());
+}
+#endif // QT_NO_TOOLBOX
+
+// ======================= QAccessibleMdiArea ======================
+#ifndef QT_NO_MDIAREA
+QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::LayeredPane)
+{
+ Q_ASSERT(qobject_cast<QMdiArea *>(widget));
+}
+
+int QAccessibleMdiArea::childCount() const
+{
+ return mdiArea()->subWindowList().count();
+}
+
+QAccessibleInterface *QAccessibleMdiArea::child(int index) const
+{
+ QList<QMdiSubWindow *> subWindows = mdiArea()->subWindowList();
+ QWidget *targetObject = subWindows.value(index);
+ if (!targetObject)
+ return 0;
+ return QAccessible::queryAccessibleInterface(targetObject);
+}
+
+
+int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || mdiArea()->subWindowList().isEmpty())
+ return -1;
+ if (QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(child->object())) {
+ return mdiArea()->subWindowList().indexOf(window);
+ }
+ return -1;
+}
+
+QMdiArea *QAccessibleMdiArea::mdiArea() const
+{
+ return static_cast<QMdiArea *>(object());
+}
+
+// ======================= QAccessibleMdiSubWindow ======================
+QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::Window)
+{
+ Q_ASSERT(qobject_cast<QMdiSubWindow *>(widget));
+}
+
+QString QAccessibleMdiSubWindow::text(QAccessible::Text textType) const
+{
+ if (textType == QAccessible::Name) {
+ QString title = mdiSubWindow()->windowTitle();
+ title.replace(QLatin1String("[*]"), QLatin1String(""));
+ return title;
+ }
+ return QAccessibleWidget::text(textType);
+}
+
+void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString &text)
+{
+ if (textType == QAccessible::Name)
+ mdiSubWindow()->setWindowTitle(text);
+ else
+ QAccessibleWidget::setText(textType, text);
+}
+
+QAccessible::State QAccessibleMdiSubWindow::state() const
+{
+ QAccessible::State state;
+ state.focusable = true;
+ if (!mdiSubWindow()->isMaximized()) {
+ state.movable = true;
+ state.sizeable = true;
+ }
+ if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget())
+ || QApplication::focusWidget() == mdiSubWindow())
+ state.focused = true;
+ if (!mdiSubWindow()->isVisible())
+ state.invisible = true;
+ if (const QWidget *parent = mdiSubWindow()->parentWidget())
+ if (!parent->contentsRect().contains(mdiSubWindow()->geometry()))
+ state.offscreen = true;
+ if (!mdiSubWindow()->isEnabled())
+ state.disabled = true;
+ return state;
+}
+
+int QAccessibleMdiSubWindow::childCount() const
+{
+ if (mdiSubWindow()->widget())
+ return 1;
+ return 0;
+}
+
+QAccessibleInterface *QAccessibleMdiSubWindow::child(int index) const
+{
+ QMdiSubWindow *source = mdiSubWindow();
+ if (index != 0 || !source->widget())
+ return 0;
+
+ return QAccessible::queryAccessibleInterface(source->widget());
+}
+
+int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (child && child->object() && child->object() == mdiSubWindow()->widget())
+ return 0;
+ return -1;
+}
+
+QRect QAccessibleMdiSubWindow::rect() const
+{
+ if (mdiSubWindow()->isHidden())
+ return QRect();
+ if (!mdiSubWindow()->parent())
+ return QAccessibleWidget::rect();
+ const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0));
+ return QRect(pos, mdiSubWindow()->size());
+}
+
+QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const
+{
+ return static_cast<QMdiSubWindow *>(object());
+}
+#endif // QT_NO_MDIAREA
+
+#ifndef QT_NO_DIALOGBUTTONBOX
+// ======================= QAccessibleDialogButtonBox ======================
+QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::Grouping)
+{
+ Q_ASSERT(qobject_cast<QDialogButtonBox*>(widget));
+}
+
+#endif // QT_NO_DIALOGBUTTONBOX
+
+#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR)
+QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget)
+ : QAccessibleTextEdit(widget)
+{
+ Q_ASSERT(qobject_cast<QTextBrowser *>(widget));
+}
+
+QAccessible::Role QAccessibleTextBrowser::role() const
+{
+ return QAccessible::StaticText;
+}
+#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR
+
+#ifndef QT_NO_CALENDARWIDGET
+// ===================== QAccessibleCalendarWidget ========================
+QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::Table)
+{
+ Q_ASSERT(qobject_cast<QCalendarWidget *>(widget));
+}
+
+int QAccessibleCalendarWidget::childCount() const
+{
+ return calendarWidget()->isNavigationBarVisible() ? 2 : 1;
+}
+
+int QAccessibleCalendarWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || childCount() <= 0)
+ return -1;
+ if (qobject_cast<QAbstractItemView *>(child->object()))
+ return childCount() - 1; // FIXME
+ return 0;
+}
+
+QAccessibleInterface *QAccessibleCalendarWidget::child(int index) const
+{
+ if (index < 0 || index >= childCount())
+ return 0;
+
+ if (childCount() > 1 && index == 0)
+ return QAccessible::queryAccessibleInterface(navigationBar());
+
+ return QAccessible::queryAccessibleInterface(calendarView());
+}
+
+QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const
+{
+ return static_cast<QCalendarWidget *>(object());
+}
+
+QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
+{
+ foreach (QObject *child, calendarWidget()->children()) {
+ if (child->objectName() == QLatin1String("qt_calendar_calendarview"))
+ return static_cast<QAbstractItemView *>(child);
+ }
+ return 0;
+}
+
+QWidget *QAccessibleCalendarWidget::navigationBar() const
+{
+ foreach (QObject *child, calendarWidget()->children()) {
+ if (child->objectName() == QLatin1String("qt_calendar_navigationbar"))
+ return static_cast<QWidget *>(child);
+ }
+ return 0;
+}
+#endif // QT_NO_CALENDARWIDGET
+
+#ifndef QT_NO_DOCKWIDGET
+
+// Dock Widget - order of children:
+// - Content widget
+// - Float button
+// - Close button
+// 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)
+{
+}
+
+QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const
+{
+ return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
+}
+
+int QAccessibleDockWidget::childCount() const
+{
+ if (dockWidget()->titleBarWidget()) {
+ return dockWidget()->widget() ? 2 : 1;
+ }
+ return dockWidgetLayout()->count();
+}
+
+QAccessibleInterface *QAccessibleDockWidget::child(int index) const
+{
+ if (dockWidget()->titleBarWidget()) {
+ if ((!dockWidget()->widget() && index == 0) || (index == 1))
+ return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget());
+ if (index == 0)
+ return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ } else {
+ QLayoutItem *item = dockWidgetLayout()->itemAt(index);
+ if (item)
+ return QAccessible::queryAccessibleInterface(item->widget());
+ }
+ return 0;
+}
+
+int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (!child || !child->object() || child->object()->parent() != object())
+ return -1;
+
+ if (dockWidget()->titleBarWidget() == child->object()) {
+ return dockWidget()->widget() ? 1 : 0;
+ }
+
+ return dockWidgetLayout()->indexOf(qobject_cast<QWidget*>(child->object()));
+}
+
+QRect QAccessibleDockWidget::rect() const
+{
+ QRect rect;
+
+ if (dockWidget()->isFloating()) {
+ rect = dockWidget()->frameGeometry();
+ } else {
+ rect = dockWidget()->rect();
+ rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
+ }
+
+ return rect;
+}
+
+QDockWidget *QAccessibleDockWidget::dockWidget() const
+{
+ return static_cast<QDockWidget *>(object());
+}
+
+QString QAccessibleDockWidget::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Name) {
+ return qt_accStripAmp(dockWidget()->windowTitle());
+ }
+ return QString();
+}
+#endif // QT_NO_DOCKWIDGET
+
+#ifndef QT_NO_CURSOR
+
+QAccessibleTextWidget::QAccessibleTextWidget(QWidget *o, QAccessible::Role r, const QString &name):
+ QAccessibleWidget(o, r, name)
+{
+
+}
+
+QAccessible::State QAccessibleTextWidget::state() const
+{
+ QAccessible::State s = QAccessibleWidget::state();
+ s.selectableText = true;
+ s.multiLine = true;
+ return s;
+}
+
+QRect QAccessibleTextWidget::characterRect(int offset) const
+{
+ QTextBlock block = textDocument()->findBlock(offset);
+ if (!block.isValid())
+ return QRect();
+
+ QTextLayout *layout = block.layout();
+ QPointF layoutPosition = layout->position();
+ int relativeOffset = offset - block.position();
+ QTextLine line = layout->lineForTextPosition(relativeOffset);
+
+ QRect r;
+
+ if (line.isValid()) {
+ qreal x = line.cursorToX(relativeOffset);
+ QFontMetrics fm(textCursor().charFormat().font());
+ const QString ch = text(offset, offset + 1);
+ if (!ch.isEmpty()) {
+ int w = fm.width(ch);
+ int h = fm.height();
+ r = QRect(layoutPosition.x() + x, layoutPosition.y() + line.y(),
+ w, h);
+ r.moveTo(viewport()->mapToGlobal(r.topLeft()));
+ }
+ r.translate(-scrollBarPosition());
+ }
+
+ return r;
+}
+
+int QAccessibleTextWidget::offsetAtPoint(const QPoint &point) const
+{
+ QPoint p = viewport()->mapFromGlobal(point);
+ // convert to document coordinates
+ p += scrollBarPosition();
+ return textDocument()->documentLayout()->hitTest(p, Qt::ExactHit);
+}
+
+int QAccessibleTextWidget::selectionCount() const
+{
+ return textCursor().hasSelection() ? 1 : 0;
+}
+
+QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *endOffset) const
+{
+ /* The list of attributes can be found at:
+ http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
+ */
+
+ // IAccessible2 defines -1 as length and -2 as cursor position
+ if (offset == -2)
+ offset = cursorPosition();
+
+ const int charCount = characterCount();
+
+ // -1 doesn't make much sense here, but it's better to return something
+ // screen readers may ask for text attributes at the cursor pos which may be equal to length
+ if (offset == -1 || offset == charCount)
+ offset = charCount - 1;
+
+ if (offset < 0 || offset > charCount) {
+ *startOffset = -1;
+ *endOffset = -1;
+ return QString();
+ }
+
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QTextBlock block = cursor.block();
+
+ int blockStart = block.position();
+ int blockEnd = blockStart + block.length();
+
+ QTextBlock::iterator iter = block.begin();
+ while (!iter.fragment().contains(offset))
+ ++iter;
+
+ QTextFragment fragment = iter.fragment();
+ int pos = fragment.position();
+
+ // text block and fragment may overlap, use the smallest common range
+ *startOffset = qMax(pos, blockStart);
+ Q_ASSERT(*startOffset <= offset);
+ *endOffset = qMin(pos + fragment.length(), blockEnd);
+ Q_ASSERT(*endOffset >= offset);
+
+ QTextCharFormat charFormat = fragment.charFormat();
+ QTextBlockFormat blockFormat = cursor.blockFormat();
+
+ QMap<QByteArray, QString> attrs;
+ QString family = charFormat.fontFamily();
+ if (!family.isEmpty()) {
+ family = family.replace('\\',QStringLiteral("\\\\"));
+ family = family.replace(':',QStringLiteral("\\:"));
+ family = family.replace(',',QStringLiteral("\\,"));
+ family = family.replace('=',QStringLiteral("\\="));
+ family = family.replace(';',QStringLiteral("\\;"));
+ family = family.replace('\"',QStringLiteral("\\\""));
+ attrs["font-family"] = QString::fromLatin1("\"%1\"").arg(family);
+ }
+
+ int fontSize = int(charFormat.fontPointSize());
+ if (fontSize)
+ attrs["font-size"] = QString::fromLatin1("%1pt").arg(fontSize);
+
+ //Different weight values are not handled
+ attrs["font-weight"] = QString::fromLatin1(charFormat.fontWeight() > QFont::Normal ? "bold" : "normal");
+
+ QFont::Style style = charFormat.font().style();
+ attrs["font-style"] = QString::fromLatin1((style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal"));
+
+ attrs["text-underline-style"] = QString::fromLatin1(charFormat.font().underline() ? "solid" : "none");
+
+ QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment();
+ attrs["text-position"] = QString::fromLatin1((alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" ));
+
+ QBrush background = charFormat.background();
+ if (background.style() == Qt::SolidPattern) {
+ attrs["background-color"] = QString::fromLatin1("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue());
+ }
+
+ QBrush foreground = charFormat.foreground();
+ if (foreground.style() == Qt::SolidPattern) {
+ attrs["color"] = QString::fromLatin1("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue());
+ }
+
+ switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) {
+ case Qt::AlignLeft:
+ attrs["text-align"] = QStringLiteral("left");
+ break;
+ case Qt::AlignRight:
+ attrs["text-align"] = QStringLiteral("right");
+ break;
+ case Qt::AlignHCenter:
+ attrs["text-align"] = QStringLiteral("center");
+ break;
+ case Qt::AlignJustify:
+ attrs["text-align"] = QStringLiteral("left");
+ break;
+ }
+
+ QString result;
+ foreach (const QByteArray &attributeName, attrs.keys()) {
+ result.append(QString::fromLatin1(attributeName)).append(':').append(attrs[attributeName]).append(';');
+ }
+
+ return result;
+}
+
+int QAccessibleTextWidget::cursorPosition() const
+{
+ return textCursor().position();
+}
+
+void QAccessibleTextWidget::selection(int selectionIndex, int *startOffset, int *endOffset) const
+{
+ *startOffset = *endOffset = 0;
+ QTextCursor cursor = textCursor();
+
+ if (selectionIndex != 0 || !cursor.hasSelection())
+ return;
+
+ *startOffset = cursor.selectionStart();
+ *endOffset = cursor.selectionEnd();
+}
+
+QString QAccessibleTextWidget::text(int startOffset, int endOffset) const
+{
+ QTextCursor cursor(textCursor());
+
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+
+ return cursor.selectedText().replace(QChar(QChar::ParagraphSeparator), QLatin1Char('\n'));
+}
+
+QPoint QAccessibleTextWidget::scrollBarPosition() const
+{
+ return QPoint(0, 0);
+}
+
+
+QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ cursor.setPosition(boundaries.first - 1);
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return text(boundaries.first, boundaries.second);
+ }
+
+
+QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ cursor.setPosition(boundaries.second);
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return text(boundaries.first, boundaries.second);
+}
+
+QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return text(boundaries.first, boundaries.second);
+}
+
+void QAccessibleTextWidget::setCursorPosition(int position)
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(position);
+ setTextCursor(cursor);
+}
+
+void QAccessibleTextWidget::addSelection(int startOffset, int endOffset)
+{
+ setSelection(0, startOffset, endOffset);
+}
+
+void QAccessibleTextWidget::removeSelection(int selectionIndex)
+{
+ if (selectionIndex != 0)
+ return;
+
+ QTextCursor cursor = textCursor();
+ cursor.clearSelection();
+ setTextCursor(cursor);
+}
+
+void QAccessibleTextWidget::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ if (selectionIndex != 0)
+ return;
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+ setTextCursor(cursor);
+}
+
+int QAccessibleTextWidget::characterCount() const
+{
+ QTextCursor cursor = textCursor();
+ cursor.movePosition(QTextCursor::End);
+ return cursor.position();
+}
+
+QTextCursor QAccessibleTextWidget::textCursorForRange(int startOffset, int endOffset) const
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
+ cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
+
+ return cursor;
+}
+
+void QAccessibleTextWidget::deleteText(int startOffset, int endOffset)
+{
+ QTextCursor cursor = textCursorForRange(startOffset, endOffset);
+ cursor.removeSelectedText();
+}
+
+void QAccessibleTextWidget::insertText(int offset, const QString &text)
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ cursor.insertText(text);
+}
+
+void QAccessibleTextWidget::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ QTextCursor cursor = textCursorForRange(startOffset, endOffset);
+ cursor.removeSelectedText();
+ cursor.insertText(text);
+}
+#endif // QT_NO_CURSOR
+
+
+#ifndef QT_NO_MAINWINDOW
+QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
+ : QAccessibleWidget(widget, QAccessible::Window) { }
+
+QAccessibleInterface *QAccessibleMainWindow::child(int index) const
+{
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ if (index >= 0 && index < kids.count()) {
+ return QAccessible::queryAccessibleInterface(kids.at(index));
+ }
+ return 0;
+}
+
+int QAccessibleMainWindow::childCount() const
+{
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ return kids.count();
+}
+
+int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const
+{
+ QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ return kids.indexOf(static_cast<QWidget*>(iface->object()));
+}
+
+QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const
+{
+ QWidget *w = widget();
+ if (!w->isVisible())
+ return 0;
+ QPoint gp = w->mapToGlobal(QPoint(0, 0));
+ if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
+ return 0;
+
+ QWidgetList kids = childWidgets(mainWindow(), true);
+ QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
+ for (int i = 0; i < kids.size(); ++i) {
+ QWidget *child = kids.at(i);
+ if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
+ return QAccessible::queryAccessibleInterface(child);
+ }
+ }
+ return 0;
+}
+
+QMainWindow *QAccessibleMainWindow::mainWindow() const
+{
+ return qobject_cast<QMainWindow *>(object());
+}
+
+#endif //QT_NO_MAINWINDOW
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/qaccessiblewidgets.h b/src/widgets/accessible/qaccessiblewidgets.h
new file mode 100644
index 0000000000..3f50010685
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidgets.h
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEWIDGETS_H
+#define QACCESSIBLEWIDGETS_H
+
+#include <QtWidgets/qaccessiblewidget.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include <QtCore/QPointer>
+#include <QtCore/QPair>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+class QStackedWidget;
+class QToolBox;
+class QMdiArea;
+class QMdiSubWindow;
+class QRubberBand;
+class QTextBrowser;
+class QCalendarWidget;
+class QAbstractItemView;
+class QDockWidget;
+class QDockWidgetLayout;
+class QMainWindow;
+class QPlainTextEdit;
+class QTextCursor;
+class QTextDocument;
+
+#ifndef QT_NO_CURSOR
+class QAccessibleTextWidget : public QAccessibleWidget,
+ public QAccessibleTextInterface,
+ public QAccessibleEditableTextInterface
+{
+public:
+ QAccessibleTextWidget(QWidget *o, QAccessible::Role r = QAccessible::EditableText, const QString &name = QString());
+
+ QAccessible::State state() const;
+
+ // QAccessibleTextInterface
+ // selection
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int selectionCount() const Q_DECL_OVERRIDE;
+ void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ void removeSelection(int selectionIndex) Q_DECL_OVERRIDE;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE;
+
+ // cursor
+ int cursorPosition() const Q_DECL_OVERRIDE;
+ void setCursorPosition(int position) Q_DECL_OVERRIDE;
+
+ // text
+ QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE;
+ QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int characterCount() const;
+
+ // character <-> geometry
+ QRect characterRect(int offset) const Q_DECL_OVERRIDE;
+ int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE;
+
+ QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+
+ // QAccessibleEditableTextInterface
+ void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ void insertText(int offset, const QString &text) Q_DECL_OVERRIDE;
+ void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE;
+
+ using QAccessibleWidget::text;
+
+protected:
+ QTextCursor textCursorForRange(int startOffset, int endOffset) const;
+ virtual QPoint scrollBarPosition() const;
+ // return the current text cursor at the caret position including a potential selection
+ virtual QTextCursor textCursor() const = 0;
+ virtual void setTextCursor(const QTextCursor &) = 0;
+ virtual QTextDocument *textDocument() const = 0;
+ virtual QWidget *viewport() const = 0;
+};
+
+#ifndef QT_NO_TEXTEDIT
+class QAccessiblePlainTextEdit : public QAccessibleTextWidget
+{
+public:
+ explicit QAccessiblePlainTextEdit(QWidget *o);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleTextInterface
+ void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE;
+
+ using QAccessibleTextWidget::text;
+
+protected:
+ QPlainTextEdit *plainTextEdit() const;
+
+ QPoint scrollBarPosition() const Q_DECL_OVERRIDE;
+ QTextCursor textCursor() const Q_DECL_OVERRIDE;
+ void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE;
+ QTextDocument *textDocument() const Q_DECL_OVERRIDE;
+ QWidget *viewport() const Q_DECL_OVERRIDE;
+};
+
+class QAccessibleTextEdit : public QAccessibleTextWidget
+{
+public:
+ explicit QAccessibleTextEdit(QWidget *o);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleTextInterface
+ void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE;
+
+ using QAccessibleTextWidget::text;
+
+protected:
+ QTextEdit *textEdit() const;
+
+ QPoint scrollBarPosition() const Q_DECL_OVERRIDE;
+ QTextCursor textCursor() const Q_DECL_OVERRIDE;
+ void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE;
+ QTextDocument *textDocument() const Q_DECL_OVERRIDE;
+ QWidget *viewport() const Q_DECL_OVERRIDE;
+};
+#endif // QT_NO_TEXTEDIT
+#endif //QT_NO_CURSOR
+
+class QAccessibleStackedWidget : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleStackedWidget(QWidget *widget);
+
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+protected:
+ QStackedWidget *stackedWidget() const;
+};
+
+class QAccessibleToolBox : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleToolBox(QWidget *widget);
+
+// FIXME we currently expose the toolbox but it is not keyboard navigatable
+// and the accessible hierarchy is not exactly beautiful.
+// int childCount() const;
+// QAccessibleInterface *child(int index) const;
+// int indexOfChild(const QAccessibleInterface *child) const;
+
+protected:
+ QToolBox *toolBox() const;
+};
+
+#ifndef QT_NO_MDIAREA
+class QAccessibleMdiArea : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleMdiArea(QWidget *widget);
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+
+protected:
+ QMdiArea *mdiArea() const;
+};
+
+class QAccessibleMdiSubWindow : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleMdiSubWindow(QWidget *widget);
+
+ QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text textType, const QString &text) Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+
+protected:
+ QMdiSubWindow *mdiSubWindow() const;
+};
+#endif // QT_NO_MDIAREA
+
+class QAccessibleDialogButtonBox : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleDialogButtonBox(QWidget *widget);
+};
+
+#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR)
+class QAccessibleTextBrowser : public QAccessibleTextEdit
+{
+public:
+ explicit QAccessibleTextBrowser(QWidget *widget);
+
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+};
+#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR
+
+#ifndef QT_NO_CALENDARWIDGET
+class QAccessibleCalendarWidget : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleCalendarWidget(QWidget *widget);
+
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+protected:
+ QCalendarWidget *calendarWidget() const;
+
+private:
+ QAbstractItemView *calendarView() const;
+ QWidget *navigationBar() const;
+};
+#endif // QT_NO_CALENDARWIDGET
+
+#ifndef QT_NO_DOCKWIDGET
+class QAccessibleDockWidget: public QAccessibleWidget
+{
+public:
+ explicit QAccessibleDockWidget(QWidget *widget);
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ QRect rect () const Q_DECL_OVERRIDE;
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ QDockWidget *dockWidget() const;
+protected:
+ QDockWidgetLayout *dockWidgetLayout() const;
+};
+
+#endif // QT_NO_DOCKWIDGET
+
+#ifndef QT_NO_MAINWINDOW
+class QAccessibleMainWindow : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleMainWindow(QWidget *widget);
+
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ QMainWindow *mainWindow() const;
+
+};
+#endif //QT_NO_MAINWINDOW
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // QACESSIBLEWIDGETS_H
diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp
new file mode 100644
index 0000000000..f2d98df719
--- /dev/null
+++ b/src/widgets/accessible/rangecontrols.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rangecontrols.h"
+
+#include <qslider.h>
+#include <qdial.h>
+#include <qspinbox.h>
+#include <qscrollbar.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qdebug.h>
+#include <qglobal.h>
+#include <QDoubleSpinBox>
+#include <QDial>
+#include <qmath.h>
+#include <private/qmath_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_SPINBOX
+QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
+: QAccessibleWidget(w, QAccessible::SpinBox)
+{
+ Q_ASSERT(abstractSpinBox());
+}
+
+/*!
+ Returns the underlying QAbstractSpinBox.
+*/
+QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
+{
+ return qobject_cast<QAbstractSpinBox*>(object());
+}
+
+QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Value)
+ return abstractSpinBox()->text();
+ return QAccessibleWidget::text(t);
+}
+
+void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ValueInterface)
+ return static_cast<QAccessibleValueInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+QVariant QAccessibleAbstractSpinBox::currentValue() const
+{
+ QVariant result = abstractSpinBox()->property("value");
+ QVariant::Type type = result.type();
+
+ // IA2 only allows numeric types
+ if (type == QVariant::Int || type == QVariant::UInt || type == QVariant::LongLong
+ || type == QVariant::ULongLong || type == QVariant::Double)
+ return result;
+
+ return QVariant();
+}
+
+void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value)
+{
+ abstractSpinBox()->setProperty("value", value);
+}
+
+QVariant QAccessibleAbstractSpinBox::maximumValue() const
+{
+ return abstractSpinBox()->property("maximum");
+}
+
+QVariant QAccessibleAbstractSpinBox::minimumValue() const
+{
+ return abstractSpinBox()->property("minimum");
+}
+
+QVariant QAccessibleAbstractSpinBox::minimumStepSize() const
+{
+ return abstractSpinBox()->property("stepSize");
+}
+
+/*!
+ \class QAccessibleSpinBox
+ \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleSpinWidget object for \a w.
+*/
+QAccessibleSpinBox::QAccessibleSpinBox(QWidget *w)
+: QAccessibleAbstractSpinBox(w)
+{
+ Q_ASSERT(spinBox());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+ addControllingSignal(QLatin1String("valueChanged(QString)"));
+}
+
+/*!
+ Returns the underlying QSpinBox.
+*/
+QSpinBox *QAccessibleSpinBox::spinBox() const
+{
+ return qobject_cast<QSpinBox*>(object());
+}
+
+
+// ================================== QAccessibleDoubleSpinBox ==================================
+QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget)
+ : QAccessibleAbstractSpinBox(widget)
+{
+ Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget));
+ addControllingSignal(QLatin1String("valueChanged(double)"));
+ addControllingSignal(QLatin1String("valueChanged(QString)"));
+}
+
+/*!
+ Returns the underlying QDoubleSpinBox.
+*/
+QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
+{
+ return static_cast<QDoubleSpinBox*>(object());
+}
+
+QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const
+{
+ if (textType == QAccessible::Value)
+ return doubleSpinBox()->textFromValue(doubleSpinBox()->value());
+ return QAccessibleWidget::text(textType);
+}
+
+#endif // QT_NO_SPINBOX
+
+#ifndef QT_NO_SCROLLBAR
+/*!
+ \class QAccessibleScrollBar
+ \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleScrollBar object for \a w.
+ \a name is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w)
+: QAccessibleAbstractSlider(w, QAccessible::ScrollBar)
+{
+ Q_ASSERT(scrollBar());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+/*! Returns the scroll bar. */
+QScrollBar *QAccessibleScrollBar::scrollBar() const
+{
+ return qobject_cast<QScrollBar*>(object());
+}
+
+QString QAccessibleScrollBar::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Value)
+ return QString::number(scrollBar()->value());
+ return QAccessibleAbstractSlider::text(t);
+}
+
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+/*!
+ \class QAccessibleSlider
+ \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleScrollBar object for \a w.
+ \a name is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleSlider::QAccessibleSlider(QWidget *w)
+: QAccessibleAbstractSlider(w)
+{
+ Q_ASSERT(slider());
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+/*! Returns the slider. */
+QSlider *QAccessibleSlider::slider() const
+{
+ return qobject_cast<QSlider*>(object());
+}
+
+QString QAccessibleSlider::text(QAccessible::Text t) const
+{
+ if (t == QAccessible::Value)
+ return QString::number(slider()->value());
+
+ return QAccessibleAbstractSlider::text(t);
+}
+
+QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r)
+ : QAccessibleWidget(w, r)
+{
+ Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
+}
+
+void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ValueInterface)
+ return static_cast<QAccessibleValueInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+QVariant QAccessibleAbstractSlider::currentValue() const
+{
+ return abstractSlider()->value();
+}
+
+void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
+{
+ abstractSlider()->setValue(value.toInt());
+}
+
+QVariant QAccessibleAbstractSlider::maximumValue() const
+{
+ return abstractSlider()->maximum();
+}
+
+QVariant QAccessibleAbstractSlider::minimumValue() const
+{
+ return abstractSlider()->minimum();
+}
+
+QVariant QAccessibleAbstractSlider::minimumStepSize() const
+{
+ return abstractSlider()->singleStep();
+}
+
+QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const
+{
+ return static_cast<QAbstractSlider *>(object());
+}
+
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_DIAL
+// ======================================= QAccessibleDial ======================================
+QAccessibleDial::QAccessibleDial(QWidget *widget)
+ : QAccessibleAbstractSlider(widget, QAccessible::Dial)
+{
+ Q_ASSERT(qobject_cast<QDial *>(widget));
+ addControllingSignal(QLatin1String("valueChanged(int)"));
+}
+
+QString QAccessibleDial::text(QAccessible::Text textType) const
+{
+ if (textType == QAccessible::Value)
+ return QString::number(dial()->value());
+
+ return QAccessibleAbstractSlider::text(textType);
+}
+
+QDial *QAccessibleDial::dial() const
+{
+ return static_cast<QDial*>(object());
+}
+#endif // QT_NO_DIAL
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
diff --git a/src/widgets/accessible/rangecontrols.h b/src/widgets/accessible/rangecontrols.h
new file mode 100644
index 0000000000..dd69788bb1
--- /dev/null
+++ b/src/widgets/accessible/rangecontrols.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RANGECONTROLS_H
+#define RANGECONTROLS_H
+
+#include <QtWidgets/qaccessiblewidget.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractSpinBox;
+class QAbstractSlider;
+class QScrollBar;
+class QSlider;
+class QSpinBox;
+class QDoubleSpinBox;
+class QDial;
+
+#ifndef QT_NO_SPINBOX
+class QAccessibleAbstractSpinBox: public QAccessibleWidget, public QAccessibleValueInterface // TODO, public QAccessibleActionInterface
+{
+public:
+ explicit QAccessibleAbstractSpinBox(QWidget *w);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleValueInterface
+ QVariant currentValue() const Q_DECL_OVERRIDE;
+ void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE;
+ QVariant maximumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumStepSize() const Q_DECL_OVERRIDE;
+
+ // FIXME Action interface
+
+protected:
+ QAbstractSpinBox *abstractSpinBox() const;
+};
+
+class QAccessibleSpinBox : public QAccessibleAbstractSpinBox
+{
+public:
+ explicit QAccessibleSpinBox(QWidget *w);
+
+protected:
+ QSpinBox *spinBox() const;
+};
+
+class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox
+{
+public:
+ explicit QAccessibleDoubleSpinBox(QWidget *widget);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+protected:
+ QDoubleSpinBox *doubleSpinBox() const;
+};
+#endif // QT_NO_SPINBOX
+
+class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface
+{
+public:
+ explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider);
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleValueInterface
+ QVariant currentValue() const Q_DECL_OVERRIDE;
+ void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE;
+ QVariant maximumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumStepSize() const Q_DECL_OVERRIDE;
+
+protected:
+ QAbstractSlider *abstractSlider() const;
+};
+
+#ifndef QT_NO_SCROLLBAR
+class QAccessibleScrollBar : public QAccessibleAbstractSlider
+{
+public:
+ explicit QAccessibleScrollBar(QWidget *w);
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+protected:
+ QScrollBar *scrollBar() const;
+};
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+class QAccessibleSlider : public QAccessibleAbstractSlider
+{
+public:
+ explicit QAccessibleSlider(QWidget *w);
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+protected:
+ QSlider *slider() const;
+};
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_DIAL
+class QAccessibleDial : public QAccessibleAbstractSlider
+{
+public:
+ explicit QAccessibleDial(QWidget *w);
+
+ QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE;
+
+protected:
+ QDial *dial() const;
+};
+#endif // QT_NO_DIAL
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // RANGECONTROLS_H
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp
new file mode 100644
index 0000000000..89bda70f31
--- /dev/null
+++ b/src/widgets/accessible/simplewidgets.cpp
@@ -0,0 +1,904 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "simplewidgets.h"
+
+#include <qabstractbutton.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qprogressbar.h>
+#include <qstatusbar.h>
+#include <qradiobutton.h>
+#include <qtoolbutton.h>
+#include <qmenu.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <qlcdnumber.h>
+#include <qlineedit.h>
+#include <private/qlineedit_p.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qtextdocument.h>
+#include <qwindow.h>
+#include <private/qwindowcontainer_p.h>
+#include <QtCore/qvarlengtharray.h>
+
+#ifdef Q_OS_MAC
+#include <qfocusframe.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
+
+QString qt_accStripAmp(const QString &text);
+QString qt_accHotKey(const QString &text);
+
+/*!
+ \class QAccessibleButton
+ \brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Creates a QAccessibleButton object for \a w.
+ \a role is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleButton::QAccessibleButton(QWidget *w, QAccessible::Role role)
+: QAccessibleWidget(w, role)
+{
+ Q_ASSERT(button());
+ if (button()->isCheckable())
+ addControllingSignal(QLatin1String("toggled(bool)"));
+ else
+ addControllingSignal(QLatin1String("clicked()"));
+}
+
+/*! Returns the button. */
+QAbstractButton *QAccessibleButton::button() const
+{
+ return qobject_cast<QAbstractButton*>(object());
+}
+
+/*! \reimp */
+QString QAccessibleButton::text(QAccessible::Text t) const
+{
+ QString str;
+ switch (t) {
+ case QAccessible::Accelerator:
+ {
+#ifndef QT_NO_SHORTCUT
+ QPushButton *pb = qobject_cast<QPushButton*>(object());
+ if (pb && pb->isDefault())
+ str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText);
+#endif
+ if (str.isEmpty())
+ str = qt_accHotKey(button()->text());
+ }
+ break;
+ case QAccessible::Name:
+ str = widget()->accessibleName();
+ if (str.isEmpty())
+ str = button()->text();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidget::text(t);
+ return qt_accStripAmp(str);
+}
+
+QAccessible::State QAccessibleButton::state() const
+{
+ QAccessible::State state = QAccessibleWidget::state();
+
+ QAbstractButton *b = button();
+ QCheckBox *cb = qobject_cast<QCheckBox *>(b);
+ if (b->isCheckable())
+ state.checkable = true;
+ if (b->isChecked())
+ state.checked = true;
+ else if (cb && cb->checkState() == Qt::PartiallyChecked)
+ state.checkStateMixed = true;
+ if (b->isDown())
+ state.pressed = true;
+ QPushButton *pb = qobject_cast<QPushButton*>(b);
+ if (pb) {
+ if (pb->isDefault())
+ state.defaultButton = true;
+#ifndef QT_NO_MENU
+ if (pb->menu())
+ state.hasPopup = true;
+#endif
+ }
+
+ return state;
+}
+
+QRect QAccessibleButton::rect() const
+{
+ QAbstractButton *ab = button();
+ if (!ab->isVisible())
+ return QRect();
+
+ if (QCheckBox *cb = qobject_cast<QCheckBox *>(ab)) {
+ QPoint wpos = cb->mapToGlobal(QPoint(0, 0));
+ QStyleOptionButton opt;
+ cb->initStyleOption(&opt);
+ return cb->style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, cb).translated(wpos);
+ } else if (QRadioButton *rb = qobject_cast<QRadioButton *>(ab)) {
+ QPoint wpos = rb->mapToGlobal(QPoint(0, 0));
+ QStyleOptionButton opt;
+ rb->initStyleOption(&opt);
+ return rb->style()->subElementRect(QStyle::SE_RadioButtonClickRect, &opt, rb).translated(wpos);
+ }
+ return QAccessibleWidget::rect();
+}
+
+QStringList QAccessibleButton::actionNames() const
+{
+ QStringList names;
+ if (widget()->isEnabled()) {
+ switch (role()) {
+ case QAccessible::ButtonMenu:
+ names << showMenuAction();
+ break;
+ case QAccessible::RadioButton:
+ names << toggleAction();
+ break;
+ default:
+ if (button()->isCheckable()) {
+ names << toggleAction();
+ } else {
+ names << pressAction();
+ }
+ break;
+ }
+ }
+ names << QAccessibleWidget::actionNames();
+ return names;
+}
+
+void QAccessibleButton::doAction(const QString &actionName)
+{
+ if (!widget()->isEnabled())
+ return;
+ if (actionName == pressAction() ||
+ actionName == showMenuAction()) {
+#ifndef QT_NO_MENU
+ QPushButton *pb = qobject_cast<QPushButton*>(object());
+ if (pb && pb->menu())
+ pb->showMenu();
+ else
+#endif
+ button()->animateClick();
+ } else if (actionName == toggleAction()) {
+ button()->toggle();
+ } else {
+ QAccessibleWidget::doAction(actionName);
+ }
+}
+
+QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const
+{
+ if (actionName == pressAction()) {
+#ifndef QT_NO_SHORTCUT
+ return QStringList() << button()->shortcut().toString();
+#endif
+ }
+ return QStringList();
+}
+
+
+#ifndef QT_NO_TOOLBUTTON
+/*!
+ \class QAccessibleToolButton
+ \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Creates a QAccessibleToolButton object for \a w.
+ \a role is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleToolButton::QAccessibleToolButton(QWidget *w, QAccessible::Role role)
+: QAccessibleButton(w, role)
+{
+ Q_ASSERT(toolButton());
+}
+
+/*! Returns the button. */
+QToolButton *QAccessibleToolButton::toolButton() const
+{
+ return qobject_cast<QToolButton*>(object());
+}
+
+/*!
+ Returns \c true if this tool button is a split button.
+*/
+bool QAccessibleToolButton::isSplitButton() const
+{
+#ifndef QT_NO_MENU
+ return toolButton()->menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup;
+#else
+ return false;
+#endif
+}
+
+QAccessible::State QAccessibleToolButton::state() const
+{
+ QAccessible::State st = QAccessibleButton::state();
+ if (toolButton()->autoRaise())
+ st.hotTracked = true;
+#ifndef QT_NO_MENU
+ if (toolButton()->menu())
+ st.hasPopup = true;
+#endif
+ return st;
+}
+
+int QAccessibleToolButton::childCount() const
+{
+ return isSplitButton() ? 1 : 0;
+}
+
+QAccessibleInterface *QAccessibleToolButton::child(int index) const
+{
+#ifndef QT_NO_MENU
+ if (index == 0 && toolButton()->menu())
+ {
+ return QAccessible::queryAccessibleInterface(toolButton()->menu());
+ }
+#endif
+ return 0;
+}
+
+/*!
+ \internal
+
+ Returns the button's text label, depending on the text \a t, and
+ the \a child.
+*/
+QString QAccessibleToolButton::text(QAccessible::Text t) const
+{
+ QString str;
+ switch (t) {
+ case QAccessible::Name:
+ str = toolButton()->accessibleName();
+ if (str.isEmpty())
+ str = toolButton()->text();
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleButton::text(t);
+ return qt_accStripAmp(str);
+}
+
+/*
+ The three different tool button types can have the following actions:
+| DelayedPopup | ShowMenuAction + (PressedAction || CheckedAction) |
+| MenuButtonPopup | ShowMenuAction + (PressedAction || CheckedAction) |
+| InstantPopup | ShowMenuAction |
+*/
+QStringList QAccessibleToolButton::actionNames() const
+{
+ QStringList names;
+ if (widget()->isEnabled()) {
+ if (toolButton()->menu())
+ names << showMenuAction();
+ if (toolButton()->popupMode() != QToolButton::InstantPopup)
+ names << QAccessibleButton::actionNames();
+ }
+ return names;
+}
+
+void QAccessibleToolButton::doAction(const QString &actionName)
+{
+ if (!widget()->isEnabled())
+ return;
+
+ if (actionName == pressAction()) {
+ button()->click();
+ } else if (actionName == showMenuAction()) {
+ if (toolButton()->popupMode() != QToolButton::InstantPopup) {
+ toolButton()->setDown(true);
+#ifndef QT_NO_MENU
+ toolButton()->showMenu();
+#endif
+ }
+ } else {
+ QAccessibleButton::doAction(actionName);
+ }
+
+}
+
+#endif // QT_NO_TOOLBUTTON
+
+/*!
+ \class QAccessibleDisplay
+ \brief The QAccessibleDisplay class implements the QAccessibleInterface for widgets that display information.
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleDisplay object for \a w.
+ \a role is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role)
+: QAccessibleWidget(w, role)
+{
+}
+
+QAccessible::Role QAccessibleDisplay::role() const
+{
+ QLabel *l = qobject_cast<QLabel*>(object());
+ if (l) {
+ if (l->pixmap())
+ return QAccessible::Graphic;
+#ifndef QT_NO_PICTURE
+ if (l->picture())
+ return QAccessible::Graphic;
+#endif
+#ifndef QT_NO_MOVIE
+ if (l->movie())
+ return QAccessible::Animation;
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ } else if (qobject_cast<QProgressBar*>(object())) {
+ return QAccessible::ProgressBar;
+#endif
+ } else if (qobject_cast<QStatusBar*>(object())) {
+ return QAccessible::StatusBar;
+ }
+ return QAccessibleWidget::role();
+}
+
+QString QAccessibleDisplay::text(QAccessible::Text t) const
+{
+ QString str;
+ switch (t) {
+ case QAccessible::Name:
+ str = widget()->accessibleName();
+ if (str.isEmpty()) {
+ if (qobject_cast<QLabel*>(object())) {
+ QLabel *label = qobject_cast<QLabel*>(object());
+ str = label->text();
+ if (label->textFormat() == Qt::RichText
+ || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) {
+ QTextDocument doc;
+ doc.setHtml(str);
+ str = doc.toPlainText();
+ }
+#ifndef QT_NO_LCDNUMBER
+ } else if (qobject_cast<QLCDNumber*>(object())) {
+ QLCDNumber *l = qobject_cast<QLCDNumber*>(object());
+ if (l->digitCount())
+ str = QString::number(l->value());
+ else
+ str = QString::number(l->intValue());
+#endif
+ } else if (qobject_cast<QStatusBar*>(object())) {
+ return qobject_cast<QStatusBar*>(object())->currentMessage();
+ }
+ }
+ break;
+ case QAccessible::Value:
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar*>(object()))
+ str = QString::number(qobject_cast<QProgressBar*>(object())->value());
+#endif
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidget::text(t);
+ return qt_accStripAmp(str);
+}
+
+/*! \reimp */
+QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
+QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
+{
+ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match);
+ if (match & QAccessible::Labelled) {
+ QVarLengthArray<QObject *, 4> relatedObjects;
+
+#ifndef QT_NO_SHORTCUT
+ if (QLabel *label = qobject_cast<QLabel*>(object())) {
+ relatedObjects.append(label->buddy());
+ }
+#endif
+ for (int i = 0; i < relatedObjects.count(); ++i) {
+ const QAccessible::Relation rel = QAccessible::Labelled;
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i));
+ if (iface)
+ rels.append(qMakePair(iface, rel));
+ }
+ }
+ return rels;
+}
+
+void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ImageInterface)
+ return static_cast<QAccessibleImageInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+/*! \internal */
+QString QAccessibleDisplay::imageDescription() const
+{
+#ifndef QT_NO_TOOLTIP
+ return widget()->toolTip();
+#else
+ return QString::null;
+#endif
+}
+
+/*! \internal */
+QSize QAccessibleDisplay::imageSize() const
+{
+ QLabel *label = qobject_cast<QLabel *>(widget());
+ if (!label)
+ return QSize();
+ const QPixmap *pixmap = label->pixmap();
+ if (!pixmap)
+ return QSize();
+ return pixmap->size();
+}
+
+/*! \internal */
+QPoint QAccessibleDisplay::imagePosition() const
+{
+ QLabel *label = qobject_cast<QLabel *>(widget());
+ if (!label)
+ return QPoint();
+ const QPixmap *pixmap = label->pixmap();
+ if (!pixmap)
+ return QPoint();
+
+ return QPoint(label->mapToGlobal(label->pos()));
+}
+
+#ifndef QT_NO_GROUPBOX
+QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w)
+: QAccessibleWidget(w)
+{
+}
+
+QGroupBox* QAccessibleGroupBox::groupBox() const
+{
+ return static_cast<QGroupBox *>(widget());
+}
+
+QString QAccessibleGroupBox::text(QAccessible::Text t) const
+{
+ QString txt = QAccessibleWidget::text(t);
+
+ if (txt.isEmpty()) {
+ switch (t) {
+ case QAccessible::Name:
+ txt = qt_accStripAmp(groupBox()->title());
+ break;
+ case QAccessible::Description:
+ txt = qt_accStripAmp(groupBox()->toolTip());
+ break;
+ default:
+ break;
+ }
+ }
+
+ return txt;
+}
+
+QAccessible::State QAccessibleGroupBox::state() const
+{
+ QAccessible::State st = QAccessibleWidget::state();
+ st.checkable = groupBox()->isCheckable();
+ st.checked = groupBox()->isChecked();
+ return st;
+}
+
+QAccessible::Role QAccessibleGroupBox::role() const
+{
+ return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping;
+}
+
+QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
+QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
+{
+ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match);
+
+ if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
+ const QList<QWidget*> kids = childWidgets(widget());
+ for (int i = 0; i < kids.count(); ++i) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i));
+ if (iface)
+ rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled)));
+ }
+ }
+ return rels;
+}
+
+QStringList QAccessibleGroupBox::actionNames() const
+{
+ QStringList actions = QAccessibleWidget::actionNames();
+
+ if (groupBox()->isCheckable()) {
+ actions.prepend(QAccessibleActionInterface::toggleAction());
+ }
+ return actions;
+}
+
+void QAccessibleGroupBox::doAction(const QString &actionName)
+{
+ if (actionName == QAccessibleActionInterface::toggleAction())
+ groupBox()->setChecked(!groupBox()->isChecked());
+}
+
+QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
+{
+ return QStringList();
+}
+
+#endif
+
+#ifndef QT_NO_LINEEDIT
+/*!
+ \class QAccessibleLineEdit
+ \brief The QAccessibleLineEdit class implements the QAccessibleInterface for widgets with editable text
+ \internal
+
+ \ingroup accessibility
+*/
+
+/*!
+ Constructs a QAccessibleLineEdit object for \a w.
+ \a name is propagated to the QAccessibleWidget constructor.
+*/
+QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
+: QAccessibleWidget(w, QAccessible::EditableText, name)
+{
+ addControllingSignal(QLatin1String("textChanged(const QString&)"));
+ addControllingSignal(QLatin1String("returnPressed()"));
+}
+
+/*! Returns the line edit. */
+QLineEdit *QAccessibleLineEdit::lineEdit() const
+{
+ return qobject_cast<QLineEdit*>(object());
+}
+
+QString QAccessibleLineEdit::text(QAccessible::Text t) const
+{
+ QString str;
+ switch (t) {
+ case QAccessible::Value:
+ if (lineEdit()->echoMode() == QLineEdit::Normal)
+ str = lineEdit()->text();
+ else if (lineEdit()->echoMode() != QLineEdit::NoEcho)
+ str = QString(lineEdit()->text().length(), QChar::fromLatin1('*'));
+ break;
+ default:
+ break;
+ }
+ if (str.isEmpty())
+ str = QAccessibleWidget::text(t);
+ return qt_accStripAmp(str);
+}
+
+void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text)
+{
+ if (t != QAccessible::Value) {
+ QAccessibleWidget::setText(t, text);
+ return;
+ }
+
+ QString newText = text;
+ if (lineEdit()->validator()) {
+ int pos = 0;
+ if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable)
+ return;
+ }
+ lineEdit()->setText(newText);
+}
+
+QAccessible::State QAccessibleLineEdit::state() const
+{
+ QAccessible::State state = QAccessibleWidget::state();
+
+ QLineEdit *l = lineEdit();
+ if (l->isReadOnly())
+ state.readOnly = true;
+ else
+ state.editable = true;
+
+ if (l->echoMode() != QLineEdit::Normal)
+ state.passwordEdit = true;
+
+ state.selectableText = true;
+ return state;
+}
+
+void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::TextInterface)
+ return static_cast<QAccessibleTextInterface*>(this);
+ if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
+ return QAccessibleWidget::interface_cast(t);
+}
+
+void QAccessibleLineEdit::addSelection(int startOffset, int endOffset)
+{
+ setSelection(0, startOffset, endOffset);
+}
+
+QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset) const
+{
+ // QLineEdit doesn't have text attributes
+ *startOffset = *endOffset = offset;
+ return QString();
+}
+
+int QAccessibleLineEdit::cursorPosition() const
+{
+ return lineEdit()->cursorPosition();
+}
+
+QRect QAccessibleLineEdit::characterRect(int offset) const
+{
+ int x = lineEdit()->d_func()->control->cursorToX(offset);
+ int y;
+ lineEdit()->getTextMargins(0, &y, 0, 0);
+ QFontMetrics fm(lineEdit()->font());
+ const QString ch = text(offset, offset + 1);
+ if (ch.isEmpty())
+ return QRect();
+ int w = fm.width(ch);
+ int h = fm.height();
+ QRect r(x, y, w, h);
+ r.moveTo(lineEdit()->mapToGlobal(r.topLeft()));
+ return r;
+}
+
+int QAccessibleLineEdit::selectionCount() const
+{
+ return lineEdit()->hasSelectedText() ? 1 : 0;
+}
+
+int QAccessibleLineEdit::offsetAtPoint(const QPoint &point) const
+{
+ QPoint p = lineEdit()->mapFromGlobal(point);
+
+ return lineEdit()->cursorPositionAt(p);
+}
+
+void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset) const
+{
+ *startOffset = *endOffset = 0;
+ if (selectionIndex != 0)
+ return;
+
+ *startOffset = lineEdit()->selectionStart();
+ *endOffset = *startOffset + lineEdit()->selectedText().count();
+}
+
+QString QAccessibleLineEdit::text(int startOffset, int endOffset) const
+{
+ if (startOffset > endOffset)
+ return QString();
+
+ if (lineEdit()->echoMode() != QLineEdit::Normal)
+ return QString();
+
+ return lineEdit()->text().mid(startOffset, endOffset - startOffset);
+}
+
+QString QAccessibleLineEdit::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+QString QAccessibleLineEdit::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+QString QAccessibleLineEdit::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+void QAccessibleLineEdit::removeSelection(int selectionIndex)
+{
+ if (selectionIndex != 0)
+ return;
+
+ lineEdit()->deselect();
+}
+
+void QAccessibleLineEdit::setCursorPosition(int position)
+{
+ lineEdit()->setCursorPosition(position);
+}
+
+void QAccessibleLineEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ if (selectionIndex != 0)
+ return;
+
+ lineEdit()->setSelection(startOffset, endOffset - startOffset);
+}
+
+int QAccessibleLineEdit::characterCount() const
+{
+ return lineEdit()->text().count();
+}
+
+void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex)
+{
+ lineEdit()->setCursorPosition(endIndex);
+ lineEdit()->setCursorPosition(startIndex);
+}
+
+void QAccessibleLineEdit::deleteText(int startOffset, int endOffset)
+{
+ lineEdit()->setText(lineEdit()->text().remove(startOffset, endOffset - startOffset));
+}
+
+void QAccessibleLineEdit::insertText(int offset, const QString &text)
+{
+ lineEdit()->setText(lineEdit()->text().insert(offset, text));
+}
+
+void QAccessibleLineEdit::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ lineEdit()->setText(lineEdit()->text().replace(startOffset, endOffset - startOffset, text));
+}
+
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_PROGRESSBAR
+QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o)
+ : QAccessibleDisplay(o)
+{
+ Q_ASSERT(progressBar());
+}
+
+void *QAccessibleProgressBar::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ValueInterface)
+ return static_cast<QAccessibleValueInterface*>(this);
+ return QAccessibleDisplay::interface_cast(t);
+}
+
+QVariant QAccessibleProgressBar::currentValue() const
+{
+ return progressBar()->value();
+}
+
+QVariant QAccessibleProgressBar::maximumValue() const
+{
+ return progressBar()->maximum();
+}
+
+QVariant QAccessibleProgressBar::minimumValue() const
+{
+ return progressBar()->minimum();
+}
+
+QVariant QAccessibleProgressBar::minimumStepSize() const
+{
+ // This is arbitrary since any value between min and max is valid.
+ // Some screen readers (orca use it to calculate how many digits to display though,
+ // so it makes sense to return a "sensible" value. Providing 100 increments seems ok.
+ return (progressBar()->maximum() - progressBar()->minimum()) / 100.0;
+}
+
+QProgressBar *QAccessibleProgressBar::progressBar() const
+{
+ return qobject_cast<QProgressBar *>(object());
+}
+#endif
+
+
+QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w)
+ : QAccessibleWidget(w)
+{
+}
+
+int QAccessibleWindowContainer::childCount() const
+{
+ if (container()->containedWindow())
+ return 1;
+ return 0;
+}
+
+int QAccessibleWindowContainer::indexOfChild(const QAccessibleInterface *child) const
+{
+ if (child->object() == container()->containedWindow())
+ return 0;
+ return -1;
+}
+
+QAccessibleInterface *QAccessibleWindowContainer::child(int i) const
+{
+ if (i == 0)
+ return QAccessible::queryAccessibleInterface(container()->containedWindow());
+ return 0;
+}
+
+QWindowContainer *QAccessibleWindowContainer::container() const
+{
+ return static_cast<QWindowContainer *>(widget());
+}
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
diff --git a/src/widgets/accessible/simplewidgets.h b/src/widgets/accessible/simplewidgets.h
new file mode 100644
index 0000000000..af67a1e669
--- /dev/null
+++ b/src/widgets/accessible/simplewidgets.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIMPLEWIDGETS_H
+#define SIMPLEWIDGETS_H
+
+#include <QtCore/qcoreapplication.h>
+#include <QtWidgets/qaccessiblewidget.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAbstractButton;
+class QLineEdit;
+class QToolButton;
+class QGroupBox;
+class QProgressBar;
+
+class QAccessibleButton : public QAccessibleWidget
+{
+ Q_DECLARE_TR_FUNCTIONS(QAccessibleButton)
+public:
+ QAccessibleButton(QWidget *w, QAccessible::Role r);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QRect rect() const Q_DECL_OVERRIDE;
+
+ QStringList actionNames() const Q_DECL_OVERRIDE;
+ void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+ QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE;
+
+protected:
+ QAbstractButton *button() const;
+};
+
+#ifndef QT_NO_TOOLBUTTON
+class QAccessibleToolButton : public QAccessibleButton
+{
+public:
+ QAccessibleToolButton(QWidget *w, QAccessible::Role role);
+
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+
+ int childCount() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ // QAccessibleActionInterface
+ QStringList actionNames() const Q_DECL_OVERRIDE;
+ void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+
+protected:
+ QToolButton *toolButton() const;
+
+ bool isSplitButton() const;
+};
+#endif // QT_NO_TOOLBUTTON
+
+class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface
+{
+public:
+ explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText);
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+
+ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE;
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleImageInterface
+ QString imageDescription() const Q_DECL_OVERRIDE;
+ QSize imageSize() const Q_DECL_OVERRIDE;
+ QPoint imagePosition() const Q_DECL_OVERRIDE;
+};
+
+#ifndef QT_NO_GROUPBOX
+class QAccessibleGroupBox : public QAccessibleWidget
+{
+public:
+ explicit QAccessibleGroupBox(QWidget *w);
+
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ QAccessible::Role role() const Q_DECL_OVERRIDE;
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+
+ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE;
+
+ //QAccessibleActionInterface
+ QStringList actionNames() const Q_DECL_OVERRIDE;
+ void doAction(const QString &actionName) Q_DECL_OVERRIDE;
+ QStringList keyBindingsForAction(const QString &) const Q_DECL_OVERRIDE;
+
+private:
+ QGroupBox *groupBox() const;
+};
+#endif
+
+#ifndef QT_NO_LINEEDIT
+class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface
+{
+public:
+ explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString());
+
+ QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
+ QAccessible::State state() const Q_DECL_OVERRIDE;
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE;
+ QRect characterRect(int offset) const Q_DECL_OVERRIDE;
+ int selectionCount() const Q_DECL_OVERRIDE;
+ int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE;
+ QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ void removeSelection(int selectionIndex) Q_DECL_OVERRIDE;
+ void setCursorPosition(int position) Q_DECL_OVERRIDE;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ int characterCount() const Q_DECL_OVERRIDE;
+ void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE;
+
+ // QAccessibleEditableTextInterface
+ void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ void insertText(int offset, const QString &text) Q_DECL_OVERRIDE;
+ void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE;
+protected:
+ QLineEdit *lineEdit() const;
+};
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_PROGRESSBAR
+class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface
+{
+public:
+ explicit QAccessibleProgressBar(QWidget *o);
+ void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+
+ // QAccessibleValueInterface
+ QVariant currentValue() const Q_DECL_OVERRIDE;
+ QVariant maximumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumValue() const Q_DECL_OVERRIDE;
+ QVariant minimumStepSize() const Q_DECL_OVERRIDE;
+ void setCurrentValue(const QVariant &) Q_DECL_OVERRIDE {}
+
+protected:
+ QProgressBar *progressBar() const;
+};
+#endif
+
+class QWindowContainer;
+class QAccessibleWindowContainer : public QAccessibleWidget
+{
+public:
+ QAccessibleWindowContainer(QWidget *w);
+ int childCount() const Q_DECL_OVERRIDE;
+ int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *child(int i) const Q_DECL_OVERRIDE;
+
+private:
+ QWindowContainer *container() const;
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // SIMPLEWIDGETS_H
diff --git a/src/widgets/accessible/widgets.pro b/src/widgets/accessible/widgets.pro
new file mode 100644
index 0000000000..c6af6d3f71
--- /dev/null
+++ b/src/widgets/accessible/widgets.pro
@@ -0,0 +1,27 @@
+TARGET = qtaccessiblewidgets
+
+PLUGIN_TYPE = accessible
+PLUGIN_EXTENDS = widgets
+PLUGIN_CLASS_NAME = AccessibleFactory
+load(qt_plugin)
+
+QT += core-private gui-private widgets-private
+
+QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)"
+
+SOURCES += main.cpp \
+ simplewidgets.cpp \
+ rangecontrols.cpp \
+ complexwidgets.cpp \
+ qaccessiblewidgets.cpp \
+ qaccessiblemenu.cpp \
+ itemviews.cpp
+
+HEADERS += qaccessiblewidgets.h \
+ simplewidgets.h \
+ rangecontrols.h \
+ complexwidgets.h \
+ qaccessiblemenu.h \
+ itemviews.h
+
+
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 3889a589c7..714dcfa1f4 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1262,9 +1262,17 @@ QColorShower::QColorShower(QColorDialog *parent)
lblHtml->setBuddy(htEd);
#endif
+#if !defined(QT_NO_REGULAREXPRESSION)
QRegularExpression regExp(QStringLiteral("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
htEd->setValidator(validator);
+#elif !defined(QT_NO_REGEXP)
+ QRegExp regExp(QStringLiteral("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
+ QRegExpValidator *validator = new QRegExpValidator(regExp, this);
+ htEd->setValidator(validator);
+#else
+ htEd->setReadOnly(true);
+#endif
lblHtml->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
gl->addWidget(lblHtml, 5, 1);
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index b294e98c30..15f922a5b8 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -1475,7 +1475,7 @@ void QWizardPrivate::updateButtonTexts()
void QWizardPrivate::updateButtonLayout()
{
if (buttonsHaveCustomLayout) {
- QVarLengthArray<QWizard::WizardButton> array(buttonsCustomLayout.count());
+ QVarLengthArray<QWizard::WizardButton, QWizard::NButtons> array(buttonsCustomLayout.count());
for (int i = 0; i < buttonsCustomLayout.count(); ++i)
array[i] = buttonsCustomLayout.at(i);
setButtonLayout(array.constData(), array.count());
diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
index 36d3dc6af4..702c17bc26 100644
--- a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
+++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
@@ -1864,3 +1864,8 @@ QTabBar::close-button:hover {
}
//! [159]
+
+//! [160]
+* { lineedit-password-mask-delay: 1000 }
+//! [160]
+
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index e8c1be4c46..32fe384c75 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -862,6 +862,9 @@
\l{#lineedit-password-character-prop}{lineedit-password-character}
property.
+ The password mask delay can be changed using the
+ \l{#lineedit-password-mask-delay-prop}{lineedit-password-mask-delay}
+
See \l{Qt Style Sheets Examples#Customizing QLineEdit}{Customizing QLineEdit}
for an example.
@@ -2009,6 +2012,23 @@
\snippet code/doc_src_stylesheet.qdoc 61
\row
+ \li \b{\c lineedit-password-mask-delay*} \target lineedit-password-mask-delay-prop
+ \li \l{#Number}{Number}
+ \li The QLineEdit password mask delay in milliseconds before
+ \l{#lineedit-password-character-prop}{lineedit-password-character} is applied to visible character.
+
+ If this property is not specified, it defaults to the
+ value specified by the current style for the
+ \l{QStyle::}{SH_LineEdit_PasswordMaskDelay} style hint.
+
+ \b{This property was added in Qt 5.4.}
+
+ Example:
+
+ \snippet code/doc_src_stylesheet.qdoc 160
+
+
+ \row
\li \b{\c margin} \target margin-prop
\li \l {Box Lengths}
\li The widget's margins. Equivalent to specifying \c
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index e327a8737a..551f229611 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -332,6 +332,8 @@
this flag is disabled; children can draw anywhere. This behavior is
enforced by QGraphicsView::drawItems() or
QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
+ \note This flag is similar to ItemContainsChildrenInShape but in addition
+ enforces the containment by clipping the children.
\value ItemIgnoresTransformations The item ignores inherited
transformations (i.e., its position is still anchored to its parent, but
@@ -423,6 +425,19 @@
ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
allows you to completely take over focus handling.
This flag was introduced in Qt 4.7. \endomit
+
+ \value ItemContainsChildrenInShape This flag indicates that all of the
+ item's direct or indirect children only draw within the item's shape.
+ Unlike ItemClipsChildrenToShape, this restriction is not enforced. Set
+ ItemContainsChildrenInShape when you manually assure that drawing
+ is bound to the item's shape and want to avoid the cost associated with
+ enforcing the clip. Setting this flag enables more efficient drawing and
+ collision detection. The flag is disabled by default.
+ \note If both this flag and ItemClipsChildrenToShape are set, the clip
+ will be enforced. This is equivalent to just setting
+ ItemClipsChildrenToShape.
+ .
+ This flag was introduced in Qt 5.4.
*/
/*!
@@ -836,6 +851,10 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
flag = AncestorIgnoresTransformations;
enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
break;
+ case QGraphicsItem::ItemContainsChildrenInShape:
+ flag = AncestorContainsChildren;
+ enabled = flags & QGraphicsItem::ItemContainsChildrenInShape;
+ break;
default:
return;
}
@@ -895,6 +914,8 @@ void QGraphicsItemPrivate::updateAncestorFlags()
flags |= AncestorClipsChildren;
if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
flags |= AncestorIgnoresTransformations;
+ if (pd->flags & QGraphicsItem::ItemContainsChildrenInShape)
+ flags |= AncestorContainsChildren;
}
if (ancestorFlags == flags)
@@ -1831,6 +1852,11 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->markParentDirty(true);
}
+ if ((flags & ItemContainsChildrenInShape) != (oldFlags & ItemContainsChildrenInShape)) {
+ // Item children containtment changes. Propagate the ancestor flag to all children.
+ d_ptr->updateAncestorFlag(ItemContainsChildrenInShape);
+ }
+
if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
// Item children clipping changes. Propagate the ancestor flag to
// all children.
@@ -2322,7 +2348,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly,
}
// Update children with explicitly = false.
- const bool updateChildren = update && !((flags & QGraphicsItem::ItemClipsChildrenToShape)
+ const bool updateChildren = update && !((flags & QGraphicsItem::ItemClipsChildrenToShape
+ || flags & QGraphicsItem::ItemContainsChildrenInShape)
&& !(flags & QGraphicsItem::ItemHasNoContents));
foreach (QGraphicsItem *child, children) {
if (!newVisible || !child->d_ptr->explicitlyHidden)
@@ -2835,7 +2862,9 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectI
#ifndef QT_NO_GRAPHICSEFFECT
Q_Q(const QGraphicsItem);
QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
- if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
+ if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren
+ || topMostEffectItem == q)
return brect;
const QGraphicsItem *effectParent = parent;
@@ -2847,6 +2876,7 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectI
brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
}
if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren
|| topMostEffectItem == effectParent) {
return brect;
}
@@ -7442,7 +7472,8 @@ QVariant QGraphicsItem::extension(const QVariant &variant) const
*/
void QGraphicsItem::addToIndex()
{
- if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
+ if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren) {
// ### add to child index only if applicable
return;
}
@@ -7459,7 +7490,8 @@ void QGraphicsItem::addToIndex()
*/
void QGraphicsItem::removeFromIndex()
{
- if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
+ if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren) {
// ### remove from child index only if applicable
return;
}
@@ -11451,6 +11483,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemStopsFocusHandling:
str = "ItemStopsFocusHandling";
break;
+ case QGraphicsItem::ItemContainsChildrenInShape:
+ str = "ItemContainsChildrenInShape";
+ break;
}
debug << str;
return debug;
diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h
index 4283deb5b8..dfc06fdaea 100644
--- a/src/widgets/graphicsview/qgraphicsitem.h
+++ b/src/widgets/graphicsview/qgraphicsitem.h
@@ -105,7 +105,8 @@ public:
ItemIsFocusScope = 0x8000, // internal
ItemSendsScenePositionChanges = 0x10000,
ItemStopsClickFocusPropagation = 0x20000,
- ItemStopsFocusHandling = 0x40000
+ ItemStopsFocusHandling = 0x40000,
+ ItemContainsChildrenInShape = 0x80000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index 3968d89a13..4d1835f178 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -172,7 +172,8 @@ public:
AncestorHandlesChildEvents = 0x1,
AncestorClipsChildren = 0x2,
AncestorIgnoresTransformations = 0x4,
- AncestorFiltersChildEvents = 0x8
+ AncestorFiltersChildEvents = 0x8,
+ AncestorContainsChildren = 0x10
};
inline QGraphicsItemPrivate()
@@ -213,7 +214,6 @@ public:
needSortChildren(0),
allChildrenDirty(0),
fullUpdatePending(0),
- dirtyChildrenBoundingRect(1),
flags(0),
paintedViewBoundingRectsNeedRepaint(0),
dirtySceneTransform(1),
@@ -239,6 +239,7 @@ public:
mayHaveChildWithGraphicsEffect(0),
isDeclarativeItem(0),
sendParentChangeNotification(0),
+ dirtyChildrenBoundingRect(1),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -544,7 +545,7 @@ public:
quint32 handlesChildEvents : 1;
quint32 itemDiscovered : 1;
quint32 hasCursor : 1;
- quint32 ancestorFlags : 4;
+ quint32 ancestorFlags : 5;
quint32 cacheMode : 2;
quint32 hasBoundingRegionGranularity : 1;
quint32 isWidget : 1;
@@ -555,10 +556,9 @@ public:
quint32 needSortChildren : 1;
quint32 allChildrenDirty : 1;
quint32 fullUpdatePending : 1;
- quint32 dirtyChildrenBoundingRect : 1;
// Packed 32 bits
- quint32 flags : 19;
+ quint32 flags : 20;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
quint32 geometryChanged : 1;
@@ -571,9 +571,9 @@ public:
quint32 filtersDescendantEvents : 1;
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
- quint32 notifyInvalidated : 1;
// New 32 bits
+ quint32 notifyInvalidated : 1;
quint32 mouseSetsFocus : 1;
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
@@ -585,7 +585,8 @@ public:
quint32 mayHaveChildWithGraphicsEffect : 1;
quint32 isDeclarativeItem : 1;
quint32 sendParentChangeNotification : 1;
- quint32 padding : 21;
+ quint32 dirtyChildrenBoundingRect : 1;
+ quint32 padding : 19;
// Optional stacking order
int globalStackingOrder;
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index bccdb1fbaa..1cd162e6bb 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -299,6 +299,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
painterStateProtection(true),
sortCacheEnabled(false),
allItemsIgnoreTouchEvents(true),
+ minimumRenderSize(0.0),
selectionChanging(0),
rectAdjust(2),
focusItem(0),
@@ -4716,19 +4717,40 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
wasDirtyParentSceneTransform = true;
}
- const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
+ || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
bool drawItem = itemHasContents && !itemIsFullyTransparent;
- if (drawItem) {
+ if (drawItem || minimumRenderSize > 0.0) {
const QRectF brect = adjustedItemEffectiveBoundingRect(item);
ENSURE_TRANSFORM_PTR
- QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
- : transformPtr->mapRect(brect).toAlignedRect();
- viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
- if (widget)
- item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
- drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
- : !viewBoundingRect.normalized().isEmpty();
- if (!drawItem) {
+ QRectF preciseViewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy())
+ : transformPtr->mapRect(brect);
+
+ bool itemIsTooSmallToRender = false;
+ if (minimumRenderSize > 0.0
+ && (preciseViewBoundingRect.width() < minimumRenderSize
+ || preciseViewBoundingRect.height() < minimumRenderSize)) {
+ itemIsTooSmallToRender = true;
+ drawItem = false;
+ }
+
+ bool itemIsOutsideVisibleRect = false;
+ if (drawItem) {
+ QRect viewBoundingRect = preciseViewBoundingRect.toAlignedRect();
+ viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
+ if (widget)
+ item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
+ drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
+ : !viewBoundingRect.normalized().isEmpty();
+ itemIsOutsideVisibleRect = !drawItem;
+ }
+
+ if (itemIsTooSmallToRender || itemIsOutsideVisibleRect) {
+ // We cannot simply use !drawItem here. If we did it is possible
+ // to enter the outter if statement with drawItem == false and minimumRenderSize > 0
+ // and finally end up inside this inner if, even though none of the above two
+ // conditions are met. In that case we should not return from this function
+ // but call draw() instead.
if (!itemHasChildren)
return;
if (itemClipsChildrenToShape) {
@@ -5200,7 +5222,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
// Process children.
if (itemHasChildren && item->d_ptr->dirtyChildren) {
- const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
+ const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
+ || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape;
// Items with no content are threated as 'dummy' items which means they are never drawn and
// 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
// such an item changes geometry, its children have to take care of the update regardless
@@ -5729,6 +5752,49 @@ bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event)
return d->sendEvent(item, event);
}
+/*!
+ \property QGraphicsScene::minimumRenderSize
+ \since 5.4
+ \brief the minimal view-transformed size an item must have to be drawn
+
+ When the scene is rendered, any item whose width or height, transformed
+ to the target view, is smaller that minimumRenderSize(), will not be
+ rendered. If an item is not rendered and it clips its children items
+ they will also not be rendered. Set this value to speed up rendering
+ of scenes with many objects rendered on a zoomed out view.
+
+ The default value is 0. If unset, or if set to 0 or a negative value,
+ all items will always be rendered.
+
+ For example, setting this property can be especially useful if a scene
+ is rendered by multiple views, one of which serves as an overview which
+ always displays all items. In scenes with many items, such a view will
+ use a high scaling factor so that all items can be shown. Due to the
+ scaling, smaller items will only make an insignificant contribution to
+ the final rendered scene. To avoid drawing these items and reduce the
+ time necessary to render the scene, you can call setMinimumRenderSize()
+ with a non-negative value.
+
+ \note Items that are not drawn as a result of being too small, are still
+ returned by methods such as items() and itemAt(), and participate in
+ collision detection and interactions. It is recommended that you set
+ minimumRenderSize() to a value less than or equal to 1 in order to
+ avoid large unrendered items that are interactive.
+
+ \sa QStyleOptionGraphicsItem::levelOfDetailFromTransform()
+*/
+qreal QGraphicsScene::minimumRenderSize() const
+{
+ Q_D(const QGraphicsScene);
+ return d->minimumRenderSize;
+}
+void QGraphicsScene::setMinimumRenderSize(qreal minSize)
+{
+ Q_D(QGraphicsScene);
+ d->minimumRenderSize = minSize;
+ update();
+}
+
void QGraphicsScenePrivate::addView(QGraphicsView *view)
{
views << view;
diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h
index cde0eda125..d95237baef 100644
--- a/src/widgets/graphicsview/qgraphicsscene.h
+++ b/src/widgets/graphicsview/qgraphicsscene.h
@@ -107,6 +107,7 @@ class Q_WIDGETS_EXPORT QGraphicsScene : public QObject
Q_PROPERTY(QFont font READ font WRITE setFont)
Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled)
Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus)
+ Q_PROPERTY(qreal minimumRenderSize READ minimumRenderSize WRITE setMinimumRenderSize)
public:
enum ItemIndexMethod {
@@ -249,6 +250,9 @@ public:
bool sendEvent(QGraphicsItem *item, QEvent *event);
+ qreal minimumRenderSize() const;
+ void setMinimumRenderSize(qreal minSize);
+
public Q_SLOTS:
void update(const QRectF &rect = QRectF());
void invalidate(const QRectF &rect = QRectF(), SceneLayers layers = AllLayers);
@@ -309,6 +313,7 @@ private:
friend class QGraphicsEffect;
friend class QGraphicsSceneIndex;
friend class QGraphicsSceneIndexPrivate;
+ friend class QGraphicsSceneLinearIndex;
friend class QGraphicsSceneBspTreeIndex;
friend class QGraphicsSceneBspTreeIndexPrivate;
friend class QGraphicsItemEffectSourcePrivate;
diff --git a/src/widgets/graphicsview/qgraphicsscene_p.h b/src/widgets/graphicsview/qgraphicsscene_p.h
index 9e5bcec488..9f50dcfea7 100644
--- a/src/widgets/graphicsview/qgraphicsscene_p.h
+++ b/src/widgets/graphicsview/qgraphicsscene_p.h
@@ -117,6 +117,8 @@ public:
quint32 allItemsIgnoreTouchEvents : 1;
quint32 padding : 15;
+ qreal minimumRenderSize;
+
QRectF growingItemsBoundingRect;
void _q_emitUpdated();
diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
index 7598163f2d..50f17ab73f 100644
--- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -169,7 +169,8 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
untransformableItems << item;
continue;
}
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren)
continue;
bsp.insertItem(item, item->d_ptr->sceneEffectiveBoundingRect());
@@ -351,7 +352,8 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec
// Avoid virtual function calls from the destructor.
purgePending = true;
removedItems << item;
- } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
+ } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren)) {
bsp.removeItem(item, item->d_ptr->sceneEffectiveBoundingRect());
}
} else {
@@ -510,7 +512,8 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *
return;
if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable()
- || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
+ || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren)) {
return; // Item is not in BSP tree; nothing to do.
}
@@ -641,8 +644,10 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value);
bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations;
bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations;
- bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
- bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape;
+ bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
+ || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape;
+ bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape
+ || newFlags & QGraphicsItem::ItemContainsChildrenInShape;
if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) {
QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
// Remove item and its descendants from the index and append
@@ -663,10 +668,13 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics
bool ignoredTransform = item->d_ptr->itemIsUntransformable();
bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations)
|| (newParent && newParent->d_ptr->itemIsUntransformable());
- bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren;
+ bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren;
bool ancestorWillClipChildren = newParent
- && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)
- || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren));
+ && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
+ || newParent->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape)
+ || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorContainsChildren));
if ((ignoredTransform != willIgnoreTransform) || (ancestorClippedChildren != ancestorWillClipChildren)) {
QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
// Remove item and its descendants from the index and append
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp
index 631aa7bf19..be91c63fad 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp
@@ -348,7 +348,7 @@ class QGraphicsSceneMouseEventPrivate : public QGraphicsSceneEventPrivate
public:
inline QGraphicsSceneMouseEventPrivate()
: button(Qt::NoButton),
- buttons(0), modifiers(0)
+ buttons(0), modifiers(0), source(Qt::MouseEventNotSynthesized), flags(0)
{ }
QPointF pos;
@@ -363,6 +363,8 @@ public:
Qt::MouseButton button;
Qt::MouseButtons buttons;
Qt::KeyboardModifiers modifiers;
+ Qt::MouseEventSource source;
+ Qt::MouseEventFlags flags;
};
/*!
@@ -626,6 +628,60 @@ Qt::KeyboardModifiers QGraphicsSceneMouseEvent::modifiers() const
}
/*!
+ \since 5.4
+
+ Returns information about the mouse event source.
+
+ The mouse event source can be used to distinguish between genuine
+ and artificial mouse events. The latter are events that are
+ synthesized from touch events by the operating system or Qt itself.
+
+ \sa Qt::MouseEventSource
+ \sa QMouseEvent::source()
+ */
+Qt::MouseEventSource QGraphicsSceneMouseEvent::source() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->source;
+}
+
+/*!
+ \since 5.4
+ \internal
+ */
+void QGraphicsSceneMouseEvent::setSource(Qt::MouseEventSource source)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->source = source;
+}
+
+/*!
+ \since 5.4
+
+ Returns the mouse event flags.
+
+ The mouse event flags provide additional information about a mouse event.
+
+ \sa Qt::MouseEventFlag
+ \sa QMouseEvent::flags()
+ */
+Qt::MouseEventFlags QGraphicsSceneMouseEvent::flags() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->flags;
+}
+
+/*!
+ \since 5.4
+ \internal
+ */
+void QGraphicsSceneMouseEvent::setFlags(Qt::MouseEventFlags flags)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->flags = flags;
+}
+
+/*!
\internal
*/
void QGraphicsSceneMouseEvent::setModifiers(Qt::KeyboardModifiers modifiers)
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.h b/src/widgets/graphicsview/qgraphicssceneevent.h
index e744d08edf..2c9c1f3f50 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.h
+++ b/src/widgets/graphicsview/qgraphicssceneevent.h
@@ -121,6 +121,12 @@ public:
Qt::KeyboardModifiers modifiers() const;
void setModifiers(Qt::KeyboardModifiers modifiers);
+ Qt::MouseEventSource source() const;
+ void setSource(Qt::MouseEventSource source);
+
+ Qt::MouseEventFlags flags() const;
+ void setFlags(Qt::MouseEventFlags);
+
private:
Q_DECLARE_PRIVATE(QGraphicsSceneMouseEvent)
Q_DISABLE_COPY(QGraphicsSceneMouseEvent)
diff --git a/src/widgets/graphicsview/qgraphicssceneindex.cpp b/src/widgets/graphicsview/qgraphicssceneindex.cpp
index 40f63937f4..d06c5523ca 100644
--- a/src/widgets/graphicsview/qgraphicssceneindex.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneindex.cpp
@@ -278,7 +278,8 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
Q_ASSERT(!item->d_ptr->dirtySceneTransform);
}
- const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
+ || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
bool processItem = !itemIsFullyTransparent;
if (processItem) {
processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
diff --git a/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h b/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h
index 7debcfb501..baf3de3755 100644
--- a/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h
+++ b/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h
@@ -70,31 +70,62 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex
Q_OBJECT
public:
- QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene)
+ QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene), m_itemsIsValid(true)
{ }
QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::DescendingOrder) const
- { Q_UNUSED(order); return m_items; }
+ {
+ Q_UNUSED(order);
+ return validList();
+ }
virtual QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const
{
Q_UNUSED(rect);
Q_UNUSED(order);
- return m_items;
+ return validList();
}
protected :
virtual void clear()
- { m_items.clear(); }
+ {
+ m_items.clear();
+ m_itemsIsValid = true;
+ }
virtual void addItem(QGraphicsItem *item)
- { m_items << item; }
+ {
+ if (m_itemsIsValid)
+ m_items << item;
+ }
virtual void removeItem(QGraphicsItem *item)
- { m_items.removeOne(item); }
+ {
+ Q_UNUSED(item);
+ m_itemsIsValid = false;
+ }
private:
- QList<QGraphicsItem*> m_items;
+ mutable QList<QGraphicsItem*> m_items;
+ mutable bool m_itemsIsValid;
+
+ QList<QGraphicsItem*>& validList() const
+ {
+ if (!m_itemsIsValid)
+ {
+ m_items.clear();
+
+ QList<QGraphicsItem*> stack = scene()->d_func()->topLevelItems;
+ m_items << stack;
+ while (!stack.isEmpty())
+ {
+ m_items << stack.last()->childItems();
+ stack << stack.takeLast()->childItems();
+ }
+ m_itemsIsValid = true;
+ }
+ return m_items;
+ }
};
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 5bcf52b6a3..9cd684a408 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -655,6 +655,8 @@ void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event)
mouseEvent.setButtons(event->buttons());
mouseEvent.setButton(event->button());
mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setSource(event->source());
+ mouseEvent.setFlags(event->flags());
lastMouseMoveScenePoint = mouseEvent.scenePos();
lastMouseMoveScreenPoint = mouseEvent.screenPos();
mouseEvent.setAccepted(false);
@@ -3217,6 +3219,8 @@ void QGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
mouseEvent.setAccepted(false);
mouseEvent.setButton(event->button());
mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setSource(event->source());
+ mouseEvent.setFlags(event->flags());
if (event->spontaneous())
qt_sendSpontaneousEvent(d->scene, &mouseEvent);
else
@@ -3265,6 +3269,8 @@ void QGraphicsView::mousePressEvent(QMouseEvent *event)
mouseEvent.setButtons(event->buttons());
mouseEvent.setButton(event->button());
mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setSource(event->source());
+ mouseEvent.setFlags(event->flags());
mouseEvent.setAccepted(false);
if (event->spontaneous())
qt_sendSpontaneousEvent(d->scene, &mouseEvent);
@@ -3392,6 +3398,8 @@ void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
mouseEvent.setButtons(event->buttons());
mouseEvent.setButton(event->button());
mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setSource(event->source());
+ mouseEvent.setFlags(event->flags());
mouseEvent.setAccepted(false);
if (event->spontaneous())
qt_sendSpontaneousEvent(d->scene, &mouseEvent);
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index b2dc614b2b..342fdac636 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -3126,6 +3126,8 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget
Q_D(QAbstractItemView);
if (!d->isIndexValid(index))
return;
+ if (indexWidget(index) == widget)
+ return;
if (QWidget *oldWidget = indexWidget(index)) {
d->persistent.remove(oldWidget);
d->removeEditor(oldWidget);
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index b12ab736f4..b6b5c63f84 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -368,8 +368,10 @@ QString QFileIconProvider::type(const QFileInfo &info) const
if (info.isRoot())
return QApplication::translate("QFileDialog", "Drive");
if (info.isFile()) {
- if (!info.suffix().isEmpty())
- return info.suffix() + QLatin1Char(' ') + QApplication::translate("QFileDialog", "File");
+ if (!info.suffix().isEmpty()) {
+ //: %1 is a file name suffix, for example txt
+ return QApplication::translate("QFileDialog", "%1 File").arg(info.suffix());
+ }
return QApplication::translate("QFileDialog", "File");
}
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index a252428a81..2bf4c62593 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1821,8 +1821,15 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
return QModelIndex();
QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
- if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result))
+ if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) {
+ if (d->hasSpans()) {
+ QSpanCollection::Span span = d->span(result.row(), result.column());
+ if (span.width() > 1 || span.height() > 1) {
+ result = d->model->sibling(span.top(), span.left(), result);
+ }
+ }
return result;
+ }
return QModelIndex();
}
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 857fe4ac91..a9b8627beb 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -33,8 +33,8 @@ HEADERS += \
kernel/qstandardgestures_p.h \
kernel/qgesturerecognizer.h \
kernel/qgesturemanager_p.h \
- kernel/qdesktopwidget_qpa_p.h \
- kernel/qwidgetwindow_qpa_p.h \
+ kernel/qdesktopwidget_p.h \
+ kernel/qwidgetwindow_p.h \
kernel/qwindowcontainer_p.h
SOURCES += \
@@ -60,9 +60,6 @@ SOURCES += \
kernel/qgesturemanager.cpp \
kernel/qdesktopwidget.cpp \
kernel/qwidgetsvariant.cpp \
- kernel/qapplication_qpa.cpp \
- kernel/qdesktopwidget_qpa.cpp \
- kernel/qwidget_qpa.cpp \
kernel/qwidgetwindow.cpp \
kernel/qwindowcontainer.cpp
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 0b983e7a9d..94fcee4553 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -57,6 +57,7 @@
#include "qstyleoption.h"
#include "qstylefactory.h"
#include "qtextcodec.h"
+#include "qtooltip.h"
#include "qtranslator.h"
#include "qvariant.h"
#include "qwidget.h"
@@ -67,7 +68,7 @@
#include "private/qstylesheetstyle_p.h"
#include "private/qstyle_p.h"
#include "qmessagebox.h"
-#include "qwidgetwindow_qpa_p.h"
+#include "qwidgetwindow_p.h"
#include <QtWidgets/qgraphicsproxywidget.h>
#include <QtGui/qstylehints.h>
#include <QtGui/qinputmethod.h>
@@ -77,6 +78,7 @@
#endif
#include "private/qkeymapper_p.h"
+#include "private/qaccessiblewidgetfactory_p.h"
#include <qthread.h>
#include <private/qthread_p.h>
@@ -96,6 +98,10 @@
#include "qlibrary.h"
#endif
+#ifdef Q_OS_WIN
+#include <QtCore/qt_windows.h> // for qt_win_display_dc()
+#endif
+
#include "qdatetime.h"
#ifdef Q_OS_WINCE
@@ -187,6 +193,11 @@ QApplicationPrivate::~QApplicationPrivate()
self = 0;
}
+void QApplicationPrivate::createEventDispatcher()
+{
+ QGuiApplicationPrivate::createEventDispatcher();
+}
+
/*!
\class QApplication
\brief The QApplication class manages the GUI application's control
@@ -364,6 +375,21 @@ QApplicationPrivate::~QApplicationPrivate()
Returns the top-level widget at the given \a point; returns 0 if
there is no such widget.
*/
+QWidget *QApplication::topLevelAt(const QPoint &pos)
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ QList<QScreen *>::const_iterator screen = screens.constBegin();
+ QList<QScreen *>::const_iterator end = screens.constEnd();
+
+ while (screen != end) {
+ if ((*screen)->geometry().contains(pos)) {
+ QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos));
+ return w ? w->widget() : 0;
+ }
+ ++screen;
+ }
+ return 0;
+}
/*!
\fn QWidget *QApplication::topLevelAt(int x, int y)
@@ -374,12 +400,6 @@ QApplicationPrivate::~QApplicationPrivate()
0 if there is no such widget.
*/
-
-/*
- The qt_init() and qt_cleanup() functions are implemented in the
- qapplication_xyz.cpp file.
-*/
-
void qt_init(QApplicationPrivate *priv, int type
);
void qt_init_tooltip_palette();
@@ -583,6 +603,11 @@ void QApplicationPrivate::construct()
qt_gui_eval_init(application_type);
#endif
+#ifndef QT_NO_ACCESSIBILITY
+ // factory for accessible interfaces for widgets shipped with Qt
+ QAccessible::installFactory(&qAccessibleFactory);
+#endif
+
#ifndef QT_NO_LIBRARY
if(load_testability) {
QLibrary testLib(QLatin1String("qttestability"));
@@ -601,6 +626,26 @@ void QApplicationPrivate::construct()
#endif
}
+void qt_init(QApplicationPrivate *priv, int type)
+{
+ Q_UNUSED(priv);
+ Q_UNUSED(type);
+
+ QColormap::initialize();
+
+ qt_init_tooltip_palette();
+
+ QApplicationPrivate::initializeWidgetFontHash();
+}
+
+void qt_init_tooltip_palette()
+{
+#ifndef QT_NO_TOOLTIP
+ if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
+ QToolTip::setPalette(*toolTipPalette);
+#endif
+}
+
#ifndef QT_NO_STATEMACHINE
void qRegisterGuiStateMachine();
void qUnregisterGuiStateMachine();
@@ -657,6 +702,91 @@ void QApplicationPrivate::initialize()
is_app_running = true; // no longer starting up
}
+static void setPossiblePalette(const QPalette *palette, const char *className)
+{
+ if (palette == 0)
+ return;
+ QApplicationPrivate::setPalette_helper(*palette, className, false);
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+ QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
+ if (!platformTheme)
+ return;
+ qt_app_palettes_hash()->clear();
+
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::CheckBoxPalette), "QCheckBox");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit");
+}
+
+void QApplicationPrivate::initializeWidgetFontHash()
+{
+ const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+ if (!theme)
+ return;
+ FontHash *fontHash = qt_app_fonts_hash();
+ fontHash->clear();
+
+ if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
+ fontHash->insert(QByteArrayLiteral("QMenu"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont))
+ fontHash->insert(QByteArrayLiteral("QMenuBar"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont))
+ fontHash->insert(QByteArrayLiteral("QMenuItem"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont))
+ fontHash->insert(QByteArrayLiteral("QMessageBox"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::LabelFont))
+ fontHash->insert(QByteArrayLiteral("QLabel"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont))
+ fontHash->insert(QByteArrayLiteral("QTipLabel"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont))
+ fontHash->insert(QByteArrayLiteral("QTitleBar"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont))
+ fontHash->insert(QByteArrayLiteral("QStatusBar"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont))
+ fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont))
+ fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont))
+ fontHash->insert(QByteArrayLiteral("QPushButton"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::CheckBoxFont))
+ fontHash->insert(QByteArrayLiteral("QCheckBox"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::RadioButtonFont))
+ fontHash->insert(QByteArrayLiteral("QRadioButton"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont))
+ fontHash->insert(QByteArrayLiteral("QToolButton"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont))
+ fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ListViewFont))
+ fontHash->insert(QByteArrayLiteral("QListViewFont"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont))
+ fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont))
+ fontHash->insert(QByteArrayLiteral("QListBox"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont))
+ fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont))
+ fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::SmallFont))
+ fontHash->insert(QByteArrayLiteral("QSmallFont"), *font);
+ if (const QFont *font = theme->font(QPlatformTheme::MiniFont))
+ fontHash->insert(QByteArrayLiteral("QMiniFont"), *font);
+}
+
/*****************************************************************************
Functions returning the active popup and modal widgets.
*****************************************************************************/
@@ -780,6 +910,32 @@ QApplication::~QApplication()
#endif
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+// #fixme: Remove.
+static HDC displayDC = 0; // display device context
+
+Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC
+{
+ Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
+ if (!displayDC)
+ displayDC = GetDC(0);
+ return displayDC;
+}
+#endif
+
+void qt_cleanup()
+{
+ QPixmapCache::clear();
+ QColormap::cleanup();
+
+ QApplicationPrivate::active_window = 0; //### this should not be necessary
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ if (displayDC) {
+ ReleaseDC(0, displayDC);
+ displayDC = 0;
+ }
+#endif
+}
/*!
\fn QWidget *QApplication::widgetAt(const QPoint &point)
@@ -2086,6 +2242,39 @@ void QApplication::setActiveWindow(QWidget* act)
}
}
+QWidget *qt_tlw_for_window(QWindow *wnd)
+{
+ // QTBUG-32177, wnd might be a QQuickView embedded via window container.
+ while (wnd && !wnd->isTopLevel()) {
+ QWindow *parent = wnd->parent();
+ // Don't end up in windows not belonging to this application
+ if (parent && parent->type() != Qt::ForeignWindow)
+ wnd = wnd->parent();
+ else
+ break;
+ }
+ if (wnd)
+ foreach (QWidget *tlw, qApp->topLevelWidgets())
+ if (tlw->windowHandle() == wnd)
+ return tlw;
+ return 0;
+}
+
+void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
+{
+ Q_UNUSED(previous);
+ QWindow *wnd = QGuiApplicationPrivate::focus_window;
+ if (inPopupMode()) // some delayed focus event to ignore
+ return;
+ QWidget *tlw = qt_tlw_for_window(wnd);
+ QApplication::setActiveWindow(tlw);
+ // QTBUG-37126, Active X controls may set the focus on native child widgets.
+ if (wnd && tlw && wnd != tlw->windowHandle()) {
+ if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd))
+ widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason);
+ }
+}
+
/*!internal
* Helper function that returns the new focus widget, but does not set the focus reason.
* Returns 0 if a new focus widget could not be found.
@@ -2454,6 +2643,44 @@ bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
return !isBlockedByModal(widget->window());
}
+bool qt_try_modal(QWidget *widget, QEvent::Type type)
+{
+ QWidget * top = 0;
+
+ if (QApplicationPrivate::tryModalHelper(widget, &top))
+ return true;
+
+ bool block_event = false;
+
+ switch (type) {
+#if 0
+ case QEvent::Focus:
+ if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
+ break;
+ // drop through
+#endif
+ case QEvent::MouseButtonPress: // disallow mouse/key events
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ block_event = true;
+ break;
+ default:
+ break;
+ }
+
+ if (block_event && top && top->parentWidget() == 0)
+ top->raise();
+
+ return !block_event;
+}
+
+bool QApplicationPrivate::modalState()
+{
+ return !self->modalWindowList.isEmpty();
+}
+
/*
\internal
*/
@@ -3520,7 +3747,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
// deliver the event
bool consumed = receiver->event(e);
- e->spont = false;
+ QCoreApplicationPrivate::setEventSpontaneous(e, false);
return consumed;
}
@@ -3529,6 +3756,123 @@ bool QApplicationPrivate::inPopupMode()
return QApplicationPrivate::popupWidgets != 0;
}
+static void ungrabKeyboardForPopup(QWidget *popup)
+{
+ if (QWidget::keyboardGrabber())
+ qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true);
+ else
+ qt_widget_private(popup)->stealKeyboardGrab(false);
+}
+
+static void ungrabMouseForPopup(QWidget *popup)
+{
+ if (QWidget::mouseGrabber())
+ qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true);
+ else
+ qt_widget_private(popup)->stealMouseGrab(false);
+}
+
+static bool popupGrabOk;
+
+static void grabForPopup(QWidget *popup)
+{
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true);
+ if (popupGrabOk) {
+ popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true);
+ if (!popupGrabOk) {
+ // transfer grab back to the keyboard grabber if any
+ ungrabKeyboardForPopup(popup);
+ }
+ }
+}
+
+extern QWidget *qt_button_down;
+extern QWidget *qt_popup_down;
+extern bool qt_replay_popup_mouse_event;
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ if (!popupWidgets)
+ return;
+ popupWidgets->removeAll(popup);
+
+ if (popup == qt_popup_down) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+
+ if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+
+ if (popupGrabOk) {
+ popupGrabOk = false;
+
+ if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX,
+ QGuiApplicationPrivate::mousePressY))
+ || popup->testAttribute(Qt::WA_NoMouseReplay)) {
+ // mouse release event or inside
+ qt_replay_popup_mouse_event = false;
+ } else { // mouse press event
+ qt_replay_popup_mouse_event = true;
+ }
+
+ // transfer grab back to mouse grabber if any, otherwise release the grab
+ ungrabMouseForPopup(popup);
+
+ // transfer grab back to keyboard grabber if any, otherwise release the grab
+ ungrabKeyboardForPopup(popup);
+ }
+
+ if (active_window) {
+ if (QWidget *fw = active_window->focusWidget()) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ QCoreApplication::sendEvent(fw, &e);
+ }
+ }
+ }
+
+ } else {
+ // A popup was closed, so the previous popup gets the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+
+ if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
+ grabForPopup(aw);
+ }
+
+}
+
+int openPopupCount = 0;
+
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ openPopupCount++;
+ if (!popupWidgets) // create list
+ popupWidgets = new QWidgetList;
+ popupWidgets->append(popup); // add to end of list
+
+ if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
+ grabForPopup(popup);
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (popupWidgets->count() == 1) { // this was the first popup
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+}
+
#ifdef QT_KEYPAD_NAVIGATION
/*!
Sets the kind of focus navigation Qt should use to \a mode.
@@ -3633,6 +3977,18 @@ bool QApplication::keypadNavigationEnabled()
window must not be hidden (i.e. not have hide() called on it, but be
visible in some sort of way) in order for this to work.
*/
+void QApplication::alert(QWidget *widget, int duration)
+{
+ if (widget) {
+ if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized))
+ return;
+ if (QWindow *window= QApplicationPrivate::windowForWidget(widget))
+ window->alert(duration);
+ } else {
+ foreach (QWidget *topLevel, topLevelWidgets())
+ QApplication::alert(topLevel, duration);
+ }
+}
/*!
\property QApplication::cursorFlashTime
@@ -3720,6 +4076,38 @@ int QApplication::keyboardInputInterval()
By default, this property has a value of 3.
*/
+#ifndef QT_NO_WHEELEVENT
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+
+void QApplication::setWheelScrollLines(int lines)
+{
+ QApplicationPrivate::wheel_scroll_lines = lines;
+}
+#endif
+
+static inline int uiEffectToFlag(Qt::UIEffect effect)
+{
+ switch (effect) {
+ case Qt::UI_General:
+ return QPlatformTheme::GeneralUiEffect;
+ case Qt::UI_AnimateMenu:
+ return QPlatformTheme::AnimateMenuUiEffect;
+ case Qt::UI_FadeMenu:
+ return QPlatformTheme::FadeMenuUiEffect;
+ case Qt::UI_AnimateCombo:
+ return QPlatformTheme::AnimateComboUiEffect;
+ case Qt::UI_AnimateTooltip:
+ return QPlatformTheme::AnimateTooltipUiEffect;
+ case Qt::UI_FadeTooltip:
+ return QPlatformTheme::FadeTooltipUiEffect;
+ case Qt::UI_AnimateToolBox:
+ return QPlatformTheme::AnimateToolBoxUiEffect;
+ }
+ return 0;
+}
/*!
\fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
@@ -3732,6 +4120,19 @@ int QApplication::keyboardInputInterval()
\sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
*/
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ int effectFlags = uiEffectToFlag(effect);
+ if (enable) {
+ if (effectFlags & QPlatformTheme::FadeMenuUiEffect)
+ effectFlags |= QPlatformTheme::AnimateMenuUiEffect;
+ if (effectFlags & QPlatformTheme::FadeTooltipUiEffect)
+ effectFlags |= QPlatformTheme::AnimateTooltipUiEffect;
+ QApplicationPrivate::enabledAnimations |= effectFlags;
+ } else {
+ QApplicationPrivate::enabledAnimations &= ~effectFlags;
+ }
+}
/*!
\fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
@@ -3746,6 +4147,12 @@ int QApplication::keyboardInputInterval()
\sa setEffectEnabled(), Qt::UIEffect
*/
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ return QColormap::instance().depth() >= 16
+ && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect)
+ && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect));
+}
/*!
\fn void QApplication::beep()
@@ -3753,6 +4160,10 @@ int QApplication::keyboardInputInterval()
Sounds the bell, using the default volume and sound. The function is \e not
available in Qt for Embedded Linux.
*/
+void QApplication::beep()
+{
+ QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep");
+}
/*!
\macro qApp
@@ -3865,11 +4276,19 @@ void QApplicationPrivate::initializeMultitouch()
initializeMultitouch_sys();
}
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+}
+
void QApplicationPrivate::cleanupMultitouch()
{
cleanupMultitouch_sys();
}
+void QApplicationPrivate::cleanupMultitouch_sys()
+{
+}
+
QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos)
{
int closestTouchPointId = -1;
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index e72fe29bdb..08a450ab32 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -228,7 +228,6 @@ private:
friend class QWidget;
friend class QWidgetPrivate;
friend class QWidgetWindow;
- friend class QETWidget;
friend class QTranslator;
friend class QWidgetAnimator;
#ifndef QT_NO_SHORTCUT
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
deleted file mode 100644
index 5893c52e1b..0000000000
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication_p.h"
-#include "qcolormap.h"
-#include "qpalette.h"
-#include "qpixmapcache.h"
-#ifndef QT_NO_CURSOR
-#include "private/qcursor_p.h"
-#endif
-#include "qscreen.h"
-
-#include "private/qwidget_p.h"
-#include "private/qevent_p.h"
-
-#include <qpa/qplatformintegrationfactory_p.h>
-#include <qdesktopwidget.h>
-#include <qpa/qplatformcursor.h>
-#include <qpa/qplatformtheme.h>
-#include <qpa/qplatformwindow.h>
-
-#include <qdebug.h>
-#include <qpa/qwindowsysteminterface.h>
-#include <qpa/qwindowsysteminterface_p.h>
-#include <qpa/qplatformintegration.h>
-
-#include "qdesktopwidget_qpa_p.h"
-#include "qwidgetwindow_qpa_p.h"
-#include "qtooltip.h"
-
-#ifdef Q_OS_WIN
-# include <QtCore/qt_windows.h> // for qt_win_display_dc()
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static QString appFont;
-static bool popupGrabOk;
-extern QWidget *qt_button_down;
-extern QWidget *qt_popup_down;
-extern bool qt_replay_popup_mouse_event;
-int openPopupCount = 0;
-extern QPointer<QWidget> qt_last_mouse_receiver;
-
-void QApplicationPrivate::createEventDispatcher()
-{
- QGuiApplicationPrivate::createEventDispatcher();
-}
-
-bool qt_try_modal(QWidget *widget, QEvent::Type type)
-{
- QWidget * top = 0;
-
- if (QApplicationPrivate::tryModalHelper(widget, &top))
- return true;
-
- bool block_event = false;
-
- switch (type) {
-#if 0
- case QEvent::Focus:
- if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
- break;
- // drop through
-#endif
- case QEvent::MouseButtonPress: // disallow mouse/key events
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- block_event = true;
- break;
- default:
- break;
- }
-
- if (block_event && top && top->parentWidget() == 0)
- top->raise();
-
- return !block_event;
-}
-
-bool QApplicationPrivate::modalState()
-{
- return !self->modalWindowList.isEmpty();
-}
-
-QWidget *qt_tlw_for_window(QWindow *wnd)
-{
- // QTBUG-32177, wnd might be a QQuickView embedded via window container.
- while (wnd && !wnd->isTopLevel()) {
- QWindow *parent = wnd->parent();
- // Don't end up in windows not belonging to this application
- if (parent && parent->type() != Qt::ForeignWindow)
- wnd = wnd->parent();
- else
- break;
- }
- if (wnd)
- foreach (QWidget *tlw, qApp->topLevelWidgets())
- if (tlw->windowHandle() == wnd)
- return tlw;
- return 0;
-}
-
-void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
-{
- Q_UNUSED(previous);
- QWindow *wnd = QGuiApplicationPrivate::focus_window;
- if (inPopupMode()) // some delayed focus event to ignore
- return;
- QWidget *tlw = qt_tlw_for_window(wnd);
- QApplication::setActiveWindow(tlw);
-}
-
-static void ungrabKeyboardForPopup(QWidget *popup)
-{
- if (QWidget::keyboardGrabber())
- qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true);
- else
- qt_widget_private(popup)->stealKeyboardGrab(false);
-}
-
-static void ungrabMouseForPopup(QWidget *popup)
-{
- if (QWidget::mouseGrabber())
- qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true);
- else
- qt_widget_private(popup)->stealMouseGrab(false);
-}
-
-static void grabForPopup(QWidget *popup)
-{
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true);
- if (popupGrabOk) {
- popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true);
- if (!popupGrabOk) {
- // transfer grab back to the keyboard grabber if any
- ungrabKeyboardForPopup(popup);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- if (!popupWidgets)
- return;
- popupWidgets->removeAll(popup);
-
- if (popup == qt_popup_down) {
- qt_button_down = 0;
- qt_popup_down = 0;
- }
-
- if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
-
- if (popupGrabOk) {
- popupGrabOk = false;
-
- if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX,
- QGuiApplicationPrivate::mousePressY))
- || popup->testAttribute(Qt::WA_NoMouseReplay)) {
- // mouse release event or inside
- qt_replay_popup_mouse_event = false;
- } else { // mouse press event
- qt_replay_popup_mouse_event = true;
- }
-
- // transfer grab back to mouse grabber if any, otherwise release the grab
- ungrabMouseForPopup(popup);
-
- // transfer grab back to keyboard grabber if any, otherwise release the grab
- ungrabKeyboardForPopup(popup);
- }
-
- if (active_window) {
- if (QWidget *fw = active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &e);
- }
- }
- }
-
- } else {
- // A popup was closed, so the previous popup gets the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
-
- if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
- grabForPopup(aw);
- }
-
-}
-
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- openPopupCount++;
- if (!popupWidgets) // create list
- popupWidgets = new QWidgetList;
- popupWidgets->append(popup); // add to end of list
-
- if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
- grabForPopup(popup);
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (popupWidgets->count() == 1) { // this was the first popup
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{
-}
-
-static void setPossiblePalette(const QPalette *palette, const char *className)
-{
- if (palette == 0)
- return;
- QApplicationPrivate::setPalette_helper(*palette, className, false);
-}
-
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
- QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
- if (!platformTheme)
- return;
- qt_app_palettes_hash()->clear();
-
- setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::CheckBoxPalette), "QCheckBox");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit");
-}
-
-void QApplicationPrivate::initializeWidgetFontHash()
-{
- const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
- if (!theme)
- return;
- FontHash *fontHash = qt_app_fonts_hash();
- fontHash->clear();
-
- if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
- fontHash->insert(QByteArrayLiteral("QMenu"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont))
- fontHash->insert(QByteArrayLiteral("QMenuBar"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont))
- fontHash->insert(QByteArrayLiteral("QMenuItem"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont))
- fontHash->insert(QByteArrayLiteral("QMessageBox"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::LabelFont))
- fontHash->insert(QByteArrayLiteral("QLabel"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont))
- fontHash->insert(QByteArrayLiteral("QTipLabel"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont))
- fontHash->insert(QByteArrayLiteral("QTitleBar"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont))
- fontHash->insert(QByteArrayLiteral("QStatusBar"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont))
- fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont))
- fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont))
- fontHash->insert(QByteArrayLiteral("QPushButton"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::CheckBoxFont))
- fontHash->insert(QByteArrayLiteral("QCheckBox"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::RadioButtonFont))
- fontHash->insert(QByteArrayLiteral("QRadioButton"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont))
- fontHash->insert(QByteArrayLiteral("QToolButton"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont))
- fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ListViewFont))
- fontHash->insert(QByteArrayLiteral("QListViewFont"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont))
- fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont))
- fontHash->insert(QByteArrayLiteral("QListBox"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont))
- fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont))
- fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::SmallFont))
- fontHash->insert(QByteArrayLiteral("QSmallFont"), *font);
- if (const QFont *font = theme->font(QPlatformTheme::MiniFont))
- fontHash->insert(QByteArrayLiteral("QMiniFont"), *font);
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int lines)
-{
- QApplicationPrivate::wheel_scroll_lines = lines;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-static inline int uiEffectToFlag(Qt::UIEffect effect)
-{
- switch (effect) {
- case Qt::UI_General:
- return QPlatformTheme::GeneralUiEffect;
- case Qt::UI_AnimateMenu:
- return QPlatformTheme::AnimateMenuUiEffect;
- case Qt::UI_FadeMenu:
- return QPlatformTheme::FadeMenuUiEffect;
- case Qt::UI_AnimateCombo:
- return QPlatformTheme::AnimateComboUiEffect;
- case Qt::UI_AnimateTooltip:
- return QPlatformTheme::AnimateTooltipUiEffect;
- case Qt::UI_FadeTooltip:
- return QPlatformTheme::FadeTooltipUiEffect;
- case Qt::UI_AnimateToolBox:
- return QPlatformTheme::AnimateToolBoxUiEffect;
- }
- return 0;
-}
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- int effectFlags = uiEffectToFlag(effect);
- if (enable) {
- if (effectFlags & QPlatformTheme::FadeMenuUiEffect)
- effectFlags |= QPlatformTheme::AnimateMenuUiEffect;
- if (effectFlags & QPlatformTheme::FadeTooltipUiEffect)
- effectFlags |= QPlatformTheme::AnimateTooltipUiEffect;
- QApplicationPrivate::enabledAnimations |= effectFlags;
- } else {
- QApplicationPrivate::enabledAnimations &= ~effectFlags;
- }
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- return QColormap::instance().depth() >= 16
- && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect)
- && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect));
-}
-
-QWidget *QApplication::topLevelAt(const QPoint &pos)
-{
- QList<QScreen *> screens = QGuiApplication::screens();
- QList<QScreen *>::const_iterator screen = screens.constBegin();
- QList<QScreen *>::const_iterator end = screens.constEnd();
-
- while (screen != end) {
- if ((*screen)->geometry().contains(pos)) {
- QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos));
- return w ? w->widget() : 0;
- }
- ++screen;
- }
- return 0;
-}
-
-void QApplication::beep()
-{
- QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep");
-}
-
-void QApplication::alert(QWidget *widget, int duration)
-{
- if (widget) {
- if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized))
- return;
- if (QWindow *window= QApplicationPrivate::windowForWidget(widget))
- window->alert(duration);
- } else {
- foreach (QWidget *topLevel, topLevelWidgets())
- QApplication::alert(topLevel, duration);
- }
-}
-
-void qt_init_tooltip_palette()
-{
-#ifndef QT_NO_TOOLTIP
- if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
- QToolTip::setPalette(*toolTipPalette);
-#endif
-}
-
-void qt_init(QApplicationPrivate *priv, int type)
-{
- Q_UNUSED(priv);
- Q_UNUSED(type);
-
- QColormap::initialize();
-
- qt_init_tooltip_palette();
-
- QApplicationPrivate::initializeWidgetFontHash();
-}
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-// #fixme: Remove.
-static HDC displayDC = 0; // display device context
-
-Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC
-{
- Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
- if (!displayDC)
- displayDC = GetDC(0);
- return displayDC;
-}
-#endif
-
-void qt_cleanup()
-{
- QPixmapCache::clear();
- QColormap::cleanup();
-
- QApplicationPrivate::active_window = 0; //### this should not be necessary
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- if (displayDC) {
- ReleaseDC(0, displayDC);
- displayDC = 0;
- }
-#endif
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 649978a912..3975e423a0 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -41,6 +41,8 @@
#include "qglobal.h"
#include "qdesktopwidget.h"
+#include "qdesktopwidget_p.h"
+#include "qscreen.h"
#include "qwidget_p.h"
QT_BEGIN_NAMESPACE
@@ -72,5 +74,145 @@ const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const
return rect;
}
+void QDesktopWidgetPrivate::_q_updateScreens()
+{
+ Q_Q(QDesktopWidget);
+ const QList<QScreen *> screenList = QGuiApplication::screens();
+ const int targetLength = screenList.length();
+ const int oldLength = screens.length();
+ int currentLength = oldLength;
+
+ // Add or remove screen widgets as necessary
+ if(currentLength > targetLength) {
+ QDesktopScreenWidget *screen;
+ while (currentLength-- > targetLength) {
+ screen = screens.takeLast();
+ delete screen;
+ }
+ }
+ else if (currentLength < targetLength) {
+ while (currentLength < targetLength) {
+ QScreen *qScreen = screenList.at(currentLength);
+ QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength++);
+ screenWidget->setGeometry(qScreen->geometry());
+ QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)),
+ q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
+ QObject::connect(qScreen, SIGNAL(destroyed()),
+ q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
+ screens.append(screenWidget);
+ }
+ }
+
+ QRegion virtualGeometry;
+
+ // update the geometry of each screen widget, determine virtual geometry
+ // and emit change signals afterwards.
+ QList<int> changedScreens;
+ for (int i = 0; i < screens.length(); i++) {
+ const QRect screenGeometry = screenList.at(i)->geometry();
+ if (screenGeometry != screens.at(i)->geometry()) {
+ screens.at(i)->setGeometry(screenGeometry);
+ changedScreens.push_back(i);
+ }
+ virtualGeometry += screenGeometry;
+ }
+
+ q->setGeometry(virtualGeometry.boundingRect());
+
+ if (oldLength != targetLength)
+ emit q->screenCountChanged(targetLength);
+
+ foreach (int changedScreen, changedScreens) {
+ emit q->resized(changedScreen);
+ emit q->workAreaResized(changedScreen);
+ }
+}
+
+QDesktopWidget::QDesktopWidget()
+ : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
+{
+ Q_D(QDesktopWidget);
+ setObjectName(QLatin1String("desktop"));
+ d->_q_updateScreens();
+ connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens()));
+}
+
+QDesktopWidget::~QDesktopWidget()
+{
+}
+
+bool QDesktopWidget::isVirtualDesktop() const
+{
+ return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1;
+}
+
+int QDesktopWidget::primaryScreen() const
+{
+ return 0;
+}
+
+int QDesktopWidget::numScreens() const
+{
+ return qMax(QGuiApplication::screens().size(), 1);
+}
+
+QWidget *QDesktopWidget::screen(int screen)
+{
+ Q_D(QDesktopWidget);
+ if (screen < 0 || screen >= d->screens.length())
+ return d->screens.at(0);
+ return d->screens.at(screen);
+}
+
+const QRect QDesktopWidget::availableGeometry(int screenNo) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ if (screenNo == -1)
+ screenNo = 0;
+ if (screenNo < 0 || screenNo >= screens.size())
+ return QRect();
+ else
+ return screens.at(screenNo)->availableGeometry();
+}
+
+const QRect QDesktopWidget::screenGeometry(int screenNo) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ if (screenNo == -1)
+ screenNo = 0;
+ if (screenNo < 0 || screenNo >= screens.size())
+ return QRect();
+ else
+ return screens.at(screenNo)->geometry();
+}
+
+int QDesktopWidget::screenNumber(const QWidget *w) const
+{
+ if (!w)
+ return 0;
+
+ QRect frame = w->frameGeometry();
+ if (!w->isWindow())
+ frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
+ const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
+ return screenNumber(midpoint);
+}
+
+int QDesktopWidget::screenNumber(const QPoint &p) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+
+ for (int i = 0; i < screens.size(); ++i)
+ if (screens.at(i)->geometry().contains(p))
+ return i;
+
+ return primaryScreen(); //even better would be closest screen
+}
+
+void QDesktopWidget::resizeEvent(QResizeEvent *)
+{
+}
+
QT_END_NAMESPACE
+#include "moc_qdesktopwidget.cpp"
diff --git a/src/widgets/kernel/qdesktopwidget_qpa_p.h b/src/widgets/kernel/qdesktopwidget_p.h
index f461869f1b..160807cf23 100644
--- a/src/widgets/kernel/qdesktopwidget_qpa_p.h
+++ b/src/widgets/kernel/qdesktopwidget_p.h
@@ -50,8 +50,8 @@
// We mean it.
//
-#ifndef QDESKTOPWIDGET_QPA_P_H
-#define QDESKTOPWIDGET_QPA_P_H
+#ifndef QDESKTOPWIDGET_P_H
+#define QDESKTOPWIDGET_P_H
#include "QDesktopWidget"
#include "private/qwidget_p.h"
diff --git a/src/widgets/kernel/qdesktopwidget_qpa.cpp b/src/widgets/kernel/qdesktopwidget_qpa.cpp
deleted file mode 100644
index 015573dfbe..0000000000
--- a/src/widgets/kernel/qdesktopwidget_qpa.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdesktopwidget.h"
-#include "qscreen.h"
-#include "private/qapplication_p.h"
-#include <QWidget>
-#include "private/qwidget_p.h"
-#include "private/qdesktopwidget_qpa_p.h"
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-void QDesktopWidgetPrivate::_q_updateScreens()
-{
- Q_Q(QDesktopWidget);
- const QList<QScreen *> screenList = QGuiApplication::screens();
- const int targetLength = screenList.length();
- const int oldLength = screens.length();
- int currentLength = oldLength;
-
- // Add or remove screen widgets as necessary
- if(currentLength > targetLength) {
- QDesktopScreenWidget *screen;
- while (currentLength-- > targetLength) {
- screen = screens.takeLast();
- delete screen;
- }
- }
- else if (currentLength < targetLength) {
- while (currentLength < targetLength) {
- QScreen *qScreen = screenList.at(currentLength);
- QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength++);
- screenWidget->setGeometry(qScreen->geometry());
- QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)),
- q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
- QObject::connect(qScreen, SIGNAL(destroyed()),
- q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
- screens.append(screenWidget);
- }
- }
-
- QRegion virtualGeometry;
-
- // update the geometry of each screen widget, determine virtual geometry
- // and emit change signals afterwards.
- QList<int> changedScreens;
- for (int i = 0; i < screens.length(); i++) {
- const QRect screenGeometry = screenList.at(i)->geometry();
- if (screenGeometry != screens.at(i)->geometry()) {
- screens.at(i)->setGeometry(screenGeometry);
- changedScreens.push_back(i);
- }
- virtualGeometry += screenGeometry;
- }
-
- q->setGeometry(virtualGeometry.boundingRect());
-
- if (oldLength != targetLength)
- emit q->screenCountChanged(targetLength);
-
- foreach (int changedScreen, changedScreens) {
- emit q->resized(changedScreen);
- emit q->workAreaResized(changedScreen);
- }
-}
-
-QDesktopWidget::QDesktopWidget()
- : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
-{
- Q_D(QDesktopWidget);
- setObjectName(QLatin1String("desktop"));
- d->_q_updateScreens();
- connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens()));
-}
-
-QDesktopWidget::~QDesktopWidget()
-{
-}
-
-bool QDesktopWidget::isVirtualDesktop() const
-{
- return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1;
-}
-
-int QDesktopWidget::primaryScreen() const
-{
- return 0;
-}
-
-int QDesktopWidget::numScreens() const
-{
- return qMax(QGuiApplication::screens().size(), 1);
-}
-
-QWidget *QDesktopWidget::screen(int screen)
-{
- Q_D(QDesktopWidget);
- if (screen < 0 || screen >= d->screens.length())
- return d->screens.at(0);
- return d->screens.at(screen);
-}
-
-const QRect QDesktopWidget::availableGeometry(int screenNo) const
-{
- QList<QScreen *> screens = QGuiApplication::screens();
- if (screenNo == -1)
- screenNo = 0;
- if (screenNo < 0 || screenNo >= screens.size())
- return QRect();
- else
- return screens.at(screenNo)->availableGeometry();
-}
-
-const QRect QDesktopWidget::screenGeometry(int screenNo) const
-{
- QList<QScreen *> screens = QGuiApplication::screens();
- if (screenNo == -1)
- screenNo = 0;
- if (screenNo < 0 || screenNo >= screens.size())
- return QRect();
- else
- return screens.at(screenNo)->geometry();
-}
-
-int QDesktopWidget::screenNumber(const QWidget *w) const
-{
- if (!w)
- return 0;
-
- QRect frame = w->frameGeometry();
- if (!w->isWindow())
- frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
- const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
- return screenNumber(midpoint);
-}
-
-int QDesktopWidget::screenNumber(const QPoint &p) const
-{
- QList<QScreen *> screens = QGuiApplication::screens();
-
- for (int i = 0; i < screens.size(); ++i)
- if (screens.at(i)->geometry().contains(p))
- return i;
-
- return primaryScreen(); //even better would be closest screen
-}
-
-void QDesktopWidget::resizeEvent(QResizeEvent *)
-{
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qdesktopwidget.cpp"
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 929e5e2fcf..532cea1f67 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -46,7 +46,7 @@
#include "private/qgraphicsitem_p.h"
#include "private/qevent_p.h"
#include "private/qapplication_p.h"
-#include "private/qwidgetwindow_qpa_p.h"
+#include "private/qwidgetwindow_p.h"
#include "qgesture.h"
#include "qevent.h"
#include "qgraphicsitem.h"
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index dcf6aed591..217f0386cb 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -51,7 +51,7 @@
#include <private/qapplication_p.h>
#include <private/qshortcutmap_p.h>
#include <private/qaction_p.h>
-#include <private/qwidgetwindow_qpa_p.h>
+#include <private/qwidgetwindow_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 7396808442..c17f5c6e2e 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -69,7 +69,7 @@
# include <private/qmainwindowlayout_p.h>
#endif
#include <qpa/qplatformwindow.h>
-#include "private/qwidgetwindow_qpa_p.h"
+#include "private/qwidgetwindow_p.h"
#include "qpainter.h"
#include "qtooltip.h"
#include "qwhatsthis.h"
@@ -357,6 +357,13 @@ void QWidgetPrivate::scrollChildren(int dx, int dy)
}
}
+void QWidgetPrivate::setWSGeometry()
+{
+ Q_Q(QWidget);
+ if (QWindow *window = q->windowHandle())
+ window->setGeometry(data.crect);
+}
+
void QWidgetPrivate::updateWidgetTransform(QEvent *event)
{
Q_Q(QWidget);
@@ -1065,7 +1072,11 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
// interpret WindowSystemMenuHint as a close button and we can't change that behavior
// we can't just add this in.
#ifndef Q_WS_MAC
- if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) {
+ if ((flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint))
+# ifdef Q_OS_WIN
+ && type != Qt::Dialog // QTBUG-2027, allow for menu-less dialogs.
+# endif
+ ) {
flags |= Qt::WindowSystemMenuHint;
#else
if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint
@@ -1348,6 +1359,154 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
d->updateFrameStrut();
}
+void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
+{
+ QObjectList children = parentWidget->children();
+ for (int i = 0; i < children.size(); i++) {
+ if (children.at(i)->isWidgetType()) {
+ const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
+ if (childWidget) { // should not be necessary
+ if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
+ if (!childWidget->internalWinId())
+ childWidget->winId();
+ if (childWidget->windowHandle()) {
+ QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle();
+ if (childWidget->isWindow())
+ childWidget->windowHandle()->setTransientParent(parentWindow);
+ else
+ childWidget->windowHandle()->setParent(parentWindow);
+ }
+ } else {
+ q_createNativeChildrenAndSetParent(childWidget);
+ }
+ }
+ }
+ }
+
+}
+
+void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
+{
+ Q_Q(QWidget);
+
+ Q_UNUSED(window);
+ Q_UNUSED(initializeWindow);
+ Q_UNUSED(destroyOldWindow);
+
+ Qt::WindowFlags flags = data.window_flags;
+
+ if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
+ return; // we only care about real toplevels
+
+ QWindow *win = topData()->window;
+ // topData() ensures the extra is created but does not ensure 'window' is non-null
+ // in case the extra was already valid.
+ if (!win) {
+ createTLSysExtra();
+ win = topData()->window;
+ }
+
+ foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) {
+ if (!qstrncmp(propertyName, "_q_platform_", 12))
+ win->setProperty(propertyName, q->property(propertyName));
+ }
+
+#ifdef Q_OS_OSX
+ if (q->testAttribute(Qt::WA_ShowWithoutActivating))
+ win->setProperty("_q_showWithoutActivating", QVariant(true));
+#endif
+ win->setFlags(data.window_flags);
+ fixPosIncludesFrame();
+ if (q->testAttribute(Qt::WA_Moved)
+ || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
+ win->setGeometry(q->geometry());
+ else
+ win->resize(q->size());
+ win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
+
+ QSurfaceFormat format = win->requestedFormat();
+ if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
+ && q->testAttribute(Qt::WA_TranslucentBackground)) {
+ format.setAlphaBufferSize(8);
+ }
+ win->setFormat(format);
+
+ if (QWidget *nativeParent = q->nativeParentWidget()) {
+ if (nativeParent->windowHandle()) {
+ if (flags & Qt::Window) {
+ win->setTransientParent(nativeParent->windowHandle());
+ win->setParent(0);
+ } else {
+ win->setTransientParent(0);
+ win->setParent(nativeParent->windowHandle());
+ }
+ }
+ }
+
+ qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
+ QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
+ win->create();
+ // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
+ if ((flags & Qt::Desktop) == Qt::Window)
+ win->handle()->setFrameStrutEventsEnabled(true);
+
+ data.window_flags = win->flags();
+
+ QBackingStore *store = q->backingStore();
+
+ if (!store) {
+ if (win && q->windowType() != Qt::Desktop) {
+ if (q->isTopLevel())
+ q->setBackingStore(new QBackingStore(win));
+ } else {
+ q->setAttribute(Qt::WA_PaintOnScreen, true);
+ }
+ }
+
+ setWindowModified_helper();
+ WId id = win->winId();
+ // See the QPlatformWindow::winId() documentation
+ Q_ASSERT(id != WId(0));
+ setWinId(id);
+
+ // Check children and create windows for them if necessary
+ q_createNativeChildrenAndSetParent(q);
+
+ if (extra && !extra->mask.isEmpty())
+ setMask_sys(extra->mask);
+
+ // If widget is already shown, set window visible, too
+ if (q->isVisible())
+ win->setVisible(true);
+}
+
+#ifdef Q_OS_WIN
+static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle";
+#endif
+
+void QWidgetPrivate::createTLSysExtra()
+{
+ Q_Q(QWidget);
+ if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) {
+ extra->topextra->window = new QWidgetWindow(q);
+ if (extra->minw || extra->minh)
+ extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
+ if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
+ extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
+ if (extra->topextra->opacity != 255 && q->isWindow())
+ extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
+#ifdef Q_OS_WIN
+ // Pass on native parent handle for Widget embedded into Active X.
+ const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
+ if (activeXNativeParentHandle.isValid())
+ extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
+ if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget"))
+ extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
+#endif
+ }
+
+}
+
/*!
Destroys the widget.
@@ -1612,6 +1771,9 @@ void QWidgetPrivate::createExtra()
}
}
+void QWidgetPrivate::createSysExtra()
+{
+}
/*!
\internal
@@ -1642,6 +1804,46 @@ void QWidgetPrivate::deleteExtra()
}
}
+void QWidgetPrivate::deleteSysExtra()
+{
+}
+
+void QWidgetPrivate::deleteTLSysExtra()
+{
+ if (extra && extra->topextra) {
+ //the qplatformbackingstore may hold a reference to the window, so the backingstore
+ //needs to be deleted first. If the backingstore holds GL resources, we need to
+ // make the context current here, since the platform bs does not have a reference
+ // to the widget.
+
+#ifndef QT_NO_OPENGL
+ if (textureChildSeen && extra->topextra->shareContext)
+ extra->topextra->shareContext->makeCurrent(extra->topextra->window);
+#endif
+ extra->topextra->backingStoreTracker.destroy();
+ delete extra->topextra->backingStore;
+ extra->topextra->backingStore = 0;
+#ifndef QT_NO_OPENGL
+ if (textureChildSeen && extra->topextra->shareContext)
+ extra->topextra->shareContext->doneCurrent();
+ delete extra->topextra->shareContext;
+ extra->topextra->shareContext = 0;
+#endif
+
+ //the toplevel might have a context with a "qglcontext associated with it. We need to
+ //delete the qglcontext before we delete the qplatformopenglcontext.
+ //One unfortunate thing about this is that we potentially create a glContext just to
+ //delete it straight afterwards.
+ if (extra->topextra->window) {
+ extra->topextra->window->destroy();
+ }
+ setWinId(0);
+ delete extra->topextra->window;
+ extra->topextra->window = 0;
+
+ }
+}
+
/*
Returns \c true if there are widgets above this which overlap with
\a rect, which is in parent's coordinate system (same as crect).
@@ -2364,6 +2566,27 @@ WId QWidget::effectiveWinId() const
return 0;
}
+/*!
+ If this is a native widget, return the associated QWindow.
+ Otherwise return null.
+
+ Native widgets include toplevel widgets, QGLWidget, and child widgets
+ on which winId() was called.
+
+ \since 5.0
+
+ \sa winId()
+*/
+QWindow *QWidget::windowHandle() const
+{
+ Q_D(const QWidget);
+ QTLWExtra *extra = d->maybeTopData();
+ if (extra)
+ return extra->window;
+
+ return 0;
+}
+
#ifndef QT_NO_STYLE_STYLESHEET
/*!
@@ -2654,6 +2877,13 @@ void QWidget::setWindowModality(Qt::WindowModality windowModality)
setAttribute(Qt::WA_SetWindowModality, true);
}
+void QWidgetPrivate::setModal_sys()
+{
+ Q_Q(QWidget);
+ if (q->windowHandle())
+ q->windowHandle()->setModality(q->windowModality());
+}
+
/*!
\fn bool QWidget::underMouse() const
@@ -2747,6 +2977,17 @@ void QWidget::overrideWindowState(Qt::WindowStates newstate)
QApplication::sendEvent(this, &e);
}
+Qt::WindowState effectiveState(Qt::WindowStates state)
+{
+ if (state & Qt::WindowMinimized)
+ return Qt::WindowMinimized;
+ else if (state & Qt::WindowFullScreen)
+ return Qt::WindowFullScreen;
+ else if (state & Qt::WindowMaximized)
+ return Qt::WindowMaximized;
+ return Qt::WindowNoState;
+}
+
/*!
\fn void QWidget::setWindowState(Qt::WindowStates windowState)
@@ -2777,6 +3018,39 @@ void QWidget::overrideWindowState(Qt::WindowStates newstate)
\sa Qt::WindowState, windowState()
*/
+void QWidget::setWindowState(Qt::WindowStates newstate)
+{
+ Q_D(QWidget);
+ Qt::WindowStates oldstate = windowState();
+ if (oldstate == newstate)
+ return;
+ if (isWindow() && !testAttribute(Qt::WA_WState_Created))
+ create();
+
+ data->window_state = newstate;
+ data->in_set_window_state = 1;
+ Qt::WindowState newEffectiveState = effectiveState(newstate);
+ Qt::WindowState oldEffectiveState = effectiveState(oldstate);
+ if (isWindow() && newEffectiveState != oldEffectiveState) {
+ // Ensure the initial size is valid, since we store it as normalGeometry below.
+ if (!testAttribute(Qt::WA_Resized) && !isVisible())
+ adjustSize();
+
+ d->createTLExtra();
+ if (oldEffectiveState == Qt::WindowNoState)
+ d->topData()->normalGeometry = geometry();
+
+ Q_ASSERT(windowHandle());
+ windowHandle()->setWindowState(newEffectiveState);
+ }
+ data->in_set_window_state = 0;
+
+ if (newstate & Qt::WindowActive)
+ activateWindow();
+
+ QWindowStateChangeEvent e(oldstate);
+ QApplication::sendEvent(this, &e);
+}
/*!
\property QWidget::fullScreen
@@ -3169,6 +3443,10 @@ void QWidget::setAcceptDrops(bool on)
}
+void QWidgetPrivate::registerDropSite(bool on)
+{
+ Q_UNUSED(on);
+}
/*!
Disables widget input events if \a disable is true; otherwise
@@ -3643,6 +3921,28 @@ bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
return true;
}
+void QWidgetPrivate::setConstraints_sys()
+{
+ Q_Q(QWidget);
+ if (extra && q->windowHandle()) {
+ QWindow *win = q->windowHandle();
+ QWindowPrivate *winp = qt_window_private(win);
+
+ winp->minimumSize = QSize(extra->minw, extra->minh);
+ winp->maximumSize = QSize(extra->maxw, extra->maxh);
+
+ if (extra->topextra) {
+ winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
+ winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
+ }
+
+ if (winp->platformWindow) {
+ fixPosIncludesFrame();
+ winp->platformWindow->propagateSizeHints();
+ }
+ }
+}
+
/*!
\overload
@@ -4293,6 +4593,10 @@ void QWidgetPrivate::setPalette_helper(const QPalette &palette)
updateIsOpaque();
}
+void QWidgetPrivate::updateSystemBackground()
+{
+}
+
/*!
\property QWidget::font
\brief the font currently set for the widget
@@ -4629,6 +4933,13 @@ void QWidget::setCursor(const QCursor &cursor)
QApplication::sendEvent(this, &event);
}
+void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+ Q_Q(QWidget);
+ qt_qpa_set_cursor(q, false);
+}
+
void QWidget::unsetCursor()
{
Q_D(QWidget);
@@ -4644,6 +4955,62 @@ void QWidget::unsetCursor()
QApplication::sendEvent(this, &event);
}
+void QWidgetPrivate::unsetCursor_sys()
+{
+ Q_Q(QWidget);
+ qt_qpa_set_cursor(q, false);
+}
+
+static inline void applyCursor(QWidget *w, QCursor c)
+{
+ if (QWindow *window = w->windowHandle())
+ window->setCursor(c);
+}
+
+static inline void unsetCursor(QWidget *w)
+{
+ if (QWindow *window = w->windowHandle())
+ window->unsetCursor();
+}
+
+void qt_qpa_set_cursor(QWidget *w, bool force)
+{
+ if (!w->testAttribute(Qt::WA_WState_Created))
+ return;
+
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ } else if (lastUnderMouse) {
+ const WId lastWinId = lastUnderMouse->effectiveWinId();
+ const WId winId = w->effectiveWinId();
+ if (lastWinId && lastWinId == winId)
+ w = lastUnderMouse;
+ } else if (!w->internalWinId()) {
+ return; // The mouse is not under this widget, and it's not native, so don't change it.
+ }
+
+ while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
+ && !w->testAttribute(Qt::WA_SetCursor))
+ w = w->parentWidget();
+
+ QWidget *nativeParent = w;
+ if (!w->internalWinId())
+ nativeParent = w->nativeParentWidget();
+ if (!nativeParent || !nativeParent->internalWinId())
+ return;
+
+ if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
+ if (w->isEnabled())
+ applyCursor(nativeParent, w->cursor());
+ else
+ // Enforce the windows behavior of clearing the cursor on
+ // disabled widgets.
+ unsetCursor(nativeParent);
+ } else {
+ unsetCursor(nativeParent);
+ }
+}
#endif
/*!
@@ -5149,8 +5516,13 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
// This widget renders into a texture which is composed later. We just need to
// punch a hole in the backingstore, so the texture will be visible.
QPainter p(q);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(q->rect(), Qt::transparent);
+ if (backingStore) {
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(q->rect(), Qt::transparent);
+ } else {
+ // We are not drawing to a backingstore: fall back to QImage
+ p.drawImage(q->rect(), grabFramebuffer());
+ }
} else {
//actually send the paint event
QPaintEvent e(toBePainted);
@@ -5604,6 +5976,17 @@ void QWidgetPrivate::setWindowTitle_helper(const QString &title)
setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
}
+void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
+{
+ Q_Q(QWidget);
+ if (!q->isWindow())
+ return;
+
+ if (QWindow *window = q->windowHandle())
+ window->setTitle(caption);
+
+}
+
void QWidgetPrivate::setWindowIconText_helper(const QString &title)
{
Q_Q(QWidget);
@@ -5611,6 +5994,11 @@ void QWidgetPrivate::setWindowIconText_helper(const QString &title)
setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q));
}
+void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
+{
+ Q_UNUSED(iconText);
+}
+
/*!
\fn void QWidget::windowIconTextChanged(const QString &iconText)
@@ -5719,6 +6107,12 @@ void QWidget::setWindowIcon(const QIcon &icon)
emit windowIconChanged(icon);
}
+void QWidgetPrivate::setWindowIcon_sys()
+{
+ Q_Q(QWidget);
+ if (QWindow *window = q->windowHandle())
+ window->setIcon(q->windowIcon());
+}
/*!
\property QWidget::windowIconText
@@ -5794,6 +6188,16 @@ void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath)
#endif
}
+void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
+{
+ Q_Q(QWidget);
+ if (!q->isWindow())
+ return;
+
+ if (QWindow *window = q->windowHandle())
+ window->setFilePath(filePath);
+}
+
/*!
Returns the window's role, or an empty string.
@@ -6053,6 +6457,21 @@ void QWidget::setFocus(Qt::FocusReason reason)
}
}
+void QWidgetPrivate::setFocus_sys()
+{
+ Q_Q(QWidget);
+ // Embedded native widget may have taken the focus; get it back to toplevel if that is the case
+ const QWidget *topLevel = q->window();
+ if (topLevel->windowType() != Qt::Popup) {
+ if (QWindow *nativeWindow = q->window()->windowHandle()) {
+ if (nativeWindow != QGuiApplication::focusWindow()
+ && q->testAttribute(Qt::WA_WState_Created)) {
+ nativeWindow->requestActivate();
+ }
+ }
+ }
+}
+
// updates focus_child on parent widgets to point into this widget
void QWidgetPrivate::updateFocusChild()
{
@@ -6554,6 +6973,31 @@ void QWidget::move(const QPoint &p)
QWindowContainer::parentWasMoved(this);
}
+// move() was invoked with Qt::WA_WState_Created not set (frame geometry
+// unknown), that is, crect has a position including the frame.
+// If we can determine the frame strut, fix that and clear the flag.
+void QWidgetPrivate::fixPosIncludesFrame()
+{
+ Q_Q(QWidget);
+ if (QTLWExtra *te = maybeTopData()) {
+ if (te->posIncludesFrame) {
+ // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
+ // example, in QGraphicsProxyWidget).
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ te->posIncludesFrame = 0;
+ } else {
+ if (q->windowHandle()) {
+ updateFrameStrut();
+ if (!q->data->fstrut_dirty) {
+ data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
+ te->posIncludesFrame = 0;
+ }
+ } // windowHandle()
+ } // !WA_DontShowOnScreen
+ } // posIncludesFrame
+ } // QTLWExtra
+}
+
/*! \fn void QWidget::resize(int w, int h)
\overload
@@ -6595,6 +7039,110 @@ void QWidget::setGeometry(const QRect &r)
QWindowContainer::parentWasMoved(this);
}
+void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
+{
+ Q_Q(QWidget);
+ if (extra) { // any size restrictions?
+ w = qMin(w,extra->maxw);
+ h = qMin(h,extra->maxh);
+ w = qMax(w,extra->minw);
+ h = qMax(h,extra->minh);
+ }
+
+ if (q->isWindow() && q->windowHandle()) {
+ QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
+ if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) {
+ x = 0;
+ y = 0;
+ w = q->windowHandle()->width();
+ h = q->windowHandle()->height();
+ }
+ }
+
+ QPoint oldp = q->geometry().topLeft();
+ QSize olds = q->size();
+ QRect r(x, y, w, h);
+
+ bool isResize = olds != r.size();
+ isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
+
+
+ // We only care about stuff that changes the geometry, or may
+ // cause the window manager to change its state
+ if (r.size() == olds && oldp == r.topLeft())
+ return;
+
+ if (!data.in_set_window_state) {
+ q->data->window_state &= ~Qt::WindowMaximized;
+ q->data->window_state &= ~Qt::WindowFullScreen;
+ if (q->isWindow())
+ topData()->normalGeometry = QRect(0, 0, -1, -1);
+ }
+
+ QPoint oldPos = q->pos();
+ data.crect = r;
+
+ bool needsShow = false;
+
+ if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
+ q->setAttribute(Qt::WA_OutsideWSRange, true);
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+ hide_sys();
+ data.crect = QRect(x, y, w, h);
+ } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
+ q->setAttribute(Qt::WA_OutsideWSRange, false);
+ needsShow = true;
+ }
+
+ if (q->isVisible()) {
+ if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
+ if (q->windowHandle()) {
+ if (q->isWindow()) {
+ q->windowHandle()->setGeometry(q->geometry());
+ } else {
+ QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
+ q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
+ }
+
+ if (needsShow)
+ show_sys();
+ }
+
+ if (!q->isWindow()) {
+ if (renderToTexture) {
+ QRegion updateRegion(q->geometry());
+ updateRegion += QRect(oldPos, olds);
+ q->parentWidget()->d_func()->invalidateBuffer(updateRegion);
+ } else if (isMove && !isResize) {
+ moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
+ } else {
+ invalidateBuffer_resizeHelper(oldPos, olds);
+ }
+ }
+ }
+
+ // generate a move event for QWidgets without window handles. QWidgets with native
+ // window handles already receive a move event from
+ // QGuiApplicationPrivate::processGeometryChangeEvent.
+ if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) {
+ QMoveEvent e(q->pos(), oldPos);
+ QApplication::sendEvent(q, &e);
+ }
+ if (isResize) {
+ QResizeEvent e(r.size(), olds);
+ QApplication::sendEvent(q, &e);
+ if (q->windowHandle())
+ q->update();
+ }
+ } else { // not visible
+ if (isMove && q->pos() != oldPos)
+ q->setAttribute(Qt::WA_PendingMoveEvent, true);
+ if (isResize)
+ q->setAttribute(Qt::WA_PendingResizeEvent, true);
+ }
+
+}
+
/*!
\since 4.2
Saves the current geometry and state for top-level widgets.
@@ -7208,6 +7756,62 @@ void QWidgetPrivate::show_helper()
data.in_show = false; // reset qws optimization
}
+void QWidgetPrivate::show_sys()
+{
+ Q_Q(QWidget);
+
+ QWindow *window = q->windowHandle();
+
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ invalidateBuffer(q->rect());
+ q->setAttribute(Qt::WA_Mapped);
+ if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
+ // add our window to the modal window list
+ QGuiApplicationPrivate::showModalWindow(window);
+ }
+ return;
+ }
+
+ if (renderToTexture && !q->isWindow())
+ QApplication::postEvent(q->parentWidget(), new QUpdateLaterEvent(q->geometry()));
+ else
+ QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
+
+ if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
+ return;
+
+ if (window) {
+ if (q->isWindow())
+ fixPosIncludesFrame();
+ QRect geomRect = q->geometry();
+ if (!q->isWindow()) {
+ QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
+ geomRect.moveTopLeft(topLeftOfWindow);
+ }
+ const QRect windowRect = window->geometry();
+ if (windowRect != geomRect) {
+ if (q->testAttribute(Qt::WA_Moved)
+ || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
+ window->setGeometry(geomRect);
+ else
+ window->resize(geomRect.size());
+ }
+
+#ifndef QT_NO_CURSOR
+ qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
+#endif
+ invalidateBuffer(q->rect());
+ window->setVisible(true);
+ // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
+ if (window->isTopLevel()) {
+ const QPoint crectTopLeft = q->data->crect.topLeft();
+ const QPoint windowTopLeft = window->geometry().topLeft();
+ if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft)
+ q->data->crect.moveTopLeft(windowTopLeft);
+ }
+ }
+}
+
/*!
Hides the widget. This function is equivalent to
setVisible(false).
@@ -7285,6 +7889,39 @@ void QWidgetPrivate::hide_helper()
#endif
}
+void QWidgetPrivate::hide_sys()
+{
+ Q_Q(QWidget);
+
+ QWindow *window = q->windowHandle();
+
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ q->setAttribute(Qt::WA_Mapped, false);
+ if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
+ // remove our window from the modal window list
+ QGuiApplicationPrivate::hideModalWindow(window);
+ }
+ // do not return here, if window non-zero, we must hide it
+ }
+
+ deactivateWidgetCleanup();
+
+ if (!q->isWindow()) {
+ QWidget *p = q->parentWidget();
+ if (p &&p->isVisible()) {
+ if (renderToTexture)
+ p->d_func()->invalidateBuffer(q->geometry());
+ else
+ invalidateBuffer(q->rect());
+ }
+ } else {
+ invalidateBuffer(q->rect());
+ }
+
+ if (window)
+ window->setVisible(false);
+}
+
/*!
\fn bool QWidget::isHidden() const
@@ -8213,6 +8850,7 @@ bool QWidget::event(QEvent *event)
case QEvent::MacSizeChange:
case QEvent::ContentsRectChange:
case QEvent::ThemeChange:
+ case QEvent::ReadOnlyChange:
changeEvent(event);
break;
@@ -8386,7 +9024,7 @@ bool QWidget::event(QEvent *event)
QEvent::ModifiedChange, QEvent::MouseTrackingChange,
QEvent::ParentChange, QEvent::WindowStateChange,
QEvent::LanguageChange, QEvent::LocaleChange,
- QEvent::LayoutDirectionChange.
+ QEvent::LayoutDirectionChange, QEvent::ReadOnlyChange.
*/
void QWidget::changeEvent(QEvent * event)
@@ -9767,6 +10405,88 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
QWindowContainer::parentWasChanged(this);
}
+void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
+{
+ Q_Q(QWidget);
+
+ Qt::WindowFlags oldFlags = data.window_flags;
+ bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
+
+ int targetScreen = -1;
+ // Handle a request to move the widget to a particular screen
+ if (newparent && newparent->windowType() == Qt::Desktop) {
+ // make sure the widget is created on the same screen as the
+ // programmer specified desktop widget
+
+ // get the desktop's screen number
+ targetScreen = newparent->window()->d_func()->topData()->screenIndex;
+ newparent = 0;
+ }
+
+ setWinId(0);
+
+ if (parent != newparent) {
+ QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
+ if (q->windowHandle()) {
+ q->windowHandle()->setFlags(f);
+ QWidget *parentWithWindow =
+ newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
+ if (parentWithWindow) {
+ if (f & Qt::Window) {
+ q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
+ q->windowHandle()->setParent(0);
+ } else {
+ q->windowHandle()->setTransientParent(0);
+ q->windowHandle()->setParent(parentWithWindow->windowHandle());
+ }
+ } else {
+ q->windowHandle()->setTransientParent(0);
+ q->windowHandle()->setParent(0);
+ }
+ }
+ }
+
+ if (!newparent) {
+ f |= Qt::Window;
+ if (targetScreen == -1) {
+ if (parent)
+ targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
+ }
+ }
+
+ bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
+
+ // Reparenting toplevel to child
+ if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
+ if (extra && extra->hasWindowContainer)
+ QWindowContainer::toplevelAboutToBeDestroyed(q);
+ q->destroy();
+ }
+
+ adjustFlags(f, q);
+ data.window_flags = f;
+ q->setAttribute(Qt::WA_WState_Created, false);
+ q->setAttribute(Qt::WA_WState_Visible, false);
+ q->setAttribute(Qt::WA_WState_Hidden, false);
+
+ if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window)))
+ q->createWinId();
+
+ if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
+ q->setAttribute(Qt::WA_WState_Hidden);
+ q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
+
+ // move the window to the selected screen
+ if (!newparent && targetScreen != -1) {
+ if (maybeTopData())
+ maybeTopData()->screenIndex = targetScreen;
+ // only if it is already created
+ if (q->testAttribute(Qt::WA_WState_Created)) {
+ q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
+ }
+ }
+}
+
/*!
Scrolls the widget including its children \a dx pixels to the
right and \a dy downward. Both \a dx and \a dy may be negative.
@@ -9812,6 +10532,13 @@ void QWidget::scroll(int dx, int dy)
d->scroll_sys(dx, dy);
}
+void QWidgetPrivate::scroll_sys(int dx, int dy)
+{
+ Q_Q(QWidget);
+ scrollChildren(dx, dy);
+ scrollRect(q->rect(), dx, dy);
+}
+
/*!
\overload
@@ -9846,6 +10573,11 @@ void QWidget::scroll(int dx, int dy, const QRect &r)
d->scroll_sys(dx, dy, r);
}
+void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
+{
+ scrollRect(r, dx, dy);
+}
+
/*!
Repaints the widget directly by calling paintEvent() immediately,
unless updates are disabled or the widget is hidden.
@@ -10093,7 +10825,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
#ifdef Q_OS_WIN
// ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release
if (attribute == Qt::WA_PaintOnScreen && on && windowType() != Qt::Desktop && !inherits("QGLWidget")) {
- // see qwidget_qpa.cpp, ::paintEngine for details
+ // see ::paintEngine for details
paintEngine();
if (d->noPaintOnScreen)
return;
@@ -10417,6 +11149,13 @@ void QWidget::setWindowOpacity(qreal opacity)
#endif
}
+void QWidgetPrivate::setWindowOpacity_sys(qreal level)
+{
+ Q_Q(QWidget);
+ if (q->windowHandle())
+ q->windowHandle()->setOpacity(level);
+}
+
/*!
\property QWidget::windowModified
\brief whether the document shown in the window has unsaved changes
@@ -10586,12 +11325,21 @@ QString QWidget::whatsThis() const
\brief the widget's name as seen by assistive technologies
- This property is used by accessible clients to identify, find, or announce
- the widget for accessible clients.
+ This is the primary name by which assistive technology such as screen readers
+ announce this widget. For most widgets setting this property is not required.
+ For example for QPushButton the button's text will be used.
+
+ It is important to set this property when the widget does not provide any
+ text. For example a button that only contains an icon needs to set this
+ property to work with screen readers.
+ The name should be short and equivalent to the visual information conveyed
+ by the widget.
+
+ This property has to be \l{Internationalization with Qt}{localized}.
By default, this property contains an empty string.
- \sa QAccessibleInterface::text()
+ \sa QWidget::accessibleDescription, QAccessibleInterface::text()
*/
void QWidget::setAccessibleName(const QString &name)
{
@@ -10612,9 +11360,16 @@ QString QWidget::accessibleName() const
\brief the widget's description as seen by assistive technologies
- By default, this property contains an empty string.
+ The accessible description of a widget should convey what a widget does.
+ While the \l accessibleName should be a short and consise string (e.g. \gui{Save}),
+ the description should give more context, such as \gui{Saves the current document}.
+
+ This property has to be \l{Internationalization with Qt}{localized}.
- \sa QAccessibleInterface::text()
+ By default, this property contains an empty string and Qt falls back
+ to using the tool tip to provide this information.
+
+ \sa QWidget::accessibleName, QAccessibleInterface::text()
*/
void QWidget::setAccessibleDescription(const QString &description)
{
@@ -10774,6 +11529,19 @@ void QWidget::raise()
QApplication::sendEvent(this, &e);
}
+void QWidgetPrivate::raise_sys()
+{
+ Q_Q(QWidget);
+ if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
+ q->windowHandle()->raise();
+ } else if (renderToTexture) {
+ if (QWidget *p = q->parentWidget()) {
+ setDirtyOpaqueRegion();
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ }
+ }
+}
+
/*!
Lowers the widget to the bottom of the parent widget's stack.
@@ -10811,6 +11579,17 @@ void QWidget::lower()
QApplication::sendEvent(this, &e);
}
+void QWidgetPrivate::lower_sys()
+{
+ Q_Q(QWidget);
+ if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ q->windowHandle()->lower();
+ } else if (QWidget *p = q->parentWidget()) {
+ setDirtyOpaqueRegion();
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ }
+}
/*!
Places the widget under \a w in the parent widget's stack.
@@ -10847,6 +11626,14 @@ void QWidget::stackUnder(QWidget* w)
QApplication::sendEvent(this, &e);
}
+void QWidgetPrivate::stackUnder_sys(QWidget*)
+{
+ Q_Q(QWidget);
+ if (QWidget *p = q->parentWidget()) {
+ setDirtyOpaqueRegion();
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ }
+}
/*!
\fn bool QWidget::isTopLevel() const
@@ -10907,6 +11694,24 @@ QRect QWidgetPrivate::frameStrut() const
return maybeTopData() ? maybeTopData()->frameStrut : QRect();
}
+void QWidgetPrivate::updateFrameStrut()
+{
+ Q_Q(QWidget);
+ if (q->data->fstrut_dirty) {
+ if (QTLWExtra *te = maybeTopData()) {
+ if (te->window) {
+ if (const QPlatformWindow *pw = te->window->handle()) {
+ const QMargins margins = pw->frameMargins();
+ if (!margins.isNull()) {
+ te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
+ q->data->fstrut_dirty = false;
+ }
+ }
+ }
+ }
+ }
+}
+
#ifdef QT_KEYPAD_NAVIGATION
/*!
\internal
@@ -11243,6 +12048,50 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
This function is usually called from the QWidget destructor.
*/
+void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+{
+ Q_D(QWidget);
+
+ d->aboutToDestroy();
+ if (!isWindow() && parentWidget())
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ d->deactivateWidgetCleanup();
+
+ if ((windowType() == Qt::Popup) && qApp)
+ qApp->d_func()->closePopup(this);
+
+ if (this == QApplicationPrivate::active_window)
+ QApplication::setActiveWindow(0);
+ if (QWidget::mouseGrabber() == this)
+ releaseMouse();
+ if (QWidget::keyboardGrabber() == this)
+ releaseKeyboard();
+
+ setAttribute(Qt::WA_WState_Created, false);
+
+ if (windowType() != Qt::Desktop) {
+ if (destroySubWindows) {
+ QObjectList childList(children());
+ for (int i = 0; i < childList.size(); i++) {
+ QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
+ if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
+ if (widget->windowHandle()) {
+ widget->destroy();
+ }
+ }
+ }
+ }
+ if (destroyWindow) {
+ d->deleteTLSysExtra();
+ } else {
+ if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
+ d->hide_sys();
+ }
+ }
+
+ d->setWinId(0);
+ }
+}
/*!
\fn QPaintEngine *QWidget::paintEngine() const
@@ -11254,6 +12103,30 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
function is called by Qt internally, and the default
implementation may not always return a valid pointer.
*/
+QPaintEngine *QWidget::paintEngine() const
+{
+ qWarning("QWidget::paintEngine: Should no longer be called");
+
+#ifdef Q_OS_WIN
+ // We set this bit which is checked in setAttribute for
+ // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
+ //
+ // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
+ // Windows which would mean suddenly their widgets stop working.
+ //
+ // 2. Users set paint on screen and subclass paintEngine() to
+ // return 0, in which case we have a "hole" in the backingstore
+ // allowing use of GDI or DirectX directly.
+ //
+ // 1 is WRONG, but to minimize silent failures, we have set this
+ // bit to ignore the setAttribute call. 2. needs to be
+ // supported because its our only means of embedding native
+ // graphics stuff.
+ const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
+#endif
+
+ return 0; //##### @@@
+}
/*!
\fn QPoint QWidget::mapToGlobal(const QPoint &pos) const
@@ -11264,6 +12137,21 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa mapFromGlobal(), mapTo(), mapToParent()
*/
+QPoint QWidget::mapToGlobal(const QPoint &pos) const
+{
+ int x = pos.x(), y = pos.y();
+ const QWidget *w = this;
+ while (w) {
+ QWindow *window = w->windowHandle();
+ if (window && window->handle())
+ return window->mapToGlobal(QPoint(x, y));
+
+ x += w->data->crect.x();
+ y += w->data->crect.y();
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ return QPoint(x, y);
+}
/*!
\fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const
@@ -11273,6 +12161,34 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa mapToGlobal(), mapFrom(), mapFromParent()
*/
+QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+{
+ int x = pos.x(), y = pos.y();
+ const QWidget *w = this;
+ while (w) {
+ QWindow *window = w->windowHandle();
+ if (window && window->handle())
+ return window->mapFromGlobal(QPoint(x, y));
+
+ x -= w->data->crect.x();
+ y -= w->data->crect.y();
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ return QPoint(x, y);
+}
+
+QWidget *qt_pressGrab = 0;
+QWidget *qt_mouseGrb = 0;
+static QWidget *keyboardGrb = 0;
+
+static inline QWindow *grabberWindow(const QWidget *w)
+{
+ QWindow *window = w->windowHandle();
+ if (!window)
+ if (const QWidget *nativeParent = w->nativeParentWidget())
+ window = nativeParent->windowHandle();
+ return window;
+}
/*!
\fn void QWidget::grabMouse()
@@ -11303,6 +12219,17 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa releaseMouse(), grabKeyboard(), releaseKeyboard()
*/
+void QWidget::grabMouse()
+{
+ if (qt_mouseGrb)
+ qt_mouseGrb->releaseMouse();
+
+ if (QWindow *window = grabberWindow(this))
+ window->setMouseGrabEnabled(true);
+
+ qt_mouseGrb = this;
+ qt_pressGrab = 0;
+}
/*!
\fn void QWidget::grabMouse(const QCursor &cursor)
@@ -11320,6 +12247,22 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
*/
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+ grabMouse();
+}
+#endif
+
+bool QWidgetPrivate::stealMouseGrab(bool grab)
+{
+ // This is like a combination of grab/releaseMouse() but with error checking
+ // and it has no effect on the result of mouseGrabber().
+ Q_Q(QWidget);
+ QWindow *window = grabberWindow(q);
+ return window ? window->setMouseGrabEnabled(grab) : false;
+}
/*!
\fn void QWidget::releaseMouse()
@@ -11328,6 +12271,14 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa grabMouse(), grabKeyboard(), releaseKeyboard()
*/
+void QWidget::releaseMouse()
+{
+ if (qt_mouseGrb == this) {
+ if (QWindow *window = grabberWindow(this))
+ window->setMouseGrabEnabled(false);
+ qt_mouseGrb = 0;
+ }
+}
/*!
\fn void QWidget::grabKeyboard()
@@ -11348,6 +12299,23 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa releaseKeyboard(), grabMouse(), releaseMouse(), focusWidget()
*/
+void QWidget::grabKeyboard()
+{
+ if (keyboardGrb)
+ keyboardGrb->releaseKeyboard();
+ if (QWindow *window = grabberWindow(this))
+ window->setKeyboardGrabEnabled(true);
+ keyboardGrb = this;
+}
+
+bool QWidgetPrivate::stealKeyboardGrab(bool grab)
+{
+ // This is like a combination of grab/releaseKeyboard() but with error
+ // checking and it has no effect on the result of keyboardGrabber().
+ Q_Q(QWidget);
+ QWindow *window = grabberWindow(q);
+ return window ? window->setKeyboardGrabEnabled(grab) : false;
+}
/*!
\fn void QWidget::releaseKeyboard()
@@ -11356,6 +12324,14 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa grabKeyboard(), grabMouse(), releaseMouse()
*/
+void QWidget::releaseKeyboard()
+{
+ if (keyboardGrb == this) {
+ if (QWindow *window = grabberWindow(this))
+ window->setKeyboardGrabEnabled(false);
+ keyboardGrb = 0;
+ }
+}
/*!
\fn QWidget *QWidget::mouseGrabber()
@@ -11367,6 +12343,12 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa grabMouse(), keyboardGrabber()
*/
+QWidget *QWidget::mouseGrabber()
+{
+ if (qt_mouseGrb)
+ return qt_mouseGrb;
+ return qt_pressGrab;
+}
/*!
\fn QWidget *QWidget::keyboardGrabber()
@@ -11378,6 +12360,10 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa grabMouse(), mouseGrabber()
*/
+QWidget *QWidget::keyboardGrabber()
+{
+ return keyboardGrb;
+}
/*!
\fn void QWidget::activateWindow()
@@ -11403,6 +12389,13 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\sa isActiveWindow(), window(), show()
*/
+void QWidget::activateWindow()
+{
+ QWindow *const wnd = window()->windowHandle();
+
+ if (wnd)
+ wnd->requestActivate();
+}
/*!
\fn int QWidget::metric(PaintDeviceMetric m) const
@@ -11412,6 +12405,62 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\a m is the metric to get.
*/
+int QWidget::metric(PaintDeviceMetric m) const
+{
+ Q_D(const QWidget);
+
+ QWindow *topLevelWindow = 0;
+ QScreen *screen = 0;
+ if (QWidget *topLevel = window())
+ topLevelWindow = topLevel->windowHandle();
+
+ if (topLevelWindow) {
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
+ if (platformScreen)
+ screen = platformScreen->screen();
+ }
+ if (!screen && QGuiApplication::primaryScreen())
+ screen = QGuiApplication::primaryScreen();
+
+ if (!screen) {
+ if (m == PdmDpiX || m == PdmDpiY)
+ return 72;
+ return QPaintDevice::metric(m);
+ }
+ int val;
+ if (m == PdmWidth) {
+ val = data->crect.width();
+ } else if (m == PdmWidthMM) {
+ val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
+ } else if (m == PdmHeight) {
+ val = data->crect.height();
+ } else if (m == PdmHeightMM) {
+ val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
+ } else if (m == PdmDepth) {
+ return screen->depth();
+ } else if (m == PdmDpiX) {
+ if (d->extra && d->extra->customDpiX)
+ return d->extra->customDpiX;
+ else if (d->parent)
+ return static_cast<QWidget *>(d->parent)->metric(m);
+ return qRound(screen->logicalDotsPerInchX());
+ } else if (m == PdmDpiY) {
+ if (d->extra && d->extra->customDpiY)
+ return d->extra->customDpiY;
+ else if (d->parent)
+ return static_cast<QWidget *>(d->parent)->metric(m);
+ return qRound(screen->logicalDotsPerInchY());
+ } else if (m == PdmPhysicalDpiX) {
+ return qRound(screen->physicalDotsPerInchX());
+ } else if (m == PdmPhysicalDpiY) {
+ return qRound(screen->physicalDotsPerInchY());
+ } else if (m == PdmDevicePixelRatio) {
+ return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
+ } else {
+ val = QPaintDevice::metric(m);// XXX
+ }
+ return val;
+}
/*!
Initializes the \a painter pen, background and font to the same as
@@ -11517,6 +12566,14 @@ void QWidget::setMask(const QRegion &newMask)
#endif
}
+void QWidgetPrivate::setMask_sys(const QRegion &region)
+{
+ Q_Q(QWidget);
+ if (const QWindow *window = q->windowHandle())
+ if (QPlatformWindow *platformWindow = window->handle())
+ platformWindow->setMask(region);
+}
+
/*!
\fn void QWidget::setMask(const QBitmap &bitmap)
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index 159011b824..9c22ad7c3d 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -694,7 +694,6 @@ private:
friend class QPixmap; // for QPixmap::fill()
friend class QFontMetrics;
friend class QFontInfo;
- friend class QETWidget;
friend class QLayout;
friend class QWidgetItem;
friend class QWidgetItemV2;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 9586d1a8c9..6520832943 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -627,7 +627,7 @@ public:
#ifndef QT_NO_OPENGL
virtual GLuint textureId() const { return 0; }
-
+ virtual QImage grabFramebuffer() const { return QImage(); }
void setRenderToTexture() { renderToTexture = true; setTextureChildSeen(); }
void setTextureChildSeen()
{
@@ -732,7 +732,7 @@ public:
// *************************** Platform specific ************************************
#if defined(Q_OS_WIN)
- uint noPaintOnScreen : 1; // see qwidget_qpa.cpp ::paintEngine()
+ uint noPaintOnScreen : 1; // see qwidget.cpp ::paintEngine()
#endif
#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
Qt::HANDLE picture;
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
deleted file mode 100644
index 70d274796b..0000000000
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ /dev/null
@@ -1,1126 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "QtWidgets/qwidget.h"
-#include "QtGui/qevent.h"
-#include "QtWidgets/qapplication.h"
-#include "private/qwidgetbackingstore_p.h"
-#include "private/qwidget_p.h"
-#include "private/qwidgetwindow_qpa_p.h"
-#include "private/qapplication_p.h"
-#include "QtWidgets/qdesktopwidget.h"
-#include <qpa/qplatformwindow.h>
-#include "QtGui/qsurfaceformat.h"
-#include <QtGui/qopenglcontext.h>
-#include <qpa/qplatformopenglcontext.h>
-#include <qpa/qplatformintegration.h>
-#include "QtGui/private/qwindow_p.h"
-#include "QtGui/private/qguiapplication_p.h"
-#include <private/qwindowcontainer_p.h>
-
-#include <qpa/qplatformcursor.h>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QScreen>
-#include <QtCore/QMargins>
-
-QT_BEGIN_NAMESPACE
-
-void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
-{
- QObjectList children = parentWidget->children();
- for (int i = 0; i < children.size(); i++) {
- if (children.at(i)->isWidgetType()) {
- const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
- if (childWidget) { // should not be necessary
- if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
- if (!childWidget->internalWinId())
- childWidget->winId();
- if (childWidget->windowHandle()) {
- QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle();
- if (childWidget->isWindow())
- childWidget->windowHandle()->setTransientParent(parentWindow);
- else
- childWidget->windowHandle()->setParent(parentWindow);
- }
- } else {
- q_createNativeChildrenAndSetParent(childWidget);
- }
- }
- }
- }
-
-}
-
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
-{
- Q_Q(QWidget);
-
- Q_UNUSED(window);
- Q_UNUSED(initializeWindow);
- Q_UNUSED(destroyOldWindow);
-
- Qt::WindowFlags flags = data.window_flags;
-
- if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
- return; // we only care about real toplevels
-
- QWindow *win = topData()->window;
- // topData() ensures the extra is created but does not ensure 'window' is non-null
- // in case the extra was already valid.
- if (!win) {
- createTLSysExtra();
- win = topData()->window;
- }
-
- foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) {
- if (!qstrncmp(propertyName, "_q_platform_", 12))
- win->setProperty(propertyName, q->property(propertyName));
- }
-
-#ifdef Q_OS_OSX
- if (q->testAttribute(Qt::WA_ShowWithoutActivating))
- win->setProperty("_q_showWithoutActivating", QVariant(true));
-#endif
- win->setFlags(data.window_flags);
- fixPosIncludesFrame();
- if (q->testAttribute(Qt::WA_Moved)
- || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
- win->setGeometry(q->geometry());
- else
- win->resize(q->size());
- win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
-
- QSurfaceFormat format = win->requestedFormat();
- if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
- && q->testAttribute(Qt::WA_TranslucentBackground)) {
- format.setAlphaBufferSize(8);
- }
- win->setFormat(format);
-
- if (QWidget *nativeParent = q->nativeParentWidget()) {
- if (nativeParent->windowHandle()) {
- if (flags & Qt::Window) {
- win->setTransientParent(nativeParent->windowHandle());
- win->setParent(0);
- } else {
- win->setTransientParent(0);
- win->setParent(nativeParent->windowHandle());
- }
- }
- }
-
- qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
- QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
- win->create();
- // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
- if ((flags & Qt::Desktop) == Qt::Window)
- win->handle()->setFrameStrutEventsEnabled(true);
-
- data.window_flags = win->flags();
-
- QBackingStore *store = q->backingStore();
-
- if (!store) {
- if (win && q->windowType() != Qt::Desktop) {
- if (q->isTopLevel())
- q->setBackingStore(new QBackingStore(win));
- } else {
- q->setAttribute(Qt::WA_PaintOnScreen, true);
- }
- }
-
- setWindowModified_helper();
- WId id = win->winId();
- // See the QPlatformWindow::winId() documentation
- Q_ASSERT(id != WId(0));
- setWinId(id);
-
- // Check children and create windows for them if necessary
- q_createNativeChildrenAndSetParent(q);
-
- if (extra && !extra->mask.isEmpty())
- setMask_sys(extra->mask);
-
- // If widget is already shown, set window visible, too
- if (q->isVisible())
- win->setVisible(true);
-}
-
-void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
-{
- Q_D(QWidget);
-
- d->aboutToDestroy();
- if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
- d->deactivateWidgetCleanup();
-
- if ((windowType() == Qt::Popup) && qApp)
- qApp->d_func()->closePopup(this);
-
- if (this == QApplicationPrivate::active_window)
- QApplication::setActiveWindow(0);
- if (QWidget::mouseGrabber() == this)
- releaseMouse();
- if (QWidget::keyboardGrabber() == this)
- releaseKeyboard();
-
- setAttribute(Qt::WA_WState_Created, false);
-
- if (windowType() != Qt::Desktop) {
- if (destroySubWindows) {
- QObjectList childList(children());
- for (int i = 0; i < childList.size(); i++) {
- QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
- if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
- if (widget->windowHandle()) {
- widget->destroy();
- }
- }
- }
- }
- if (destroyWindow) {
- d->deleteTLSysExtra();
- } else {
- if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
- d->hide_sys();
- }
- }
-
- d->setWinId(0);
- }
-}
-
-void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
-
- Qt::WindowFlags oldFlags = data.window_flags;
- bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
-
- int targetScreen = -1;
- // Handle a request to move the widget to a particular screen
- if (newparent && newparent->windowType() == Qt::Desktop) {
- // make sure the widget is created on the same screen as the
- // programmer specified desktop widget
-
- // get the desktop's screen number
- targetScreen = newparent->window()->d_func()->topData()->screenIndex;
- newparent = 0;
- }
-
- setWinId(0);
-
- if (parent != newparent) {
- QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
- if (q->windowHandle()) {
- q->windowHandle()->setFlags(f);
- QWidget *parentWithWindow =
- newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
- if (parentWithWindow) {
- if (f & Qt::Window) {
- q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
- q->windowHandle()->setParent(0);
- } else {
- q->windowHandle()->setTransientParent(0);
- q->windowHandle()->setParent(parentWithWindow->windowHandle());
- }
- } else {
- q->windowHandle()->setTransientParent(0);
- q->windowHandle()->setParent(0);
- }
- }
- }
-
- if (!newparent) {
- f |= Qt::Window;
- if (targetScreen == -1) {
- if (parent)
- targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
- }
- }
-
- bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
-
- // Reparenting toplevel to child
- if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
- if (extra && extra->hasWindowContainer)
- QWindowContainer::toplevelAboutToBeDestroyed(q);
- q->destroy();
- }
-
- adjustFlags(f, q);
- data.window_flags = f;
- q->setAttribute(Qt::WA_WState_Created, false);
- q->setAttribute(Qt::WA_WState_Visible, false);
- q->setAttribute(Qt::WA_WState_Hidden, false);
-
- if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window)))
- q->createWinId();
-
- if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
- q->setAttribute(Qt::WA_WState_Hidden);
- q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
-
- // move the window to the selected screen
- if (!newparent && targetScreen != -1) {
- if (maybeTopData())
- maybeTopData()->screenIndex = targetScreen;
- // only if it is already created
- if (q->testAttribute(Qt::WA_WState_Created)) {
- q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
- }
- }
-}
-
-QPoint QWidget::mapToGlobal(const QPoint &pos) const
-{
- int x = pos.x(), y = pos.y();
- const QWidget *w = this;
- while (w) {
- QWindow *window = w->windowHandle();
- if (window && window->handle())
- return window->mapToGlobal(QPoint(x, y));
-
- x += w->data->crect.x();
- y += w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-{
- int x = pos.x(), y = pos.y();
- const QWidget *w = this;
- while (w) {
- QWindow *window = w->windowHandle();
- if (window && window->handle())
- return window->mapFromGlobal(QPoint(x, y));
-
- x -= w->data->crect.x();
- y -= w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-void QWidgetPrivate::updateSystemBackground() {}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
-{
- Q_UNUSED(cursor);
- Q_Q(QWidget);
- qt_qpa_set_cursor(q, false);
-}
-
-void QWidgetPrivate::unsetCursor_sys()
-{
- Q_Q(QWidget);
- qt_qpa_set_cursor(q, false);
-}
-
-#endif //QT_NO_CURSOR
-
-void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
-{
- Q_Q(QWidget);
- if (!q->isWindow())
- return;
-
- if (QWindow *window = q->windowHandle())
- window->setTitle(caption);
-
-}
-
-void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
-{
- Q_Q(QWidget);
- if (!q->isWindow())
- return;
-
- if (QWindow *window = q->windowHandle())
- window->setFilePath(filePath);
-}
-
-void QWidgetPrivate::setWindowIcon_sys()
-{
- Q_Q(QWidget);
- if (QWindow *window = q->windowHandle())
- window->setIcon(q->windowIcon());
-}
-
-void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
-{
- Q_UNUSED(iconText);
-}
-
-QWidget *qt_pressGrab = 0;
-QWidget *qt_mouseGrb = 0;
-static QWidget *keyboardGrb = 0;
-
-static inline QWindow *grabberWindow(const QWidget *w)
-{
- QWindow *window = w->windowHandle();
- if (!window)
- if (const QWidget *nativeParent = w->nativeParentWidget())
- window = nativeParent->windowHandle();
- return window;
-}
-
-void QWidget::grabMouse()
-{
- if (qt_mouseGrb)
- qt_mouseGrb->releaseMouse();
-
- if (QWindow *window = grabberWindow(this))
- window->setMouseGrabEnabled(true);
-
- qt_mouseGrb = this;
- qt_pressGrab = 0;
-}
-
-#ifndef QT_NO_CURSOR
-void QWidget::grabMouse(const QCursor &cursor)
-{
- Q_UNUSED(cursor);
- grabMouse();
-}
-#endif
-
-bool QWidgetPrivate::stealMouseGrab(bool grab)
-{
- // This is like a combination of grab/releaseMouse() but with error checking
- // and it has no effect on the result of mouseGrabber().
- Q_Q(QWidget);
- QWindow *window = grabberWindow(q);
- return window ? window->setMouseGrabEnabled(grab) : false;
-}
-
-void QWidget::releaseMouse()
-{
- if (qt_mouseGrb == this) {
- if (QWindow *window = grabberWindow(this))
- window->setMouseGrabEnabled(false);
- qt_mouseGrb = 0;
- }
-}
-
-void QWidget::grabKeyboard()
-{
- if (keyboardGrb)
- keyboardGrb->releaseKeyboard();
- if (QWindow *window = grabberWindow(this))
- window->setKeyboardGrabEnabled(true);
- keyboardGrb = this;
-}
-
-bool QWidgetPrivate::stealKeyboardGrab(bool grab)
-{
- // This is like a combination of grab/releaseKeyboard() but with error
- // checking and it has no effect on the result of keyboardGrabber().
- Q_Q(QWidget);
- QWindow *window = grabberWindow(q);
- return window ? window->setKeyboardGrabEnabled(grab) : false;
-}
-
-void QWidget::releaseKeyboard()
-{
- if (keyboardGrb == this) {
- if (QWindow *window = grabberWindow(this))
- window->setKeyboardGrabEnabled(false);
- keyboardGrb = 0;
- }
-}
-
-QWidget *QWidget::mouseGrabber()
-{
- if (qt_mouseGrb)
- return qt_mouseGrb;
- return qt_pressGrab;
-}
-
-QWidget *QWidget::keyboardGrabber()
-{
- return keyboardGrb;
-}
-
-void QWidget::activateWindow()
-{
- QWindow *const wnd = window()->windowHandle();
-
- if (wnd)
- wnd->requestActivate();
-}
-
-// move() was invoked with Qt::WA_WState_Created not set (frame geometry
-// unknown), that is, crect has a position including the frame.
-// If we can determine the frame strut, fix that and clear the flag.
-void QWidgetPrivate::fixPosIncludesFrame()
-{
- Q_Q(QWidget);
- if (QTLWExtra *te = maybeTopData()) {
- if (te->posIncludesFrame) {
- // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
- // example, in QGraphicsProxyWidget).
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- te->posIncludesFrame = 0;
- } else {
- if (q->windowHandle()) {
- updateFrameStrut();
- if (!q->data->fstrut_dirty) {
- data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
- te->posIncludesFrame = 0;
- }
- } // windowHandle()
- } // !WA_DontShowOnScreen
- } // posIncludesFrame
- } // QTLWExtra
-}
-
-void QWidgetPrivate::show_sys()
-{
- Q_Q(QWidget);
-
- QWindow *window = q->windowHandle();
-
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
- q->setAttribute(Qt::WA_Mapped);
- if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
- // add our window to the modal window list
- QGuiApplicationPrivate::showModalWindow(window);
- }
- return;
- }
-
- if (renderToTexture && !q->isWindow())
- QApplication::postEvent(q->parentWidget(), new QUpdateLaterEvent(q->geometry()));
- else
- QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
-
- if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
- return;
-
- if (window) {
- if (q->isWindow())
- fixPosIncludesFrame();
- QRect geomRect = q->geometry();
- if (!q->isWindow()) {
- QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
- geomRect.moveTopLeft(topLeftOfWindow);
- }
- const QRect windowRect = window->geometry();
- if (windowRect != geomRect) {
- if (q->testAttribute(Qt::WA_Moved)
- || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement))
- window->setGeometry(geomRect);
- else
- window->resize(geomRect.size());
- }
-
-#ifndef QT_NO_CURSOR
- qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
-#endif
- invalidateBuffer(q->rect());
- window->setVisible(true);
- // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
- if (window->isTopLevel()) {
- const QPoint crectTopLeft = q->data->crect.topLeft();
- const QPoint windowTopLeft = window->geometry().topLeft();
- if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft)
- q->data->crect.moveTopLeft(windowTopLeft);
- }
- }
-}
-
-
-void QWidgetPrivate::hide_sys()
-{
- Q_Q(QWidget);
-
- QWindow *window = q->windowHandle();
-
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- q->setAttribute(Qt::WA_Mapped, false);
- if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
- // remove our window from the modal window list
- QGuiApplicationPrivate::hideModalWindow(window);
- }
- // do not return here, if window non-zero, we must hide it
- }
-
- deactivateWidgetCleanup();
-
- if (!q->isWindow()) {
- QWidget *p = q->parentWidget();
- if (p &&p->isVisible()) {
- if (renderToTexture)
- p->d_func()->invalidateBuffer(q->geometry());
- else
- invalidateBuffer(q->rect());
- }
- } else {
- invalidateBuffer(q->rect());
- }
-
- if (window)
- window->setVisible(false);
-}
-
-Qt::WindowState effectiveState(Qt::WindowStates state)
- {
- if (state & Qt::WindowMinimized)
- return Qt::WindowMinimized;
- else if (state & Qt::WindowFullScreen)
- return Qt::WindowFullScreen;
- else if (state & Qt::WindowMaximized)
- return Qt::WindowMaximized;
- return Qt::WindowNoState;
- }
-
-void QWidget::setWindowState(Qt::WindowStates newstate)
-{
- Q_D(QWidget);
- Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
- return;
- if (isWindow() && !testAttribute(Qt::WA_WState_Created))
- create();
-
- data->window_state = newstate;
- data->in_set_window_state = 1;
- Qt::WindowState newEffectiveState = effectiveState(newstate);
- Qt::WindowState oldEffectiveState = effectiveState(oldstate);
- if (isWindow() && newEffectiveState != oldEffectiveState) {
- // Ensure the initial size is valid, since we store it as normalGeometry below.
- if (!testAttribute(Qt::WA_Resized) && !isVisible())
- adjustSize();
-
- d->createTLExtra();
- if (oldEffectiveState == Qt::WindowNoState)
- d->topData()->normalGeometry = geometry();
-
- Q_ASSERT(windowHandle());
- windowHandle()->setWindowState(newEffectiveState);
- }
- data->in_set_window_state = 0;
-
- if (newstate & Qt::WindowActive)
- activateWindow();
-
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendEvent(this, &e);
-}
-
-void QWidgetPrivate::setFocus_sys()
-{
- Q_Q(QWidget);
- // Embedded native widget may have taken the focus; get it back to toplevel if that is the case
- const QWidget *topLevel = q->window();
- if (topLevel->windowType() != Qt::Popup) {
- if (QWindow *nativeWindow = q->window()->windowHandle()) {
- if (nativeWindow != QGuiApplication::focusWindow()
- && q->testAttribute(Qt::WA_WState_Created)) {
- nativeWindow->requestActivate();
- }
- }
- }
-}
-
-void QWidgetPrivate::raise_sys()
-{
- Q_Q(QWidget);
- if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
- q->windowHandle()->raise();
- } else if (renderToTexture) {
- if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
- }
-}
-
-void QWidgetPrivate::lower_sys()
-{
- Q_Q(QWidget);
- if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- q->windowHandle()->lower();
- } else if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::stackUnder_sys(QWidget*)
-{
- Q_Q(QWidget);
- if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
-{
- Q_Q(QWidget);
- if (extra) { // any size restrictions?
- w = qMin(w,extra->maxw);
- h = qMin(h,extra->maxh);
- w = qMax(w,extra->minw);
- h = qMax(h,extra->minh);
- }
-
- if (q->isWindow() && q->windowHandle()) {
- QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
- if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) {
- x = 0;
- y = 0;
- w = q->windowHandle()->width();
- h = q->windowHandle()->height();
- }
- }
-
- QPoint oldp = q->geometry().topLeft();
- QSize olds = q->size();
- QRect r(x, y, w, h);
-
- bool isResize = olds != r.size();
- isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
-
-
- // We only care about stuff that changes the geometry, or may
- // cause the window manager to change its state
- if (r.size() == olds && oldp == r.topLeft())
- return;
-
- if (!data.in_set_window_state) {
- q->data->window_state &= ~Qt::WindowMaximized;
- q->data->window_state &= ~Qt::WindowFullScreen;
- if (q->isWindow())
- topData()->normalGeometry = QRect(0, 0, -1, -1);
- }
-
- QPoint oldPos = q->pos();
- data.crect = r;
-
- bool needsShow = false;
-
- if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
- q->setAttribute(Qt::WA_OutsideWSRange, true);
- if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
- hide_sys();
- data.crect = QRect(x, y, w, h);
- } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
- q->setAttribute(Qt::WA_OutsideWSRange, false);
- needsShow = true;
- }
-
- if (q->isVisible()) {
- if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
- if (q->windowHandle()) {
- if (q->isWindow()) {
- q->windowHandle()->setGeometry(q->geometry());
- } else {
- QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
- q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
- }
-
- if (needsShow)
- show_sys();
- }
-
- if (!q->isWindow()) {
- if (renderToTexture) {
- QRegion updateRegion(q->geometry());
- updateRegion += QRect(oldPos, olds);
- q->parentWidget()->d_func()->invalidateBuffer(updateRegion);
- } else if (isMove && !isResize) {
- moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
- } else {
- invalidateBuffer_resizeHelper(oldPos, olds);
- }
- }
- }
-
- // generate a move event for QWidgets without window handles. QWidgets with native
- // window handles already receive a move event from
- // QGuiApplicationPrivate::processGeometryChangeEvent.
- if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) {
- QMoveEvent e(q->pos(), oldPos);
- QApplication::sendEvent(q, &e);
- }
- if (isResize) {
- QResizeEvent e(r.size(), olds);
- QApplication::sendEvent(q, &e);
- if (q->windowHandle())
- q->update();
- }
- } else { // not visible
- if (isMove && q->pos() != oldPos)
- q->setAttribute(Qt::WA_PendingMoveEvent, true);
- if (isResize)
- q->setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-
-}
-
-void QWidgetPrivate::setConstraints_sys()
-{
- Q_Q(QWidget);
- if (extra && q->windowHandle()) {
- QWindow *win = q->windowHandle();
- QWindowPrivate *winp = qt_window_private(win);
-
- winp->minimumSize = QSize(extra->minw, extra->minh);
- winp->maximumSize = QSize(extra->maxw, extra->maxh);
-
- if (extra->topextra) {
- winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
- winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
- }
-
- if (winp->platformWindow) {
- fixPosIncludesFrame();
- winp->platformWindow->propagateSizeHints();
- }
- }
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy)
-{
- Q_Q(QWidget);
- scrollChildren(dx, dy);
- scrollRect(q->rect(), dx, dy);
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
-{
- scrollRect(r, dx, dy);
-}
-
-int QWidget::metric(PaintDeviceMetric m) const
-{
- Q_D(const QWidget);
-
- QWindow *topLevelWindow = 0;
- QScreen *screen = 0;
- if (QWidget *topLevel = window())
- topLevelWindow = topLevel->windowHandle();
-
- if (topLevelWindow) {
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
- if (platformScreen)
- screen = platformScreen->screen();
- }
- if (!screen && QGuiApplication::primaryScreen())
- screen = QGuiApplication::primaryScreen();
-
- if (!screen) {
- if (m == PdmDpiX || m == PdmDpiY)
- return 72;
- return QPaintDevice::metric(m);
- }
- int val;
- if (m == PdmWidth) {
- val = data->crect.width();
- } else if (m == PdmWidthMM) {
- val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
- } else if (m == PdmHeight) {
- val = data->crect.height();
- } else if (m == PdmHeightMM) {
- val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
- } else if (m == PdmDepth) {
- return screen->depth();
- } else if (m == PdmDpiX) {
- if (d->extra && d->extra->customDpiX)
- return d->extra->customDpiX;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- return qRound(screen->logicalDotsPerInchX());
- } else if (m == PdmDpiY) {
- if (d->extra && d->extra->customDpiY)
- return d->extra->customDpiY;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- return qRound(screen->logicalDotsPerInchY());
- } else if (m == PdmPhysicalDpiX) {
- return qRound(screen->physicalDotsPerInchX());
- } else if (m == PdmPhysicalDpiY) {
- return qRound(screen->physicalDotsPerInchY());
- } else if (m == PdmDevicePixelRatio) {
- return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
- } else {
- val = QPaintDevice::metric(m);// XXX
- }
- return val;
-}
-
-/*!
- If this is a native widget, return the associated QWindow.
- Otherwise return null.
-
- Native widgets include toplevel widgets, QGLWidget, and child widgets
- on which winId() was called.
-
- \since 5.0
-
- \sa winId()
-*/
-QWindow *QWidget::windowHandle() const
-{
- Q_D(const QWidget);
- QTLWExtra *extra = d->maybeTopData();
- if (extra)
- return extra->window;
-
- return 0;
-}
-
-void QWidgetPrivate::createSysExtra()
-{
-}
-
-void QWidgetPrivate::deleteSysExtra()
-{
-
-}
-
-#ifdef Q_OS_WIN
-static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle";
-#endif
-
-void QWidgetPrivate::createTLSysExtra()
-{
- Q_Q(QWidget);
- if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) {
- extra->topextra->window = new QWidgetWindow(q);
- if (extra->minw || extra->minh)
- extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
- if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
- extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
- if (extra->topextra->opacity != 255 && q->isWindow())
- extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
-#ifdef Q_OS_WIN
- // Pass on native parent handle for Widget embedded into Active X.
- const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
- if (activeXNativeParentHandle.isValid())
- extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
- if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget"))
- extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
-#endif
- }
-
-}
-
-void QWidgetPrivate::deleteTLSysExtra()
-{
- if (extra && extra->topextra) {
- //the qplatformbackingstore may hold a reference to the window, so the backingstore
- //needs to be deleted first. If the backingstore holds GL resources, we need to
- // make the context current here, since the platform bs does not have a reference
- // to the widget.
-
-#ifndef QT_NO_OPENGL
- if (textureChildSeen && extra->topextra->shareContext)
- extra->topextra->shareContext->makeCurrent(extra->topextra->window);
-#endif
- extra->topextra->backingStoreTracker.destroy();
- delete extra->topextra->backingStore;
- extra->topextra->backingStore = 0;
-#ifndef QT_NO_OPENGL
- if (textureChildSeen && extra->topextra->shareContext)
- extra->topextra->shareContext->doneCurrent();
- delete extra->topextra->shareContext;
- extra->topextra->shareContext = 0;
-#endif
-
- //the toplevel might have a context with a "qglcontext associated with it. We need to
- //delete the qglcontext before we delete the qplatformopenglcontext.
- //One unfortunate thing about this is that we potentially create a glContext just to
- //delete it straight afterwards.
- if (extra->topextra->window) {
- extra->topextra->window->destroy();
- }
- setWinId(0);
- delete extra->topextra->window;
- extra->topextra->window = 0;
-
- }
-}
-
-void QWidgetPrivate::registerDropSite(bool on)
-{
- Q_UNUSED(on);
-}
-
-void QWidgetPrivate::setMask_sys(const QRegion &region)
-{
- if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) {
- qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName()));
- return;
- }
- Q_Q(QWidget);
- if (const QWindow *window = q->windowHandle())
- if (QPlatformWindow *platformWindow = window->handle())
- platformWindow->setMask(region);
-}
-
-void QWidgetPrivate::updateFrameStrut()
-{
- Q_Q(QWidget);
- if (q->data->fstrut_dirty) {
- if (QTLWExtra *te = maybeTopData()) {
- if (te->window) {
- if (const QPlatformWindow *pw = te->window->handle()) {
- const QMargins margins = pw->frameMargins();
- if (!margins.isNull()) {
- te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
- q->data->fstrut_dirty = false;
- }
- }
- }
- }
- }
-}
-
-void QWidgetPrivate::setWindowOpacity_sys(qreal level)
-{
- Q_Q(QWidget);
- if (q->windowHandle())
- q->windowHandle()->setOpacity(level);
-}
-
-void QWidgetPrivate::setWSGeometry()
-{
- Q_Q(QWidget);
- if (QWindow *window = q->windowHandle())
- window->setGeometry(data.crect);
-}
-
-QPaintEngine *QWidget::paintEngine() const
-{
- qWarning("QWidget::paintEngine: Should no longer be called");
-
-#ifdef Q_OS_WIN
- // We set this bit which is checked in setAttribute for
- // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
- //
- // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
- // Windows which would mean suddenly their widgets stop working.
- //
- // 2. Users set paint on screen and subclass paintEngine() to
- // return 0, in which case we have a "hole" in the backingstore
- // allowing use of GDI or DirectX directly.
- //
- // 1 is WRONG, but to minimize silent failures, we have set this
- // bit to ignore the setAttribute call. 2. needs to be
- // supported because its our only means of embedding native
- // graphics stuff.
- const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
-#endif
-
- return 0; //##### @@@
-}
-
-void QWidgetPrivate::setModal_sys()
-{
- Q_Q(QWidget);
- if (q->windowHandle())
- q->windowHandle()->setModality(q->windowModality());
-}
-
-#ifndef QT_NO_CURSOR
-static inline void applyCursor(QWidget *w, QCursor c)
-{
- if (QWindow *window = w->windowHandle())
- window->setCursor(c);
-}
-
-static inline void unsetCursor(QWidget *w)
-{
- if (QWindow *window = w->windowHandle())
- window->unsetCursor();
-}
-
-void qt_qpa_set_cursor(QWidget *w, bool force)
-{
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
-
- static QPointer<QWidget> lastUnderMouse = 0;
- if (force) {
- lastUnderMouse = w;
- } else if (lastUnderMouse) {
- const WId lastWinId = lastUnderMouse->effectiveWinId();
- const WId winId = w->effectiveWinId();
- if (lastWinId && lastWinId == winId)
- w = lastUnderMouse;
- } else if (!w->internalWinId()) {
- return; // The mouse is not under this widget, and it's not native, so don't change it.
- }
-
- while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
- && !w->testAttribute(Qt::WA_SetCursor))
- w = w->parentWidget();
-
- QWidget *nativeParent = w;
- if (!w->internalWinId())
- nativeParent = w->nativeParentWidget();
- if (!nativeParent || !nativeParent->internalWinId())
- return;
-
- if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
- if (w->isEnabled())
- applyCursor(nativeParent, w->cursor());
- else
- // Enforce the windows behavior of clearing the cursor on
- // disabled widgets.
- unsetCursor(nativeParent);
- } else {
- unsetCursor(nativeParent);
- }
-}
-#endif //QT_NO_CURSOR
-
-QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index 473e9deef4..88404ce205 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -294,7 +294,6 @@ private:
friend QRegion qt_dirtyRegion(QWidget *);
friend class QWidgetPrivate;
friend class QWidget;
- friend class QETWidget;
friend class QBackingStore;
};
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index fc328e7af0..9a7017503f 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "private/qwindow_p.h"
-#include "qwidgetwindow_qpa_p.h"
+#include "qwidgetwindow_p.h"
#include "private/qwidget_p.h"
#include "private/qapplication_p.h"
@@ -443,7 +443,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
// Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
const QPoint localPos = win->mapFromGlobal(event->globalPos());
QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
- e->spont = 1;
+ QCoreApplicationPrivate::setEventSpontaneous(e, true);
QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
e->setTimestamp(event->timestamp());
QCoreApplication::postEvent(win, e);
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index 06ba8ea646..be2adddff5 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QWIDGETWINDOW_QPA_P_H
-#define QWIDGETWINDOW_QPA_P_H
+#ifndef QWIDGETWINDOW_P_H
+#define QWIDGETWINDOW_P_H
#include <QtGui/qwindow.h>
@@ -122,4 +122,4 @@ private:
QT_END_NAMESPACE
-#endif // QWIDGETWINDOW_QPA_P_H
+#endif // QWIDGETWINDOW_P_H
diff --git a/src/widgets/statemachine/qguistatemachine.cpp b/src/widgets/statemachine/qguistatemachine.cpp
index d737a1e323..9824b96334 100644
--- a/src/widgets/statemachine/qguistatemachine.cpp
+++ b/src/widgets/statemachine/qguistatemachine.cpp
@@ -312,6 +312,8 @@ static QEvent *cloneEvent(QEvent *e)
me2->setButtons(me->buttons());
me2->setButton(me->button());
me2->setModifiers(me->modifiers());
+ me2->setSource(me->source());
+ me2->setFlags(me->flags());
return me2;
}
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index d7030c5d72..94498f48c9 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -4930,6 +4930,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = hint.toChar().unicode();
break;
}
+ case SH_LineEdit_PasswordMaskDelay:
+ ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::PasswordMaskDelay).toInt();
+ break;
case SH_ToolBox_SelectedPageTitleBold:
ret = 1;
break;
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index b3c0463bca..531f538820 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -152,13 +152,32 @@ static uint qHash(const QPointer<QObject> &ptr)
return qHash(ptr.data());
}
-// These colors specify the titlebar gradient colors on
-// Leopard. Ideally we should get them from the system.
-static const QColor titlebarGradientActiveBegin(220, 220, 220);
-static const QColor titlebarGradientActiveEnd(151, 151, 151);
+// Title bar gradient colors for Lion were determined by inspecting PSDs exported
+// using CoreUI's CoreThemeDocument; there is no public API to retrieve them
+
+static QLinearGradient titlebarGradientActive()
+{
+ static QLinearGradient gradient;
+ if (gradient == QLinearGradient()) {
+ gradient.setColorAt(0, QColor(235, 235, 235));
+ gradient.setColorAt(0.5, QColor(210, 210, 210));
+ gradient.setColorAt(0.75, QColor(195, 195, 195));
+ gradient.setColorAt(1, QColor(180, 180, 180));
+ }
+ return gradient;
+}
+
+static QLinearGradient titlebarGradientInactive()
+{
+ static QLinearGradient gradient;
+ if (gradient == QLinearGradient()) {
+ gradient.setColorAt(0, QColor(250, 250, 250));
+ gradient.setColorAt(1, QColor(225, 225, 225));
+ }
+ return gradient;
+}
+
static const QColor titlebarSeparatorLineActive(111, 111, 111);
-static const QColor titlebarGradientInactiveBegin(241, 241, 241);
-static const QColor titlebarGradientInactiveEnd(207, 207, 207);
static const QColor titlebarSeparatorLineInactive(131, 131, 131);
// Gradient colors used for the dock widget title bar and
@@ -526,25 +545,6 @@ public:
};
} // anonymous namespace
-static QColor qcolorFromCGColor(CGColorRef cgcolor)
-{
- QColor pc;
- CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(cgcolor));
- const CGFloat *components = CGColorGetComponents(cgcolor);
- if (model == kCGColorSpaceModelRGB) {
- pc.setRgbF(components[0], components[1], components[2], components[3]);
- } else if (model == kCGColorSpaceModelCMYK) {
- pc.setCmykF(components[0], components[1], components[2], components[3]);
- } else if (model == kCGColorSpaceModelMonochrome) {
- pc.setRgbF(components[0], components[0], components[0], components[1]);
- } else {
- // Colorspace we can't deal with.
- qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model);
- Q_ASSERT(false);
- }
- return pc;
-}
-
OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon)
{
QRegion *region = static_cast<QRegion *>(inRefcon);
@@ -702,7 +702,6 @@ static bool qt_macWindowMainWindow(const QWidget *window)
const int qt_mac_hitheme_version = 0; //the HITheme version we speak
const int macItemFrame = 2; // menu item frame width
const int macItemHMargin = 3; // menu item hor text margin
-const int macItemVMargin = 2; // menu item ver text margin
const int macRightBorder = 12; // right border on mac
const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
QPixmap *qt_mac_backgroundPattern = 0; // stores the standard widget background.
@@ -3150,7 +3149,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
[triangleCell setButtonType:NSOnOffButton];
[triangleCell setState:(opt->state & State_Open) ? NSOnState : NSOffState];
[triangleCell setBezelStyle:NSDisclosureBezelStyle];
- [triangleCell setBackgroundStyle:((opt->state & State_Selected) && w->hasFocus()) ? NSBackgroundStyleDark : NSBackgroundStyleLight];
+ bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus);
+ [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleDark : NSBackgroundStyleLight];
CGContextSaveGState(cg);
[NSGraphicsContext saveGraphicsState];
@@ -3263,14 +3263,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
} break;
case PE_PanelStatusBar: {
// Fill the status bar with the titlebar gradient.
- QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
+ QLinearGradient linearGrad;
if (w ? qt_macWindowMainWindow(w->window()) : (opt->state & QStyle::State_Active)) {
- linearGrad.setColorAt(0, titlebarGradientActiveBegin);
- linearGrad.setColorAt(1, titlebarGradientActiveEnd);
+ linearGrad = titlebarGradientActive();
} else {
- linearGrad.setColorAt(0, titlebarGradientInactiveBegin);
- linearGrad.setColorAt(1, titlebarGradientInactiveEnd);
+ linearGrad = titlebarGradientInactive();
}
+
+ linearGrad.setStart(0, opt->rect.top());
+ linearGrad.setFinalStop(0, opt->rect.bottom());
p->fillRect(opt->rect, linearGrad);
// Draw the black separator line at the top of the status bar.
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 4c5c7cd17e..8774d71c0c 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1784,6 +1784,9 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_LineEdit_PasswordCharacter The Unicode character to be
used for passwords.
+ \value SH_LineEdit_PasswordMaskDelay Determines the delay before visible character is masked
+ with password character, in milliseconds. This enum value was added in Qt 5.4.
+
\value SH_Table_GridLineColor The RGB value of the grid for a table.
\value SH_UnderlineShortcut Whether shortcuts are underlined.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 136daa9abd..ea012faf46 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -703,6 +703,7 @@ public:
SH_Widget_Animate,
SH_Splitter_OpaqueResize,
SH_ComboBox_UseNativePopup,
+ SH_LineEdit_PasswordMaskDelay,
// Add new style hint values here
SH_CustomBase = 0xf0000000
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 5913b2f261..f642a05d13 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -3702,6 +3702,8 @@ QStyleOptionGraphicsItem::QStyleOptionGraphicsItem(int version)
of the painter used to draw the item. By default, if no
transformations are applied, its value is 1. If zoomed out 1:2, the level
of detail will be 0.5, and if zoomed in 2:1, its value is 2.
+
+ \sa QGraphicsScene::minimumRenderSize()
*/
qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &worldTransform)
{
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 60bfc8e075..b82aa1b5a0 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -645,6 +645,7 @@ static const char *knownStyleHints[] = {
"icon-size",
"leftarrow-icon",
"lineedit-password-character",
+ "lineedit-password-mask-delay",
"mdi-fill-space-on-maximize",
"menu-scrollable",
"menubar-altkey-navigation",
@@ -5143,6 +5144,7 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi
QString s;
switch (sh) {
case SH_LineEdit_PasswordCharacter: s = QLatin1String("lineedit-password-character"); break;
+ case SH_LineEdit_PasswordMaskDelay: s = QLatin1String("lineedit-password-mask-delay"); break;
case SH_DitherDisabledText: s = QLatin1String("dither-disabled-text"); break;
case SH_EtchDisabledText: s = QLatin1String("etch-disabled-text"); break;
case SH_ItemView_ActivateItemOnSingleClick: s = QLatin1String("activate-on-singleclick"); break;
@@ -5804,6 +5806,25 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c
break;
#endif //QT_NO_TOOLBAR
+ // On mac we make pixel adjustments to layouts which are not
+ // desireable when you have custom style sheets on them
+ case SE_CheckBoxLayoutItem:
+ case SE_ComboBoxLayoutItem:
+ case SE_DateTimeEditLayoutItem:
+ case SE_LabelLayoutItem:
+ case SE_ProgressBarLayoutItem:
+ case SE_PushButtonLayoutItem:
+ case SE_RadioButtonLayoutItem:
+ case SE_SliderLayoutItem:
+ case SE_SpinBoxLayoutItem:
+ case SE_ToolButtonLayoutItem:
+ case SE_FrameLayoutItem:
+ case SE_GroupBoxLayoutItem:
+ case SE_TabWidgetLayoutItem:
+ if (!rule.hasNativeBorder())
+ return opt->rect;
+ break;
+
default:
break;
}
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index bc78ea3296..e3699da7ef 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -1421,15 +1421,14 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
break;
case CE_DockWidgetTitle:
- if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget);
QRect rect = option->rect;
- if (dockWidget->isFloating()) {
+ if (dockWidget && dockWidget->isFloating()) {
QWindowsXPStyle::drawControl(element, option, painter, widget);
break; //otherwise fall through
}
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
-
const QStyleOptionDockWidgetV2 *v2
= qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
@@ -1490,7 +1489,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
}
break;
- }
#ifndef QT_NO_ITEMVIEWS
case CE_ItemViewItem:
{
diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp
index b0cd4a9540..a372a7fe0d 100644
--- a/src/widgets/util/qflickgesture.cpp
+++ b/src/widgets/util/qflickgesture.cpp
@@ -101,6 +101,8 @@ static QMouseEvent *copyMouseEvent(QEvent *e)
copy->setButtons(me->buttons());
copy->setButton(me->button());
copy->setModifiers(me->modifiers());
+ copy->setSource(me->source());
+ copy->setFlags(me->flags());
return copy;
#endif
}
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index f1a69e6b36..fa318f3233 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -672,6 +672,74 @@ void QBalloonTip::timerEvent(QTimerEvent *e)
QWidget::timerEvent(e);
}
+//////////////////////////////////////////////////////////////////////
+void QSystemTrayIconPrivate::install_sys_qpa()
+{
+ qpa_sys->init();
+ QObject::connect(qpa_sys, SIGNAL(activated(QPlatformSystemTrayIcon::ActivationReason)),
+ q_func(), SLOT(_q_emitActivated(QPlatformSystemTrayIcon::ActivationReason)));
+ QObject::connect(qpa_sys, &QPlatformSystemTrayIcon::messageClicked,
+ q_func(), &QSystemTrayIcon::messageClicked);
+ updateMenu_sys();
+ updateIcon_sys();
+ updateToolTip_sys();
+}
+
+void QSystemTrayIconPrivate::remove_sys_qpa()
+{
+ qpa_sys->cleanup();
+}
+
+QRect QSystemTrayIconPrivate::geometry_sys_qpa() const
+{
+ return qpa_sys->geometry();
+}
+
+void QSystemTrayIconPrivate::updateIcon_sys_qpa()
+{
+ qpa_sys->updateIcon(icon);
+}
+
+void QSystemTrayIconPrivate::updateMenu_sys_qpa()
+{
+ if (menu) {
+ if (!menu->platformMenu()) {
+ QPlatformMenu *platformMenu = qpa_sys->createMenu();
+ if (platformMenu)
+ menu->setPlatformMenu(platformMenu);
+ }
+ qpa_sys->updateMenu(menu->platformMenu());
+ }
+}
+
+void QSystemTrayIconPrivate::updateToolTip_sys_qpa()
+{
+ qpa_sys->updateToolTip(toolTip);
+}
+
+void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &message,
+ const QString &title,
+ QSystemTrayIcon::MessageIcon icon,
+ int msecs)
+{
+ QIcon notificationIcon;
+ switch (icon) {
+ case QSystemTrayIcon::Information:
+ notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
+ break;
+ case QSystemTrayIcon::Warning:
+ notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
+ break;
+ case QSystemTrayIcon::Critical:
+ notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
+ break;
+ default:
+ break;
+ }
+ qpa_sys->showMessage(message, title, notificationIcon,
+ static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs);
+}
+
QT_END_NAMESPACE
#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h
index 211ef308f1..317664a365 100644
--- a/src/widgets/util/qsystemtrayicon_p.h
+++ b/src/widgets/util/qsystemtrayicon_p.h
@@ -98,6 +98,15 @@ public:
QSystemTrayIconSys *sys;
QPlatformSystemTrayIcon *qpa_sys;
bool visible;
+
+private:
+ void install_sys_qpa();
+ void remove_sys_qpa();
+ void updateIcon_sys_qpa();
+ void updateToolTip_sys_qpa();
+ void updateMenu_sys_qpa();
+ QRect geometry_sys_qpa() const;
+ void showMessage_sys_qpa(const QString &msg, const QString &title, QSystemTrayIcon::MessageIcon icon, int secs);
};
class QBalloonTip : public QWidget
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
index f98aeaf678..045641c509 100644
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
@@ -65,28 +65,20 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
void QSystemTrayIconPrivate::install_sys()
{
- if (qpa_sys) {
- qpa_sys->init();
- QObject::connect(qpa_sys, SIGNAL(activated(QPlatformSystemTrayIcon::ActivationReason)),
- q_func(), SLOT(_q_emitActivated(QPlatformSystemTrayIcon::ActivationReason)));
- QObject::connect(qpa_sys, SIGNAL(messageClicked()),
- q_func(), SIGNAL(messageClicked()));
- updateMenu_sys();
- updateIcon_sys();
- updateToolTip_sys();
- }
+ if (qpa_sys)
+ install_sys_qpa();
}
void QSystemTrayIconPrivate::remove_sys()
{
if (qpa_sys)
- qpa_sys->cleanup();
+ remove_sys_qpa();
}
QRect QSystemTrayIconPrivate::geometry_sys() const
{
if (qpa_sys)
- return qpa_sys->geometry();
+ return geometry_sys_qpa();
else
return QRect();
}
@@ -94,25 +86,19 @@ QRect QSystemTrayIconPrivate::geometry_sys() const
void QSystemTrayIconPrivate::updateIcon_sys()
{
if (qpa_sys)
- qpa_sys->updateIcon(icon);
+ updateIcon_sys_qpa();
}
void QSystemTrayIconPrivate::updateMenu_sys()
{
- if (qpa_sys && menu) {
- if (!menu->platformMenu()) {
- QPlatformMenu *platformMenu = qpa_sys->createMenu();
- if (platformMenu)
- menu->setPlatformMenu(platformMenu);
- }
- qpa_sys->updateMenu(menu->platformMenu());
- }
+ if (qpa_sys)
+ updateMenu_sys_qpa();
}
void QSystemTrayIconPrivate::updateToolTip_sys()
{
if (qpa_sys)
- qpa_sys->updateToolTip(toolTip);
+ updateToolTip_sys_qpa();
}
bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
@@ -138,25 +124,8 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &message,
QSystemTrayIcon::MessageIcon icon,
int msecs)
{
- if (!qpa_sys)
- return;
-
- QIcon notificationIcon;
- switch (icon) {
- case QSystemTrayIcon::Information:
- notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
- break;
- case QSystemTrayIcon::Warning:
- notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
- break;
- case QSystemTrayIcon::Critical:
- notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
- break;
- default:
- break;
- }
- qpa_sys->showMessage(message, title, notificationIcon,
- static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs);
+ if (qpa_sys)
+ showMessage_sys_qpa(message, title, icon, msecs);
}
QT_END_NAMESPACE
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 21ce23437f..06eaf86004 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -55,6 +55,9 @@
#include <qscreen.h>
#include <qbackingstore.h>
#include <qpa/qplatformnativeinterface.h>
+#include <qpa/qplatformsystemtrayicon.h>
+#include <qpa/qplatformtheme.h>
+#include <private/qguiapplication_p.h>
#include <qdebug.h>
#ifndef QT_NO_SYSTEMTRAYICON
@@ -215,16 +218,22 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *)
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
: sys(0),
+ qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
visible(false)
{
}
QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
{
+ delete qpa_sys;
}
void QSystemTrayIconPrivate::install_sys()
{
+ if (qpa_sys) {
+ install_sys_qpa();
+ return;
+ }
Q_Q(QSystemTrayIcon);
if (!sys && locateSystemTray()) {
sys = new QSystemTrayIconSys(q);
@@ -235,6 +244,8 @@ void QSystemTrayIconPrivate::install_sys()
QRect QSystemTrayIconPrivate::geometry_sys() const
{
+ if (qpa_sys)
+ return geometry_sys_qpa();
if (!sys)
return QRect();
return sys->globalGeometry();
@@ -242,6 +253,10 @@ QRect QSystemTrayIconPrivate::geometry_sys() const
void QSystemTrayIconPrivate::remove_sys()
{
+ if (qpa_sys) {
+ remove_sys_qpa();
+ return;
+ }
if (!sys)
return;
QBalloonTip::hideBalloon();
@@ -252,17 +267,26 @@ void QSystemTrayIconPrivate::remove_sys()
void QSystemTrayIconPrivate::updateIcon_sys()
{
+ if (qpa_sys) {
+ updateIcon_sys_qpa();
+ return;
+ }
if (sys)
sys->updateIcon();
}
void QSystemTrayIconPrivate::updateMenu_sys()
{
-
+ if (qpa_sys)
+ updateMenu_sys_qpa();
}
void QSystemTrayIconPrivate::updateToolTip_sys()
{
+ if (qpa_sys) {
+ updateToolTip_sys_qpa();
+ return;
+ }
if (!sys)
return;
#ifndef QT_NO_TOOLTIP
@@ -272,6 +296,11 @@ void QSystemTrayIconPrivate::updateToolTip_sys()
bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
{
+ QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon());
+ if (sys)
+ return sys->isSystemTrayAvailable();
+
+ // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior
const QString platform = QGuiApplication::platformName();
if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0)
return locateSystemTray();
@@ -280,12 +309,21 @@ bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
bool QSystemTrayIconPrivate::supportsMessages_sys()
{
+ QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon());
+ if (sys)
+ return sys->supportsMessages();
+
+ // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior
return true;
}
void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QString &title,
QSystemTrayIcon::MessageIcon icon, int msecs)
{
+ if (qpa_sys) {
+ showMessage_sys_qpa(message, title, icon, msecs);
+ return;
+ }
if (!sys)
return;
const QPoint g = sys->globalGeometry().topLeft();
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 0b289c75ae..c2cf4b7dfe 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -8,9 +8,6 @@ DEFINES += QT_NO_USING_NAMESPACE
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
-MODULE_PLUGIN_TYPES += \
- accessible/libqtaccessiblewidgets.so
-
QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf
load(qt_module)
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 92af91b66e..43f5d6fd31 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -315,6 +315,8 @@ void QAbstractSpinBox::setReadOnly(bool enable)
Q_D(QAbstractSpinBox);
d->readOnly = enable;
d->edit->setReadOnly(enable);
+ QEvent event(QEvent::ReadOnlyChange);
+ QApplication::sendEvent(this, &event);
update();
}
diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h
index 9adf5f6567..db6be7d1c0 100644
--- a/src/widgets/widgets/qcheckbox.h
+++ b/src/widgets/widgets/qcheckbox.h
@@ -86,6 +86,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QCheckBox)
Q_DISABLE_COPY(QCheckBox)
+ friend class QAccessibleButton;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ba4dbcc878..b6b7ffb1a2 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1348,6 +1348,8 @@ void QLineEdit::setReadOnly(bool enable)
#ifndef QT_NO_CURSOR
setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
#endif
+ QEvent event(QEvent::ReadOnlyChange);
+ QCoreApplication::sendEvent(this, &event);
update();
}
}
@@ -2188,6 +2190,7 @@ void QLineEdit::changeEvent(QEvent *ev)
QStyleOptionFrameV2 opt;
initStyleOption(&opt);
d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
+ d->control->setPasswordMaskDelay(style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, this));
}
d->m_iconSize = QSize();
update();
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 10689b2fc3..adec9cae18 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -205,6 +205,7 @@ void QLineEditPrivate::init(const QString& txt)
QStyleOptionFrameV2 opt;
q->initStyleOption(&opt);
control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, q));
+ control->setPasswordMaskDelay(q->style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, q));
#ifndef QT_NO_CURSOR
q->setCursor(Qt::IBeamCursor);
#endif
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
index 8411bf9f6b..6c392ca4cc 100644
--- a/src/widgets/widgets/qmainwindow.h
+++ b/src/widgets/widgets/qmainwindow.h
@@ -155,7 +155,6 @@ public:
void removeToolBar(QToolBar *toolbar);
void removeToolBarBreak(QToolBar *before);
- void setUnifiedTitleAndToolBarOnMac(bool set);
bool unifiedTitleAndToolBarOnMac() const;
Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
@@ -182,12 +181,14 @@ public:
virtual QMenu *createPopupMenu();
#endif
-
-#ifndef QT_NO_DOCKWIDGET
public Q_SLOTS:
+#ifndef QT_NO_DOCKWIDGET
void setAnimated(bool enabled);
void setDockNestingEnabled(bool enabled);
#endif
+#ifndef QT_NO_TOOLBAR
+ void setUnifiedTitleAndToolBarOnMac(bool set);
+#endif
Q_SIGNALS:
void iconSizeChanged(const QSize &iconSize);
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 17f73b2809..beabaa87da 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -169,7 +169,7 @@
#include <QResizeEvent>
#include <QScrollBar>
#include <QtAlgorithms>
-#include <QMutableListIterator>
+#include <QMutableVectorIterator>
#include <QPainter>
#include <QFontMetrics>
#include <QStyleOption>
@@ -413,7 +413,7 @@ void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const
\internal
Calculates the accumulated overlap (intersection area) between 'source' and 'rects'.
*/
-int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QList<QRect> &rects)
+int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QVector<QRect> &rects)
{
int accOverlap = 0;
foreach (const QRect &rect, rects) {
@@ -429,7 +429,7 @@ int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QList<QRect>
Finds among 'source' the rectangle with the minimum accumulated overlap with the
rectangles in 'rects'.
*/
-QRect MinOverlapPlacer::findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects)
+QRect MinOverlapPlacer::findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects)
{
int minAccOverlap = -1;
QRect minAccOverlapRect;
@@ -447,28 +447,37 @@ QRect MinOverlapPlacer::findMinOverlapRect(const QList<QRect> &source, const QLi
\internal
Gets candidates for the final placement.
*/
-void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRect> &rects,
- const QRect &domain,QList<QRect> &candidates)
+QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QVector<QRect> &rects,
+ const QRect &domain)
{
- QSet<int> xset;
- QSet<int> yset;
- xset << domain.left() << domain.right() - size.width() + 1;
- yset << domain.top();
+ QVector<QRect> result;
+
+ QVector<int> xlist;
+ xlist.reserve(2 + rects.size());
+ xlist << domain.left() << domain.right() - size.width() + 1;
+
+ QVector<int> ylist;
+ ylist.reserve(2 + rects.size());
+ ylist << domain.top();
if (domain.bottom() - size.height() + 1 >= 0)
- yset << domain.bottom() - size.height() + 1;
+ ylist << domain.bottom() - size.height() + 1;
+
foreach (const QRect &rect, rects) {
- xset << rect.right() + 1;
- yset << rect.bottom() + 1;
+ xlist << rect.right() + 1;
+ ylist << rect.bottom() + 1;
}
- QList<int> xlist = xset.values();
std::sort(xlist.begin(), xlist.end());
- QList<int> ylist = yset.values();
+ xlist.erase(std::unique(xlist.begin(), xlist.end()), xlist.end());
+
std::sort(ylist.begin(), ylist.end());
+ ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end());
+ result.reserve(ylist.size() * xlist.size());
foreach (int y, ylist)
foreach (int x, xlist)
- candidates << QRect(QPoint(x, y), size);
+ result << QRect(QPoint(x, y), size);
+ return result;
}
/*!
@@ -476,10 +485,12 @@ void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRe
Finds all rectangles in 'source' not completely inside 'domain'. The result is stored
in 'result' and also removed from 'source'.
*/
-void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source,
- QList<QRect> &result)
+QVector<QRect> MinOverlapPlacer::findNonInsiders(const QRect &domain, QVector<QRect> &source)
{
- QMutableListIterator<QRect> it(source);
+ QVector<QRect> result;
+ result.reserve(source.size());
+
+ QMutableVectorIterator<QRect> it(source);
while (it.hasNext()) {
const QRect srcRect = it.next();
if (!domain.contains(srcRect)) {
@@ -487,6 +498,8 @@ void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source
it.remove();
}
}
+
+ return result;
}
/*!
@@ -494,9 +507,11 @@ void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source
Finds all rectangles in 'source' that overlaps 'domain' by the maximum overlap area
between 'domain' and any rectangle in 'source'. The result is stored in 'result'.
*/
-void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect> &source,
- QList<QRect> &result)
+QVector<QRect> MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QVector<QRect> &source)
{
+ QVector<QRect> result;
+ result.reserve(source.size());
+
int maxOverlap = -1;
foreach (const QRect &srcRect, source) {
QRect intersection = domain.intersected(srcRect);
@@ -509,6 +524,8 @@ void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect
result << srcRect;
}
}
+
+ return result;
}
/*!
@@ -517,17 +534,15 @@ void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect
placement that overlaps the rectangles in 'rects' as little as possible while at the
same time being as much as possible inside 'domain'.
*/
-QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QList<QRect> &rects,
- QList<QRect> &source)
+QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QVector<QRect> &rects,
+ QVector<QRect> &source)
{
- QList<QRect> nonInsiders;
- findNonInsiders(domain, source, nonInsiders);
+ const QVector<QRect> nonInsiders = findNonInsiders(domain, source);
if (!source.empty())
return findMinOverlapRect(source, rects).topLeft();
- QList<QRect> maxOverlappers;
- findMaxOverlappers(domain, nonInsiders, maxOverlappers);
+ QVector<QRect> maxOverlappers = findMaxOverlappers(domain, nonInsiders);
return findMinOverlapRect(maxOverlappers, rects).topLeft();
}
@@ -538,7 +553,7 @@ QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QList<QRec
overlaps 'rects' as little as possible and 'domain' as much as possible.
Returns the position of the resulting rectangle.
*/
-QPoint MinOverlapPlacer::place(const QSize &size, const QList<QRect> &rects,
+QPoint MinOverlapPlacer::place(const QSize &size, const QVector<QRect> &rects,
const QRect &domain) const
{
if (size.isEmpty() || !domain.isValid())
@@ -548,8 +563,7 @@ QPoint MinOverlapPlacer::place(const QSize &size, const QList<QRect> &rects,
return QPoint();
}
- QList<QRect> candidates;
- getCandidatePlacements(size, rects, domain, candidates);
+ QVector<QRect> candidates = getCandidatePlacements(size, rects, domain);
return findBestPlacement(domain, rects, candidates);
}
@@ -882,7 +896,8 @@ void QMdiAreaPrivate::place(Placer *placer, QMdiSubWindow *child)
return;
}
- QList<QRect> rects;
+ QVector<QRect> rects;
+ rects.reserve(childWindows.size());
QRect parentRect = q->rect();
foreach (QMdiSubWindow *window, childWindows) {
if (!sanityCheck(window, "QMdiArea::place") || window == child || !window->isVisibleTo(q)
diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h
index 90db55438a..360ed2508c 100644
--- a/src/widgets/widgets/qmdiarea_p.h
+++ b/src/widgets/widgets/qmdiarea_p.h
@@ -59,6 +59,7 @@
#ifndef QT_NO_MDIAREA
#include <QList>
+#include <QVector>
#include <QRect>
#include <QPoint>
#include <QtWidgets/qapplication.h>
@@ -116,24 +117,19 @@ public:
// Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
// Returns the position of the resulting rectangle.
virtual QPoint place(
- const QSize &size, const QList<QRect> &rects, const QRect &domain) const = 0;
+ const QSize &size, const QVector<QRect> &rects, const QRect &domain) const = 0;
virtual ~Placer() {}
};
class MinOverlapPlacer : public Placer
{
- QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const;
- static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects);
- static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects);
- static void getCandidatePlacements(
- const QSize &size, const QList<QRect> &rects, const QRect &domain,
- QList<QRect> &candidates);
- static QPoint findBestPlacement(
- const QRect &domain, const QList<QRect> &rects, QList<QRect> &source);
- static void findNonInsiders(
- const QRect &domain, QList<QRect> &source, QList<QRect> &result);
- static void findMaxOverlappers(
- const QRect &domain, const QList<QRect> &source, QList<QRect> &result);
+ QPoint place(const QSize &size, const QVector<QRect> &rects, const QRect &domain) const;
+ static int accumulatedOverlap(const QRect &source, const QVector<QRect> &rects);
+ static QRect findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects);
+ static QVector<QRect> getCandidatePlacements(const QSize &size, const QVector<QRect> &rects, const QRect &domain);
+ static QPoint findBestPlacement(const QRect &domain, const QVector<QRect> &rects, QVector<QRect> &source);
+ static QVector<QRect> findNonInsiders(const QRect &domain, QVector<QRect> &source);
+ static QVector<QRect> findMaxOverlappers(const QRect &domain, const QVector<QRect> &source);
};
} // namespace QMdi
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 7e48badea5..846199ebe2 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -187,8 +187,8 @@ void QMenuPrivate::syncPlatformMenu()
QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
QAction *action = it.previous();
menuItem->setTag(reinterpret_cast<quintptr>(action));
- QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()));
- QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()));
+ QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection);
+ QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection);
copyActionToPlatformItem(action, menuItem);
platformMenu->insertMenuItem(menuItem, beforeItem);
beforeItem = menuItem;
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 23c1e99231..df13085dee 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -2537,6 +2537,8 @@ void QPlainTextEdit::setReadOnly(bool ro)
}
setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
d->control->setTextInteractionFlags(flags);
+ QEvent event(QEvent::ReadOnlyChange);
+ QApplication::sendEvent(this, &event);
}
/*!
diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h
index 104d4a12e0..8888ccf86d 100644
--- a/src/widgets/widgets/qradiobutton.h
+++ b/src/widgets/widgets/qradiobutton.h
@@ -73,6 +73,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QRadioButton)
Q_DISABLE_COPY(QRadioButton)
+ friend class QAccessibleButton;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index a33ac0817f..f106b70c12 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -2122,6 +2122,8 @@ void QTextEdit::setReadOnly(bool ro)
}
d->control->setTextInteractionFlags(flags);
setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
+ QEvent event(QEvent::ReadOnlyChange);
+ QApplication::sendEvent(this, &event);
}
/*!
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index b16477246f..1f70dd719b 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -355,8 +355,10 @@ void QWidgetLineControl::init(const QString &txt)
m_text = txt;
updateDisplayText();
m_cursor = m_text.length();
- if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
+ if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
m_keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
+ m_passwordMaskDelay = theme->themeHint(QPlatformTheme::PasswordMaskDelay).toInt();
+ }
// Generalize for X11
if (m_keyboardScheme == QPlatformTheme::KdeKeyboardScheme
|| m_keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
@@ -787,7 +789,7 @@ void QWidgetLineControl::internalInsert(const QString &s)
if (m_echoMode == QLineEdit::Password) {
if (m_passwordEchoTimer != 0)
killTimer(m_passwordEchoTimer);
- int delay = qGuiApp->styleHints()->passwordMaskDelay();
+ int delay = m_passwordMaskDelay;
#ifdef QT_BUILD_INTERNAL
if (m_passwordMaskDelayOverride >= 0)
delay = m_passwordMaskDelayOverride;
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 1cee67bfd2..ba73e9e25e 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -90,6 +90,7 @@ public:
m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
, m_passwordEchoTimer(0)
+ , m_passwordMaskDelay(-1)
#if defined(Q_WS_MAC)
, m_threadChecks(false)
, m_textLayoutThread(0)
@@ -313,6 +314,9 @@ public:
QChar passwordCharacter() const { return m_passwordCharacter; }
void setPasswordCharacter(QChar character) { m_passwordCharacter = character; updateDisplayText(); }
+ int passwordMaskDelay() const { return m_passwordMaskDelay; }
+ void setPasswordMaskDelay(int delay) { m_passwordMaskDelay = delay; }
+
Qt::LayoutDirection layoutDirection() const {
if (m_layoutDirection == Qt::LayoutDirectionAuto) {
if (m_text.isEmpty())
@@ -481,6 +485,7 @@ private:
bool m_passwordEchoEditing;
QChar m_passwordCharacter;
int m_passwordEchoTimer;
+ int m_passwordMaskDelay;
void cancelPasswordEchoTimer()
{
if (m_passwordEchoTimer != 0) {
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 96438a0bdf..a6b1aceb66 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -651,7 +651,9 @@ void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, i
if (QAccessible::isActive() && q->parent() && q->parent()->isWidgetType()) {
QTextCursor tmp(doc);
tmp.setPosition(from);
- tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
+ // when setting a new text document the length is off
+ // QTBUG-32583 - characterCount is off by 1 requires the -1
+ tmp.setPosition(qMin(doc->characterCount() - 1, from + charsAdded), QTextCursor::KeepAnchor);
QString newText = tmp.selectedText();
// always report the right number of removed chars, but in lack of the real string use spaces