summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 10:11:49 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 12:48:52 +0200
commit04d0a9626ce61b2e05a40f9562c2bcf12e234639 (patch)
treef1643f829aedc9ac51fcc260f7df2639dfe08360 /src/widgets
parent17f3451daa286b88a52f18c802d7b158dfb653b2 (diff)
parentbdc417b3828737334723eae23097c85f70c23a33 (diff)
Merge branch 'master' into refactor
Conflicts: src/gui/kernel/qapplication_qpa.cpp src/gui/kernel/qcursor_qpa.cpp src/gui/kernel/qwindowsysteminterface_qpa.cpp src/gui/kernel/qwindowsysteminterface_qpa.h src/gui/kernel/qwindowsysteminterface_qpa_p.h src/gui/text/qtextcontrol.cpp src/plugins/platforms/wayland/wayland.pro src/widgets/accessible/qaccessible2.h src/widgets/widgets/qwidgetlinecontrol_p.h Change-Id: I5e6f4eb184159dccc67e8f13673edb884d179c74
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/accessible/qaccessible.cpp5
-rw-r--r--src/widgets/accessible/qaccessible.h10
-rw-r--r--src/widgets/accessible/qaccessible2.cpp112
-rw-r--r--src/widgets/accessible/qaccessible2.h112
-rw-r--r--src/widgets/accessible/qaccessible_mac.mm2
-rw-r--r--src/widgets/accessible/qaccessible_unix.cpp11
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp11
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp32
-rw-r--r--src/widgets/graphicsview/qgraphicslayout_p.h4
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp95
-rw-r--r--src/widgets/itemviews/qabstractitemview.h1
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h1
-rw-r--r--src/widgets/itemviews/qlistview.cpp12
-rw-r--r--src/widgets/itemviews/qtableview.cpp17
-rw-r--r--src/widgets/itemviews/qtableview_p.h5
-rw-r--r--src/widgets/itemviews/qtreeview.cpp52
-rw-r--r--src/widgets/itemviews/qtreeview.h3
-rw-r--r--src/widgets/itemviews/qtreeview_p.h6
-rw-r--r--src/widgets/itemviews/qwidgetitemdata_p.h2
-rw-r--r--src/widgets/kernel/qwidget.cpp4
-rw-r--r--src/widgets/platforms/mac/qeventdispatcher_mac_p.h2
-rw-r--r--src/widgets/widgets/qcombobox.cpp18
-rw-r--r--src/widgets/widgets/qlabel.cpp7
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp47
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h39
25 files changed, 550 insertions, 60 deletions
diff --git a/src/widgets/accessible/qaccessible.cpp b/src/widgets/accessible/qaccessible.cpp
index 337bb9992d..10e5785cd5 100644
--- a/src/widgets/accessible/qaccessible.cpp
+++ b/src/widgets/accessible/qaccessible.cpp
@@ -1048,6 +1048,11 @@ const QAccessibleInterface *other, int otherChild) const
*/
/*!
+ \fn QAccessibleTable2Interface *QAccessibleInterface::table2Interface()
+ \internal
+*/
+
+/*!
\fn QAccessibleActionInterface *QAccessibleInterface::actionInterface()
\internal
*/
diff --git a/src/widgets/accessible/qaccessible.h b/src/widgets/accessible/qaccessible.h
index 517dac492b..312e2a3088 100644
--- a/src/widgets/accessible/qaccessible.h
+++ b/src/widgets/accessible/qaccessible.h
@@ -151,6 +151,7 @@ public:
ReadOnly = 0x00000040,
HotTracked = 0x00000080,
DefaultButton = 0x00000100,
+ // #### Qt5 Expandable
Expanded = 0x00000200,
Collapsed = 0x00000400,
Busy = 0x00000800,
@@ -175,6 +176,8 @@ public:
HasPopup = 0x40000000,
Modal = 0x80000000,
+ // #### Qt5 ManagesDescendants
+ // #### Qt5 remove HasInvokeExtension
HasInvokeExtension = 0x10000000 // internal
};
Q_DECLARE_FLAGS(State, StateFlag)
@@ -345,7 +348,8 @@ namespace QAccessible2
ValueInterface,
TableInterface,
ActionInterface,
- ImageInterface
+ ImageInterface,
+ Table2Interface
};
}
@@ -356,6 +360,7 @@ class QAccessibleValueInterface;
class QAccessibleTableInterface;
class QAccessibleActionInterface;
class QAccessibleImageInterface;
+class QAccessibleTable2Interface;
class Q_WIDGETS_EXPORT QAccessibleInterface : public QAccessible
{
@@ -419,6 +424,9 @@ public:
inline QAccessibleImageInterface *imageInterface()
{ return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); }
+ inline QAccessibleTable2Interface *table2Interface()
+ { return reinterpret_cast<QAccessibleTable2Interface *>(cast_helper(QAccessible2::Table2Interface)); }
+
private:
QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
};
diff --git a/src/widgets/accessible/qaccessible2.cpp b/src/widgets/accessible/qaccessible2.cpp
index 35b24f6e24..078ff13e2c 100644
--- a/src/widgets/accessible/qaccessible2.cpp
+++ b/src/widgets/accessible/qaccessible2.cpp
@@ -42,6 +42,7 @@
#include "qaccessible2.h"
#include "qapplication.h"
#include "qclipboard.h"
+#include "qtextboundaryfinder.h"
#ifndef QT_NO_ACCESSIBILITY
@@ -132,6 +133,117 @@ QT_BEGIN_NAMESPACE
\link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
*/
+
+/*!
+ \internal
+*/
+QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ if (!boundary.isAtBoundary()) {
+ boundary.toPreviousBoundary();
+ }
+ boundary.toPreviousBoundary();
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
+/*!
+ \internal
+*/
+QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ boundary.toNextBoundary();
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
+/*!
+ \internal
+*/
+QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ if (!boundary.isAtBoundary()) {
+ boundary.toPreviousBoundary();
+ }
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
QAccessibleInterface *accessibleInterface)
: iface(accessibleInterface)
diff --git a/src/widgets/accessible/qaccessible2.h b/src/widgets/accessible/qaccessible2.h
index 1f18ac5501..69c19499c2 100644
--- a/src/widgets/accessible/qaccessible2.h
+++ b/src/widgets/accessible/qaccessible2.h
@@ -52,6 +52,8 @@ QT_MODULE(Gui)
#ifndef QT_NO_ACCESSIBILITY
+class QModelIndex;
+
namespace QAccessible2
{
enum CoordinateType
@@ -68,6 +70,24 @@ namespace QAccessible2
LineBoundary,
NoBoundary
};
+
+ enum TableModelChangeType {
+ TableModelChangeInsert,
+ TableModelChangeDelete,
+ TableModelChangeUpdate
+ };
+
+ struct TableModelChange {
+ int firstColumn;
+ int firstRow;
+ int lastColumn;
+ int lastRow;
+ TableModelChangeType type;
+
+ TableModelChange()
+ : firstColumn(0), firstRow(0), lastColumn(0), lastRow(0), type(TableModelChangeUpdate)
+ {}
+ };
}
class Q_WIDGETS_EXPORT QAccessible2Interface
@@ -83,6 +103,7 @@ inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; }
#define Q_ACCESSIBLE_OBJECT \
public: \
@@ -101,6 +122,8 @@ inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
return qAccessibleActionCastHelper(); \
case QAccessible2::ImageInterface: \
return qAccessibleImageCastHelper(); \
+ case QAccessible2::Table2Interface: \
+ return qAccessibleTable2CastHelper(); \
} \
return 0; \
} \
@@ -214,6 +237,95 @@ public:
int *columnSpan, bool *isSelected) = 0;
};
+class Q_WIDGETS_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
+{
+public:
+ // Returns the number of columns occupied by this cell accessible.
+ virtual int columnExtent() const = 0;
+
+ // Returns the column headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0;
+
+ // Translates this cell accessible into the corresponding column index.
+ virtual int columnIndex() const = 0;
+ // Returns the number of rows occupied by this cell accessible.
+ virtual int rowExtent() const = 0;
+ // Returns the row headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> rowHeaderCells() const = 0;
+ // Translates this cell accessible into the corresponding row index.
+ virtual int rowIndex() const = 0;
+ // Returns a boolean value indicating whether this cell is selected.
+ virtual bool isSelected() const = 0;
+
+ // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected.
+ virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0;
+ // Returns a reference to the accessbile of the containing table.
+ virtual QAccessibleTable2Interface* table() const = 0;
+
+ // #### Qt5 this should not be here but part of the state
+ virtual bool isExpandable() const = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; }
+
+ // Returns the cell at the specified row and column in the table.
+ virtual QAccessibleTable2CellInterface *cellAt (int row, int column) const = 0;
+ // Returns the caption for the table.
+ virtual QAccessibleInterface *caption() const = 0;
+ // Returns the description text of the specified column in the table.
+ virtual QString columnDescription(int column) const = 0;
+ // Returns the total number of columns in table.
+ virtual int columnCount() const = 0;
+ // Returns the total number of rows in table.
+ virtual int rowCount() const = 0;
+ // Returns the total number of selected cells.
+ virtual int selectedCellCount() const = 0;
+ // Returns the total number of selected columns.
+ virtual int selectedColumnCount() const = 0;
+ // Returns the total number of selected rows.
+ virtual int selectedRowCount() const = 0;
+ // Returns the description text of the specified row in the table.
+ virtual QString rowDescription(int row) const = 0;
+ // Returns a list of accessibles currently selected.
+ virtual QList<QAccessibleTable2CellInterface*> selectedCells() const = 0;
+ // Returns a list of column indexes currently selected (0 based).
+ virtual QList<int> selectedColumns() const = 0;
+ // Returns a list of row indexes currently selected (0 based).
+ virtual QList<int> selectedRows() const = 0;
+ // Returns the summary description of the table.
+ virtual QAccessibleInterface *summary() const = 0;
+ // Returns a boolean value indicating whether the specified column is completely selected.
+ virtual bool isColumnSelected(int column) const = 0;
+ // Returns a boolean value indicating whether the specified row is completely selected.
+ virtual bool isRowSelected(int row) const = 0;
+ // Selects a row and unselects all previously selected rows.
+ virtual bool selectRow(int row) = 0;
+ // Selects a column and unselects all previously selected columns.
+ virtual bool selectColumn(int column) = 0;
+ // Unselects one row, leaving other selected rows selected (if any).
+ virtual bool unselectRow(int row) = 0;
+ // Unselects one column, leaving other selected columns selected (if any).
+ virtual bool unselectColumn(int column) = 0;
+ // Returns the type and extents describing how a table changed.
+ virtual QAccessible2::TableModelChange modelChange() const = 0;
+
+protected:
+ // These functions are called when the model changes.
+ virtual void modelReset() = 0;
+ virtual void rowsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) = 0;
+ virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column) = 0;
+
+friend class QAbstractItemView;
+friend class QAbstractItemViewPrivate;
+};
+
class Q_WIDGETS_EXPORT QAccessibleActionInterface : public QAccessible2Interface
{
public:
diff --git a/src/widgets/accessible/qaccessible_mac.mm b/src/widgets/accessible/qaccessible_mac.mm
index 432b536577..a250730493 100644
--- a/src/widgets/accessible/qaccessible_mac.mm
+++ b/src/widgets/accessible/qaccessible_mac.mm
@@ -2427,7 +2427,7 @@ void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
}
// There is no equivalent Mac notification for ObjectShow/Hide, so we call HIObjectSetAccessibilityIgnored
- // and isItIntersting which will mark the HIObject accociated with the element as ignored if the
+ // and isItInteresting which will mark the HIObject accociated with the element as ignored if the
// QAccessible::Invisible state bit is set.
QAInterface interface = accessibleHierarchyManager()->lookup(element);
if (interface.isValid()) {
diff --git a/src/widgets/accessible/qaccessible_unix.cpp b/src/widgets/accessible/qaccessible_unix.cpp
index a6b7ec3345..19fbe78301 100644
--- a/src/widgets/accessible/qaccessible_unix.cpp
+++ b/src/widgets/accessible/qaccessible_unix.cpp
@@ -103,6 +103,17 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
if (!iface)
return;
+ // updates for List/Table/Tree should send child
+ if (who) {
+ QAccessibleInterface *child;
+ iface->navigate(QAccessible::Child, who, &child);
+ if (child) {
+ delete iface;
+ iface = child;
+ who = 0;
+ }
+ }
+
for (int i = 0; i < bridges()->count(); ++i)
bridges()->at(i)->notifyAccessibilityUpdate(reason, iface, who);
delete iface;
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
index 9605e38c5a..05948dcc9c 100644
--- a/src/widgets/accessible/qaccessiblewidget.cpp
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -704,13 +704,16 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry,
int sibCount = pIface->childCount();
QAccessibleInterface *candidate = 0;
for (int i = 0; i < sibCount && entry; ++i) {
- pIface->navigate(Child, i+1, &candidate);
- Q_ASSERT(candidate);
- if (candidate->relationTo(0, this, 0) & Label)
+ const int childId = pIface->navigate(Child, i+1, &candidate);
+ Q_ASSERT(childId >= 0);
+ if (childId > 0)
+ candidate = pIface;
+ if (candidate->relationTo(childId, this, 0) & Label)
--entry;
if (!entry)
break;
- delete candidate;
+ if (candidate != pIface)
+ delete candidate;
candidate = 0;
}
if (!candidate) {
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 7070d49579..c0f6339deb 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -1171,24 +1171,26 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
// Update focus scope item ptr in new scope.
QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
if (newFocusScopeItem && newParent) {
- if (subFocusItem) {
- // Find the subFocusItem's topmost focus scope.
- QGraphicsItem *ancestorScope = 0;
- QGraphicsItem *p = subFocusItem->d_ptr->parent;
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
- ancestorScope = p;
- if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel)
- break;
- p = p->d_ptr->parent;
- }
- if (ancestorScope)
- newFocusScopeItem = ancestorScope;
- }
-
QGraphicsItem *p = newParent;
while (p) {
if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
+ if (subFocusItem && subFocusItem != q_ptr) {
+ // Find the subFocusItem's topmost focus scope within the new parent's focusscope
+ QGraphicsItem *ancestorScope = 0;
+ QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
+ while (p2 && p2 != p) {
+ if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
+ ancestorScope = p2;
+ if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
+ break;
+ if (p2 == q_ptr)
+ break;
+ p2 = p2->d_ptr->parent;
+ }
+ if (ancestorScope)
+ newFocusScopeItem = ancestorScope;
+ }
+
p->d_ptr->focusScopeItem = newFocusScopeItem;
newFocusScopeItem->d_ptr->focusScopeItemChange(true);
// Ensure the new item is no longer the subFocusItem. The
diff --git a/src/widgets/graphicsview/qgraphicslayout_p.h b/src/widgets/graphicsview/qgraphicslayout_p.h
index 94150cb9fd..f11bfbf38c 100644
--- a/src/widgets/graphicsview/qgraphicslayout_p.h
+++ b/src/widgets/graphicsview/qgraphicslayout_p.h
@@ -98,9 +98,9 @@ public:
inline QStyle *style() const { return m_style; }
inline QWidget *widget() const { return m_widget; }
- inline bool operator==(const QLayoutStyleInfo &other)
+ inline bool operator==(const QLayoutStyleInfo &other) const
{ return m_style == other.m_style && m_widget == other.m_widget; }
- inline bool operator!=(const QLayoutStyleInfo &other)
+ inline bool operator!=(const QLayoutStyleInfo &other) const
{ return !(*this == other); }
inline void setDefaultSpacing(Qt::Orientation o, qreal spacing){
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 6aed17c049..d3875c8961 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -60,6 +60,7 @@
#include <private/qabstractitemmodel_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qsoftkeymanager_p.h>
#ifndef QT_NO_GESTURE
@@ -682,6 +683,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
@@ -712,6 +715,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(_q_headerDataChanged()));
connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(rowsInserted(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
@@ -1095,6 +1100,14 @@ void QAbstractItemView::reset()
setRootIndex(QModelIndex());
if (d->selectionModel)
d->selectionModel->reset();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -2849,7 +2862,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor)
*/
void QAbstractItemView::setHorizontalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -2878,7 +2891,7 @@ int QAbstractItemView::horizontalStepsPerItem() const
*/
void QAbstractItemView::setVerticalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -3311,12 +3324,24 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3379,27 +3404,72 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+
/*!
\internal
This slot is called when rows have been inserted.
*/
-void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+/*!
+ \internal
+ This slot is called when columns have been inserted.
+*/
+void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
/*!
\internal
@@ -3417,7 +3487,16 @@ void QAbstractItemViewPrivate::_q_modelDestroyed()
*/
void QAbstractItemViewPrivate::_q_layoutChanged()
{
+ Q_Q(QAbstractItemView);
doDelayedItemsLayout();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3742,7 +3821,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM
QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
const QModelIndex &index, const QEvent *event) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
if (event) {
switch (event->type()) {
diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h
index 2ba7c8de1c..8a2e1cb04e 100644
--- a/src/widgets/itemviews/qabstractitemview.h
+++ b/src/widgets/itemviews/qabstractitemview.h
@@ -355,6 +355,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index b76e579880..cd15694ffe 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -108,6 +108,7 @@ public:
void init();
virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end);
virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 983b0d38e3..d879e65c14 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -3169,7 +3169,11 @@ void QListView::currentChanged(const QModelIndex &current, const QModelIndex &pr
if (QAccessible::isActive()) {
if (current.isValid()) {
int entry = visualIndex(current) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3188,12 +3192,20 @@ void QListView::selectionChanged(const QItemSelection &selected,
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
int entry = visualIndex(sel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
int entry = visualIndex(desel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 617409ff3f..6f532eb7c7 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -3164,10 +3164,16 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
if (current.isValid()) {
+#ifdef Q_WS_X11
+ Q_D(QTableView);
+ int entry = d->accessibleTable2Index(current);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
int entry = visualIndex(current) + 1;
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3180,22 +3186,33 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
void QTableView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ Q_D(QTableView);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index f973acf3ce..dce0ed06ac 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -167,6 +167,11 @@ public:
return horizontalHeader->logicalIndex(visualCol);
}
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (index.row() + (horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + (verticalHeader ? 1 : 0))
+ + index.column() + (verticalHeader ? 1 : 0) + 1;
+ }
+
int sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const;
int sectionSpanSize(const QHeaderView *header, int logical, int span) const;
bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 6a992dbab6..9228ac82a2 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -54,6 +54,7 @@
#include <qdebug.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qtreeview_p.h>
@@ -2883,20 +2884,36 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
{
+ Q_Q(QTreeView);
viewItems.insert(pos, count, viewItem);
QTreeViewItem *items = viewItems.data();
for (int i = pos + count; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem += count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
void QTreeViewPrivate::removeViewItems(int pos, int count)
{
+ Q_Q(QTreeView);
viewItems.remove(pos, count);
QTreeViewItem *items = viewItems.data();
for (int i = pos; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem -= count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
#if 0
@@ -3687,14 +3704,6 @@ void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
*/
void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- int entry = visualIndex(current) + 1;
- if (header())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
- }
-#endif
QAbstractItemView::currentChanged(current, previous);
if (allColumnsShowFocus()) {
@@ -3711,6 +3720,19 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
viewport()->update(currentRect);
}
}
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive() && current.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(current) + (header()?1:0))*current.model()->columnCount()+current.column() + 1;
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
+ int entry = visualIndex(current) + 1;
+ if (header())
+ ++entry;
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
+ }
+#endif
}
/*!
@@ -3719,26 +3741,38 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
void QTreeView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ QAbstractItemView::selectionChanged(selected, deselected);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(sel) + (header()?1:0))*sel.model()->columnCount()+sel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(desel) + (header()?1:0))*desel.model()->columnCount()+desel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(desel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
- QAbstractItemView::selectionChanged(selected, deselected);
}
int QTreeView::visualIndex(const QModelIndex &index) const
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index a78bad341f..47cac2faed 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -219,6 +219,9 @@ protected:
private:
friend class QAccessibleItemView;
+ friend class QAccessibleTable2;
+ friend class QAccessibleTree;
+ friend class QAccessibleTable2Cell;
int visualIndex(const QModelIndex &index) const;
Q_DECLARE_PRIVATE(QTreeView)
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index b6d84586ee..a9dc452398 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -78,7 +78,7 @@ struct QTreeViewItem
Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE);
-class QTreeViewPrivate : public QAbstractItemViewPrivate
+class Q_GUI_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
{
Q_DECLARE_PUBLIC(QTreeView)
public:
@@ -223,6 +223,10 @@ public:
inline void invalidateHeightCache(int item) const
{ viewItems[item].height = 0; }
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1;
+ }
+
// used for spanning rows
QVector<QPersistentModelIndex> spanningIndexes;
diff --git a/src/widgets/itemviews/qwidgetitemdata_p.h b/src/widgets/itemviews/qwidgetitemdata_p.h
index 19724a3ccc..e7a08de378 100644
--- a/src/widgets/itemviews/qwidgetitemdata_p.h
+++ b/src/widgets/itemviews/qwidgetitemdata_p.h
@@ -62,7 +62,7 @@ public:
inline QWidgetItemData(int r, QVariant v) : role(r), value(v) {}
int role;
QVariant value;
- inline bool operator==(const QWidgetItemData &other) { return role == other.role && value == other.value; }
+ inline bool operator==(const QWidgetItemData &other) const { return role == other.role && value == other.value; }
};
#ifndef QT_NO_DATASTREAM
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 0e7a12c021..9587ac44e0 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -6376,6 +6376,10 @@ void QWidget::setFocus(Qt::FocusReason reason)
if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId()))
//setFocusWidget will already post a focus event for us (that the AT client receives) on Windows
# endif
+# ifdef Q_OS_UNIX
+ // menus update the focus manually and this would create bogus events
+ if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
+# endif
QAccessible::updateAccessibility(f, 0, QAccessible::Focus);
#endif
#ifndef QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/platforms/mac/qeventdispatcher_mac_p.h b/src/widgets/platforms/mac/qeventdispatcher_mac_p.h
index 485b14c38f..f4cf16e8a0 100644
--- a/src/widgets/platforms/mac/qeventdispatcher_mac_p.h
+++ b/src/widgets/platforms/mac/qeventdispatcher_mac_p.h
@@ -141,7 +141,7 @@ struct MacTimerInfo {
QObject *obj;
bool pending;
CFRunLoopTimerRef runLoopTimer;
- bool operator==(const MacTimerInfo &other)
+ bool operator==(const MacTimerInfo &other) const
{
return (id == other.id);
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index bf6730e9e3..650227214a 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -80,6 +80,9 @@
#if defined(Q_WS_S60)
#include "private/qt_s60_p.h"
#endif
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -1018,6 +1021,9 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn
}
q->update();
}
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(q, 0, QAccessible::NameChanged);
+#endif
}
void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
@@ -1271,6 +1277,9 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
Q_Q(QComboBox);
emit q->currentIndexChanged(index.row());
emit q->currentIndexChanged(itemText(index));
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(q, 0, QAccessible::NameChanged);
+#endif
}
QString QComboBoxPrivate::itemText(const QModelIndex &index) const
@@ -2635,6 +2644,9 @@ void QComboBox::clear()
{
Q_D(QComboBox);
d->model->removeRows(0, d->model->rowCount(d->root), d->root);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+#endif
}
/*!
@@ -2651,6 +2663,9 @@ void QComboBox::clearEditText()
Q_D(QComboBox);
if (d->lineEdit)
d->lineEdit->clear();
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+#endif
}
/*!
@@ -2661,6 +2676,9 @@ void QComboBox::setEditText(const QString &text)
Q_D(QComboBox);
if (d->lineEdit)
d->lineEdit->setText(text);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+#endif
}
/*!
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 7db7b42ef2..fa75aeaebc 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -88,6 +88,13 @@ QT_BEGIN_NAMESPACE
by clear().
\endtable
+ \warning When passing a QString to the constructor or calling setText(),
+ make sure to sanitize your input, as QLabel tries to guess whether it
+ displays the text as plain text or as rich text. You may want to call
+ setTextFormat() explicitly, e.g. in case you expect the text to be in
+ plain format but cannot control the text source (for instance when
+ displaying data loaded from the Web).
+
When the content is changed using any of these functions, any
previous content is cleared.
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index fee401d6ae..28c0973e04 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -60,6 +60,28 @@
QT_BEGIN_NAMESPACE
/*!
+ \internal
+
+ Updates the internal text layout. Returns the ascent of the
+ created QTextLine.
+*/
+int QWidgetLineControl::redoTextLayout() const
+{
+ m_textLayout.clearLayout();
+
+ m_textLayout.beginLayout();
+ QTextLine l = m_textLayout.createLine();
+ m_textLayout.endLayout();
+
+#if defined(Q_WS_MAC)
+ if (m_threadChecks)
+ m_textLayoutThread = QThread::currentThread();
+#endif
+
+ return qRound(l.ascent());
+}
+
+/*!
\internal
Updates the display text based of the current edit text
@@ -92,15 +114,12 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate)
m_textLayout.setText(str);
- QTextOption option;
+ QTextOption option = m_textLayout.textOption();
option.setTextDirection(m_layoutDirection);
option.setFlags(QTextOption::IncludeTrailingSpaces);
m_textLayout.setTextOption(option);
- m_textLayout.beginLayout();
- QTextLine l = m_textLayout.createLine();
- m_textLayout.endLayout();
- m_ascent = qRound(l.ascent());
+ m_ascent = redoTextLayout();
if (str != orig || forceUpdate)
emit displayTextChanged(str);
@@ -196,7 +215,7 @@ void QWidgetLineControl::del()
if (hasSelectedText()) {
removeSelectedText();
} else {
- int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor;
+ int n = textLayout()->nextCursorPosition(m_cursor) - m_cursor;
while (n--)
internalDelete();
}
@@ -324,7 +343,7 @@ void QWidgetLineControl::updatePasswordEchoEditing(bool editing)
*/
int QWidgetLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
{
- return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn);
+ return textLayout()->lineAt(0).xToCursor(x, betweenOrOn);
}
/*!
@@ -335,7 +354,7 @@ int QWidgetLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) con
*/
QRect QWidgetLineControl::cursorRect() const
{
- QTextLine l = m_textLayout.lineAt(0);
+ QTextLine l = textLayout()->lineAt(0);
int c = m_cursor;
if (m_preeditCursor != -1)
c += m_preeditCursor;
@@ -538,14 +557,14 @@ void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRe
}
if (flags & DrawText)
- m_textLayout.draw(painter, offset, selections, clip);
+ textLayout()->draw(painter, offset, selections, clip);
if (flags & DrawCursor){
int cursor = m_cursor;
if (m_preeditCursor != -1)
cursor += m_preeditCursor;
if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
- m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth);
+ textLayout()->drawCursor(painter, offset, cursor, m_cursorWidth);
}
}
@@ -561,10 +580,10 @@ void QWidgetLineControl::selectWordAtPos(int cursor)
int next = cursor + 1;
if(next > end())
--next;
- int c = m_textLayout.previousCursorPosition(next, QTextLayout::SkipWords);
+ int c = textLayout()->previousCursorPosition(next, QTextLayout::SkipWords);
moveCursor(c, false);
// ## text layout should support end of words.
- int end = m_textLayout.nextCursorPosition(c, QTextLayout::SkipWords);
+ int end = textLayout()->nextCursorPosition(c, QTextLayout::SkipWords);
while (end > cursor && m_text[end-1].isSpace())
--end;
moveCursor(end, true);
@@ -1392,9 +1411,9 @@ bool QWidgetLineControl::processEvent(QEvent* ev)
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMousePress:{
QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
- QMouseEvent* mouse = new QMouseEvent(ev->type(),
+ QMouseEvent mouse(ev->type(),
gvEv->pos().toPoint(), gvEv->button(), gvEv->buttons(), gvEv->modifiers());
- processMouseEvent(mouse); break;
+ processMouseEvent(&mouse); break;
}
#endif
case QEvent::MouseButtonPress:
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index edc8d16e7f..2237c27887 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -64,6 +64,10 @@
#include "QtGui/qclipboard.h"
#include "QtCore/qpoint.h"
#include "QtWidgets/qcompleter.h"
+#include "QtWidgets/qaccessible.h"
+#include "QtCore/qthread.h"
+
+#include "qplatformdefs.h"
QT_BEGIN_HEADER
@@ -84,6 +88,13 @@ public:
m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ , m_passwordEchoTimer(0)
+#endif
+#if defined(Q_WS_MAC)
+ , m_threadChecks(false)
+ , m_textLayoutThread(0)
+ #endif
{
init(txt);
}
@@ -319,11 +330,27 @@ public:
bool processEvent(QEvent *ev);
- QTextLayout *textLayout()
+ QTextLayout *textLayout() const
{
+#if defined(Q_WS_MAC)
+ if (m_threadChecks && QThread::currentThread() != m_textLayoutThread)
+ redoTextLayout();
+#endif
return &m_textLayout;
}
+#if defined(Q_WS_MAC)
+ void setThreadChecks(bool threadChecks)
+ {
+ m_threadChecks = threadChecks;
+ }
+
+ bool threadChecks() const
+ {
+ return m_threadChecks;
+ }
+#endif
+
private:
void init(const QString &txt);
void removeSelectedText();
@@ -420,12 +447,18 @@ private:
QString stripString(const QString &str) const;
int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
- // complex text layout
- QTextLayout m_textLayout;
+ // complex text layout (must be mutable so it can be reshaped at will)
+ mutable QTextLayout m_textLayout;
bool m_passwordEchoEditing;
QChar m_passwordCharacter;
+ int redoTextLayout() const;
+#if defined(Q_WS_MAC)
+ bool m_threadChecks;
+ mutable QThread *m_textLayoutThread;
+#endif
+
Q_SIGNALS:
void cursorPositionChanged(int, int);
void selectionChanged();