summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/accessible/complexwidgets.cpp11
-rw-r--r--src/widgets/accessible/complexwidgets_p.h2
-rw-r--r--src/widgets/accessible/itemviews.cpp10
-rw-r--r--src/widgets/accessible/qaccessiblemenu.cpp7
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp4
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp2
-rw-r--r--src/widgets/dialogs/qcolordialog.h5
-rw-r--r--src/widgets/dialogs/qdialog.cpp20
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp12
-rw-r--r--src/widgets/dialogs/qfiledialog.h2
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h14
-rw-r--r--src/widgets/dialogs/qfilesystemmodel_p.h2
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp33
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.cpp98
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.h4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp16
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp25
-rw-r--r--src/widgets/itemviews/qheaderview.cpp6
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp68
-rw-r--r--src/widgets/itemviews/qlistview.cpp66
-rw-r--r--src/widgets/itemviews/qlistview.h4
-rw-r--r--src/widgets/itemviews/qlistview_p.h2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp9
-rw-r--r--src/widgets/itemviews/qtableview.cpp47
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp36
-rw-r--r--src/widgets/itemviews/qtablewidget.h1
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h5
-rw-r--r--src/widgets/itemviews/qtreeview.cpp48
-rw-r--r--src/widgets/itemviews/qtreeview_p.h2
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp57
-rw-r--r--src/widgets/itemviews/qtreewidget.h11
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h7
-rw-r--r--src/widgets/kernel/kernel.pri6
-rw-r--r--src/widgets/kernel/qapplication.cpp84
-rw-r--r--src/widgets/kernel/qapplication_p.h2
-rw-r--r--src/widgets/kernel/qgesture.cpp4
-rw-r--r--src/widgets/kernel/qlayout.cpp20
-rw-r--r--src/widgets/kernel/qlayout.h1
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer_p.h18
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp3
-rw-r--r--src/widgets/kernel/qshortcut.cpp12
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.cpp113
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.h61
-rw-r--r--src/widgets/kernel/qtooltip.cpp54
-rw-r--r--src/widgets/kernel/qwhatsthis.cpp10
-rw-r--r--src/widgets/kernel/qwhatsthis.h4
-rw-r--r--src/widgets/kernel/qwidget.cpp122
-rw-r--r--src/widgets/kernel/qwidget.h1
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp87
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp112
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h3
-rw-r--r--src/widgets/qtwidgets.tracepoints4
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-16.pngbin0 -> 396 bytes
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-32.pngbin0 -> 661 bytes
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-48.pngbin0 -> 891 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-16.pngbin0 -> 158 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-32.pngbin0 -> 163 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-48.pngbin0 -> 167 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-16.pngbin0 -> 166 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-32.pngbin0 -> 171 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-48.pngbin0 -> 175 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-16.pngbin0 -> 253 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-32.pngbin0 -> 282 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-48.pngbin0 -> 339 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-16.pngbin0 -> 244 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-32.pngbin0 -> 294 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-48.pngbin0 -> 336 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-16.pngbin0 -> 349 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-32.pngbin0 -> 568 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-8.pngbin0 -> 220 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-16.pngbin0 -> 128 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-32.pngbin0 -> 148 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-8.pngbin0 -> 114 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-macstyle.png (renamed from src/widgets/styles/images/toolbar-ext.png)bin516 -> 516 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-macstyle@2x.png (renamed from src/widgets/styles/images/toolbar-ext@2x.png)bin505 -> 505 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-10.pngbin0 -> 387 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-20.pngbin0 -> 625 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-5.pngbin0 -> 223 bytes
-rw-r--r--src/widgets/styles/qcommonstyle.cpp140
-rw-r--r--src/widgets/styles/qstyle.cpp7
-rw-r--r--src/widgets/styles/qstyle.h1
-rw-r--r--src/widgets/styles/qstyle.qrc28
-rw-r--r--src/widgets/styles/qstylehelper.cpp8
-rw-r--r--src/widgets/styles/qstylehelper_p.h1
-rw-r--r--src/widgets/styles/qstyleoption.cpp8
-rw-r--r--src/widgets/styles/qstyleoption.h2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp74
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h7
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp3
-rw-r--r--src/widgets/util/qcompleter.cpp4
-rw-r--r--src/widgets/util/qcompleter.h2
-rw-r--r--src/widgets/util/qscroller.cpp4
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp70
-rw-r--r--src/widgets/util/qundostack.cpp55
-rw-r--r--src/widgets/util/qundostack.h5
-rw-r--r--src/widgets/widgets.pro3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp61
-rw-r--r--src/widgets/widgets/qabstractspinbox.h7
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h4
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp12
-rw-r--r--src/widgets/widgets/qlabel.cpp30
-rw-r--r--src/widgets/widgets/qlineedit.cpp22
-rw-r--r--src/widgets/widgets/qlineedit.h1
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp11
-rw-r--r--src/widgets/widgets/qmainwindow.cpp4
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp56
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h12
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp6
-rw-r--r--src/widgets/widgets/qspinbox.cpp116
-rw-r--r--src/widgets/widgets/qspinbox.h8
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp6
-rw-r--r--src/widgets/widgets/qsplitter.cpp17
-rw-r--r--src/widgets/widgets/qtabbar.cpp22
-rw-r--r--src/widgets/widgets/qtabbar_p.h17
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp7
-rw-r--r--src/widgets/widgets/qtextedit.cpp3
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp10
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h1
125 files changed, 1599 insertions, 631 deletions
diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp
index 6cdc06d702..63c6fbb9bb 100644
--- a/src/widgets/accessible/complexwidgets.cpp
+++ b/src/widgets/accessible/complexwidgets.cpp
@@ -120,7 +120,14 @@ public:
return rec;
}
- bool isValid() const override { return m_parent.data() && m_parent->count() > m_index; }
+ bool isValid() const override {
+ if (m_parent) {
+ if (static_cast<QWidget *>(m_parent.data())->d_func()->data.in_destructor)
+ return false;
+ return m_parent->count() > m_index;
+ }
+ return false;
+ }
QAccessibleInterface *childAt(int, int) const override { return 0; }
int childCount() const override { return 0; }
@@ -199,7 +206,7 @@ QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
QAccessibleTabBar::~QAccessibleTabBar()
{
- foreach (QAccessible::Id id, m_childInterfaces)
+ for (QAccessible::Id id : qAsConst(m_childInterfaces))
QAccessible::deleteAccessibleInterface(id);
}
diff --git a/src/widgets/accessible/complexwidgets_p.h b/src/widgets/accessible/complexwidgets_p.h
index 96db2dab70..e7a32c7264 100644
--- a/src/widgets/accessible/complexwidgets_p.h
+++ b/src/widgets/accessible/complexwidgets_p.h
@@ -90,8 +90,6 @@ public:
int indexOfChild(const QAccessibleInterface *child) const override;
bool isValid() const override;
QAccessibleInterface *childAt(int x, int y) const override;
-
-//protected:
QAbstractScrollArea *abstractScrollArea() const;
private:
diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp
index 4d37400dc9..04a5dcc878 100644
--- a/src/widgets/accessible/itemviews.cpp
+++ b/src/widgets/accessible/itemviews.cpp
@@ -115,7 +115,7 @@ bool QAccessibleTable::isValid() const
QAccessibleTable::~QAccessibleTable()
{
- Q_FOREACH (QAccessible::Id id, childToId)
+ for (QAccessible::Id id : qAsConst(childToId))
QAccessible::deleteAccessibleInterface(id);
}
@@ -221,7 +221,7 @@ QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const
return cells;
const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes();
cells.reserve(selectedIndexes.size());
- Q_FOREACH (const QModelIndex &index, selectedIndexes)
+ for (const QModelIndex &index : selectedIndexes)
cells.append(child(logicalIndex(index)));
return cells;
}
@@ -233,7 +233,7 @@ QList<int> QAccessibleTable::selectedColumns() const
QList<int> columns;
const QModelIndexList selectedColumns = view()->selectionModel()->selectedColumns();
columns.reserve(selectedColumns.size());
- Q_FOREACH (const QModelIndex &index, selectedColumns)
+ for (const QModelIndex &index : selectedColumns)
columns.append(index.column());
return columns;
@@ -246,7 +246,7 @@ QList<int> QAccessibleTable::selectedRows() const
QList<int> rows;
const QModelIndexList selectedRows = view()->selectionModel()->selectedRows();
rows.reserve(selectedRows.size());
- Q_FOREACH (const QModelIndex &index, selectedRows)
+ for (const QModelIndex &index : selectedRows)
rows.append(index.row());
return rows;
@@ -553,7 +553,7 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)
switch (event->modelChangeType()) {
case QAccessibleTableModelChangeEvent::ModelReset:
- Q_FOREACH (QAccessible::Id id, childToId)
+ for (QAccessible::Id id : qAsConst(childToId))
QAccessible::deleteAccessibleInterface(id);
childToId.clear();
break;
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp
index 8b3353f625..507584eb02 100644
--- a/src/widgets/accessible/qaccessiblemenu.cpp
+++ b/src/widgets/accessible/qaccessiblemenu.cpp
@@ -117,10 +117,9 @@ QAccessibleInterface *QAccessibleMenu::child(int index) const
QAccessibleInterface *QAccessibleMenu::parent() const
{
if (QAction *menuAction = menu()->menuAction()) {
- QList<QWidget *> parentCandidates;
- parentCandidates << menu()->parentWidget();
- parentCandidates << menuAction->associatedWidgets();
- foreach (QWidget *w, parentCandidates) {
+ const QList<QWidget*> parentCandidates =
+ QList<QWidget*>() << menu()->parentWidget() << menuAction->associatedWidgets();
+ for (QWidget *w : parentCandidates) {
if (qobject_cast<QMenu*>(w)
#if QT_CONFIG(menubar)
|| qobject_cast<QMenuBar*>(w)
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index 872ddcded5..0d87cc486d 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -569,7 +569,7 @@ QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const
QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
{
- foreach (QObject *child, calendarWidget()->children()) {
+ for (QObject *child : calendarWidget()->children()) {
if (child->objectName() == QLatin1String("qt_calendar_calendarview"))
return static_cast<QAbstractItemView *>(child);
}
@@ -578,7 +578,7 @@ QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
QWidget *QAccessibleCalendarWidget::navigationBar() const
{
- foreach (QObject *child, calendarWidget()->children()) {
+ for (QObject *child : calendarWidget()->children()) {
if (child->objectName() == QLatin1String("qt_calendar_navigationbar"))
return static_cast<QWidget *>(child);
}
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 99946d341d..e6a8ec47a4 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -2162,6 +2162,7 @@ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QStr
return dlg.selectedColor();
}
+#if QT_DEPRECATED_SINCE(5, 12)
/*!
\obsolete
@@ -2187,6 +2188,7 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
*ok = color.isValid();
return result;
}
+#endif
/*!
Destroys the color dialog.
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index 6451ff9bde..cdbe0e7fb4 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -92,8 +92,9 @@ public:
const QString &title = QString(),
ColorDialogOptions options = ColorDialogOptions());
- // obsolete
- static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = nullptr, QWidget *parent = nullptr);
+#if QT_DEPRECATED_SINCE(5, 12)
+ QT_DEPRECATED_X("Use getColor()") static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = nullptr, QWidget *parent = nullptr);
+#endif
static int customCount();
static QColor customColor(int index);
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index f5db4481ee..06f0393b4c 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -100,6 +100,10 @@ static inline int themeDialogType(const QDialog *dialog)
if (qobject_cast<const QErrorMessage *>(dialog))
return QPlatformTheme::MessageDialog;
#endif
+#if !QT_CONFIG(filedialog) && !QT_CONFIG(colordialog) && !QT_CONFIG(fontdialog) && \
+ !QT_CONFIG(messagebox) && !QT_CONFIG(errormessage)
+ Q_UNUSED(dialog);
+#endif
return -1;
}
@@ -514,6 +518,13 @@ void QDialog::open()
interaction with the parent window is blocked while the dialog is open.
By default, the dialog is application modal.
+ \note Avoid using this function; instead, use \c{open()}. Unlike exec(),
+ open() is asynchronous, and does not spin an additional event loop. This
+ prevents a series of dangerous bugs from happening (e.g. deleting the
+ dialog's parent while the dialog is open via exec()). When using open() you
+ can connect to the finished() signal of QDialog to be notified when the
+ dialog is closed.
+
\sa open(), show(), result(), setWindowModality()
*/
@@ -560,9 +571,12 @@ int QDialog::exec()
}
/*!
- Closes the dialog and sets its result code to \a r. If this dialog
- is shown with exec(), done() causes the local event loop to finish,
- and exec() to return \a r.
+ Closes the dialog and sets its result code to \a r. The finished() signal
+ will emit \a r; if \a r is QDialog::Accepted or QDialog::Rejected, the
+ accepted() or the rejected() signals will also be emitted, respectively.
+
+ If this dialog is shown with exec(), done() also causes the local event loop
+ to finish, and exec() to return \a r.
As with QWidget::close(), done() deletes the dialog if the
Qt::WA_DeleteOnClose flag is set. If the dialog is the application's
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index ecd2ab6776..2742b152f2 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -517,7 +517,7 @@ void QFileDialog::changeEvent(QEvent *e)
QFileDialogPrivate::QFileDialogPrivate()
:
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
proxyModel(0),
#endif
model(0),
@@ -663,7 +663,7 @@ void QFileDialogPrivate::retranslateStrings()
QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -2813,7 +2813,7 @@ bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPo
QList<QAction*> actions = headerView->actions();
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -2982,7 +2982,7 @@ void QFileDialogPrivate::createWidgets()
q, SLOT(_q_showHeader(QAction*)));;
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -3063,7 +3063,7 @@ void QFileDialogPrivate::_q_showHeader(QAction *action)
qFileDialogUi->treeView->header()->setSectionHidden(actionGroup->actions().indexOf(action) + 1, !action->isChecked());
}
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
/*!
\since 4.3
@@ -3141,7 +3141,7 @@ QAbstractProxyModel *QFileDialog::proxyModel() const
Q_D(const QFileDialog);
return d->proxyModel;
}
-#endif // QT_NO_PROXYMODEL
+#endif // QT_CONFIG(proxymodel)
/*!
\internal
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 1cbd690f24..8646894750 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -178,7 +178,7 @@ public:
void setSupportedSchemes(const QStringList &schemes);
QStringList supportedSchemes() const;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
void setProxyModel(QAbstractProxyModel *model);
QAbstractProxyModel *proxyModel() const;
#endif
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 17290381d3..3a93a53911 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -227,7 +227,7 @@ public:
void _q_fileRenamed(const QString &path, const QString &oldName, const QString &newName);
// layout
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
QAbstractProxyModel *proxyModel;
#endif
@@ -346,17 +346,17 @@ private:
};
QModelIndex QFileDialogPrivate::mapToSource(const QModelIndex &index) const {
-#ifdef QT_NO_PROXYMODEL
- return index;
-#else
+#if QT_CONFIG(proxymodel)
return proxyModel ? proxyModel->mapToSource(index) : index;
+#else
+ return index;
#endif
}
QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) const {
-#ifdef QT_NO_PROXYMODEL
- return index;
-#else
+#if QT_CONFIG(proxymodel)
return proxyModel ? proxyModel->mapFromSource(index) : index;
+#else
+ return index;
#endif
}
diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h
index a2a02e2d41..1e72bb69a8 100644
--- a/src/widgets/dialogs/qfilesystemmodel_p.h
+++ b/src/widgets/dialogs/qfilesystemmodel_p.h
@@ -294,8 +294,6 @@ public:
void _q_fileSystemChanged(const QString &path, const QVector<QPair<QString, QFileInfo> > &);
void _q_resolvedName(const QString &fileName, const QString &resolvedName);
- static int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs);
-
QDir rootDir;
#if QT_CONFIG(filesystemwatcher)
# ifdef Q_OS_WIN
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
index 71027f00a2..86c1fa243c 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -2526,7 +2526,7 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
// Check if this constraint have some overlap with current
// trunk variables...
- foreach (QSimplexVariable *ad, trunkVariables) {
+ for (QSimplexVariable *ad : qAsConst(trunkVariables)) {
if (c->variables.contains(ad)) {
match = true;
break;
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index fdf21fb499..203b879020 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -7310,7 +7310,7 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
selectedItems = d_ptr->scene->selectedItems();
initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
if (initialPositions.isEmpty()) {
- foreach (QGraphicsItem *item, selectedItems)
+ for (QGraphicsItem *item : qAsConst(selectedItems))
initialPositions[item] = item->pos();
initialPositions[this] = pos();
}
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 37c631483a..7cc694a613 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -4331,7 +4331,8 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &
pix->fill(Qt::transparent);
pixmapPainter.begin(pix);
} else {
- subPix = QPixmap(br.size());
+ subPix = QPixmap(br.size() * pix->devicePixelRatio());
+ subPix.setDevicePixelRatio(pix->devicePixelRatio());
subPix.fill(Qt::transparent);
pixmapPainter.begin(&subPix);
pixmapPainter.translate(-br.topLeft());
@@ -4409,6 +4410,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
return;
}
+ const qreal devicePixelRatio = painter->device()->devicePixelRatio();
const qreal oldPainterOpacity = painter->opacity();
qreal newPainterOpacity = oldPainterOpacity;
QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
@@ -4428,6 +4430,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Fetch the off-screen transparent buffer and exposed area info.
QPixmapCache::Key pixmapKey;
QPixmap pix;
+
bool pixmapFound;
QGraphicsItemCache *itemCache = itemd->extraItemCache();
if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
@@ -4442,18 +4445,20 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Render using item coordinate cache mode.
if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
QSize pixmapSize;
- bool fixedCacheSize = false;
+ bool fixedCacheSize = itemCache->fixedSize.isValid();
QRect br = brect.toAlignedRect();
- if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
+ if (fixedCacheSize) {
pixmapSize = itemCache->fixedSize;
} else {
pixmapSize = br.size();
}
+ pixmapSize *= devicePixelRatio;
+
// Create or recreate the pixmap.
int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
QSize adjustSize(adjust*2, adjust*2);
- br.adjust(-adjust, -adjust, adjust, adjust);
+ br.adjust(-adjust / devicePixelRatio, -adjust / devicePixelRatio, adjust / devicePixelRatio, adjust / devicePixelRatio);
if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
pix = QPixmap(pixmapSize + adjustSize);
itemCache->boundingRect = br;
@@ -4476,7 +4481,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Fit the item's bounding rect into the pixmap's coordinates.
QTransform itemToPixmap;
if (fixedCacheSize) {
- const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
+ const QPointF scale((pixmapSize.width() / devicePixelRatio) / brect.width(),
+ (pixmapSize.height() / devicePixelRatio) / brect.height());
itemToPixmap.scale(scale.x(), scale.y());
}
itemToPixmap.translate(-br.x(), -br.y());
@@ -4498,6 +4504,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
styleOptionTmp.exposedRect = exposedRect;
// Render.
+ pix.setDevicePixelRatio(devicePixelRatio);
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
&styleOptionTmp, painterStateProtection);
@@ -4595,21 +4602,22 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Copy / "scroll" the old pixmap onto the new ole and calculate
// scrolled exposure.
- if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
+ if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size() / devicePixelRatio) {
QPoint diff = newCacheIndent - deviceData->cacheIndent;
- QPixmap newPix(deviceRect.size());
+ QPixmap newPix(deviceRect.size() * devicePixelRatio);
// ### Investigate removing this fill (test with Plasma and
// graphicssystem raster).
newPix.fill(Qt::transparent);
if (!pix.isNull()) {
+ newPix.setDevicePixelRatio(devicePixelRatio);
QPainter newPixPainter(&newPix);
newPixPainter.drawPixmap(-diff, pix);
newPixPainter.end();
}
QRegion exposed;
- exposed += newPix.rect();
+ exposed += QRect(QPoint(0,0), newPix.size() / devicePixelRatio);
if (!pix.isNull())
- exposed -= QRect(-diff, pix.size());
+ exposed -= QRect(-diff, pix.size() / devicePixelRatio);
scrollExposure = exposed;
pix = newPix;
@@ -4621,9 +4629,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
deviceData->cacheIndent = QPoint();
// Auto-adjust the pixmap size.
- if (deviceRect.size() != pix.size()) {
+ if (deviceRect.size() != pix.size() / devicePixelRatio) {
// exposed needs to cover the whole pixmap
- pix = QPixmap(deviceRect.size());
+ pix = QPixmap(deviceRect.size() * devicePixelRatio);
pixModified = true;
itemCache->allExposed = true;
itemCache->exposed.clear();
@@ -4667,6 +4675,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
// Render the exposed areas.
+ pix.setDevicePixelRatio(devicePixelRatio);
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
&styleOptionTmp, painterStateProtection);
@@ -6391,7 +6400,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
ev.setWidget(event->widget());
sendEvent(receiver.data(), &ev);
QSet<QGesture *> ignoredGestures;
- foreach (QGesture *g, gestures) {
+ for (QGesture *g : qAsConst(gestures)) {
if (!ev.isAccepted() && !ev.isAccepted(g)) {
// if the gesture was ignored by its target, we will update the
// targetItems list with a possible target items (items that
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp
index f7f09486e9..398ef1aaf5 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp
@@ -259,8 +259,9 @@
#include "qgraphicssceneevent.h"
-#ifndef QT_NO_DEBUG
+#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
+#include <private/qdebug_p.h>
#endif
#include <QtCore/qmap.h>
#include <QtCore/qpoint.h>
@@ -1730,4 +1731,99 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos)
d->newPos = pos;
}
+#ifndef QT_NO_DEBUG_STREAM
+template <class Event>
+static inline void formatPositions(QDebug &debug, const Event *event)
+{
+ debug << ", pos=";
+ QtDebugUtils::formatQPoint(debug, event->pos());
+ debug << ", scenePos=";
+ QtDebugUtils::formatQPoint(debug, event->scenePos());
+ debug << ", screenPos=";
+ QtDebugUtils::formatQPoint(debug, event->screenPos());
+}
+
+QDebug operator<<(QDebug debug, const QGraphicsSceneEvent *event)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ if (!event) {
+ debug << "QGraphicsSceneEvent(0)";
+ return debug;
+ }
+
+ const QEvent::Type type = event->type();
+ switch (type) {
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ const QGraphicsSceneMouseEvent *me = static_cast<const QGraphicsSceneMouseEvent *>(event);
+ const Qt::MouseButton button = me->button();
+ const Qt::MouseButtons buttons = me->buttons();
+ debug << "QGraphicsSceneMouseEvent(";
+ QtDebugUtils::formatQEnum(debug, type);
+ if (type != QEvent::GraphicsSceneMouseMove) {
+ debug << ", ";
+ QtDebugUtils::formatQEnum(debug, button);
+ }
+ if (buttons && button != buttons) {
+ debug << ", buttons=";
+ QtDebugUtils::formatQFlags(debug, buttons);
+ }
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", me->modifiers());
+ formatPositions(debug, me);
+ QtDebugUtils::formatNonNullQEnum(debug, ", ", me->source());
+ QtDebugUtils::formatNonNullQFlags(debug, ", flags=", me->flags());
+ debug << ')';
+ }
+ break;
+ case QEvent::GraphicsSceneContextMenu: {
+ const QGraphicsSceneContextMenuEvent *ce = static_cast<const QGraphicsSceneContextMenuEvent *>(event);
+ debug << "QGraphicsSceneContextMenuEvent(reason=" << ce->reason();
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", ce->modifiers());
+ formatPositions(debug, ce);
+ debug << ')';
+ }
+ break;
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneHoverLeave:
+ debug << "QGraphicsSceneHoverEvent(";
+ formatPositions(debug, static_cast<const QGraphicsSceneHoverEvent *>(event));
+ debug << ')';
+ break;
+ case QEvent::GraphicsSceneHelp:
+ break;
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop: {
+ const QGraphicsSceneDragDropEvent *de = static_cast<const QGraphicsSceneDragDropEvent *>(event);
+ debug << "QGraphicsSceneDragDropEvent(proposedAction=";
+ QtDebugUtils::formatQEnum(debug, de->proposedAction());
+ debug << ", possibleActions=";
+ QtDebugUtils::formatQFlags(debug, de->possibleActions());
+ debug << ", source=" << de->source();
+ QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", de->buttons());
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", de->modifiers());
+ formatPositions(debug, de);
+ }
+ break;
+ case QEvent::GraphicsSceneWheel: {
+ const QGraphicsSceneWheelEvent *we = static_cast<const QGraphicsSceneWheelEvent *>(event);
+ debug << "QGraphicsSceneWheelEvent(";
+ QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", we->buttons());
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", we->modifiers());
+ formatPositions(debug, we);
+ debug << ')';
+ }
+ break;
+ default:
+ break;
+ }
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.h b/src/widgets/graphicsview/qgraphicssceneevent.h
index 77b53e401d..9d940be2c0 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.h
+++ b/src/widgets/graphicsview/qgraphicssceneevent.h
@@ -320,6 +320,10 @@ public:
void setNewPos(const QPointF &pos);
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QGraphicsSceneEvent *);
+#endif
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index f79ee41e10..24647dd74c 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -2703,7 +2703,7 @@ void QGraphicsView::updateScene(const QList<QRectF> &rects)
dirtyViewportRects << xrect;
}
- foreach (const QRect &rect, dirtyViewportRects) {
+ for (const QRect &rect : qAsConst(dirtyViewportRects)) {
// Add the exposed rect to the update region. In rect update
// mode, we only count the bounding rect of items.
if (!boundingRectUpdate) {
@@ -3483,7 +3483,9 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Recreate the background pixmap, and flag the whole background as
// exposed.
if (d->mustResizeBackgroundPixmap) {
- d->backgroundPixmap = QPixmap(viewport()->size());
+ const qreal dpr = d->viewport->devicePixelRatioF();
+ d->backgroundPixmap = QPixmap(viewport()->size() * dpr);
+ d->backgroundPixmap.setDevicePixelRatio(dpr);
QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
if (!bgBrush.isOpaque())
d->backgroundPixmap.fill(Qt::transparent);
@@ -3679,14 +3681,20 @@ void QGraphicsView::scrollContentsBy(int dx, int dy)
&& X11->use_xrender
#endif
) {
+ // Below, QPixmap::scroll() works in device pixels, while the delta values
+ // and backgroundPixmapExposed are in device independent pixels.
+ const qreal dpr = d->backgroundPixmap.devicePixelRatio();
+ const qreal inverseDpr = qreal(1) / dpr;
+
// Scroll the background pixmap
QRegion exposed;
if (!d->backgroundPixmap.isNull())
- d->backgroundPixmap.scroll(dx, dy, d->backgroundPixmap.rect(), &exposed);
+ d->backgroundPixmap.scroll(dx * dpr, dy * dpr, d->backgroundPixmap.rect(), &exposed);
// Invalidate the background pixmap
d->backgroundPixmapExposed.translate(dx, dy);
- d->backgroundPixmapExposed += exposed;
+ const QRegion exposedScaled = QTransform::fromScale(inverseDpr, inverseDpr).map(exposed);
+ d->backgroundPixmapExposed += exposedScaled;
}
// Always replay on scroll.
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index c9f321c3f6..7bc0ece4b3 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -599,18 +599,21 @@ QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const Q
case QVariant::DateTime:
text = locale.toString(value.toDateTime(), formatType);
break;
- default: {
- if (value.canConvert<QJsonValue>()) {
- const QJsonValue val = value.toJsonValue();
- if (val.isBool())
- text = QVariant(val.toBool()).toString();
- else if (val.isDouble())
- text = locale.toString(val.toDouble(), 'g', precision);
- else if (val.isString())
- text = val.toString();
- } else {
- text = value.toString();
+ case QVariant::Type(QMetaType::QJsonValue): {
+ const QJsonValue val = value.toJsonValue();
+ if (val.isBool()) {
+ text = QVariant(val.toBool()).toString();
+ break;
+ }
+ if (val.isDouble()) {
+ text = locale.toString(val.toDouble(), 'g', precision);
+ break;
}
+ // val is a string (or null) here
+ Q_FALLTHROUGH();
+ }
+ default: {
+ text = value.toString();
if (role == Qt::DisplayRole)
text.replace(QLatin1Char('\n'), QChar::LineSeparator);
break;
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 9a8206de45..70f8b28299 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1853,11 +1853,13 @@ bool QHeaderView::restoreState(const QByteArray &state)
*/
void QHeaderView::reset()
{
+ Q_D(QHeaderView);
QAbstractItemView::reset();
// it would be correct to call clear, but some apps rely
// on the header keeping the sections, even after calling reset
//d->clear();
initializeSections();
+ d->invalidateCachedSizeHint();
}
/*!
@@ -2871,6 +2873,7 @@ bool QHeaderView::viewportEvent(QEvent *e)
}
return true; }
#endif // QT_CONFIG(statustip)
+ case QEvent::Resize:
case QEvent::FontChange:
case QEvent::StyleChange:
d->invalidateCachedSizeHint();
@@ -3831,6 +3834,7 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
void QHeaderViewPrivate::setDefaultSectionSize(int size)
{
Q_Q(QHeaderView);
+ size = qBound(q->minimumSectionSize(), size, q->maximumSectionSize());
executePostedLayout();
invalidateCachedSizeHint();
defaultSectionSize = size;
@@ -4086,7 +4090,7 @@ bool QHeaderViewPrivate::read(QDataStream &in)
}
int sectionItemsLengthTotal = 0;
- foreach (const SectionItem &section, newSectionItems)
+ for (const SectionItem &section : qAsConst(newSectionItems))
sectionItemsLengthTotal += section.size;
if (sectionItemsLengthTotal != lengthIn)
return false;
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index 91122283a4..dff4cc4593 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -103,7 +103,10 @@ public:
QItemEditorFactory *f;
bool clipPainting;
- QRect textLayoutBounds(const QStyleOptionViewItem &options) const;
+ QRect displayRect(const QModelIndex &index, const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const;
+ QRect textLayoutBounds(const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const;
QSizeF doTextLayout(int lineWidth) const;
mutable QTextLayout textLayout;
mutable QTextOption textOption;
@@ -121,21 +124,53 @@ public:
} tmp;
};
-QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItem &option) const
+QRect QItemDelegatePrivate::displayRect(const QModelIndex &index, const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const
+{
+ Q_Q(const QItemDelegate);
+ const QVariant value = index.data(Qt::DisplayRole);
+ if (!value.isValid() || value.isNull())
+ return QRect();
+
+ const QString text = valueToText(value, option);
+ const QVariant fontVal = index.data(Qt::FontRole);
+ const QFont fnt = qvariant_cast<QFont>(fontVal).resolve(option.font);
+ return q->textRectangle(nullptr,
+ textLayoutBounds(option, decorationRect, checkRect),
+ fnt, text);
+}
+
+// similar to QCommonStylePrivate::viewItemSize(Qt::DisplayRole)
+QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const
{
QRect rect = option.rect;
+ const QWidget *w = widget(option);
+ QStyle *style = w ? w->style() : QApplication::style();
const bool wrapText = option.features & QStyleOptionViewItem::WrapText;
+ // see QItemDelegate::drawDisplay
+ const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, w) + 1;
switch (option.decorationPosition) {
case QStyleOptionViewItem::Left:
case QStyleOptionViewItem::Right:
- rect.setWidth(wrapText && rect.isValid() ? rect.width() : (QFIXED_MAX));
+ rect.setWidth(wrapText && rect.isValid() ? rect.width() - 2 * textMargin : (QFIXED_MAX));
break;
case QStyleOptionViewItem::Top:
case QStyleOptionViewItem::Bottom:
- rect.setWidth(wrapText ? option.decorationSize.width() : (QFIXED_MAX));
+ rect.setWidth(wrapText ? option.decorationSize.width() - 2 * textMargin : (QFIXED_MAX));
break;
}
+ if (wrapText) {
+ if (!decorationRect.isNull())
+ rect.setWidth(rect.width() - decorationRect.width() - 2 * textMargin);
+ if (!checkRect.isNull())
+ rect.setWidth(rect.width() - checkRect.width() - 2 * textMargin);
+ // adjust height to be sure that the text fits
+ const QSizeF size = doTextLayout(rect.width());
+ rect.setHeight(qCeil(size.height()));
+ }
+
return rect;
}
@@ -395,14 +430,6 @@ void QItemDelegate::paint(QPainter *painter,
decorationRect = QRect();
}
- QString text;
- QRect displayRect;
- value = index.data(Qt::DisplayRole);
- if (value.isValid() && !value.isNull()) {
- text = d->valueToText(value, opt);
- displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
- }
-
QRect checkRect;
Qt::CheckState checkState = Qt::Unchecked;
value = index.data(Qt::CheckStateRole);
@@ -411,6 +438,14 @@ void QItemDelegate::paint(QPainter *painter,
checkRect = doCheck(opt, opt.rect, value);
}
+ QString text;
+ QRect displayRect;
+ value = index.data(Qt::DisplayRole);
+ if (value.isValid() && !value.isNull()) {
+ text = d->valueToText(value, opt);
+ displayRect = d->displayRect(index, opt, decorationRect, checkRect);
+ }
+
// do the layout
doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
@@ -440,12 +475,13 @@ void QItemDelegate::paint(QPainter *painter,
QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
+ Q_D(const QItemDelegate);
QVariant value = index.data(Qt::SizeHintRole);
if (value.isValid())
return qvariant_cast<QSize>(value);
QRect decorationRect = rect(option, index, Qt::DecorationRole);
- QRect displayRect = rect(option, index, Qt::DisplayRole);
QRect checkRect = rect(option, index, Qt::CheckStateRole);
+ QRect displayRect = d->displayRect(index, option, decorationRect, checkRect);
doLayout(option, &checkRect, &decorationRect, &displayRect, true);
@@ -1000,8 +1036,8 @@ QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette,
/*!
\internal
+ Only used (and usable) for Qt::DecorationRole and Qt::CheckStateRole
*/
-
QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
const QModelIndex &index, int role) const
{
@@ -1032,7 +1068,9 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
const QString text = d->valueToText(value, option);
value = index.data(Qt::FontRole);
QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
- return textRectangle(0, d->textLayoutBounds(option), fnt, text); }
+ return textRectangle(nullptr,
+ d->textLayoutBounds(option, QRect(), QRect()),
+ fnt, text); }
}
}
return QRect();
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index a7174a92e8..e5769940d4 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1631,6 +1631,32 @@ bool QListView::isSelectionRectVisible() const
}
/*!
+ \property QListView::itemAlignment
+ \brief the alignment of each item in its cell
+ \since 5.12
+
+ This is only supported in ListMode with TopToBottom flow
+ and with wrapping enabled.
+ The default alignment is 0, which means that an item fills
+ its cell entirely.
+*/
+void QListView::setItemAlignment(Qt::Alignment alignment)
+{
+ Q_D(QListView);
+ if (d->itemAlignment == alignment)
+ return;
+ d->itemAlignment = alignment;
+ if (viewMode() == ListMode && flow() == QListView::TopToBottom && isWrapping())
+ d->doDelayedItemsLayout();
+}
+
+Qt::Alignment QListView::itemAlignment() const
+{
+ Q_D(const QListView);
+ return d->itemAlignment;
+}
+
+/*!
\reimp
*/
bool QListView::event(QEvent *e)
@@ -1656,7 +1682,8 @@ QListViewPrivate::QListViewPrivate()
column(0),
uniformItemSizes(false),
batchSize(100),
- showElasticBand(false)
+ showElasticBand(false),
+ itemAlignment(Qt::Alignment())
{
}
@@ -2366,6 +2393,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
options.rect.setSize(contentsSize);
QSize size = (uniformItemSizes() && cachedItemSize().isValid())
? cachedItemSize() : itemSize(options, index);
+ QSize cellSize = size;
QPoint pos;
if (flow() == QListView::LeftToRight) {
@@ -2378,12 +2406,22 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
int right = (segment + 1 >= segmentPositions.count()
? contentsSize.width()
: segmentPositions.at(segment + 1));
- size.setWidth(right - pos.x());
+ cellSize.setWidth(right - pos.x());
} else { // make the items as wide as the viewport
- size.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
+ cellSize.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
}
}
+ if (dd->itemAlignment & Qt::AlignHorizontal_Mask) {
+ size.setWidth(qMin(size.width(), cellSize.width()));
+ if (dd->itemAlignment & Qt::AlignRight)
+ pos.setX(pos.x() + cellSize.width() - size.width());
+ if (dd->itemAlignment & Qt::AlignHCenter)
+ pos.setX(pos.x() + (cellSize.width() - size.width()) / 2);
+ } else {
+ size.setWidth(cellSize.width());
+ }
+
return QListViewItem(QRect(pos, size), index.row());
}
@@ -2562,8 +2600,18 @@ QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
if (isHidden(row))
continue;
QModelIndex index = modelIndex(row);
- if (index.isValid())
- ret += index;
+ if (index.isValid()) {
+ if (flow() == QListView::LeftToRight || dd->itemAlignment == Qt::Alignment()) {
+ ret += index;
+ } else {
+ const auto viewItem = indexToListViewItem(index);
+ const int iw = viewItem.width();
+ const int startPos = qMax(segStartPosition, segmentPositions.at(seg));
+ const int endPos = qMin(segmentPositions.at(seg + 1), segEndPosition);
+ if (endPos >= viewItem.x && startPos < viewItem.x + iw)
+ ret += index;
+ }
+ }
#if 0 // for debugging
else
qWarning("intersectingSet: row %d was invalid", row);
@@ -2603,7 +2651,7 @@ int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wr
positions = segmentPositions;
else if (!flowPositions.isEmpty()) {
positions.reserve(scrollValueMap.size());
- foreach (int itemShown, scrollValueMap)
+ for (int itemShown : scrollValueMap)
positions.append(flowPositions.at(itemShown));
}
if (positions.isEmpty() || bounds <= length)
@@ -2767,6 +2815,8 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
drag->setHotSpot(dd->pressedPosition - rect.topLeft());
Qt::DropAction action = drag->exec(supportedActions, dd->defaultDropAction);
draggedItems.clear();
+ // for internal moves the action was set to Qt::CopyAction in
+ // filterDropEvent() to avoid the deletion here
if (action == Qt::MoveAction)
dd->clearOrRemove();
}
@@ -2784,7 +2834,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
if (qq->acceptDrops()) {
const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
- foreach (const QModelIndex &index, dropIndices)
+ for (const QModelIndex &index : dropIndices)
if ((index.flags() & dropableFlags) == dropableFlags)
return false;
}
@@ -2803,6 +2853,8 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
dd->stopAutoScroll();
draggedItems.clear();
dd->emitIndexesMoved(indexes);
+ // do not delete item on internal move, see filterStartDrag()
+ e->setDropAction(Qt::CopyAction);
e->accept(); // we have handled the event
// if the size has not grown, we need to check if it has shrinked
if (contentsSize != contents) {
diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h
index 9fc4035999..8a5d5e02ae 100644
--- a/src/widgets/itemviews/qlistview.h
+++ b/src/widgets/itemviews/qlistview.h
@@ -65,6 +65,7 @@ class Q_WIDGETS_EXPORT QListView : public QAbstractItemView
Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize)
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible)
+ Q_PROPERTY(Qt::Alignment itemAlignment READ itemAlignment WRITE setItemAlignment)
public:
enum Movement { Static, Free, Snap };
@@ -125,6 +126,9 @@ public:
void setSelectionRectVisible(bool show);
bool isSelectionRectVisible() const;
+ void setItemAlignment(Qt::Alignment alignment);
+ Qt::Alignment itemAlignment() const;
+
QRect visualRect(const QModelIndex &index) const override;
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
QModelIndex indexAt(const QPoint &p) const override;
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index ca947292e3..181386d4d0 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -431,6 +431,8 @@ public:
QRect elasticBand;
bool showElasticBand;
+
+ Qt::Alignment itemAlignment;
};
// inline implementations
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 4f1c7fe80a..72e0a67a64 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -48,9 +48,6 @@
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug (?)
-typedef bool(*LessThan)(const QPair<QListWidgetItem*,int>&,const QPair<QListWidgetItem*,int>&);
-
class QListWidgetMimeData : public QMimeData
{
Q_OBJECT
@@ -301,7 +298,7 @@ void QListModel::sort(int column, Qt::SortOrder order)
sorting[i].second = i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromIndexes;
QModelIndexList toIndexes;
@@ -338,7 +335,7 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en
sorting[i].second = start + i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes = persistentIndexList();
@@ -1847,7 +1844,7 @@ QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*> items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
cachedIndexes.reserve(items.count());
- foreach (QListWidgetItem *item, items)
+ for (QListWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
QMimeData *result = d->listModel()->internalMimeData();
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 1938fd8e92..9c2b3e5b54 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -74,7 +74,7 @@ void QSpanCollection::addSpan(QSpanCollection::Span *span)
//the previouslist is the list of spans that sarts _before_ the row of the span.
// and which may intersect this row.
const SubIndex previousList = it_y.value();
- foreach(Span *s, previousList) {
+ for (Span *s : previousList) {
//If a subspans intersect the row, we need to split it into subspans
if(s->bottom() >= span->top())
sub_index.insert(-s->left(), s);
@@ -798,6 +798,7 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
const QStyleOptionViewItem &option, QBitArray *drawn,
int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)
{
+ Q_Q(const QTableView);
bool alternateBase = false;
QRegion region = viewport->rect();
@@ -816,7 +817,7 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
visibleSpans = set.toList();
}
- foreach (QSpanCollection::Span *span, visibleSpans) {
+ for (QSpanCollection::Span *span : qAsConst(visibleSpans)) {
int row = span->top();
int col = span->left();
QModelIndex index = model->index(row, col, root);
@@ -831,6 +832,18 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
alternateBase = alternatingColors && (span->top() & 1);
opt.features.setFlag(QStyleOptionViewItem::Alternate, alternateBase);
drawCell(painter, opt, index);
+ if (showGrid) {
+ // adjust the clip rect to be able to paint the top & left grid lines
+ // if the headers are not visible, see paintEvent()
+ if (horizontalHeader->visualIndex(row) == 0)
+ rect.setTop(rect.top() + 1);
+ if (verticalHeader->visualIndex(row) == 0) {
+ if (q->isLeftToRight())
+ rect.setLeft(rect.left() + 1);
+ else
+ rect.setRight(rect.right() - 1);
+ }
+ }
region -= rect;
for (int r = span->top(); r <= span->bottom(); ++r) {
const int vr = visualRow(r);
@@ -1163,7 +1176,6 @@ void QTableView::doItemsLayout()
{
Q_D(QTableView);
QAbstractItemView::doItemsLayout();
- d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (!d->verticalHeader->updatesEnabled())
d->verticalHeader->setUpdatesEnabled(true);
}
@@ -1321,10 +1333,10 @@ void QTableView::scrollContentsBy(int dx, int dy)
//we need to update the first line of the previous top item in the view
//because it has the grid drawn if the header is invisible.
//It is strictly related to what's done at then end of the paintEvent
- if (dy > 0 && d->horizontalHeader->isHidden() && d->verticalScrollMode == ScrollPerItem) {
+ if (dy > 0 && d->horizontalHeader->isHidden()) {
d->viewport->update(0, dy, d->viewport->width(), dy);
}
- if (dx > 0 && d->verticalHeader->isHidden() && d->horizontalScrollMode == ScrollPerItem) {
+ if (dx > 0 && d->verticalHeader->isHidden()) {
d->viewport->update(dx, 0, dx, d->viewport->height());
}
}
@@ -1504,10 +1516,26 @@ void QTableView::paintEvent(QPaintEvent *event)
//draw the top & left grid lines if the headers are not visible.
//We do update this line when subsequent scroll happen (see scrollContentsBy)
- if (horizontalHeader->isHidden() && verticalScrollMode() == ScrollPerItem)
- painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
- if (verticalHeader->isHidden() && horizontalScrollMode() == ScrollPerItem)
- painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
+ if (horizontalHeader->isHidden() && top == 0) {
+ const int row = verticalHeader->logicalIndex(top);
+ if (!verticalHeader->isSectionHidden(row)) {
+ const int rowY = rowViewportPosition(row) + offset.y();
+ if (rowY == dirtyArea.top())
+ painter.drawLine(dirtyArea.left(), rowY, dirtyArea.right(), rowY);
+ }
+ }
+ if (verticalHeader->isHidden() && left == 0) {
+ const int col = horizontalHeader->logicalIndex(left);
+ if (!horizontalHeader->isSectionHidden(col)) {
+ int colX = columnViewportPosition(col) + offset.x();
+ if (!isLeftToRight())
+ colX += columnWidth(left) - 1;
+ if (isLeftToRight() && colX == dirtyArea.left())
+ painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
+ if (!isLeftToRight() && colX == dirtyArea.right())
+ painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
+ }
+ }
painter.setPen(old);
}
}
@@ -2194,6 +2222,7 @@ void QTableView::updateGeometries()
verticalScrollBar()->setRange(0, verticalLength - vsize.height());
verticalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
}
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
d->geometryRecursionBlock = false;
QAbstractItemView::updateGeometries();
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 9d5a2aa1bd..11925af7a0 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -453,17 +453,20 @@ bool QTableModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
QTableWidget *view = qobject_cast<QTableWidget*>(QObject::parent());
QTableWidgetItem *itm = item(index);
if (itm) {
- itm->view = 0; // prohibits item from calling itemChanged()
- bool changed = false;
+ itm->view = nullptr; // prohibits item from calling itemChanged()
+ QVector<int> rolesVec;
for (QMap<int, QVariant>::ConstIterator it = roles.constBegin(); it != roles.constEnd(); ++it) {
- if (itm->data(it.key()) != it.value()) {
- itm->setData(it.key(), it.value());
- changed = true;
+ const int role = (it.key() == Qt::EditRole ? Qt::DisplayRole : it.key());
+ if (itm->data(role) != it.value()) {
+ itm->setData(role, it.value());
+ rolesVec += role;
+ if (role == Qt::DisplayRole)
+ rolesVec += Qt::EditRole;
}
}
itm->view = view;
- if (changed)
- itemChanged(itm);
+ if (!rolesVec.isEmpty())
+ itemChanged(itm, rolesVec);
return true;
}
@@ -506,7 +509,7 @@ void QTableModel::sort(int column, Qt::SortOrder order)
unsortable.append(row);
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sortable.begin(), sortable.end(), compare);
QVector<QTableWidgetItem*> sorted_table(tableItems.count());
@@ -558,7 +561,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
sorting.append(QPair<QTableWidgetItem*,int>(itm, row));
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes, newPersistentIndexes;
QVector<QTableWidgetItem*> newTable = tableItems;
@@ -771,7 +774,7 @@ void QTableModel::clearContents()
endResetModel();
}
-void QTableModel::itemChanged(QTableWidgetItem *item)
+void QTableModel::itemChanged(QTableWidgetItem *item, const QVector<int> &roles)
{
if (!item)
return;
@@ -787,7 +790,7 @@ void QTableModel::itemChanged(QTableWidgetItem *item)
} else {
QModelIndex idx = index(item);
if (idx.isValid())
- emit dataChanged(idx, idx);
+ emit dataChanged(idx, idx, roles);
}
}
@@ -1386,8 +1389,13 @@ void QTableWidgetItem::setData(int role, const QVariant &value)
}
if (!found)
values.append(QWidgetItemData(role, value));
- if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : 0))
- model->itemChanged(this);
+ if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : nullptr))
+ {
+ const QVector<int> roles((role == Qt::DisplayRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
+ model->itemChanged(this, roles);
+ }
}
/*!
@@ -2595,7 +2603,7 @@ QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*> items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
cachedIndexes.reserve(items.count());
- foreach (QTableWidgetItem *item, items)
+ for (QTableWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
QMimeData *result = d->tableModel()->internalMimeData();
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index 7322e3aed7..9de27d164f 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -302,6 +302,7 @@ Q_SIGNALS:
void itemActivated(QTableWidgetItem *item);
void itemEntered(QTableWidgetItem *item);
+ // ### Qt 6: add changed roles
void itemChanged(QTableWidgetItem *item);
void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous);
diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h
index 6412477be0..9899272fce 100644
--- a/src/widgets/itemviews/qtablewidget_p.h
+++ b/src/widgets/itemviews/qtablewidget_p.h
@@ -62,9 +62,6 @@ QT_REQUIRE_CONFIG(tablewidget);
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug
-typedef bool(*LessThan)(const QPair<QTableWidgetItem*,int>&,const QPair<QTableWidgetItem*,int>&);
-
class QTableWidgetMimeData : public QMimeData
{
Q_OBJECT
@@ -160,7 +157,7 @@ public:
void clear();
void clearContents();
- void itemChanged(QTableWidgetItem *item);
+ void itemChanged(QTableWidgetItem *item, const QVector<int> &roles = QVector<int>());
QTableWidgetItem *createItem() const;
const QTableWidgetItem *itemPrototype() const;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index fbfbe56246..b339fe0f3b 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -632,11 +632,8 @@ bool QTreeView::isFirstColumnSpanned(int row, const QModelIndex &parent) const
Q_D(const QTreeView);
if (d->spanningIndexes.isEmpty() || !d->model)
return false;
- QModelIndex index = d->model->index(row, 0, parent);
- for (int i = 0; i < d->spanningIndexes.count(); ++i)
- if (d->spanningIndexes.at(i) == index)
- return true;
- return false;
+ const QModelIndex index = d->model->index(row, 0, parent);
+ return d->spanningIndexes.contains(index);
}
/*!
@@ -653,20 +650,14 @@ void QTreeView::setFirstColumnSpanned(int row, const QModelIndex &parent, bool s
Q_D(QTreeView);
if (!d->model)
return;
- QModelIndex index = d->model->index(row, 0, parent);
+ const QModelIndex index = d->model->index(row, 0, parent);
if (!index.isValid())
return;
- if (span) {
- QPersistentModelIndex persistent(index);
- if (!d->spanningIndexes.contains(persistent))
- d->spanningIndexes.append(persistent);
- } else {
- QPersistentModelIndex persistent(index);
- int i = d->spanningIndexes.indexOf(persistent);
- if (i >= 0)
- d->spanningIndexes.remove(i);
- }
+ if (span)
+ d->spanningIndexes.insert(index);
+ else
+ d->spanningIndexes.remove(index);
d->executePostedLayout();
int i = d->viewIndex(index);
@@ -1420,7 +1411,7 @@ QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList
if (spanningIndexes.isEmpty())
return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);
QModelIndexList list;
- foreach (const QModelIndex &idx, indexes) {
+ for (const QModelIndex &idx : indexes) {
if (idx.column() > 0 && q->isFirstColumnSpanned(idx.row(), idx.parent()))
continue;
list << idx;
@@ -2000,19 +1991,21 @@ void QTreeView::keyPressEvent(QKeyEvent *event)
if (d->isIndexValid(current) && d->model && d->itemsExpandable) {
switch (event->key()) {
case Qt::Key_Asterisk: {
+ // do layouting only once after expanding is done
+ d->doDelayedItemsLayout();
QStack<QModelIndex> parents;
parents.push(current);
- while (!parents.isEmpty()) {
- QModelIndex parent = parents.pop();
- for (int row = 0; row < d->model->rowCount(parent); ++row) {
- QModelIndex child = d->model->index(row, 0, parent);
- if (!d->isIndexValid(child))
- break;
- parents.push(child);
- expand(child);
- }
+ while (!parents.isEmpty()) {
+ QModelIndex parent = parents.pop();
+ for (int row = 0; row < d->model->rowCount(parent); ++row) {
+ QModelIndex child = d->model->index(row, 0, parent);
+ if (!d->isIndexValid(child))
+ break;
+ parents.push(child);
+ expand(child);
}
- expand(current);
+ }
+ expand(current);
break; }
case Qt::Key_Plus:
expand(current);
@@ -2495,7 +2488,6 @@ void QTreeView::scrollContentsBy(int dx, int dy)
int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy)
int currentViewIndex = currentScrollbarValue; // the first visible item
int previousViewIndex = previousScrollbarValue;
- const QVector<QTreeViewItem> viewItems = d->viewItems;
dy = 0;
if (previousViewIndex < currentViewIndex) { // scrolling down
for (int i = previousViewIndex; i < currentViewIndex; ++i) {
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 9a391ee88a..8b217036a2 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -247,7 +247,7 @@ public:
void updateIndentationFromStyle();
// used for spanning rows
- QVector<QPersistentModelIndex> spanningIndexes;
+ QSet<QPersistentModelIndex> spanningIndexes;
// used for updating resized columns
int columnResizeTimerID;
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 654c241079..d0728b1af2 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -52,9 +52,6 @@
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug (?)
-typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&);
-
class QTreeModelLessThan
{
public:
@@ -610,7 +607,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
sorting[i].second = start + i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes;
@@ -777,7 +774,7 @@ bool QTreeModel::isChanging() const
if column is -1 then all columns have changed
*/
-void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
+void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles)
{
if (signalsBlocked())
return;
@@ -800,7 +797,7 @@ void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
topLeft = index(item, column);
bottomRight = topLeft;
}
- emit dataChanged(topLeft, bottomRight);
+ emit dataChanged(topLeft, bottomRight, roles);
}
void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count)
@@ -850,7 +847,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO
}
// do the sorting
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromList;
@@ -1004,7 +1001,6 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
*/
/*!
- \fn void QTreeWidgetItem::setHidden(bool hide)
\since 4.2
Hides the item if \a hide is true, otherwise shows the item.
@@ -1015,6 +1011,14 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa isHidden()
*/
+void QTreeWidgetItem::setHidden(bool ahide)
+{
+ if (view) {
+ view->setItemHidden(this, ahide);
+ d->hidden = ahide;
+ }
+}
+
/*!
\fn bool QTreeWidgetItem::isHidden() const
\since 4.2
@@ -1024,6 +1028,11 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa setHidden()
*/
+bool QTreeWidgetItem::isHidden() const
+{
+ return (view ? d->hidden : false);
+}
+
/*!
\fn void QTreeWidgetItem::setExpanded(bool expand)
\since 4.2
@@ -1651,6 +1660,25 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
itemChanged();
}
+void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
+{
+ QTreeModel *model = (item->view ? qobject_cast<QTreeModel*>(item->view->model()) : 0);
+ if (!model)
+ return;
+ QStack<QTreeWidgetItem *> parents;
+ parents.push(item);
+ while (!parents.isEmpty()) {
+ QTreeWidgetItem *parent = parents.pop();
+ QModelIndex index = model->index(parent, 0);
+ if (parent->d->hidden)
+ item->view->setRowHidden(index.row(), index.parent(), inserting);
+ for (int i = 0; i < parent->children.count(); ++i) {
+ QTreeWidgetItem *child = parent->children.at(i);
+ parents.push(child);
+ }
+ }
+}
+
void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
{
Q_ASSERT(item);
@@ -1766,11 +1794,14 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
}
if (model) {
- model->emitDataChanged(this, column);
+ const QVector<int> roles((role == Qt::DisplayRole || role == Qt::EditRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
+ model->emitDataChanged(this, column, roles);
if (role == Qt::CheckStateRole) {
QTreeWidgetItem *p;
for (p = par; p && (p->itemFlags & Qt::ItemIsAutoTristate); p = p->par)
- model->emitDataChanged(p, column);
+ model->emitDataChanged(p, column, roles);
}
}
}
@@ -1937,6 +1968,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
stack.push(i->children.at(c));
}
children.insert(index, child);
+ d->updateHiddenStatus(child, true);
model->endInsertItems();
model->skipPendingSort = wasSkipSort;
} else {
@@ -1974,6 +2006,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
}
if (index >= 0 && index < children.count()) {
if (model) model->beginRemoveItems(this, index, 1);
+ d->updateHiddenStatus(children.at(index), false);
QTreeWidgetItem *item = children.takeAt(index);
item->par = 0;
QStack<QTreeWidgetItem*> stack;
@@ -2052,6 +2085,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
this->children.insert(index + n, child);
if (child->par)
d->propagateDisabled(child);
+ d->updateHiddenStatus(child, true);
}
if (model) model->endInsertItems();
}
@@ -3099,6 +3133,8 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
*/
void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
{
+ if (!item)
+ return;
Q_D(QTreeWidget);
if (item == d->treeModel()->headerItem) {
header()->setHidden(hide);
@@ -3106,6 +3142,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
const QModelIndex index = d->index(item);
setRowHidden(index.row(), index.parent(), hide);
}
+ item->d->hidden = hide;
}
/*!
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
index a31af0428a..975f208702 100644
--- a/src/widgets/itemviews/qtreewidget.h
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -82,8 +82,8 @@ public:
inline void setSelected(bool select);
inline bool isSelected() const;
- inline void setHidden(bool hide);
- inline bool isHidden() const;
+ void setHidden(bool hide);
+ bool isHidden() const;
inline void setExpanded(bool expand);
inline bool isExpanded() const;
@@ -339,6 +339,7 @@ Q_SIGNALS:
void itemDoubleClicked(QTreeWidgetItem *item, int column);
void itemActivated(QTreeWidgetItem *item, int column);
void itemEntered(QTreeWidgetItem *item, int column);
+ // ### Qt 6: add changed roles
void itemChanged(QTreeWidgetItem *item, int column);
void itemExpanded(QTreeWidgetItem *item);
void itemCollapsed(QTreeWidgetItem *item);
@@ -409,12 +410,6 @@ inline void QTreeWidgetItem::setSelected(bool aselect)
inline bool QTreeWidgetItem::isSelected() const
{ return (view ? view->isItemSelected(this) : false); }
-inline void QTreeWidgetItem::setHidden(bool ahide)
-{ if (view) view->setItemHidden(this, ahide); }
-
-inline bool QTreeWidgetItem::isHidden() const
-{ return (view ? view->isItemHidden(this) : false); }
-
inline void QTreeWidgetItem::setExpanded(bool aexpand)
{ if (view) view->setItemExpanded(this, aexpand); }
diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h
index f4625842ef..adc2c2c421 100644
--- a/src/widgets/itemviews/qtreewidget_p.h
+++ b/src/widgets/itemviews/qtreewidget_p.h
@@ -139,7 +139,7 @@ public:
protected:
QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = 0);
- void emitDataChanged(QTreeWidgetItem *item, int column);
+ void emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles);
void beginInsertItems(QTreeWidgetItem *parent, int row, int count);
void endInsertItems();
void beginRemoveItems(QTreeWidgetItem *parent, int row, int count);
@@ -187,13 +187,16 @@ class QTreeWidgetItemPrivate
{
public:
QTreeWidgetItemPrivate(QTreeWidgetItem *item)
- : q(item), disabled(false), selected(false), rowGuess(-1), policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
+ : q(item), disabled(false), selected(false), hidden(false), rowGuess(-1),
+ policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
void propagateDisabled(QTreeWidgetItem *item);
+ void updateHiddenStatus(QTreeWidgetItem *item, bool inserting);
void sortChildren(int column, Qt::SortOrder order, bool climb);
QTreeWidgetItem *q;
QVariantList display;
uint disabled : 1;
uint selected : 1;
+ uint hidden : 1;
int rowGuess;
QTreeWidgetItem::ChildIndicatorPolicy policy;
};
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 1bdcecbc81..c2f6e4ce75 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -35,7 +35,8 @@ HEADERS += \
kernel/qgesturemanager_p.h \
kernel/qdesktopwidget_p.h \
kernel/qwidgetwindow_p.h \
- kernel/qwindowcontainer_p.h
+ kernel/qwindowcontainer_p.h \
+ kernel/qtestsupport_widgets.h
SOURCES += \
kernel/qaction.cpp \
@@ -60,7 +61,8 @@ SOURCES += \
kernel/qdesktopwidget.cpp \
kernel/qwidgetsvariant.cpp \
kernel/qwidgetwindow.cpp \
- kernel/qwindowcontainer.cpp
+ kernel/qwindowcontainer.cpp \
+ kernel/qtestsupport_widgets.cpp
macx: {
HEADERS += kernel/qmacgesturerecognizer_p.h
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index ba315d4338..581b7c9c94 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -110,6 +110,8 @@
#include <qpa/qplatformwindow.h>
+#include <qtwidgets_tracepoints_p.h>
+
//#define ALIEN_DEBUG
static void initResources()
@@ -1025,17 +1027,17 @@ QString QApplication::styleSheet() const
void QApplication::setStyleSheet(const QString& styleSheet)
{
QApplicationPrivate::styleSheet = styleSheet;
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
+ QStyleSheetStyle *styleSheetStyle = qt_styleSheet(QApplicationPrivate::app_style);
if (styleSheet.isEmpty()) { // application style sheet removed
- if (!proxy)
+ if (!styleSheetStyle)
return; // there was no stylesheet before
- setStyle(proxy->base);
- } else if (proxy) { // style sheet update, just repolish
- proxy->repolish(qApp);
+ setStyle(styleSheetStyle->base);
+ } else if (styleSheetStyle) { // style sheet update, just repolish
+ styleSheetStyle->repolish(qApp);
} else { // stylesheet set the first time
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
- QApplicationPrivate::app_style->setParent(newProxy);
- setStyle(newProxy);
+ QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(QApplicationPrivate::app_style);
+ QApplicationPrivate::app_style->setParent(newStyleSheetStyle);
+ setStyle(newStyleSheetStyle);
}
}
@@ -1145,11 +1147,11 @@ void QApplication::setStyle(QStyle *style)
QStyle *old = QApplicationPrivate::app_style; // save
#ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
+ if (!QApplicationPrivate::styleSheet.isEmpty() && !qt_styleSheet(style)) {
// we have a stylesheet already and a new style is being set
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
- style->setParent(newProxy);
- QApplicationPrivate::app_style = newProxy;
+ QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(style);
+ style->setParent(newStyleSheetStyle);
+ QApplicationPrivate::app_style = newStyleSheetStyle;
} else
#endif // QT_NO_STYLE_STYLESHEET
QApplicationPrivate::app_style = style;
@@ -1199,8 +1201,8 @@ void QApplication::setStyle(QStyle *style)
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
- oldProxy->deref();
+ if (QStyleSheetStyle *oldStyleSheetStyle = qt_styleSheet(old)) {
+ oldStyleSheetStyle->deref();
} else
#endif
if (old && old->parent() == qApp) {
@@ -2627,7 +2629,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QWidget *alienWidget, QWidget *nativeWidget,
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous)
+ bool spontaneous, bool onlyDispatchEnterLeave)
{
Q_ASSERT(receiver);
Q_ASSERT(event);
@@ -2688,11 +2690,17 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
// We need this quard in case someone opens a modal dialog / popup. If that's the case
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
- bool result;
- if (spontaneous)
- result = QApplication::sendSpontaneousEvent(receiver, event);
- else
- result = QApplication::sendEvent(receiver, event);
+ bool result = true;
+ // This code is used for sending the synthetic enter/leave events for cases where it is needed
+ // due to other events causing the widget under the mouse to change. However in those cases
+ // we do not want to send the mouse event associated with this call, so this enables us to
+ // not send the unneeded mouse event
+ if (!onlyDispatchEnterLeave) {
+ if (spontaneous)
+ result = QApplication::sendSpontaneousEvent(receiver, event);
+ else
+ result = QApplication::sendEvent(receiver, event);
+ }
if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
@@ -2767,9 +2775,10 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
if (widget->data->in_destructor && qt_button_down == widget)
qt_button_down = 0;
- // Send enter/leave events followed by a mouse move on the entered widget.
+ // A mouse move is not actually sent, but we utilize the sendMouseEvent() call to send the
+ // enter/leave events as appropriate
QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
- sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
+ sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver, true, true);
#else // !QT_NO_CURSOR
Q_UNUSED(widget);
#endif // QT_NO_CURSOR
@@ -2947,8 +2956,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->checkReceiverThread(receiver);
#endif
- if (receiver->isWindowType())
- QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(receiver), e);
+ if (receiver->isWindowType()) {
+ if (QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(receiver), e))
+ return true; // Platform plugin ate the event
+ }
if(e->spontaneous()) {
// Capture the current mouse and keyboard states. Doing so here is
@@ -3288,6 +3299,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), phase, wheel->source(), wheel->inverted());
+ we.setTimestamp(wheel->timestamp());
bool eventAccepted;
do {
we.spont = spontaneous && w == receiver;
@@ -3324,6 +3336,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos());
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), wheel->phase(), wheel->source());
+ we.setTimestamp(wheel->timestamp());
we.spont = true;
we.ignore();
d->notify_helper(QApplicationPrivate::wheel_widget, &we);
@@ -3649,7 +3662,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
break;
w = w->parentWidget();
}
- foreach (QGesture *g, allGestures)
+ for (QGesture *g : qAsConst(allGestures))
gestureEvent->setAccepted(g, false);
gestureEvent->m_accept = false; // to make sure we check individual gestures
} else {
@@ -3696,11 +3709,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
{
+ // These tracepoints (and the whole function, actually) are very similar
+ // to the ones in QCoreApplicationPrivate::notify_helper; the reason for their
+ // duplication is because tracepoint symbols are not exported by QtCore.
+ // If you adjust the tracepoints here, consider adjusting QCoreApplicationPrivate too.
+ Q_TRACE(QApplication_notify_entry, receiver, e, e->type());
+
// send to all application event filters
if (threadRequiresCoreApplication()
&& receiver->d_func()->threadData->thread == mainThread()
- && sendThroughApplicationEventFilters(receiver, e))
+ && sendThroughApplicationEventFilters(receiver, e)) {
+ Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type());
return true;
+ }
if (receiver->isWidgetType()) {
QWidget *widget = static_cast<QWidget *>(receiver);
@@ -3720,11 +3741,18 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
}
// send to all receiver event filters
- if (sendThroughObjectEventFilters(receiver, e))
+ if (sendThroughObjectEventFilters(receiver, e)) {
+ Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type());
return true;
+ }
+
+ Q_TRACE(QApplication_notify_before_delivery, receiver, e, e->type());
// deliver the event
- bool consumed = receiver->event(e);
+ const bool consumed = receiver->event(e);
+
+ Q_TRACE(QApplication_notify_after_delivery, receiver, e, e->type(), consumed);
+
QCoreApplicationPrivate::setEventSpontaneous(e, false);
return consumed;
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 488ca6cbfd..2d9468cc21 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -226,7 +226,7 @@ public:
QWidget *buttonDown, QWidget *alienWidget);
static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous = true);
+ bool spontaneous = true, bool onlyDispatchEnterLeave = false);
void sendSyntheticEnterLeave(QWidget *widget);
static QWindow *windowForWidget(const QWidget *widget)
diff --git a/src/widgets/kernel/qgesture.cpp b/src/widgets/kernel/qgesture.cpp
index 7f8bf18e90..fc715687c6 100644
--- a/src/widgets/kernel/qgesture.cpp
+++ b/src/widgets/kernel/qgesture.cpp
@@ -916,7 +916,7 @@ QGesture *QGestureEvent::gesture(Qt::GestureType type) const
QList<QGesture *> QGestureEvent::activeGestures() const
{
QList<QGesture *> gestures;
- foreach (QGesture *gesture, m_gestures) {
+ for (QGesture *gesture : m_gestures) {
if (gesture->state() != Qt::GestureCanceled)
gestures.append(gesture);
}
@@ -929,7 +929,7 @@ QList<QGesture *> QGestureEvent::activeGestures() const
QList<QGesture *> QGestureEvent::canceledGestures() const
{
QList<QGesture *> gestures;
- foreach (QGesture *gesture, m_gestures) {
+ for (QGesture *gesture : m_gestures) {
if (gesture->state() == Qt::GestureCanceled)
gestures.append(gesture);
}
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 9ce1c1c2d4..80ea27fee8 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -1246,6 +1246,26 @@ int QLayout::indexOf(QWidget *widget) const
}
/*!
+ \since 5.12
+ Searches for layout item \a layoutItem in this layout (not including child
+ layouts).
+
+ Returns the index of \a layoutItem, or -1 if \a layoutItem is not found.
+*/
+int QLayout::indexOf(QLayoutItem *layoutItem) const
+{
+ int i = 0;
+ QLayoutItem *item = itemAt(i);
+ while (item) {
+ if (item == layoutItem)
+ return i;
+ ++i;
+ item = itemAt(i);
+ }
+ return -1;
+}
+
+/*!
\enum QLayout::SizeConstraint
The possible values are:
diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h
index bcc33a0811..616f4e7164 100644
--- a/src/widgets/kernel/qlayout.h
+++ b/src/widgets/kernel/qlayout.h
@@ -122,6 +122,7 @@ public:
virtual QLayoutItem *itemAt(int index) const = 0;
virtual QLayoutItem *takeAt(int index) = 0;
virtual int indexOf(QWidget *) const;
+ QT6_VIRTUAL int indexOf(QLayoutItem *) const;
virtual int count() const = 0;
bool isEmpty() const override;
QSizePolicy::ControlTypes controlTypes() const override;
diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h
index e381a6cc2f..739fc201b7 100644
--- a/src/widgets/kernel/qmacgesturerecognizer_p.h
+++ b/src/widgets/kernel/qmacgesturerecognizer_p.h
@@ -66,9 +66,9 @@ class QMacSwipeGestureRecognizer : public QGestureRecognizer
public:
QMacSwipeGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
};
class QMacPinchGestureRecognizer : public QGestureRecognizer
@@ -76,9 +76,9 @@ class QMacPinchGestureRecognizer : public QGestureRecognizer
public:
QMacPinchGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
};
class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
@@ -86,9 +86,9 @@ class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
public:
QMacPanGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
protected:
void timerEvent(QTimerEvent *ev) override;
private:
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index c96b6812c4..51e78ec765 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -938,7 +938,8 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer()
q->makeCurrent();
}
- QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), false, false);
+ const bool hasAlpha = q->format().hasAlpha();
+ QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), hasAlpha, hasAlpha);
res.setDevicePixelRatio(q->devicePixelRatioF());
// While we give no guarantees of what is going to be left bound, prefer the
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index fde039c75e..a680ff7913 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -149,8 +149,16 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge
bool visible = w->isVisible();
#if QT_CONFIG(menubar)
if (QMenuBar *menuBar = qobject_cast<QMenuBar *>(w)) {
- if (menuBar->isNativeMenuBar())
- visible = true;
+ if (auto *pmb = menuBar->platformMenuBar()) {
+ if (menuBar->parentWidget()) {
+ visible = true;
+ } else {
+ if (auto *ww = qobject_cast<QWidgetWindow *>(pmb->parentWindow()))
+ w = ww->widget(); // Good enough since we only care about the window
+ else
+ return false; // This is not a QWidget window. We won't deliver
+ }
+ }
}
#endif
diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp
new file mode 100644
index 0000000000..b227e6ff5d
--- /dev/null
+++ b/src/widgets/kernel/qtestsupport_widgets.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestsupport_widgets.h"
+
+#include "qwidget.h"
+
+#include <QtGui/qwindow.h>
+#include <QtGui/qtestsupport_gui.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \fn bool qWaitForWindowActive(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is active.
+
+ Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
+
+ \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
+*/
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
+{
+ if (QWindow *window = widget->window()->windowHandle())
+ return QTest::qWaitForWindowActive(window, timeout);
+ return false;
+}
+
+/*! \fn bool qWaitForWindowExposed(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen.
+
+ Note that a window that is mapped to screen may still not be considered exposed if the window client
+ area is completely covered by other windows, or if the window is otherwise not visible. This function
+ will then time out when waiting for such a window.
+
+ A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS:
+ The viewport widget gets the expose event, not the parent widget.
+
+ \sa QTest::qWaitForWindowActive()
+*/
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
+{
+ if (QWindow *window = widget->window()->windowHandle())
+ return QTest::qWaitForWindowExposed(window, timeout);
+ return false;
+}
+
+/*! \fn bool qWaitForWindowShown(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+ \deprecated
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This function does the same as qWaitForWindowExposed().
+
+ Example:
+
+ \code
+ QWidget widget;
+ widget.show();
+ QTest::qWaitForWindowShown(&widget);
+ \endcode
+
+ \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qtestsupport_widgets.h b/src/widgets/kernel/qtestsupport_widgets.h
new file mode 100644
index 0000000000..ca1406b0b2
--- /dev/null
+++ b/src/widgets/kernel/qtestsupport_widgets.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTSUPPORT_WIDGETS_H
+#define QTESTSUPPORT_WIDGETS_H
+
+#include "qtwidgetsglobal.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+namespace QTest {
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowActive(QWidget *widget, int timeout = 5000);
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowExposed(QWidget *widget, int timeout = 5000);
+
+#if QT_DEPRECATED_SINCE(5, 0)
+QT_DEPRECATED Q_REQUIRED_RESULT inline static bool qWaitForWindowShown(QWidget *widget, int timeout = 5000)
+{ return QTest::qWaitForWindowExposed(widget, timeout); }
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index ed7184302a..8c5573d3a3 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -123,11 +123,11 @@ class QTipLabel : public QLabel
{
Q_OBJECT
public:
- QTipLabel(const QString &text, QWidget *w, int msecDisplayTime);
+ QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime);
~QTipLabel();
static QTipLabel *instance;
- void updateSize();
+ void updateSize(const QPoint &pos);
bool eventFilter(QObject *, QEvent *) override;
@@ -135,7 +135,7 @@ public:
bool fadingOut;
- void reuseTip(const QString &text, int msecDisplayTime);
+ void reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos);
void hideTip();
void hideTipImmediately();
void setTipRect(QWidget *w, const QRect &r);
@@ -171,7 +171,7 @@ private:
QTipLabel *QTipLabel::instance = 0;
-QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
+QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime)
#ifndef QT_NO_STYLE_STYLESHEET
: QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0)
#else
@@ -192,7 +192,7 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
setMouseTracking(true);
fadingOut = false;
- reuseTip(text, msecDisplayTime);
+ reuseTip(text, msecDisplayTime, pos);
}
void QTipLabel::restartExpireTimer(int msecDisplayTime)
@@ -204,7 +204,7 @@ void QTipLabel::restartExpireTimer(int msecDisplayTime)
hideTimer.stop();
}
-void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
+void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos)
{
#ifndef QT_NO_STYLE_STYLESHEET
if (styleSheetParent){
@@ -214,20 +214,30 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
}
#endif
- setWordWrap(Qt::mightBeRichText(text));
+ setWordWrap(true);
setText(text);
- updateSize();
+ updateSize(pos);
restartExpireTimer(msecDisplayTime);
}
-void QTipLabel::updateSize()
+void QTipLabel::updateSize(const QPoint &pos)
{
QFontMetrics fm(font());
QSize extra(1, 0);
// Make it look good with the default ToolTip font on Mac, which has a small descent.
if (fm.descent() == 2 && fm.ascent() >= 11)
++extra.rheight();
- resize(sizeHint() + extra);
+ QSize sh = sizeHint();
+ if (wordWrap()) {
+ const QRect screenRect = QGuiApplication::screenAt(pos)->geometry();
+ if (sh.width() > screenRect.width()) {
+ // Try to use widely accepted 75chars max length or 80% of the screen width else.
+ // See https://en.wikipedia.org/wiki/Line_length
+ sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenRect.width() * .8)));
+ sh.setHeight(heightForWidth(sh.width()));
+ }
+ }
+ resize(sh + extra);
}
void QTipLabel::paintEvent(QPaintEvent *ev)
@@ -254,13 +264,13 @@ void QTipLabel::resizeEvent(QResizeEvent *e)
void QTipLabel::mouseMoveEvent(QMouseEvent *e)
{
- if (rect.isNull())
- return;
- QPoint pos = e->globalPos();
- if (widget)
- pos = widget->mapFromGlobal(pos);
- if (!rect.contains(pos))
- hideTip();
+ if (!rect.isNull()) {
+ QPoint pos = e->globalPos();
+ if (widget)
+ pos = widget->mapFromGlobal(pos);
+ if (!rect.contains(pos))
+ hideTip();
+ }
QLabel::mouseMoveEvent(e);
}
@@ -381,7 +391,7 @@ int QTipLabel::getTipScreen(const QPoint &pos, QWidget *w)
void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
{
#ifndef QT_NO_STYLE_STYLESHEET
- if (testAttribute(Qt::WA_StyleSheet) || (w && qobject_cast<QStyleSheetStyle *>(w->style()))) {
+ if (testAttribute(Qt::WA_StyleSheet) || (w && qt_styleSheet(w->style()))) {
//the stylesheet need to know the real parent
QTipLabel::instance->setProperty("_q_stylesheet_parent", QVariant::fromValue(w));
//we force the style to be the QStyleSheetStyle, and force to clear the cache as well.
@@ -394,7 +404,7 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
QTipLabel::instance, SLOT(styleSheetParentDestroyed()));
// QTBUG-64550: A font inherited by the style sheet might change the size,
// particular on Windows, where the tip is not parented on a window.
- QTipLabel::instance->updateSize();
+ QTipLabel::instance->updateSize(pos);
}
}
#endif //QT_NO_STYLE_STYLESHEET
@@ -497,7 +507,7 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (w)
localPos = w->mapFromGlobal(pos);
if (QTipLabel::instance->tipChanged(localPos, text, w)){
- QTipLabel::instance->reuseTip(text, msecDisplayTime);
+ QTipLabel::instance->reuseTip(text, msecDisplayTime, pos);
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
}
@@ -511,10 +521,10 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
// raised when the tooltip will be shown
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
- new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
+ new QTipLabel(text, pos, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
QT_WARNING_POP
#else
- new QTipLabel(text, w, msecDisplayTime); // sets QTipLabel::instance to itself
+ new QTipLabel(text, pos, w, msecDisplayTime); // sets QTipLabel::instance to itself
#endif
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp
index 96d0cf61c4..1fa83d3238 100644
--- a/src/widgets/kernel/qwhatsthis.cpp
+++ b/src/widgets/kernel/qwhatsthis.cpp
@@ -48,7 +48,9 @@
#include "qscreen.h"
#include "qpainter.h"
#include "qtimer.h"
+#if QT_CONFIG(action)
#include "qaction.h"
+#endif // QT_CONFIG(action)
#include "qcursor.h"
#include "qbitmap.h"
#include "qtextdocument.h"
@@ -366,7 +368,9 @@ class QWhatsThisPrivate : public QObject
~QWhatsThisPrivate();
static QWhatsThisPrivate *instance;
bool eventFilter(QObject *, QEvent *) override;
+#if QT_CONFIG(action)
QPointer<QAction> action;
+#endif // QT_CONFIG(action)
static void say(QWidget *, const QString &, int x = 0, int y = 0);
static void notifyToplevels(QEvent *e);
bool leaveOnMouseRelease;
@@ -408,8 +412,10 @@ QWhatsThisPrivate::QWhatsThisPrivate()
QWhatsThisPrivate::~QWhatsThisPrivate()
{
+#if QT_CONFIG(action)
if (action)
action->setChecked(false);
+#endif // QT_CONFIG(action)
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
@@ -485,6 +491,7 @@ bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e)
return true;
}
+#if QT_CONFIG(action)
class QWhatsThisAction: public QAction
{
Q_OBJECT
@@ -516,6 +523,7 @@ void QWhatsThisAction::actionTriggered()
QWhatsThisPrivate::instance->action = this;
}
}
+#endif // QT_CONFIG(action)
/*!
This function switches the user interface into "What's This?"
@@ -672,10 +680,12 @@ void QWhatsThis::hideText()
The returned QAction provides a convenient way to let users enter
"What's This?" mode.
*/
+#if QT_CONFIG(action)
QAction *QWhatsThis::createAction(QObject *parent)
{
return new QWhatsThisAction(parent);
}
+#endif // QT_CONFIG(action)
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwhatsthis.h b/src/widgets/kernel/qwhatsthis.h
index 1f0f82b2a2..59c0b01c9b 100644
--- a/src/widgets/kernel/qwhatsthis.h
+++ b/src/widgets/kernel/qwhatsthis.h
@@ -48,7 +48,9 @@ QT_REQUIRE_CONFIG(whatsthis);
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(action)
class QAction;
+#endif // QT_CONFIG(action)
class Q_WIDGETS_EXPORT QWhatsThis
{
@@ -62,7 +64,9 @@ public:
static void showText(const QPoint &pos, const QString &text, QWidget *w = nullptr);
static void hideText();
+#if QT_CONFIG(action)
static QAction *createAction(QObject *parent = nullptr);
+#endif // QT_CONFIG(action)
};
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 1e249dc191..0a4efc980c 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1849,7 +1849,7 @@ void QWidgetPrivate::deleteExtra()
deleteSysExtra();
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
+ if (QStyleSheetStyle *proxy = qt_styleSheet(extra->style))
proxy->deref();
#endif
if (extra->topextra) {
@@ -1905,19 +1905,21 @@ void QWidgetPrivate::deleteTLSysExtra()
}
/*
- Returns \c true if there are widgets above this which overlap with
+ Returns \c region of widgets above this which overlap with
\a rect, which is in parent's coordinate system (same as crect).
*/
-bool QWidgetPrivate::isOverlapped(const QRect &rect) const
+QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst) const
{
Q_Q(const QWidget);
const QWidget *w = q;
QRect r = rect;
+ QPoint p;
+ QRegion region;
while (w) {
if (w->isWindow())
- return false;
+ break;
QWidgetPrivate *pd = w->parentWidget()->d_func();
bool above = false;
for (int i = 0; i < pd->children.size(); ++i) {
@@ -1929,19 +1931,23 @@ bool QWidgetPrivate::isOverlapped(const QRect &rect) const
continue;
}
- if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
+ const QRect siblingRect = sibling->d_func()->effectiveRectFor(sibling->data->crect);
+ if (qRectIntersects(siblingRect, r)) {
const QWExtra *siblingExtra = sibling->d_func()->extra;
if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
continue;
}
- return true;
+ region += siblingRect.translated(-p);
+ if (breakAfterFirst)
+ break;
}
}
w = w->parentWidget();
r.translate(pd->data.crect.topLeft());
+ p += pd->data.crect.topLeft();
}
- return false;
+ return region;
}
void QWidgetPrivate::syncBackingStore()
@@ -2398,7 +2404,8 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrus
#endif
} else if (brush.gradient()
- && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
+ && (brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode
+ || brush.gradient()->coordinateMode() == QGradient::ObjectMode)) {
painter->save();
painter->setClipRegion(rgn);
painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
@@ -2659,7 +2666,7 @@ void QWidget::setStyleSheet(const QString& styleSheet)
return;
d->createExtra();
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
+ QStyleSheetStyle *proxy = qt_styleSheet(d->extra->style);
d->extra->styleSheet = styleSheet;
if (styleSheet.isEmpty()) { // stylesheet removed
if (!proxy)
@@ -2724,12 +2731,12 @@ void QWidget::setStyle(QStyle *style)
setAttribute(Qt::WA_SetStyle, style != 0);
d->createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
+ if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) {
//if for some reason someone try to set a QStyleSheetStyle, ref it
//(this may happen for exemple in QButtonDialogBox which propagates its style)
- proxy->ref();
+ styleSheetStyle->ref();
d->setStyle_helper(style, false);
- } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
+ } else if (qt_styleSheet(d->extra->style) || !qApp->styleSheet().isEmpty()) {
// if we have an application stylesheet or have a proxy already, propagate
d->setStyle_helper(new QStyleSheetStyle(style), true);
} else
@@ -2737,48 +2744,22 @@ void QWidget::setStyle(QStyle *style)
d->setStyle_helper(style, false);
}
-void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- metalHack
-#endif
- )
+void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
{
Q_Q(QWidget);
- QStyle *oldStyle = q->style();
-#ifndef QT_NO_STYLE_STYLESHEET
- QPointer<QStyle> origStyle;
-#endif
+ QStyle *oldStyle = q->style();
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
- // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
- // set when changing that attribute and passes the widget's CURRENT style.
- // therefore no need to do a reassignment.
- if (!metalHack)
-#endif
- {
- createExtra();
+ createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
- origStyle = extra->style.data();
+ QPointer<QStyle> origStyle = extra->style;
#endif
- extra->style = newStyle;
- }
+ extra->style = newStyle;
// repolish
- if (q->windowType() != Qt::Desktop) {
- if (polished) {
- oldStyle->unpolish(q);
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- if (metalHack)
- macUpdateMetalAttribute();
-#endif
- q->style()->polish(q);
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- } else if (metalHack) {
- macUpdateMetalAttribute();
-#endif
- }
+ if (polished && q->windowType() != Qt::Desktop) {
+ oldStyle->unpolish(q);
+ q->style()->polish(q);
}
if (propagate) {
@@ -2792,8 +2773,8 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
- if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
+ if (!qt_styleSheet(newStyle)) {
+ if (const QStyleSheetStyle* cssStyle = qt_styleSheet(origStyle)) {
cssStyle->clearWidgetFont(q);
}
}
@@ -2804,7 +2785,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the old stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
+ if (QStyleSheetStyle *proxy = qt_styleSheet(origStyle))
proxy->deref();
#endif
}
@@ -2815,7 +2796,9 @@ void QWidgetPrivate::inheritStyle()
#ifndef QT_NO_STYLE_STYLESHEET
Q_Q(QWidget);
- QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
+ QStyle *extraStyle = extra ? (QStyle*)extra->style : nullptr;
+
+ QStyleSheetStyle *proxy = qt_styleSheet(extraStyle);
if (!q->styleSheet().isEmpty()) {
Q_ASSERT(proxy);
@@ -2823,16 +2806,16 @@ void QWidgetPrivate::inheritStyle()
return;
}
- QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
+ QStyle *origStyle = proxy ? proxy->base : extraStyle;
QWidget *parent = q->parentWidget();
QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
// If we have stylesheet on app or parent has stylesheet style, we need
// to be running a proxy
- if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
+ if (!qApp->styleSheet().isEmpty() || qt_styleSheet(parentStyle)) {
QStyle *newStyle = parentStyle;
if (q->testAttribute(Qt::WA_SetStyle))
newStyle = new QStyleSheetStyle(origStyle);
- else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
+ else if (QStyleSheetStyle *newProxy = qt_styleSheet(parentStyle))
newProxy->ref();
setStyle_helper(newStyle, true);
@@ -2841,7 +2824,7 @@ void QWidgetPrivate::inheritStyle()
// So, we have no stylesheet on parent/app and we have an empty stylesheet
// we just need our original style back
- if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
+ if (origStyle == extraStyle) // is it any different?
return;
// We could have inherited the proxy from our parent (which has a custom style)
@@ -4690,9 +4673,8 @@ void QWidget::setFont(const QFont &font)
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* style;
- if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) {
+ if (d->extra && (style = qt_styleSheet(d->extra->style)))
style->saveWidgetFont(this, font);
- }
#endif
setAttribute(Qt::WA_SetFont, font.resolve() != 0);
@@ -4788,7 +4770,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
Q_Q(QWidget);
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* cssStyle;
- cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
+ cssStyle = extra ? qt_styleSheet(extra->style) : 0;
const bool useStyleSheetPropagationInWidgetStyles =
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
#endif
@@ -7381,7 +7363,8 @@ QByteArray QWidget::saveGeometry() const
// Version history:
// - Qt 4.2 - 4.8.6, 5.0 - 5.3 : Version 1.0
// - Qt 4.8.6 - today, 5.4 - today: Version 2.0, save screen width in addition to check for high DPI scaling.
- quint16 majorVersion = 2;
+ // - Qt 5.12 - today : Version 3.0, save QWidget::geometry()
+ quint16 majorVersion = 3;
quint16 minorVersion = 0;
const int screenNumber = QDesktopWidgetPrivate::screenNumber(this);
stream << magicNumber
@@ -7397,7 +7380,8 @@ QByteArray QWidget::saveGeometry() const
<< qint32(screenNumber)
<< quint8(windowState() & Qt::WindowMaximized)
<< quint8(windowState() & Qt::WindowFullScreen)
- << qint32(QDesktopWidgetPrivate::screenGeometry(screenNumber).width()); // 1.1 onwards
+ << qint32(QDesktopWidgetPrivate::screenGeometry(screenNumber).width()) // added in 2.0
+ << geometry(); // added in 3.0
return array;
}
@@ -7437,7 +7421,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (storedMagicNumber != magicNumber)
return false;
- const quint16 currentMajorVersion = 2;
+ const quint16 currentMajorVersion = 3;
quint16 majorVersion = 0;
quint16 minorVersion = 0;
@@ -7448,7 +7432,8 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
// (Allow all minor versions.)
QRect restoredFrameGeometry;
- QRect restoredNormalGeometry;
+ QRect restoredGeometry;
+ QRect restoredNormalGeometry;
qint32 restoredScreenNumber;
quint8 maximized;
quint8 fullScreen;
@@ -7462,6 +7447,10 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (majorVersion > 1)
stream >> restoredScreenWidth;
+ if (majorVersion > 2)
+ stream >> restoredGeometry;
+
+ // ### Qt 6 - Perhaps it makes sense to dumb down the restoreGeometry() logic, see QTBUG-69104
if (restoredScreenNumber >= QDesktopWidgetPrivate::numScreens())
restoredScreenNumber = QDesktopWidgetPrivate::primaryScreen();
@@ -7548,14 +7537,11 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
setWindowState(ws);
d_func()->topData()->normalGeometry = restoredNormalGeometry;
} else {
- QPoint offset;
-#if 0 // Used to be included in Qt4 for Q_WS_X11
- if (isFullScreen())
- offset = d_func()->topData()->fullScreenOffset;
-#endif
setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
- move(restoredFrameGeometry.topLeft() + offset);
- resize(restoredNormalGeometry.size());
+ if (majorVersion > 2)
+ setGeometry(restoredGeometry);
+ else
+ setGeometry(restoredNormalGeometry);
}
return true;
}
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index 9f9f167002..9d5fe89c70 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -714,6 +714,7 @@ private:
friend class QWidgetWindow;
friend class QAccessibleWidget;
friend class QAccessibleTable;
+ friend class QAccessibleTabButton;
#ifndef QT_NO_GESTURES
friend class QGestureManager;
friend class QWinNativePanGestureRecognizer;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index e8b550b1cd..20c4a682ed 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -395,7 +395,7 @@ public:
void setLocale_helper(const QLocale &l, bool forceUpdate = false);
void resolveLocale();
- void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false);
+ void setStyle_helper(QStyle *newStyle, bool propagate);
void inheritStyle();
void setUpdatesEnabled_helper(bool );
@@ -453,7 +453,7 @@ public:
// ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
void invalidateBuffer(const QRegion &);
void invalidateBuffer(const QRect &);
- bool isOverlapped(const QRect&) const;
+ QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
void syncBackingStore();
void syncBackingStore(const QRegion &region);
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 3b093283cd..cbf949be92 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -59,6 +59,7 @@
#include <private/qgraphicseffect_p.h>
#endif
#include <QtGui/private/qwindow_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformbackingstore.h>
@@ -793,6 +794,25 @@ QWidgetBackingStore::~QWidgetBackingStore()
delete dirtyOnScreenWidgets;
}
+static QVector<QRect> getSortedRectsToScroll(const QRegion &region, int dx, int dy)
+{
+ QVector<QRect> rects;
+ std::copy(region.begin(), region.end(), std::back_inserter(rects));
+ if (rects.count() > 1) {
+ std::sort(rects.begin(), rects.end(), [=](const QRect &r1, const QRect &r2) {
+ if (r1.y() == r2.y()) {
+ if (dx > 0)
+ return r1.x() > r2.x();
+ return r1.x() < r2.x();
+ }
+ if (dy > 0)
+ return r1.y() > r2.y();
+ return r1.y() < r2.y();
+ });
+ }
+ return rects;
+}
+
//parent's coordinates; move whole rect; update parent and widget
//assume the screen blt has already been done, so we don't need to refresh that part
void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
@@ -820,12 +840,12 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
const QRect parentRect(rect & clipR);
const bool nativeWithTextureChild = textureChildSeen && q->internalWinId();
- bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
+ const bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
#if QT_CONFIG(graphicsview)
// No accelerate move for proxy widgets.
&& !tlw->d_func()->extra->proxyWidget
#endif
- && !isOverlapped(sourceRect) && !isOverlapped(destRect);
+ ;
if (!accelerateMove) {
QRegion parentR(effectiveRectFor(parentRect));
@@ -841,18 +861,39 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
QWidgetBackingStore *wbs = x->backingStoreTracker.data();
QRegion childExpose(newRect & clipR);
+ QRegion overlappedExpose;
- if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw))
- childExpose -= destRect;
+ if (sourceRect.isValid()) {
+ overlappedExpose = (overlappedRegion(sourceRect) | overlappedRegion(destRect)) & clipR;
+
+ const qreal factor = QHighDpiScaling::factor(q->windowHandle());
+ if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
+ const QVector<QRect> rectsToScroll
+ = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
+ for (QRect rect : rectsToScroll) {
+ if (wbs->bltRect(rect, dx, dy, pw)) {
+ childExpose -= rect.translated(dx, dy);
+ }
+ }
+ }
+
+ childExpose -= overlappedExpose;
+ }
if (!pw->updatesEnabled())
return;
const bool childUpdatesEnabled = q->updatesEnabled();
- if (childUpdatesEnabled && !childExpose.isEmpty()) {
- childExpose.translate(-data.crect.topLeft());
- wbs->markDirty(childExpose, q);
- isMoved = true;
+ if (childUpdatesEnabled) {
+ if (!overlappedExpose.isEmpty()) {
+ overlappedExpose.translate(-data.crect.topLeft());
+ invalidateBuffer(overlappedExpose);
+ }
+ if (!childExpose.isEmpty()) {
+ childExpose.translate(-data.crect.topLeft());
+ wbs->markDirty(childExpose, q);
+ isMoved = true;
+ }
}
QRegion parentExpose(parentRect);
@@ -888,13 +929,12 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_SCROLL") == 0;
- QRect scrollRect = rect & clipRect();
- bool overlapped = false;
- bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent)
- && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
+ const QRect clipR = clipRect();
+ const QRect scrollRect = rect & clipR;
+ const bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent);
if (!accelerateScroll) {
- if (overlapped) {
+ if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) {
QRegion region(scrollRect);
subtractOpaqueSiblings(region);
invalidateBuffer(region);
@@ -906,12 +946,23 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
const QRect sourceRect = destRect.translated(-dx, -dy);
+ const QRegion overlappedExpose = (overlappedRegion(scrollRect.translated(data.crect.topLeft())))
+ .translated(-data.crect.topLeft()) & clipR;
QRegion childExpose(scrollRect);
- if (sourceRect.isValid()) {
- if (wbs->bltRect(sourceRect, dx, dy, q))
- childExpose -= destRect;
+
+ const qreal factor = QHighDpiScaling::factor(q->windowHandle());
+ if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
+ const QVector<QRect> rectsToScroll
+ = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
+ for (const QRect &rect : rectsToScroll) {
+ if (wbs->bltRect(rect, dx, dy, q)) {
+ childExpose -= rect.translated(dx, dy);
+ }
+ }
}
+ childExpose -= overlappedExpose;
+
if (inDirtyList) {
if (rect == q->rect()) {
dirty.translate(dx, dy);
@@ -928,6 +979,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
if (!q->updatesEnabled())
return;
+ if (!overlappedExpose.isEmpty())
+ invalidateBuffer(overlappedExpose);
if (!childExpose.isEmpty()) {
wbs->markDirty(childExpose, q);
isScrolled = true;
@@ -991,7 +1044,7 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
}
}
- if (QWidgetPrivate::get(tlw)->textureChildSeen) {
+ if (QWidgetPrivate::get(widget)->textureChildSeen) {
// No render-to-texture widgets in the (sub-)tree due to hidden or native
// children. Returning null results in using the normal backingstore flush path
// without OpenGL-based compositing. This is very desirable normally. However,
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 1f3057b008..1c73588b7c 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -311,8 +311,10 @@ bool QWidgetWindow::event(QEvent *event)
#if QT_CONFIG(draganddrop)
case QEvent::DragEnter:
+ handleDragEnterEvent(static_cast<QDragEnterEvent *>(event));
+ return true;
case QEvent::DragMove:
- handleDragEnterMoveEvent(static_cast<QDragMoveEvent *>(event));
+ handleDragMoveEvent(static_cast<QDragMoveEvent *>(event));
return true;
case QEvent::DragLeave:
handleDragLeaveEvent(static_cast<QDragLeaveEvent *>(event));
@@ -841,6 +843,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(rootWidget, pos);
QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted());
+ translated.setTimestamp(event->timestamp());
QGuiApplication::forwardEvent(widget, &translated, event);
}
@@ -848,62 +851,80 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
#if QT_CONFIG(draganddrop)
-void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
+static QWidget *findDnDTarget(QWidget *parent, const QPoint &pos)
{
- Q_ASSERT(event->type() ==QEvent::DragMove || !m_dragTarget);
// Find a target widget under mouse that accepts drops (QTBUG-22987).
- QWidget *widget = m_widget->childAt(event->pos());
+ QWidget *widget = parent->childAt(pos);
if (!widget)
- widget = m_widget;
+ widget = parent;
for ( ; widget && !widget->isWindow() && !widget->acceptDrops(); widget = widget->parentWidget()) ;
if (widget && !widget->acceptDrops())
- widget = 0;
- // Target widget unchanged: DragMove
- if (widget && widget == m_dragTarget.data()) {
- Q_ASSERT(event->type() == QEvent::DragMove);
- const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
- QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- translated.setDropAction(event->dropAction());
- if (event->isAccepted()) { // Handling 'DragEnter' should suffice for the application.
- translated.accept();
- translated.setDropAction(event->dropAction());
- }
- QGuiApplication::forwardEvent(widget, &translated, event);
- if (translated.isAccepted()) {
- event->accept();
- } else {
- event->ignore();
- }
- event->setDropAction(translated.dropAction());
- return;
- }
- // Target widget changed: Send DragLeave to previous, DragEnter to new if there is any
- if (m_dragTarget.data()) {
- QDragLeaveEvent le;
- QGuiApplication::forwardEvent(m_dragTarget.data(), &le, event);
- m_dragTarget = 0;
- }
+ widget = nullptr;
+ return widget;
+}
+
+void QWidgetWindow::handleDragEnterEvent(QDragEnterEvent *event, QWidget *widget)
+{
+ Q_ASSERT(m_dragTarget == nullptr);
+ if (!widget)
+ widget = findDnDTarget(m_widget, event->pos());
if (!widget) {
- event->ignore();
- return;
+ event->ignore();
+ return;
}
m_dragTarget = widget;
+
const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
- QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::forwardEvent(widget, &translated, event);
- if (translated.isAccepted()) {
- event->accept();
- } else {
+ QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(),
+ event->mouseButtons(), event->keyboardModifiers());
+ translated.setDropAction(event->dropAction());
+ translated.setAccepted(event->isAccepted());
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ event->setAccepted(translated.isAccepted());
+ event->setDropAction(translated.dropAction());
+}
+
+void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
+{
+ auto *widget = findDnDTarget(m_widget, event->pos());
+ if (!widget) {
event->ignore();
+ if (m_dragTarget) { // Send DragLeave to previous
+ QDragLeaveEvent leaveEvent;
+ QGuiApplication::forwardEvent(m_dragTarget, &leaveEvent, event);
+ m_dragTarget = nullptr;
+ }
+ } else {
+ const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
+ QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(),
+ event->mouseButtons(), event->keyboardModifiers());
+ translated.setDropAction(event->dropAction());
+ translated.setAccepted(event->isAccepted());
+
+ if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ } else {
+ if (m_dragTarget) { // Send DragLeave to previous
+ QDragLeaveEvent leaveEvent;
+ QGuiApplication::forwardEvent(m_dragTarget, &leaveEvent, event);
+ m_dragTarget = nullptr;
+ }
+ // Send DragEnter to new widget.
+ handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
+ // The drag enter event is always immediately followed by a drag move event,
+ // see QDragEnterEvent documentation.
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ }
+ event->setAccepted(translated.isAccepted());
+ event->setDropAction(translated.dropAction());
}
- event->setDropAction(translated.dropAction());
}
void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
{
if (m_dragTarget)
- QGuiApplication::forwardEvent(m_dragTarget.data(), event);
- m_dragTarget = 0;
+ QGuiApplication::forwardEvent(m_dragTarget, event);
+ m_dragTarget = nullptr;
}
void QWidgetWindow::handleDropEvent(QDropEvent *event)
@@ -913,13 +934,12 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event)
event->ignore();
return;
}
- const QPoint mapped = m_dragTarget.data()->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
+ const QPoint mapped = m_dragTarget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::forwardEvent(m_dragTarget.data(), &translated, event);
- if (translated.isAccepted())
- event->accept();
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ event->setAccepted(translated.isAccepted());
event->setDropAction(translated.dropAction());
- m_dragTarget = 0;
+ m_dragTarget = nullptr;
}
#endif // QT_CONFIG(draganddrop)
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index ead099390e..0728135467 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -96,7 +96,8 @@ protected:
void handleWheelEvent(QWheelEvent *);
#endif
#if QT_CONFIG(draganddrop)
- void handleDragEnterMoveEvent(QDragMoveEvent *);
+ void handleDragEnterEvent(QDragEnterEvent *, QWidget *widget = nullptr);
+ void handleDragMoveEvent(QDragMoveEvent *);
void handleDragLeaveEvent(QDragLeaveEvent *);
void handleDropEvent(QDropEvent *);
#endif
diff --git a/src/widgets/qtwidgets.tracepoints b/src/widgets/qtwidgets.tracepoints
new file mode 100644
index 0000000000..01a1383670
--- /dev/null
+++ b/src/widgets/qtwidgets.tracepoints
@@ -0,0 +1,4 @@
+QApplication_notify_entry(QObject *receiver, QEvent *event, int type)
+QApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type)
+QApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type)
+QApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed)
diff --git a/src/widgets/styles/images/titlebar-contexthelp-16.png b/src/widgets/styles/images/titlebar-contexthelp-16.png
new file mode 100644
index 0000000000..2cead19910
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-contexthelp-32.png b/src/widgets/styles/images/titlebar-contexthelp-32.png
new file mode 100644
index 0000000000..1cd4843d5e
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-contexthelp-48.png b/src/widgets/styles/images/titlebar-contexthelp-48.png
new file mode 100644
index 0000000000..9b170687be
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-16.png b/src/widgets/styles/images/titlebar-max-16.png
new file mode 100644
index 0000000000..101a7eac2b
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-32.png b/src/widgets/styles/images/titlebar-max-32.png
new file mode 100644
index 0000000000..529c54f61d
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-48.png b/src/widgets/styles/images/titlebar-max-48.png
new file mode 100644
index 0000000000..cfa0b67edf
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-16.png b/src/widgets/styles/images/titlebar-min-16.png
new file mode 100644
index 0000000000..95e714b522
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-32.png b/src/widgets/styles/images/titlebar-min-32.png
new file mode 100644
index 0000000000..0b9afedecf
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-48.png b/src/widgets/styles/images/titlebar-min-48.png
new file mode 100644
index 0000000000..b59a336d36
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-16.png b/src/widgets/styles/images/titlebar-shade-16.png
new file mode 100644
index 0000000000..cc870a1e5c
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-32.png b/src/widgets/styles/images/titlebar-shade-32.png
new file mode 100644
index 0000000000..b785b8e216
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-48.png b/src/widgets/styles/images/titlebar-shade-48.png
new file mode 100644
index 0000000000..42b75b4a0c
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-16.png b/src/widgets/styles/images/titlebar-unshade-16.png
new file mode 100644
index 0000000000..ef19de6c2f
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-32.png b/src/widgets/styles/images/titlebar-unshade-32.png
new file mode 100644
index 0000000000..9f74bb0ac7
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-48.png b/src/widgets/styles/images/titlebar-unshade-48.png
new file mode 100644
index 0000000000..bd17c3cf48
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-48.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-16.png b/src/widgets/styles/images/toolbar-ext-h-16.png
new file mode 100644
index 0000000000..c6bd1b1784
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-16.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-32.png b/src/widgets/styles/images/toolbar-ext-h-32.png
new file mode 100644
index 0000000000..99c62698f2
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-32.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-8.png b/src/widgets/styles/images/toolbar-ext-h-8.png
new file mode 100644
index 0000000000..340a374bce
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-8.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-16.png b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png
new file mode 100644
index 0000000000..31c72892b4
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-32.png b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png
new file mode 100644
index 0000000000..bfc333daac
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-8.png b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png
new file mode 100644
index 0000000000..538e408310
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext.png b/src/widgets/styles/images/toolbar-ext-macstyle.png
index 37bd403ff8..37bd403ff8 100644
--- a/src/widgets/styles/images/toolbar-ext.png
+++ b/src/widgets/styles/images/toolbar-ext-macstyle.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext@2x.png b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png
index 6fc729efb0..6fc729efb0 100644
--- a/src/widgets/styles/images/toolbar-ext@2x.png
+++ b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-10.png b/src/widgets/styles/images/toolbar-ext-v-10.png
new file mode 100644
index 0000000000..2a6d0e4c70
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-10.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-20.png b/src/widgets/styles/images/toolbar-ext-v-20.png
new file mode 100644
index 0000000000..adc27f52b5
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-20.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-5.png b/src/widgets/styles/images/toolbar-ext-v-5.png
new file mode 100644
index 0000000000..21c670446c
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-5.png
Binary files differ
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 3b9186e61a..3ee3e856bc 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -936,55 +936,53 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
viewItemTextLayout(textLayout, textRect.width());
- QString elidedText;
- qreal height = 0;
- qreal width = 0;
- int elidedIndex = -1;
- const int lineCount = textLayout.lineCount();
- for (int j = 0; j < lineCount; ++j) {
- const QTextLine line = textLayout.lineAt(j);
- if (j + 1 <= lineCount - 1) {
- const QTextLine nextLine = textLayout.lineAt(j + 1);
- if ((nextLine.y() + nextLine.height()) > textRect.height()) {
- int start = line.textStart();
- int length = line.textLength() + nextLine.textLength();
- const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
- elidedText = engine.elidedText(option->textElideMode, textRect.width());
- height += line.height();
- width = textRect.width();
- elidedIndex = j;
- break;
- }
- }
- if (line.naturalTextWidth() > textRect.width()) {
- int start = line.textStart();
- int length = line.textLength();
- const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
- elidedText = engine.elidedText(option->textElideMode, textRect.width());
- height += line.height();
- width = textRect.width();
- elidedIndex = j;
- break;
- }
- width = qMax<qreal>(width, line.width());
- height += line.height();
- }
-
+ const QRectF boundingRect = textLayout.boundingRect();
const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
- QSize(int(width), int(height)), textRect);
+ boundingRect.size().toSize(), textRect);
const QPointF position = layoutRect.topLeft();
+ const int lineCount = textLayout.lineCount();
+
+ qreal height = 0;
for (int i = 0; i < lineCount; ++i) {
const QTextLine line = textLayout.lineAt(i);
- if (i == elidedIndex) {
- qreal x = position.x() + line.x();
- qreal y = position.y() + line.y() + line.ascent();
+ height += line.height();
+
+ // above visible rect
+ if (height + layoutRect.top() <= textRect.top())
+ continue;
+
+ const int start = line.textStart();
+ const int length = line.textLength();
+
+ const bool drawElided = line.naturalTextWidth() > textRect.width();
+ bool elideLastVisibleLine = false;
+ if (!drawElided && i + 1 < lineCount) {
+ const QTextLine nextLine = textLayout.lineAt(i + 1);
+ const int nextHeight = height + nextLine.height() / 2;
+ // elide when less than the next half line is visible
+ if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
+ elideLastVisibleLine = true;
+ }
+
+ if (drawElided || elideLastVisibleLine) {
+ QString text = textLayout.text().mid(start, length);
+ if (elideLastVisibleLine)
+ text += QChar(0x2026);
+ const QStackTextEngine engine(text, option->font);
+ const QString elidedText = engine.elidedText(option->textElideMode, textRect.width());
+ const QPointF pos(position.x() + line.x(),
+ position.y() + line.y() + line.ascent());
p->save();
p->setFont(option->font);
- p->drawText(QPointF(x, y), elidedText);
+ p->drawText(pos, elidedText);
p->restore();
- break;
+ } else {
+ line.draw(p, position);
}
- line.draw(p, position);
+
+ // below visible text, can stop
+ if (height + layoutRect.top() >= textRect.bottom())
+ break;
}
}
@@ -1673,8 +1671,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
alignment |= Qt::AlignLeft | Qt::AlignVCenter;
}
tr.translate(shiftX, shiftY);
+ const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, tr.width());
proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
- toolbutton->state & State_Enabled, toolbutton->text,
+ toolbutton->state & State_Enabled, text,
QPalette::ButtonText);
} else {
rect.translate(shiftX, shiftY);
@@ -2861,8 +2860,8 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_TabBarScrollLeftButton: {
const bool vertical = opt->rect.width() < opt->rect.height();
const Qt::LayoutDirection ld = widget->layoutDirection();
- const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
- const int buttonOverlap = pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget);
+ const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+ const int buttonOverlap = proxy()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget);
r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth)
: QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height()));
@@ -2870,7 +2869,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_TabBarScrollRightButton: {
const bool vertical = opt->rect.width() < opt->rect.height();
const Qt::LayoutDirection ld = widget->layoutDirection();
- const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+ const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth)
: QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()));
@@ -3085,7 +3084,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
//have all the information we need (ie. the layout's margin)
const QToolBar *tb = qobject_cast<const QToolBar*>(widget);
const int margin = tb && tb->layout() ? tb->layout()->margin() : 2;
- const int handleExtent = pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
+ const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
if (tbopt->state & QStyle::State_Horizontal) {
r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin);
r = QStyle::visualRect(tbopt->direction, tbopt->rect, r);
@@ -4940,8 +4939,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths
- int buttonWidth = 20;
- int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
+ const int buttonWidth = (vopt->subControls & (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown)) != 0 ? 20 : 0;
+ const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
sz += QSize(buttonWidth + 2*fw, 2*fw);
}
break;
@@ -5310,6 +5309,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_SpinBox_ButtonsInsideFrame:
ret = true;
break;
+ case SH_SpinBox_StepModifier:
+ ret = Qt::ControlModifier;
+ break;
default:
ret = 0;
break;
@@ -5722,14 +5724,14 @@ static inline QString iconPngSuffix() { return QStringLiteral(".png"); }
static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon)
{
- for (size_t i = 0; i < count; ++i) {
- const int size = sizes[i];
- icon.addFile(prefix + QString::number(size) + iconPngSuffix(), QSize(size, size));
- }
+ for (size_t i = 0; i < count; ++i)
+ icon.addFile(prefix + QString::number(sizes[i]) + iconPngSuffix());
}
static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64};
-
+static const int titleBarSizes[] = {16, 32, 48};
+static const int toolBarExtHSizes[] = {8, 16, 32};
+static const int toolBarExtVSizes[] = {5, 10, 20};
#endif // imageformat_png
/*!
@@ -6044,6 +6046,27 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
+ case SP_TitleBarMinButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-min-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarMaxButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-max-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarShadeButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-shade-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+
+ break;
+ case SP_TitleBarUnshadeButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-unshade-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarContextHelpButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
case SP_FileDialogNewFolder:
icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16));
icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32));
@@ -6252,6 +6275,17 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"),
dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
break;
+ case SP_ToolBarHorizontalExtensionButton: {
+ QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-");
+ if (rtl)
+ prefix += QStringLiteral("rtl-");
+ addIconFiles(prefix, toolBarExtHSizes, sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon);
+ }
+ break;
+ case SP_ToolBarVerticalExtensionButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"),
+ toolBarExtVSizes, sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon);
+ break;
#endif // QT_NO_IMAGEFORMAT_PNG
default:
icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget));
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 73a6554f1a..8006be8c27 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -2001,6 +2001,13 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
Determnines if the spin box buttons are inside the line edit frame.
This enum value has been introduced in Qt 5.11.
+ \value SH_SpinBox_StepModifier
+ Determines which Qt::KeyboardModifier increases the step rate of
+ QAbstractSpinBox. Possible values are Qt::NoModifier,
+ Qt::ControlModifier (default) or Qt::ShiftModifier. Qt::NoModifier
+ disables this feature.
+ This enum value has been introduced in Qt 5.12.
+
\sa styleHint()
*/
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index cef569d514..9192dae864 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -741,6 +741,7 @@ public:
SH_Widget_Animation_Duration,
SH_ComboBox_AllowWheelScrolling,
SH_SpinBox_ButtonsInsideFrame,
+ SH_SpinBox_StepModifier,
// Add new style hint values here
SH_CustomBase = 0xf0000000
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
index 2dc3207e6d..d3511ee754 100644
--- a/src/widgets/styles/qstyle.qrc
+++ b/src/widgets/styles/qstyle.qrc
@@ -140,13 +140,37 @@
<file>images/normalizedockup-32.png</file>
<file>images/normalizedockup-48.png</file>
<file>images/normalizedockup-64.png</file>
+ <file>images/toolbar-ext-h-8.png</file>
+ <file>images/toolbar-ext-h-16.png</file>
+ <file>images/toolbar-ext-h-32.png</file>
+ <file>images/toolbar-ext-h-rtl-8.png</file>
+ <file>images/toolbar-ext-h-rtl-16.png</file>
+ <file>images/toolbar-ext-h-rtl-32.png</file>
+ <file>images/toolbar-ext-v-5.png</file>
+ <file>images/toolbar-ext-v-10.png</file>
+ <file>images/toolbar-ext-v-20.png</file>
+ <file>images/titlebar-contexthelp-16.png</file>
+ <file>images/titlebar-contexthelp-32.png</file>
+ <file>images/titlebar-contexthelp-48.png</file>
+ <file>images/titlebar-max-16.png</file>
+ <file>images/titlebar-max-32.png</file>
+ <file>images/titlebar-max-48.png</file>
+ <file>images/titlebar-min-16.png</file>
+ <file>images/titlebar-min-32.png</file>
+ <file>images/titlebar-min-48.png</file>
+ <file>images/titlebar-shade-16.png</file>
+ <file>images/titlebar-shade-32.png</file>
+ <file>images/titlebar-shade-48.png</file>
+ <file>images/titlebar-unshade-16.png</file>
+ <file>images/titlebar-unshade-32.png</file>
+ <file>images/titlebar-unshade-48.png</file>
</qresource>
<qresource prefix="/qt-project.org/styles/macstyle">
<file alias="images/closedock-16.png">images/closedock-macstyle-16.png</file>
<file alias="images/closedock-down-16.png">images/closedock-down-macstyle-16.png</file>
<file alias="images/dockdock-16.png">images/dockdock-macstyle-16.png</file>
<file alias="images/dockdock-down-16.png">images/dockdock-down-macstyle-16.png</file>
- <file>images/toolbar-ext.png</file>
- <file>images/toolbar-ext@2x.png</file>
+ <file alias="images/toolbar-ext.png">images/toolbar-ext-macstyle.png</file>
+ <file alias="images/toolbar-ext@2x.png">images/toolbar-ext-macstyle@2x.png</file>
</qresource>
</RCC>
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index 8679d96eda..0b910d46df 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -403,14 +403,6 @@ QColor backgroundColor(const QPalette &pal, const QWidget* widget)
return pal.color(QPalette::Base);
}
-QWindow *styleObjectWindow(QObject *so)
-{
- if (so)
- return so->property("_q_styleObjectWindow").value<QWindow *>();
-
- return 0;
-}
-
WidgetSizePolicy widgetSizePolicy(const QWidget *widget, const QStyleOption *opt)
{
while (widget) {
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
index 260860bf4d..d79dfe4288 100644
--- a/src/widgets/styles/qstylehelper_p.h
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -90,7 +90,6 @@ namespace QStyleHelper
Q_WIDGETS_EXPORT bool hasAncestor(QObject *obj, QAccessible::Role role);
#endif
Q_WIDGETS_EXPORT QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
- Q_WIDGETS_EXPORT QWindow *styleObjectWindow(QObject *so);
enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 };
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index e7fa26e2d4..97631a5841 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1842,10 +1842,12 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
/*!
\variable QStyleOptionMenuItem::tabWidth
- \brief the tab width for the menu item
+ \brief the reserved width for the menu item's shortcut
- The tab width is the distance between the text of the menu item
- and the shortcut. The default value is 0.
+ QMenu sets it to the width occupied by the widest shortcut among
+ all visible items within the menu.
+
+ The default value is 0.
*/
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
index 9fbaf34a86..8ae07efc81 100644
--- a/src/widgets/styles/qstyleoption.h
+++ b/src/widgets/styles/qstyleoption.h
@@ -366,7 +366,7 @@ public:
QString text;
QIcon icon;
int maxIconWidth;
- int tabWidth;
+ int tabWidth; // ### Qt 6: rename to reservedShortcutWidth
QFont font;
QStyleOptionMenuItem();
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index c046ac52f9..fccc4f33a2 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -530,6 +530,8 @@ public:
const QStyleSheetGeometryData *geometry() const { return geo; }
const QStyleSheetPositionData *position() const { return p; }
+ bool hasModification() const;
+
bool hasPalette() const { return pal != 0; }
bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
@@ -1041,7 +1043,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
if (const QWidget *widget = qobject_cast<const QWidget *>(object)) {
QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
if (!style)
- style = qobject_cast<QStyleSheetStyle *>(widget->style());
+ style = qt_styleSheet(widget->style());
if (style)
fixupBorder(style->nativeFrameWidth(widget));
}
@@ -1444,6 +1446,21 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
}
+bool QRenderRule::hasModification() const
+{
+ return hasPalette() ||
+ hasBackground() ||
+ hasGradientBackground() ||
+ !hasNativeBorder() ||
+ !hasNativeOutline() ||
+ hasBox() ||
+ hasPosition() ||
+ hasGeometry() ||
+ hasImage() ||
+ hasFont ||
+ !styleHints.isEmpty();
+}
+
///////////////////////////////////////////////////////////////////////////////
// Style rules
#define OBJECT_PTR(x) (static_cast<QObject *>(x.ptr))
@@ -1502,7 +1519,7 @@ public:
return className;
} else if (name == QLatin1String("style")) {
QWidget *w = qobject_cast<QWidget *>(obj);
- QStyleSheetStyle *proxy = w ? qobject_cast<QStyleSheetStyle *>(w->style()) : 0;
+ QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : 0;
if (proxy) {
QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
cache[name] = styleName;
@@ -1923,11 +1940,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption
break;
case QTabBar::RoundedEast:
case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
+ extraClass |= PseudoClass_Right;
break;
case QTabBar::RoundedWest:
case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
+ extraClass |= PseudoClass_Left;
break;
default:
break;
@@ -1960,11 +1977,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption
break;
case QTabBar::RoundedEast:
case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
+ extraClass |= PseudoClass_Right;
break;
case QTabBar::RoundedWest:
case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
+ extraClass |= PseudoClass_Left;
break;
default:
break;
@@ -2734,7 +2751,7 @@ QStyle *QStyleSheetStyle::baseStyle() const
{
if (base)
return base;
- if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style()))
+ if (QStyleSheetStyle *me = qt_styleSheet(QApplication::style()))
return me->base;
return QApplication::style();
}
@@ -2823,6 +2840,9 @@ void QStyleSheetStyle::polish(QWidget *w)
#endif
QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
+
+ w->setAttribute(Qt::WA_StyleSheetTarget, rule.hasModification());
+
if (rule.hasDrawable() || rule.hasBox()) {
if (w->metaObject() == &QWidget::staticMetaObject
#if QT_CONFIG(itemviews)
@@ -2906,6 +2926,7 @@ void QStyleSheetStyle::unpolish(QWidget *w)
styleSheetCaches->styleSheetCache.remove(w);
unsetPalette(w);
setGeometry(w);
+ w->setAttribute(Qt::WA_StyleSheetTarget, false);
w->setAttribute(Qt::WA_StyleSheet, false);
QObject::disconnect(w, 0, this, 0);
#if QT_CONFIG(scrollarea)
@@ -3670,6 +3691,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
bool dis = !(opt->state & QStyle::State_Enabled),
act = opt->state & QStyle::State_Selected;
+ int checkableOffset = 0;
+ if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ QStyleOptionMenuItem newMi = mi;
+ newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ checkableOffset = newMi.rect.width();
+ if (subSubRule.hasDrawable() || checked)
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+
+ int iconOffset = 0;
if (!mi.icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis)
@@ -3689,20 +3721,22 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
iconRule.geo->height = pixh;
}
QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
+ if (opt->direction == Qt::LeftToRight)
+ iconRect.moveLeft(iconRect.left() + checkableOffset);
+ else
+ iconRect.moveRight(iconRect.right() - checkableOffset);
iconRule.drawRule(p, iconRect);
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(iconRect.center());
p->drawPixmap(pmr.topLeft(), pixmap);
- } else if (checkable) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
- if (subSubRule.hasDrawable() || checked) {
- QStyleOptionMenuItem newMi = mi;
- newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
- }
+ iconOffset = iconRule.geo->width;
}
QRect textRect = subRule.contentsRect(opt->rect);
+ if (opt->direction == Qt::LeftToRight)
+ textRect.setLeft(textRect.left() + checkableOffset + iconOffset);
+ else
+ textRect.setRight(textRect.right() - checkableOffset - iconOffset);
textRect.setWidth(textRect.width() - mi.tabWidth);
QStringRef s(&mi.text);
p->setPen(mi.palette.buttonText().color());
@@ -5048,6 +5082,16 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
int width = csz.width();
if (mi->text.contains(QLatin1Char('\t')))
width += 12; //as in QCommonStyle
+ bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable;
+ if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ width += checkmarkRect.width();
+ }
+ if (!mi->icon.isNull()) {
+ QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize));
+ width += pixmap.width();
+ }
return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
}
}
@@ -5198,7 +5242,7 @@ static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp)
case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon");
case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon");
case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon");
- case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon");
+ case QStyle::SP_DialogDiscardButton: return QLatin1String("dialog-discard-icon");
case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon");
case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon");
case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon");
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
index 042abf5c22..d1647fb107 100644
--- a/src/widgets/styles/qstylesheetstyle_p.h
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -215,6 +215,13 @@ template <typename T>
class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>>
: QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {};
+
+// Returns a QStyleSheet from the given style.
+inline QStyleSheetStyle* qt_styleSheet(QStyle *style)
+{
+ return qobject_cast<QStyleSheetStyle *>(style);
+}
+
QT_END_NAMESPACE
#endif // QT_NO_STYLE_STYLESHEET
#endif // QSTYLESHEETSTYLE_P_H
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 7c9d917784..4b9d0b5adc 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -1148,9 +1148,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
const int pixw = pixmap.width() / pixmap.devicePixelRatio();
const int pixh = pixmap.height() / pixmap.devicePixelRatio();
- if (act && !dis && !checked)
- qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1,
- &menuitem->palette.brush(QPalette::Button));
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(vCheckRect.center());
p->setPen(menuitem->palette.text().color());
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 599b983748..96dde64ccc 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -1000,7 +1000,7 @@ QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent)
d->init(model);
}
-#ifndef QT_NO_STRINGLISTMODEL
+#if QT_CONFIG(stringlistmodel)
/*!
Constructs a QCompleter object with the given \a parent that uses the specified
\a list as a source of possible completions.
@@ -1011,7 +1011,7 @@ QCompleter::QCompleter(const QStringList& list, QObject *parent)
Q_D(QCompleter);
d->init(new QStringListModel(list, this));
}
-#endif // QT_NO_STRINGLISTMODEL
+#endif // QT_CONFIG(stringlistmodel)
/*!
Destroys the completer object.
diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h
index de79302e15..fd1191d123 100644
--- a/src/widgets/util/qcompleter.h
+++ b/src/widgets/util/qcompleter.h
@@ -84,7 +84,7 @@ public:
QCompleter(QObject *parent = nullptr);
QCompleter(QAbstractItemModel *model, QObject *parent = nullptr);
-#ifndef QT_NO_STRINGLISTMODEL
+#if QT_CONFIG(stringlistmodel)
QCompleter(const QStringList& completions, QObject *parent = nullptr);
#endif
~QCompleter();
diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 903a141e49..28504f5631 100644
--- a/src/widgets/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
@@ -1894,7 +1894,7 @@ qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientatio
if (orientation == Qt::Horizontal) {
// the snap points in the list
- foreach (qreal snapPos, snapPositionsX) {
+ for (qreal snapPos : snapPositionsX) {
qreal snapPosDist = snapPos - p;
if ((dir > 0 && snapPosDist < 0) ||
(dir < 0 && snapPosDist > 0))
@@ -1941,7 +1941,7 @@ qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientatio
} else { // (orientation == Qt::Vertical)
// the snap points in the list
- foreach (qreal snapPos, snapPositionsY) {
+ for (qreal snapPos : snapPositionsY) {
qreal snapPosDist = snapPos - p;
if ((dir > 0 && snapPosDist < 0) ||
(dir < 0 && snapPosDist > 0))
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 86c824afdb..d15f5e5955 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -523,6 +523,8 @@ QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title,
closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
closeButton->setFixedSize(closeButtonSize, closeButtonSize);
QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
+#else
+ Q_UNUSED(closeButtonSize);
#endif
#if QT_CONFIG(label)
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index df93e15f80..86532456c7 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -63,8 +63,6 @@
#include <private/qguiapplication_p.h>
#include <qdebug.h>
-#include <QtPlatformHeaders/qxcbwindowfunctions.h>
-#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
#ifndef QT_NO_SYSTEMTRAYICON
QT_BEGIN_NAMESPACE
@@ -98,10 +96,7 @@ private slots:
void systemTrayWindowChanged(QScreen *screen);
private:
- bool addToTray();
-
QSystemTrayIcon *q;
- QPixmap background;
};
QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
@@ -117,55 +112,13 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
const QSize size(22, 22); // Gnome, standard size
setGeometry(QRect(QPoint(0, 0), size));
setMinimumSize(size);
-
- // We need two different behaviors depending on whether the X11 visual for the system tray
- // (a) exists and (b) supports an alpha channel, i.e. is 32 bits.
- // If we have a visual that has an alpha channel, we can paint this widget with a transparent
- // background and it will work.
- // However, if there's no alpha channel visual, in order for transparent tray icons to work,
- // we do not have a transparent background on the widget, but set the BackPixmap property of our
- // window to ParentRelative (so that it inherits the background of its X11 parent window), call
- // xcb_clear_region before painting (so that the inherited background is visible) and then grab
- // the just-drawn background from the X11 server.
- bool hasAlphaChannel = QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannel();
- setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel);
- if (!hasAlphaChannel) {
- createWinId();
- QXcbWindowFunctions::setParentRelativeBackPixmap(windowHandle());
-
- // XXX: This is actually required, but breaks things ("QWidget::paintEngine: Should no
- // longer be called"). Why is this needed? When the widget is drawn, we use tricks to grab
- // the tray icon's background from the server. If the tray icon isn't visible (because
- // another window is on top of it), the trick fails and instead uses the content of that
- // other window as the background.
- // setAttribute(Qt::WA_PaintOnScreen);
- }
-
- addToTray();
-}
-
-bool QSystemTrayIconSys::addToTray()
-{
- if (!locateSystemTray())
- return false;
-
- createWinId();
+ setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
-
- if (!QXcbWindowFunctions::requestSystemTrayWindowDock(windowHandle()))
- return false;
-
- if (!background.isNull())
- background = QPixmap();
- show();
- return true;
}
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
{
- if (locateSystemTray()) {
- addToTray();
- } else {
+ if (!locateSystemTray()) {
QBalloonTip::hideBalloon();
hide(); // still no luck
destroy();
@@ -174,7 +127,7 @@ void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
QRect QSystemTrayIconSys::globalGeometry() const
{
- return QXcbWindowFunctions::systemTrayWindowGlobalGeometry(windowHandle());
+ return QRect(mapToGlobal(QPoint(0, 0)), size());
}
void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
@@ -227,22 +180,6 @@ void QSystemTrayIconSys::paintEvent(QPaintEvent *)
const QRect rect(QPoint(0, 0), geometry().size());
QPainter painter(this);
- // If we have Qt::WA_TranslucentBackground set, during widget creation
- // we detected the systray visual supported an alpha channel
- if (testAttribute(Qt::WA_TranslucentBackground)) {
- painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(rect, Qt::transparent);
- } else {
- // clearRegion() was called on XEMBED_EMBEDDED_NOTIFY, so we hope that got done by now.
- // Grab the tray background pixmap, before rendering the icon for the first time.
- if (background.isNull()) {
- background = QGuiApplication::primaryScreen()->grabWindow(winId(),
- 0, 0, rect.size().width(), rect.size().height());
- }
- // Then paint over the icon area with the background before compositing the icon on top.
- painter.drawPixmap(QPoint(0, 0), background);
- }
- painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
q->icon().paint(&painter, rect);
}
@@ -285,6 +222,7 @@ void QSystemTrayIconPrivate::install_sys()
sys = new QSystemTrayIconSys(q);
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
sys, SLOT(systemTrayWindowChanged(QScreen*)));
+ sys->show();
}
}
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index b371e903a6..e928b9fe37 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -742,6 +742,17 @@ void QUndoStack::resetClean()
}
/*!
+ \since 5.12
+ \property QUndoStack::clean
+ \brief the clean status of this stack.
+
+ This property indicates whether or not the stack is clean. For example, a
+ stack is clean when a document has been saved.
+
+ \sa isClean(), setClean(), resetClean(), cleanIndex()
+*/
+
+/*!
If the stack is in the clean state, returns \c true; otherwise returns \c false.
\sa setClean(), cleanIndex()
@@ -940,6 +951,17 @@ void QUndoStack::setIndex(int idx)
}
/*!
+ \since 5.12
+ \property QUndoStack::canUndo
+ \brief whether this stack can undo.
+
+ This property indicates whether or not there is a command that can be
+ undone.
+
+ \sa canUndo(), index(), canRedo()
+*/
+
+/*!
Returns \c true if there is a command available for undo; otherwise returns \c false.
This function returns \c false if the stack is empty, or if the bottom command
@@ -959,6 +981,17 @@ bool QUndoStack::canUndo() const
}
/*!
+ \since 5.12
+ \property QUndoStack::canRedo
+ \brief whether this stack can redo.
+
+ This property indicates whether or not there is a command that can be
+ redone.
+
+ \sa canRedo(), index(), canUndo()
+*/
+
+/*!
Returns \c true if there is a command available for redo; otherwise returns \c false.
This function returns \c false if the stack is empty or if the top command
@@ -978,6 +1011,17 @@ bool QUndoStack::canRedo() const
}
/*!
+ \since 5.12
+ \property QUndoStack::undoText
+ \brief the undo text of the next command that is undone.
+
+ This property holds the text of the command which will be undone in the
+ next call to undo().
+
+ \sa undoText(), QUndoCommand::actionText(), redoText()
+*/
+
+/*!
Returns the text of the command which will be undone in the next call to undo().
\sa QUndoCommand::actionText(), redoText()
@@ -994,6 +1038,17 @@ QString QUndoStack::undoText() const
}
/*!
+ \since 5.12
+ \property QUndoStack::redoText
+ \brief the redo text of the next command that is redone.
+
+ This property holds the text of the command which will be redone in the
+ next call to redo().
+
+ \sa redoText(), QUndoCommand::actionText(), undoText()
+*/
+
+/*!
Returns the text of the command which will be redone in the next call to redo().
\sa QUndoCommand::actionText(), undoText()
diff --git a/src/widgets/util/qundostack.h b/src/widgets/util/qundostack.h
index 4be24eadab..b5716b2e9b 100644
--- a/src/widgets/util/qundostack.h
+++ b/src/widgets/util/qundostack.h
@@ -90,6 +90,11 @@ class Q_WIDGETS_EXPORT QUndoStack : public QObject
Q_DECLARE_PRIVATE(QUndoStack)
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
+ Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
+ Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
+ Q_PROPERTY(QString undoText READ undoText NOTIFY undoTextChanged)
+ Q_PROPERTY(QString redoText READ redoText NOTIFY redoTextChanged)
+ Q_PROPERTY(bool clean READ isClean NOTIFY cleanChanged)
public:
explicit QUndoStack(QObject *parent = nullptr);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index e028a691c8..e556cb8b10 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -6,6 +6,9 @@ CONFIG += $$MODULE_CONFIG
DEFINES += QT_NO_USING_NAMESPACE
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000
+TRACEPOINT_PROVIDER = $$PWD/qtwidgets.tracepoints
+CONFIG += qt_tracepoints
+
QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf
#platforms
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index f059980c5c..822d896ee6 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -100,6 +100,16 @@ QT_BEGIN_NAMESPACE
integer value to signify how many steps were taken. E.g. Pressing
Qt::Key_Down will trigger a call to stepBy(-1).
+ When the user triggers a step whilst holding the Qt::ControlModifier,
+ QAbstractSpinBox steps by 10 instead of making a single step. This
+ step modifier affects wheel events, key events and interaction with
+ the spinbox buttons. Note that on macOS, Control corresponds to the
+ Command key.
+
+ Since Qt 5.12, QStyle::SH_SpinBox_StepModifier can be used to select
+ which Qt::KeyboardModifier increases the step rate. Qt::NoModifier
+ disables this feature.
+
QAbstractSpinBox also provide a virtual function stepEnabled() to
determine whether stepping up/down is allowed at any point. This
function returns a bitset of StepEnabled.
@@ -640,7 +650,15 @@ void QAbstractSpinBox::stepBy(int steps)
e = AlwaysEmit;
}
if (!dontstep) {
- d->setValue(d->bound(d->value + (d->singleStep * steps), old, steps), e);
+ QVariant singleStep;
+ switch (d->stepType) {
+ case QAbstractSpinBox::StepType::AdaptiveDecimalStepType:
+ singleStep = d->calculateAdaptiveDecimalStep(steps);
+ break;
+ default:
+ singleStep = d->singleStep;
+ }
+ d->setValue(d->bound(d->value + (singleStep * steps), old, steps), e);
} else if (e == AlwaysEmit) {
d->emitSignals(e, old);
}
@@ -826,9 +844,13 @@ void QAbstractSpinBox::changeEvent(QEvent *event)
style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this);
if (d->edit)
d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
+ d->stepModifier = static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier, nullptr, this));
d->reset();
d->updateEditFieldGeometry();
break;
+ case QEvent::LocaleChange:
+ d->updateEdit();
+ break;
case QEvent::EnabledChange:
if (!isEnabled()) {
d->reset();
@@ -1008,6 +1030,8 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up);
if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled)))
return;
+ if (!isPgUpOrDown && (event->modifiers() & d->stepModifier))
+ steps *= 10;
if (!up)
steps *= -1;
if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
@@ -1134,11 +1158,24 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
void QAbstractSpinBox::wheelEvent(QWheelEvent *event)
{
Q_D(QAbstractSpinBox);
+#ifdef Q_OS_MACOS
+ // If the event comes from a real mouse wheel, rather than a track pad
+ // (Qt::MouseEventSynthesizedBySystem), the shift modifier changes the
+ // scroll orientation to horizontal.
+ // Convert horizontal events back to vertical whilst shift is held.
+ if ((event->modifiers() & Qt::ShiftModifier)
+ && event->source() == Qt::MouseEventNotSynthesized) {
+ d->wheelDeltaRemainder += event->angleDelta().x();
+ } else {
+ d->wheelDeltaRemainder += event->angleDelta().y();
+ }
+#else
d->wheelDeltaRemainder += event->angleDelta().y();
+#endif
const int steps = d->wheelDeltaRemainder / 120;
d->wheelDeltaRemainder -= steps * 120;
if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled))
- stepBy(event->modifiers() & Qt::ControlModifier ? steps * 10 : steps);
+ stepBy(event->modifiers() & d->stepModifier ? steps * 10 : steps);
event->accept();
}
#endif
@@ -1238,18 +1275,19 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
}
if (doStep) {
+ const bool increaseStepRate = QGuiApplication::keyboardModifiers() & d->stepModifier;
const StepEnabled st = stepEnabled();
if (d->buttonState & Up) {
if (!(st & StepUpEnabled)) {
d->reset();
} else {
- stepBy(1);
+ stepBy(increaseStepRate ? 10 : 1);
}
} else if (d->buttonState & Down) {
if (!(st & StepDownEnabled)) {
d->reset();
} else {
- stepBy(-1);
+ stepBy(increaseStepRate ? -10 : -1);
}
}
return;
@@ -1377,8 +1415,9 @@ QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
- acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0),
- showGroupSeparator(0), wheelDeltaRemainder(0)
+ stepModifier(Qt::ControlModifier), acceleration(0), hoverControl(QStyle::SC_None),
+ buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0), showGroupSeparator(0),
+ wheelDeltaRemainder(0)
{
}
@@ -1629,7 +1668,10 @@ void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false
: QAbstractSpinBox::StepDownEnabled))) {
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
- q->stepBy(up ? 1 : -1);
+ int steps = up ? 1 : -1;
+ if (QGuiApplication::keyboardModifiers() & stepModifier)
+ steps *= 10;
+ q->stepBy(steps);
#ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(q, value);
QAccessible::updateAccessibility(&event);
@@ -1898,6 +1940,11 @@ void QAbstractSpinBoxPrivate::clearCache() const
cachedState = QValidator::Acceptable;
}
+QVariant QAbstractSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ Q_UNUSED(steps)
+ return singleStep;
+}
// --- QSpinBoxValidator ---
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 83bf83d779..87d46c7326 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -127,6 +127,13 @@ public:
virtual void fixup(QString &input) const;
virtual void stepBy(int steps);
+
+ enum StepType {
+ DefaultStepType,
+ AdaptiveDecimalStepType
+ };
+ Q_ENUM(StepType)
+
public Q_SLOTS:
void stepUp();
void stepDown();
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index 8f312fa900..fce88e43f4 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -122,6 +122,8 @@ public:
static int variantCompare(const QVariant &arg1, const QVariant &arg2);
static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max);
+ virtual QVariant calculateAdaptiveDecimalStep(int steps) const;
+
QLineEdit *edit;
QString prefix, suffix, specialValueText;
QVariant value, minimum, maximum, singleStep;
@@ -143,6 +145,8 @@ public:
uint cleared : 1;
uint ignoreUpdateEdit : 1;
QAbstractSpinBox::CorrectionMode correctionMode;
+ QAbstractSpinBox::StepType stepType = QAbstractSpinBox::StepType::DefaultStepType;
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
int acceleration;
QStyle::SubControl hoverControl;
QRect hoverRect;
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 75289e9d1f..3026a5b7d6 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -2629,8 +2629,9 @@ void QDockAreaLayout::removePlaceHolder(const QString &name)
QList<int> index = indexOfPlaceHolder(name);
if (!index.isEmpty())
remove(index);
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
if (!index.isEmpty()) {
dwgw->layoutInfo()->remove(index);
@@ -3065,8 +3066,9 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
{
QDockAreaLayoutItem *item = 0;
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
if (!index.isEmpty()) {
dockWidget->setParent(dwgw);
@@ -3175,7 +3177,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
if (!info->tabbed && info->o == o) {
info->item_list[path.constLast()].size = size;
int totalSize = 0;
- foreach (const QDockAreaLayoutItem &item, info->item_list) {
+ for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) {
if (!item.skip()) {
if (totalSize != 0)
totalSize += sep;
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 5d09e14073..60f88df9af 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -288,7 +288,7 @@ void QLabel::setText(const QString &text)
return;
QWidgetTextControl *oldControl = d->control;
- d->control = 0;
+ d->control = nullptr;
d->clearContents();
d->text = text;
@@ -303,7 +303,7 @@ void QLabel::setText(const QString &text)
d->ensureTextControl();
} else {
delete d->control;
- d->control = 0;
+ d->control = nullptr;
}
if (d->isRichText) {
@@ -714,7 +714,7 @@ void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags)
d->ensureTextControl();
} else {
delete d->control;
- d->control = 0;
+ d->control = nullptr;
}
if (d->control)
@@ -1021,13 +1021,13 @@ void QLabel::paintEvent(QPaintEvent *)
QStyleOption opt;
opt.initFrom(this);
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
cssStyle->styleSheetPalette(this, &opt, &opt.palette);
- }
#endif
if (d->control) {
#ifndef QT_NO_SHORTCUT
- const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
+ const bool underline = static_cast<bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
+ nullptr, this, nullptr));
if (d->shortcutId != 0
&& underline != d->shortcutCursor.charFormat().fontUnderline()) {
QTextCharFormat fmt;
@@ -1294,20 +1294,20 @@ void QLabel::setMovie(QMovie *movie)
void QLabelPrivate::clearContents()
{
delete control;
- control = 0;
+ control = nullptr;
isTextLabel = false;
hasShortcut = false;
#ifndef QT_NO_PICTURE
delete picture;
- picture = 0;
+ picture = nullptr;
#endif
delete scaledpixmap;
- scaledpixmap = 0;
+ scaledpixmap = nullptr;
delete cachedimage;
- cachedimage = 0;
+ cachedimage = nullptr;
delete pixmap;
- pixmap = 0;
+ pixmap = nullptr;
text.clear();
Q_Q(QLabel);
@@ -1321,7 +1321,7 @@ void QLabelPrivate::clearContents()
QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
}
- movie = 0;
+ movie = nullptr;
#endif
#ifndef QT_NO_CURSOR
if (onAnchor) {
@@ -1428,9 +1428,9 @@ void QLabel::setScaledContents(bool enable)
d->scaledcontents = enable;
if (!enable) {
delete d->scaledpixmap;
- d->scaledpixmap = 0;
+ d->scaledpixmap = nullptr;
delete d->cachedimage;
- d->cachedimage = 0;
+ d->cachedimage = nullptr;
}
update(contentsRect());
}
@@ -1629,7 +1629,7 @@ QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
}
if (linkToCopy.isEmpty() && !control)
- return 0;
+ return nullptr;
return control->createStandardContextMenu(p, q_func());
}
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ca6aacc16c..190ff8d2c5 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -497,6 +497,8 @@ void QLineEdit::setClearButtonEnabled(bool enable)
d->removeAction(clearAction);
delete clearAction;
}
+#else
+ Q_UNUSED(enable);
#endif // QT_CONFIG(action)
}
@@ -1676,6 +1678,21 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
*/
/*!
+ \fn void QLineEdit::inputRejected()
+
+ This signal is emitted when the user presses a key that is not
+ considered to be acceptable input. For example, if a key press
+ results in a validator's validate() call to return Invalid.
+ Another case is when trying to enter in more characters beyond the
+ maximum length of the line edit.
+
+ Note: This signal will still be emitted in a case where part of
+ the text is accepted but not all of it is. For example, if there
+ is a maximum length set and the clipboard text is longer than the
+ maximum length when it is pasted.
+*/
+
+/*!
Converts the given key press \a event into a line edit action.
If Return or Enter is pressed and the current text is valid (or
@@ -1946,8 +1963,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
if (!d->placeholderText.isEmpty()) {
const Qt::LayoutDirection layoutDir = d->placeholderText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
const Qt::Alignment alignPhText = QStyle::visualAlignment(layoutDir, QFlag(d->alignment));
- QColor col = pal.text().color();
- col.setAlpha(128);
+ const QColor col = pal.placeholderText().color();
QPen oldpen = p.pen();
p.setPen(col);
Qt::LayoutDirection oldLayoutDir = p.layoutDirection();
@@ -2002,7 +2018,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
// draw text, selections and cursors
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) {
cssStyle->styleSheetPalette(this, &panel, &pal);
}
#endif
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index 6c70a8f44a..de82927f74 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -207,6 +207,7 @@ Q_SIGNALS:
void returnPressed();
void editingFinished();
void selectionChanged();
+ void inputRejected();
protected:
void mousePressEvent(QMouseEvent *) override;
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 0eeff196a8..33d542abc0 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -216,6 +216,7 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(updateNeeded(QRect)),
q, SLOT(_q_updateNeeded(QRect)));
+ QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected()));
QStyleOptionFrame opt;
q->initStyleOption(&opt);
@@ -348,11 +349,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *)
QWindow *window = nullptr;
if (const QWidget *nativeParent = nativeParentWidget())
window = nativeParent->windowHandle();
- // Note isDown should really use the active state but in most styles
- // this has no proper feedback
QIcon::Mode state = QIcon::Disabled;
if (isEnabled())
- state = isDown() ? QIcon::Selected : QIcon::Normal;
+ state = isDown() ? QIcon::Active : QIcon::Normal;
const QLineEditPrivate *lep = lineEditPrivate();
const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
const QSize iconSize(iconWidth, iconWidth);
@@ -466,6 +465,8 @@ void QLineEditPrivate::setClearButtonEnabled(bool enabled)
break;
}
}
+#else
+ Q_UNUSED(enabled);
#endif
}
@@ -483,6 +484,8 @@ void QLineEditPrivate::positionSideWidgets()
#if QT_CONFIG(action)
if (e.action->isVisible())
widgetGeometry.moveLeft(widgetGeometry.left() + delta);
+#else
+ Q_UNUSED(delta);
#endif
}
widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin);
@@ -596,6 +599,8 @@ void QLineEditPrivate::removeAction(QAction *action)
if (!hasSideWidgets()) // Last widget, remove connection
QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
q->update();
+#else
+ Q_UNUSED(action);
#endif // QT_CONFIG(action)
}
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 2014bdabf3..aca38884a7 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1312,8 +1312,12 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
bool QMainWindow::event(QEvent *event)
{
Q_D(QMainWindow);
+
+#if QT_CONFIG(dockwidget)
if (d->layout && d->layout->windowEvent(event))
return true;
+#endif
+
switch (event->type()) {
#if QT_CONFIG(toolbar)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 43c22910f9..053bfbf024 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -426,7 +426,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
}
// Make sure to reparent the possibly floating or hidden QDockWidgets to the parent
- foreach (QDockWidget *dw, findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto dockWidgets = findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidget *dw : dockWidgets) {
bool wasFloating = dw->isFloating();
bool wasHidden = dw->isHidden();
dw->setParent(parentWidget());
@@ -445,7 +446,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
dw->show();
}
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tb, findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly))
+ const auto tabBars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QTabBar *tb : tabBars)
tb->setParent(parentWidget());
#endif
deleteLater();
@@ -1037,10 +1039,10 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const
#if QT_CONFIG(dockwidget)
dockAreaLayout.saveState(stream);
#if QT_CONFIG(tabbar)
- QList<QDockWidgetGroupWindow *> floatingTabs =
+ const QList<QDockWidgetGroupWindow *> floatingTabs =
mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
- foreach (QDockWidgetGroupWindow *floating, floatingTabs) {
+ for (QDockWidgetGroupWindow *floating : floatingTabs) {
if (floating->layoutInfo()->isEmpty())
continue;
stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry();
@@ -1528,9 +1530,9 @@ void QMainWindowLayout::setDocumentMode(bool enabled)
_documentMode = enabled;
// Update the document mode for all tab bars
- foreach (QTabBar *bar, usedTabBars)
+ for (QTabBar *bar : qAsConst(usedTabBars))
bar->setDocumentMode(_documentMode);
- foreach (QTabBar *bar, unusedTabBars)
+ for (QTabBar *bar : qAsConst(unusedTabBars))
bar->setDocumentMode(_documentMode);
}
#endif // QT_CONFIG(tabbar)
@@ -1809,8 +1811,9 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget)
QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget);
if (info)
return info;
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
info = dwgw->layoutInfo()->info(widget);
if (info)
return info;
@@ -2077,8 +2080,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
layoutState.remove(previousPath);
previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget);
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
if (dwgw == currentHoveredFloat)
continue;
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
@@ -2106,8 +2110,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
#if QT_CONFIG(dockwidget)
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
if (!path.isEmpty())
dwgw->layoutInfo()->remove(path);
@@ -2249,7 +2254,8 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
#if QT_CONFIG(dockwidget)
parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ const auto usedTabBarsCopy = usedTabBars; // list potentially modified by animations
+ for (QTabBar *tab_bar : usedTabBarsCopy)
tab_bar->show();
#endif // QT_CONFIG(tabbar)
#endif // QT_CONFIG(dockwidget)
@@ -2533,7 +2539,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
// Check if we are over another floating dock widget
QVarLengthArray<QWidget *, 10> candidates;
- foreach (QObject *c, parentWidget()->children()) {
+ const auto siblings = parentWidget()->children();
+ for (QObject *c : siblings) {
QWidget *w = qobject_cast<QWidget*>(c);
if (!w)
continue;
@@ -2543,7 +2550,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
candidates << w;
if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) {
// Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent.
- foreach (QObject *c, group->children()) {
+ const auto groupChildren = group->children();
+ for (QObject *c : groupChildren) {
if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) {
if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized())
candidates << dw;
@@ -2671,14 +2679,14 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
{
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars();
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups)
used += dwgw->layoutInfo()->usedTabBars();
- }
- QSet<QTabBar*> retired = usedTabBars - used;
+ const QSet<QTabBar*> retired = usedTabBars - used;
usedTabBars = used;
- foreach (QTabBar *tab_bar, retired) {
+ for (QTabBar *tab_bar : retired) {
tab_bar->hide();
while (tab_bar->count() > 0)
tab_bar->removeTab(0);
@@ -2686,10 +2694,10 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
}
if (sep == 1) {
- QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
- QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
+ const QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
+ const QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
usedSeparatorWidgets = usedSeps;
- foreach (QWidget *sepWidget, retiredSeps) {
+ for (QWidget *sepWidget : retiredSeps) {
unusedSeparatorWidgets.append(sepWidget);
}
}
@@ -2731,7 +2739,7 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
#if QT_CONFIG(dockwidget)
if (parentWidget()->isVisible()) {
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ for (QTabBar *tab_bar : qAsConst(usedTabBars))
tab_bar->show();
#endif
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 4ccfb1786e..72cbec2350 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -92,6 +92,7 @@ public:
QPoint hoverPos;
#if QT_CONFIG(dockwidget)
+
#if QT_CONFIG(cursor)
QCursor separatorCursor(const QList<int> &path);
void adjustCursor(const QPoint &pos);
@@ -108,13 +109,15 @@ public:
bool startSeparatorMove(const QPoint &pos);
bool separatorMove(const QPoint &pos);
bool endSeparatorMove(const QPoint &pos);
+ bool windowEvent(QEvent *e);
#endif // QT_CONFIG(dockwidget)
- bool windowEvent(QEvent *e);
};
-#if QT_CONFIG(dockwidget) && QT_CONFIG(cursor)
+#if QT_CONFIG(dockwidget)
+
+#if QT_CONFIG(cursor)
template <typename Layout>
QCursor QMainWindowLayoutSeparatorHelper<Layout>::separatorCursor(const QList<int> &path)
{
@@ -187,14 +190,13 @@ void QMainWindowLayoutSeparatorHelper<Layout>::adjustCursor(const QPoint &pos)
}
}
}
-#endif // QT_CONFIG(cursor) && QT_CONFIG(dockwidget)
+#endif // QT_CONFIG(cursor)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
{
QWidget *w = window();
switch (event->type()) {
-#if QT_CONFIG(dockwidget)
case QEvent::Paint: {
QPainter p(w);
QRegion r = static_cast<QPaintEvent *>(event)->region();
@@ -290,14 +292,12 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
return true;
}
break;
-#endif // QT_CONFIG(dockwidget)
default:
break;
}
return false;
}
-#if QT_CONFIG(dockwidget)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::startSeparatorMove(const QPoint &pos)
{
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 45c01dec80..8639f57ea1 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -471,8 +471,8 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const
ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end());
result.reserve(ylist.size() * xlist.size());
- foreach (int y, ylist)
- foreach (int x, xlist)
+ for (int y : qAsConst(ylist))
+ for (int x : qAsConst(xlist))
result << QRect(QPoint(x, y), size);
return result;
}
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 363647aee0..96635ae505 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2433,7 +2433,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
atAction = d->defaultAction;
// TODO: This works for first level menus, not yet sub menus
} else {
- foreach (QAction *action, d->actions)
+ for (QAction *action : qAsConst(d->actions))
if (action->isEnabled()) {
atAction = action;
break;
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index a4c463fb5b..252d5a79df 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -48,6 +48,7 @@
#include <qdrag.h>
#endif
#include <qclipboard.h>
+#include <qmath.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
#endif
@@ -382,6 +383,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
line.setLineWidth(availableWidth);
line.setPosition(QPointF(margin, height));
height += line.height();
+ if (line.leading() < 0)
+ height += qCeil(line.leading());
blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
}
tl->endLayout();
@@ -1927,8 +1930,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
painter.setClipRect(er);
if (d->placeholderVisible) {
- QColor col = d->control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = d->control->palette().placeholderText().color();
painter.setPen(col);
painter.setClipRect(e->rect());
const int margin = int(document()->documentMargin());
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 561215ec85..7f29c0c52c 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -45,6 +45,8 @@
#include <qvalidator.h>
#include <qdebug.h>
+#include <algorithm>
+#include <cmath>
#include <float.h>
QT_BEGIN_NAMESPACE
@@ -75,6 +77,8 @@ public:
}
int displayIntegerBase;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@@ -100,6 +104,8 @@ public:
// When fiddling with the decimals property, we may lose precision in these properties.
double actualMin;
double actualMax;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
@@ -415,6 +421,41 @@ void QSpinBox::setRange(int minimum, int maximum)
}
/*!
+ Sets the step type for the spin box: single step or adaptive
+ decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \sa QAbstractSpinBox::groupSeparator()
+ \since 5.12
+*/
+
+void QSpinBox::setStepType(QAbstractSpinBox::StepType stepType)
+{
+ Q_D(QSpinBox);
+ d->stepType = stepType;
+}
+
+QAbstractSpinBox::StepType QSpinBox::stepType() const
+{
+ Q_D(const QSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QSpinBox::displayIntegerBase
\brief the base used to display the value of the spin box
@@ -847,6 +888,44 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
}
/*!
+ Sets the step type for the spin box: single step or adaptive
+ decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ It also works for any decimal values, 0.041 is increased to 0.042
+ by stepping once.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \sa QAbstractSpinBox::groupSeparator()
+ \since 5.12
+*/
+
+void QDoubleSpinBox::setStepType(StepType stepType)
+{
+ Q_D(QDoubleSpinBox);
+ d->stepType = stepType;
+}
+
+QAbstractSpinBox::StepType QDoubleSpinBox::stepType() const
+{
+ Q_D(const QDoubleSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QDoubleSpinBox::decimals
\brief the precision of the spin box, in decimals
@@ -1078,6 +1157,22 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
return cachedValue;
}
+QVariant QSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const int intValue = value.toInt();
+ const int absValue = qAbs(intValue);
+
+ if (absValue < 100)
+ return 1;
+
+ const bool valueNegative = intValue < 0;
+ const bool stepsNegative = steps < 0;
+ const int signCompensation = (valueNegative == stepsNegative) ? 0 : 1;
+
+ const int log = static_cast<int>(std::log10(absValue - signCompensation)) - 1;
+ return static_cast<int>(std::pow(10, log));
+}
+
// --- QDoubleSpinBoxPrivate ---
/*!
@@ -1303,6 +1398,27 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
return q->textFromValue(f.toDouble());
}
+QVariant QDoubleSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const double doubleValue = value.toDouble();
+ const double minStep = std::pow(10, -decimals);
+ double absValue = qAbs(doubleValue);
+
+ if (absValue < minStep)
+ return minStep;
+
+ const bool valueNegative = doubleValue < 0;
+ const bool stepsNegative = steps < 0;
+ if (valueNegative != stepsNegative)
+ absValue /= 1.01;
+
+ const double shift = std::pow(10, 1 - std::floor(std::log10(absValue)));
+ const double absRounded = round(absValue * shift) / shift;
+ const double log = floorf(std::log10(absRounded)) - 1;
+
+ return std::max(minStep, std::pow(10, log));
+}
+
/*! \reimp */
bool QSpinBox::event(QEvent *event)
{
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index 73489c9a68..d2eac903fb 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -58,6 +58,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
@@ -86,6 +87,9 @@ public:
void setRange(int min, int max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int displayIntegerBase() const;
void setDisplayIntegerBase(int base);
@@ -121,6 +125,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox
Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
public:
explicit QDoubleSpinBox(QWidget *parent = nullptr);
@@ -147,6 +152,9 @@ public:
void setRange(double min, double max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int decimals() const;
void setDecimals(int prec);
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index 44b9f7d9a1..277d2fd99f 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -327,7 +327,13 @@ void QSplashScreen::drawContents(QPainter *painter)
cursor.select(QTextCursor::Document);
QTextBlockFormat fmt;
fmt.setAlignment(Qt::Alignment(d->currAlign));
+ fmt.setLayoutDirection(layoutDirection());
cursor.mergeBlockFormat(fmt);
+ const QSizeF txtSize = doc.size();
+ if (d->currAlign & Qt::AlignBottom)
+ r.setTop(r.height() - txtSize.height());
+ else if (d->currAlign & Qt::AlignVCenter)
+ r.setTop(r.height() / 2 - txtSize.height() / 2);
painter->save();
painter->translate(r.topLeft());
doc.drawContents(painter);
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 6ee49aa9f0..9e38c8f18a 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -826,7 +826,7 @@ QSplitterLayoutStruct *QSplitterPrivate::findWidget(QWidget *w) const
if (list.at(i)->widget == w)
return list.at(i);
}
- return 0;
+ return nullptr;
}
@@ -855,7 +855,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show
QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
{
Q_Q(QSplitter);
- QSplitterLayoutStruct *sls = 0;
+ QSplitterLayoutStruct *sls = nullptr;
int i;
int last = list.count();
for (i = 0; i < list.size(); ++i) {
@@ -872,12 +872,9 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
if (sls) {
list.move(i,index);
} else {
- QSplitterHandle *newHandle = 0;
sls = new QSplitterLayoutStruct;
- QString tmp = QLatin1String("qt_splithandle_");
- tmp += w->objectName();
- newHandle = q->createHandle();
- newHandle->setObjectName(tmp);
+ QSplitterHandle *newHandle = q->createHandle();
+ newHandle->setObjectName(QLatin1String("qt_splithandle_") + w->objectName());
sls->handle = newHandle;
sls->widget = w;
w->lower();
@@ -1248,7 +1245,7 @@ QSplitterHandle *QSplitter::handle(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->handle;
}
@@ -1262,7 +1259,7 @@ QWidget *QSplitter::widget(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->widget;
}
@@ -1463,7 +1460,7 @@ void QSplitter::moveSplitter(int pos, int index)
void QSplitter::getRange(int index, int *min, int *max) const
{
Q_D(const QSplitter);
- d->getRange(index, min, 0, 0, max);
+ d->getRange(index, min, nullptr, nullptr, max);
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 8af70d0f9c..5959dd0ae4 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -74,6 +74,23 @@
QT_BEGIN_NAMESPACE
+namespace {
+class CloseButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ explicit CloseButton(QWidget *parent = 0);
+
+ QSize sizeHint() const override;
+ QSize minimumSizeHint() const override
+ { return sizeHint(); }
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
+};
+}
+
QMovableTabWidget::QMovableTabWidget(QWidget *parent)
: QWidget(parent)
{
@@ -2686,7 +2703,7 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant &cu
priv->moveTab(priv->tabList.indexOf(*tab), current.toInt());
}
-void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State newState)
+void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State)
{
if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab));
}
@@ -2695,5 +2712,4 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State
QT_END_NAMESPACE
#include "moc_qtabbar.cpp"
-
-#include "moc_qtabbar_p.cpp"
+#include "qtabbar.moc"
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 1092878f2c..3948b42bc1 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -144,7 +144,7 @@ public:
void updateCurrentValue(const QVariant &current) override;
- void updateState(State, State newState) override;
+ void updateState(State newState, State) override;
private:
//these are needed for the callbacks
Tab *tab;
@@ -271,21 +271,6 @@ public:
};
-class CloseButton : public QAbstractButton
-{
- Q_OBJECT
-
-public:
- explicit CloseButton(QWidget *parent = 0);
-
- QSize sizeHint() const override;
- QSize minimumSizeHint() const override
- { return sizeHint(); }
- void enterEvent(QEvent *event) override;
- void leaveEvent(QEvent *event) override;
- void paintEvent(QPaintEvent *event) override;
-};
-
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index fa4dd14c92..46b973bae7 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -163,10 +163,13 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const
fileName = name.toLocalFile();
}
+ if (fileName.isEmpty())
+ return fileName;
+
if (QFileInfo(fileName).isAbsolute())
return fileName;
- foreach (QString path, searchPaths) {
+ for (QString path : qAsConst(searchPaths)) {
if (!path.endsWith(QLatin1Char('/')))
path.append(QLatin1Char('/'));
path.append(fileName);
@@ -1089,6 +1092,8 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)
QByteArray data;
QString fileName = d->findFile(d->resolveUrl(name));
+ if (fileName.isEmpty())
+ return QVariant();
QFile f(fileName);
if (f.open(QFile::ReadOnly)) {
data = f.readAll();
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 5790b1e32e..3a368651de 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1518,8 +1518,7 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
layout->setViewport(QRect());
if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
- QColor col = control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = control->palette().placeholderText().color();
p->setPen(col);
const int margin = int(doc->documentMargin());
p->drawText(viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, placeholderText);
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
index b813cd5e2c..a788d30450 100644
--- a/src/widgets/widgets/qtoolbarlayout_p.h
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -97,7 +97,7 @@ public:
void insertAction(int index, QAction *action);
int indexOf(QAction *action) const;
- int indexOf(QWidget *widget) const override { return QLayout::indexOf(widget); }
+ using QLayout::indexOf; // bring back the hidden members
bool layoutActions(const QSize &size);
QSize expandedSize(const QSize &size) const;
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index c4a928410b..cf2d885b52 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -711,10 +711,12 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
if (m_validInput) {
if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy, false);
+ internalSetText(textCopy, cursorCopy, edited);
return true;
}
m_cursor = cursorCopy;
+ } else {
+ emit inputRejected();
}
}
#endif
@@ -762,6 +764,8 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
if (m_maskData) {
m_text = maskString(0, txt, true);
m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ if (edited && oldText == m_text)
+ emit inputRejected();
} else {
m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
}
@@ -839,6 +843,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
if (m_maskData) {
QString ms = maskString(m_cursor, s);
+ if (ms.isEmpty() && !s.isEmpty())
+ emit inputRejected();
#ifndef QT_NO_ACCESSIBILITY
QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms);
QAccessible::updateAccessibility(&insertEvent);
@@ -867,6 +873,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
m_textDirty = true;
}
+ if (s.length() > remaining)
+ emit inputRejected();
}
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index ca70e2c02f..3e33bc0605 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -545,6 +545,7 @@ Q_SIGNALS:
void accepted();
void editingFinished();
void updateNeeded(const QRect &);
+ void inputRejected();
#ifdef QT_KEYPAD_NAVIGATION
void editFocusChange(bool);