summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp4
-rw-r--r--src/widgets/dialogs/qdialog.cpp3
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp11
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp5
-rw-r--r--src/widgets/dialogs/qmessagebox.qrc5
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp3
-rw-r--r--src/widgets/dialogs/qwizard.cpp6
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp22
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf3
-rw-r--r--src/widgets/doc/snippets/CMakeLists.txt2
-rw-r--r--src/widgets/doc/src/external-resources.qdoc4
-rw-r--r--src/widgets/doc/src/guibooks.qdoc91
-rw-r--r--src/widgets/doc/src/includes/cmake-find-package-widgets.qdocinc2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp1
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp5
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp3
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp60
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h1
-rw-r--r--src/widgets/itemviews/qlistview.cpp2
-rw-r--r--src/widgets/itemviews/qtableview.cpp10
-rw-r--r--src/widgets/itemviews/qtableview_p.h2
-rw-r--r--src/widgets/itemviews/qtablewidget.h8
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp3
-rw-r--r--src/widgets/kernel/qapplication.cpp46
-rw-r--r--src/widgets/kernel/qapplication_p.h4
-rw-r--r--src/widgets/kernel/qlayout.cpp8
-rw-r--r--src/widgets/kernel/qshortcut_widgets.cpp2
-rw-r--r--src/widgets/kernel/qsizepolicy.cpp3
-rw-r--r--src/widgets/kernel/qsizepolicy.h10
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.cpp23
-rw-r--r--src/widgets/kernel/qwidget.cpp24
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetrepaintmanager.cpp117
-rw-r--r--src/widgets/kernel/qwidgetrepaintmanager_p.h5
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp28
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h3
-rw-r--r--src/widgets/styles/qfusionstyle.cpp128
-rw-r--r--src/widgets/styles/qstyle.cpp48
-rw-r--r--src/widgets/styles/qstyle.qrc179
-rw-r--r--src/widgets/styles/qstyleoption.cpp1
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp154
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp10
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp82
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h2
-rw-r--r--src/widgets/widgets/qcheckbox.cpp2
-rw-r--r--src/widgets/widgets/qcombobox.cpp3
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp5
-rw-r--r--src/widgets/widgets/qdial.cpp2
-rw-r--r--src/widgets/widgets/qdockwidget.cpp6
-rw-r--r--src/widgets/widgets/qeffects.cpp2
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp127
-rw-r--r--src/widgets/widgets/qfontcombobox.h9
-rw-r--r--src/widgets/widgets/qframe.cpp5
-rw-r--r--src/widgets/widgets/qlabel.cpp3
-rw-r--r--src/widgets/widgets/qlineedit.cpp6
-rw-r--r--src/widgets/widgets/qmainwindow.cpp13
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qmdisubwindow_p.h2
-rw-r--r--src/widgets/widgets/qmenu.cpp38
-rw-r--r--src/widgets/widgets/qmenu.h2
-rw-r--r--src/widgets/widgets/qmenu_p.h1
-rw-r--r--src/widgets/widgets/qmenubar.cpp2
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp6
-rw-r--r--src/widgets/widgets/qplaintextedit_p.h1
-rw-r--r--src/widgets/widgets/qprogressbar.cpp2
-rw-r--r--src/widgets/widgets/qpushbutton.cpp4
-rw-r--r--src/widgets/widgets/qradiobutton.cpp3
-rw-r--r--src/widgets/widgets/qscrollarea.cpp11
-rw-r--r--src/widgets/widgets/qscrollbar.cpp7
-rw-r--r--src/widgets/widgets/qslider.cpp20
-rw-r--r--src/widgets/widgets/qsplitter.cpp12
-rw-r--r--src/widgets/widgets/qstatusbar.cpp3
-rw-r--r--src/widgets/widgets/qtabbar.cpp121
-rw-r--r--src/widgets/widgets/qtabbar_p.h4
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp3
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp47
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h4
78 files changed, 808 insertions, 810 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 9db8d5687c..8696797b64 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1566,7 +1566,9 @@ QColor QColorDialogPrivate::grabScreenColor(const QPoint &p)
QScreen *screen = QGuiApplication::screenAt(p);
if (!screen)
screen = QGuiApplication::primaryScreen();
- const QPixmap pixmap = screen->grabWindow(0, p.x(), p.y(), 1, 1);
+ const QRect screenRect = screen->geometry();
+ const QPixmap pixmap =
+ screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
const QImage i = pixmap.toImage();
return i.pixel(0, 0);
}
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 8b018969c8..9799f045d9 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -380,8 +380,7 @@ void QDialogPrivate::deletePlatformHelper()
\snippet dialogs/dialogs.cpp 0
- \sa QDialogButtonBox, QTabWidget, QWidget, QProgressDialog,
- {fowler}{GUI Design Handbook: Dialogs, Standard}, {Extension Example},
+ \sa QDialogButtonBox, QTabWidget, QWidget, QProgressDialog, {Extension Example},
{Standard Dialogs Example}
*/
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 935cfeb409..89ecaab81d 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1250,8 +1250,9 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &files
QFileInfo info(name);
// if the filename has no suffix, add the default suffix
const QString defaultSuffix = options->defaultSuffix();
- if (!defaultSuffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1)
+ if (!defaultSuffix.isEmpty() && !info.isDir() && !info.fileName().contains(u'.'))
name += QLatin1Char('.') + defaultSuffix;
+
if (info.isAbsolute()) {
files.append(name);
} else {
@@ -1277,8 +1278,12 @@ QList<QUrl> QFileDialogPrivate::addDefaultSuffixToUrls(const QList<QUrl> &urlsTo
QUrl url = urlsToFix.at(i);
// if the filename has no suffix, add the default suffix
const QString defaultSuffix = options->defaultSuffix();
- if (!defaultSuffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1)
- url.setPath(url.path() + QLatin1Char('.') + defaultSuffix);
+ if (!defaultSuffix.isEmpty()) {
+ const QString urlPath = url.path();
+ const auto idx = urlPath.lastIndexOf(u'/');
+ if (idx != (urlPath.size() - 1) && !QStringView{urlPath}.mid(idx + 1).contains(u'.'))
+ url.setPath(urlPath + u'.' + defaultSuffix);
+ }
urls.append(url);
}
return urls;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 09c14f1ec1..9572b7a807 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -749,8 +749,7 @@ void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button
When an escape button can't be determined using these rules,
pressing \uicontrol Esc has no effect.
- \sa QDialogButtonBox, {fowler}{GUI Design Handbook: Message Box}, {Standard Dialogs Example},
- {Qt Widgets - Application Example}
+ \sa QDialogButtonBox, {Standard Dialogs Example}, {Qt Widgets - Application Example}
*/
/*!
@@ -1896,7 +1895,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
"<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
"<p>Qt is The Qt Company Ltd product developed as an open source "
"project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
- ).arg(QStringLiteral("2021"),
+ ).arg(QStringLiteral("2022"),
QStringLiteral("qt.io/licensing"),
QStringLiteral("qt.io"));
QMessageBox *msgBox = new QMessageBox(parent);
diff --git a/src/widgets/dialogs/qmessagebox.qrc b/src/widgets/dialogs/qmessagebox.qrc
deleted file mode 100644
index de217773ec..0000000000
--- a/src/widgets/dialogs/qmessagebox.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/qt-project.org/qmessagebox">
- <file>images/qtlogo-64.png</file>
-</qresource>
-</RCC>
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index 448acfc7f9..86effc3cb0 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -251,8 +251,7 @@ void QProgressDialogPrivate::_q_disconnectOnClose()
\image fusion-progressdialog.png A progress dialog shown in the Fusion widget style.
- \sa QDialog, QProgressBar, {fowler}{GUI Design Handbook: Progress Indicator},
- {Find Files Example}, {Pixelator Example}
+ \sa QDialog, QProgressBar, {Find Files Example}, {Pixelator Example}
*/
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index e584db0f15..5acc7b880f 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -254,11 +254,11 @@ public:
bool extension = false;
bool sideWidget = false;
- bool operator==(const QWizardLayoutInfo &other);
- inline bool operator!=(const QWizardLayoutInfo &other) { return !operator==(other); }
+ bool operator==(const QWizardLayoutInfo &other) const;
+ inline bool operator!=(const QWizardLayoutInfo &other) const { return !operator==(other); }
};
-bool QWizardLayoutInfo::operator==(const QWizardLayoutInfo &other)
+bool QWizardLayoutInfo::operator==(const QWizardLayoutInfo &other) const
{
return topLevelMarginLeft == other.topLevelMarginLeft
&& topLevelMarginRight == other.topLevelMarginRight
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index 24aa24de20..de180adba1 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -187,8 +187,7 @@ void QVistaHelper::updateCustomMargins(bool vistaMargins)
bool QVistaHelper::isCompositionEnabled()
{
- BOOL bEnabled;
- return SUCCEEDED(DwmIsCompositionEnabled(&bEnabled)) && bEnabled;
+ return true;
}
bool QVistaHelper::isThemeActive()
@@ -669,26 +668,9 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
return value;
}
-#ifndef Q_CC_MSVC
-static inline int getWindowBottomMargin()
-{
- return GetSystemMetrics(SM_CYSIZEFRAME);
-}
-#else
-// QTBUG-36192, GetSystemMetrics(SM_CYSIZEFRAME) returns bogus values
-// for MSVC2012 which leads to the custom margin having no effect since
-// that only works when removing the entire margin.
-static inline int getWindowBottomMargin()
-{
- RECT rect = {0, 0, 0, 0};
- AdjustWindowRectEx(&rect, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
- return qAbs(rect.bottom);
-}
-#endif // Q_CC_MSVC
-
int QVistaHelper::frameSizeDp()
{
- return getWindowBottomMargin();
+ return GetSystemMetrics(SM_CYSIZEFRAME);
}
int QVistaHelper::captionSizeDp()
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index 4659478c38..a67cceef69 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -61,3 +61,6 @@ imagedirs += images \
navigation.landingpage = "Qt Widgets"
navigation.cppclassespage = "Qt Widgets C++ Classes"
manifestmeta.highlighted.names = "QtWidgets/Qt Widgets - Application Example"
+
+# Fail the documentation build if there are more warnings than the limit
+warninglimit = 0
diff --git a/src/widgets/doc/snippets/CMakeLists.txt b/src/widgets/doc/snippets/CMakeLists.txt
index ebf9b38dc2..9bd47894c2 100644
--- a/src/widgets/doc/snippets/CMakeLists.txt
+++ b/src/widgets/doc/snippets/CMakeLists.txt
@@ -1,4 +1,4 @@
#! [cmake_use]
-find_package(Qt6 COMPONENTS Widgets REQUIRED)
+find_package(Qt6 REQUIRED COMPONENTS Widgets)
target_link_libraries(mytarget PRIVATE Qt6::Widgets)
#! [cmake_use]
diff --git a/src/widgets/doc/src/external-resources.qdoc b/src/widgets/doc/src/external-resources.qdoc
index 7e60e995a1..444d538169 100644
--- a/src/widgets/doc/src/external-resources.qdoc
+++ b/src/widgets/doc/src/external-resources.qdoc
@@ -35,3 +35,7 @@
\externalpage http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm
\title Sinclair Spectrum
*/
+/*!
+ \externalpage https://www.pearson.com/us/higher-education/program/Gamma-Design-Patterns-Elements-of-Reusable-Object-Oriented-Software/PGM14333.html
+ \title Design Patterns
+*/
diff --git a/src/widgets/doc/src/guibooks.qdoc b/src/widgets/doc/src/guibooks.qdoc
deleted file mode 100644
index b245e09b5d..0000000000
--- a/src/widgets/doc/src/guibooks.qdoc
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page guibooks.html
- \title Books about GUI Design
- \ingroup best-practices
- \brief Some recommended books about GUI design.
-
- This is not a comprehensive list -- there are many other books worth
- buying. Here we mention just a few user interface books that don't
- gather dust on our shelves.
-
- \b{\l{http://www.amazon.com/gp/product/0132354160/ref=ase_trolltech/}{C++
- GUI Programming with Qt 4, Second Edition}}
- by Jasmin Blanchette and Mark
- Summerfield, ISBN 0-13-235416-0. This is the official Qt book written
- by two veteran Qt Developers. The first edition, which is based on Qt 4.1, is
- \l{http://www.qtrac.eu/C++-GUI-Programming-with-Qt-4-1st-ed.zip}{available for free online}.
- The second edition, based on Qt 4.3, is
- \l{http://www.informit.com/store/product.aspx?isbn=0132354160}{available for purchase as an eBook}.
- The book predates QML and only covers widget based user interfaces.
-
- \b{\l{http://www.amazon.com/exec/obidos/ASIN/0385267746/trolltech/t}{The Design of Everyday Things}}
- by Donald Norman, ISBN 0-38526774-6, is one of the classics of human
- interface design. Norman shows how badly something as simple as a
- kitchen stove can be designed, and everyone should read it who will
- design a dialog box, write an error message, or design just about
- anything else humans are supposed to use.
-
- \target fowler
- \b{\l{http://www.amazon.com/exec/obidos/ASIN/0070592748/trolltech/t}{GUI Design Handbook}}
- by Susan Fowler, ISBN 0-07-059274-8, is an
- alphabetical dictionary of widgets and other user interface elements,
- with comprehensive coverage of each. Each chapter covers one widget
- or other element, contains the most important recommendation from the
- \macos, Windows and Motif style guides, notes about common
- problems, comparison with other widgets that can serve some of the
- same roles as this one, etc.
-
- \target Design Patterns
- \b{\l{http://www.amazon.com/exec/obidos/ASIN/0201633612/103-8144203-3273444}
- {Design Patterns - Elements of Reusable Object-Oriented Software}}
- by Gamma, Helm, Johnson, and Vlissides, ISBN 0-201-63361-2, provides
- more information on the Model-View-Controller (MVC) paradigm, explaining
- MVC and its sub-patterns in detail.
-
- \b{\l{http://www.amazon.com/exec/obidos/ASIN/0201622165/trolltech/t}{Macintosh
- Human Interface Guidelines}}, Second Edition, ISBN
- 0-201-62216-5, is worth buying for the \e {don't}s alone. Even
- if you are not writing software for \macos, avoiding most of what it
- advises against will produce more easily comprehensible software.
- Doing what it tells you to do may also help.
-
- \b{\l{http://www.amazon.com/New-Windows-Interface-Microsoft-Press/dp/1556156790/}{The
- Microsoft Windows User Experience}}, ISBN 1-55615-679-0,
- is Microsoft's look and feel bible. Indispensable for everyone who
- has customers that worship Microsoft, and it's quite good, too.
-
- \b{\l{http://www.amazon.com/exec/obidos/ASIN/047159900X/trolltech/t}{The Icon Book}}
- by William Horton, ISBN 0-471-59900-X, is perhaps the only thorough
- coverage of icons and icon use in software. In order for icons to be
- successful, people must be able to do four things with them: decode,
- recognize, find and activate them. This book explains these goals
- from scratch and how to reach them, both with single icons and icon
- families. Some 500 examples are scattered throughout the text.
-*/
diff --git a/src/widgets/doc/src/includes/cmake-find-package-widgets.qdocinc b/src/widgets/doc/src/includes/cmake-find-package-widgets.qdocinc
index 547e39c0cc..3911ee80b6 100644
--- a/src/widgets/doc/src/includes/cmake-find-package-widgets.qdocinc
+++ b/src/widgets/doc/src/includes/cmake-find-package-widgets.qdocinc
@@ -1,5 +1,5 @@
The command is defined in the \c Widgets component of the \c Qt6 package. Load the package with:
\code
-find_package(Qt6 COMPONENTS Widgets REQUIRED)
+find_package(Qt6 REQUIRED COMPONENTS Widgets)
\endcode
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 69a331a563..606244dd3c 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -10093,6 +10093,7 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event)
case QEvent::GraphicsSceneMouseRelease:
case QEvent::KeyPress:
case QEvent::KeyRelease:
+ case QEvent::InputMethod:
// Reset the focus widget's input context, regardless
// of how this item gained or lost focus.
if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index e6ce275bef..7b381367c3 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -1576,6 +1576,10 @@ void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsIt
if (exposedWidgetRect.isEmpty())
return;
+ // When rendering to pdf etc. painting may go outside widget boundaries unless clipped
+ if (painter->device()->devType() != QInternal::Widget && (flags() & ItemClipsChildrenToShape))
+ painter->setClipRect(d->widget->geometry(), Qt::IntersectClip);
+
d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
}
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 0eceaeacb2..f41ced1a38 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -244,6 +244,7 @@
#include <QtGui/qinputmethod.h>
#include <private/qapplication_p.h>
#include <private/qevent_p.h>
+#include <QtGui/private/qeventpoint_p.h>
#include <private/qobject_p.h>
#if QT_CONFIG(graphicseffect)
#include <private/qgraphicseffect_p.h>
@@ -5840,8 +5841,8 @@ void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouch
item->d_ptr->genericMapFromSceneTransform(static_cast<const QWidget *>(touchEvent->target()));
for (int i = 0; i < touchEvent->pointCount(); ++i) {
- auto &pt = QMutableEventPoint::from(touchEvent->point(i));
- QMutableEventPoint::from(pt).setPosition(mapFromScene.map(pt.scenePosition()));
+ auto &pt = touchEvent->point(i);
+ QMutableEventPoint::setPosition(pt, mapFromScene.map(pt.scenePosition()));
}
}
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index f4b9228e51..df5a275616 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -294,6 +294,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime <
#include <QtWidgets/qstyleoption.h>
#include <private/qevent_p.h>
+#include <QtGui/private/qeventpoint_p.h>
QT_BEGIN_NAMESPACE
@@ -314,7 +315,7 @@ void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEv
auto &pt = touchEvent->point(i);
// the scene will set the item local pos, startPos, lastPos, and rect before delivering to
// an item, but for now those functions are returning the view's local coordinates
- QMutableEventPoint::from(pt).setScenePosition(d->mapToScene(pt.position()));
+ QMutableEventPoint::setScenePosition(pt, d->mapToScene(pt.position()));
// screenPos, startScreenPos, and lastScreenPos are already set
}
}
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index d782eb71ab..43919a2efb 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1791,6 +1791,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
void QAbstractItemView::mousePressEvent(QMouseEvent *event)
{
Q_D(QAbstractItemView);
+ d->releaseFromDoubleClick = false;
d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
QPoint pos = event->position().toPoint();
QPersistentModelIndex index = indexAt(pos);
@@ -1798,8 +1799,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
// this is the mouse press event that closed the last editor (via focus event)
d->pressClosedEditor = d->pressClosedEditorWatcher.isActive() && d->lastEditedIndex == index;
- if (!d->selectionModel
- || (d->state == EditingState && d->hasEditor(index)))
+ if (!d->selectionModel || (d->state == EditingState && d->hasEditor(index)))
return;
d->pressedAlreadySelected = d->selectionModel->isSelected(index);
@@ -1808,10 +1808,9 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
- d->pressedPosition = pos + offset;
- if ((command & QItemSelectionModel::Current) == 0) {
+ d->pressedPosition = d->draggedPosition = pos + offset;
+ if (!(command & QItemSelectionModel::Current))
d->currentSelectionStartIndex = index;
- }
else if (!d->currentSelectionStartIndex.isValid())
d->currentSelectionStartIndex = currentIndex();
@@ -1863,6 +1862,8 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
QPoint topLeft;
QPoint bottomRight = event->position().toPoint();
+ d->draggedPosition = bottomRight + d->offset();
+
if (state() == ExpandingState || state() == CollapsingState)
return;
@@ -1922,10 +1923,10 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
setSelection(selectionRect, command);
// set at the end because it might scroll the view
- if (index.isValid()
- && (index != d->selectionModel->currentIndex())
- && d->isIndexEnabled(index))
+ if (index.isValid() && (index != d->selectionModel->currentIndex()) && d->isIndexEnabled(index))
d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ else if (d->shouldAutoScroll(event->pos()) && !d->autoScrollTimer.isActive())
+ startAutoScroll();
}
}
@@ -2047,6 +2048,7 @@ void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
{
Q_D(QAbstractItemView);
+ d->draggedPosition = event->position().toPoint() + d->offset();
if (dragDropMode() == InternalMove
&& (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
return;
@@ -3980,17 +3982,17 @@ void QAbstractItemView::doAutoScroll()
}
}
- int verticalStep = verticalScroll->pageStep();
- int horizontalStep = horizontalScroll->pageStep();
+ const int verticalStep = verticalScroll->pageStep();
+ const int horizontalStep = horizontalScroll->pageStep();
if (d->autoScrollCount < qMax(verticalStep, horizontalStep))
++d->autoScrollCount;
- int margin = d->autoScrollMargin;
- int verticalValue = verticalScroll->value();
- int horizontalValue = horizontalScroll->value();
+ const int margin = d->autoScrollMargin;
+ const int verticalValue = verticalScroll->value();
+ const int horizontalValue = horizontalScroll->value();
- QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
- QRect area = QWidgetPrivate::get(d->viewport)->clipRect();
+ const QPoint pos = d->draggedPosition - d->offset();
+ const QRect area = QWidgetPrivate::get(d->viewport)->clipRect();
// do the scrolling if we are in the scroll margins
if (pos.y() - area.top() < margin)
@@ -4002,8 +4004,8 @@ void QAbstractItemView::doAutoScroll()
else if (area.right() - pos.x() < margin)
horizontalScroll->setValue(horizontalValue + d->autoScrollCount);
// if nothing changed, stop scrolling
- bool verticalUnchanged = (verticalValue == verticalScroll->value());
- bool horizontalUnchanged = (horizontalValue == horizontalScroll->value());
+ const bool verticalUnchanged = (verticalValue == verticalScroll->value());
+ const bool horizontalUnchanged = (horizontalValue == horizontalScroll->value());
if (verticalUnchanged && horizontalUnchanged) {
stopAutoScroll();
} else {
@@ -4011,6 +4013,30 @@ void QAbstractItemView::doAutoScroll()
d->dropIndicatorRect = QRect();
d->dropIndicatorPosition = QAbstractItemView::OnViewport;
#endif
+ switch (state()) {
+ case QAbstractItemView::DragSelectingState: {
+ // mouseMoveEvent updates the drag-selection rectangle, so fake an event. This also
+ // updates draggedPosition taking the now scrolled viewport into account.
+ const QPoint globalPos = d->viewport->mapToGlobal(pos);
+ const QPoint windowPos = window()->mapFromGlobal(globalPos);
+ QMouseEvent mm(QEvent::MouseMove, pos, windowPos, globalPos,
+ Qt::NoButton, Qt::LeftButton, d->pressedModifiers,
+ Qt::MouseEventSynthesizedByQt);
+ QApplication::sendEvent(viewport(), &mm);
+ break;
+ }
+ case QAbstractItemView::DraggingState: {
+ // we can't simulate mouse (it would throw off the drag'n'drop state logic) or drag
+ // (we don't have the mime data or the actions) move events during drag'n'drop, so
+ // update our dragged position manually after the scroll. "pos" is the old
+ // draggedPosition - d->offset(), and d->offset() is now updated after scrolling, so
+ // pos + d->offset() gives us the new position.
+ d->draggedPosition = pos + d->offset();
+ break;
+ }
+ default:
+ break;
+ }
d->viewport->update();
}
}
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 74850de992..14fae86c87 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -375,6 +375,7 @@ public:
QPersistentModelIndex currentSelectionStartIndex;
Qt::KeyboardModifiers pressedModifiers;
QPoint pressedPosition;
+ QPoint draggedPosition;
bool pressedAlreadySelected;
bool releaseFromDoubleClick;
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 0dba849711..4dd7365113 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -690,7 +690,7 @@ void QListView::reset()
void QListView::setRootIndex(const QModelIndex &index)
{
Q_D(QListView);
- d->column = qBound(0, d->column, d->model->columnCount(index) - 1);
+ d->column = qMax(0, qMin(d->column, d->model->columnCount(index) - 1));
QAbstractItemView::setRootIndex(index);
// sometimes we get an update before reset() is called
d->clear();
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index c3138860fa..d1b82c2511 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1496,7 +1496,7 @@ void QTableView::paintEvent(QPaintEvent *event)
const int gridSize = showGrid ? 1 : 0;
const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);
const QColor gridColor = QColor::fromRgba(static_cast<QRgb>(gridHint));
- const QPen gridPen = QPen(gridColor, 0, d->gridStyle);
+ const QPen gridPen = QPen(gridColor, 1, d->gridStyle);
const QHeaderView *verticalHeader = d->verticalHeader;
const QHeaderView *horizontalHeader = d->horizontalHeader;
const bool alternate = d->alternatingColors;
@@ -1630,7 +1630,8 @@ void QTableView::paintEvent(QPaintEvent *event)
int rowY = rowViewportPosition(row);
rowY += offset.y();
int rowh = rowHeight(row) - gridSize;
- painter.drawLine(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
+ QLineF line(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
+ painter.drawLine(line.translated(0.5, 0.5));
}
// Paint each column
@@ -1642,7 +1643,8 @@ void QTableView::paintEvent(QPaintEvent *event)
colp += offset.x();
if (!rightToLeft)
colp += columnWidth(col) - gridSize;
- painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());
+ QLineF line(colp, dirtyArea.top(), colp, dirtyArea.bottom());
+ painter.drawLine(line.translated(0.5, 0.5));
}
const bool drawWhenHidden = style()->styleHint(QStyle::SH_Table_AlwaysDrawLeftTopGridLines,
&option, this);
@@ -3465,7 +3467,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
if (q->selectionMode() != QTableView::SingleSelection
&& command.testFlag(QItemSelectionModel::Toggle)) {
if (anchor)
- ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
+ ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns(row).contains(index)
? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
command &= ~QItemSelectionModel::Toggle;
command |= ctrlDragSelectionFlag;
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 23095c0087..a0c22cd9f5 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -130,7 +130,7 @@ private:
Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_RELOCATABLE_TYPE);
-class QTableViewPrivate : public QAbstractItemViewPrivate
+class Q_AUTOTEST_EXPORT QTableViewPrivate : public QAbstractItemViewPrivate
{
Q_DECLARE_PUBLIC(QTableView)
public:
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index 3978bc23d6..46711c8fa0 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -57,12 +57,12 @@ public:
: m_top(top), m_left(left), m_bottom(bottom), m_right(right)
{}
- friend inline bool operator==(const QTableWidgetSelectionRange &lhs,
- const QTableWidgetSelectionRange &rhs)
+ friend bool operator==(const QTableWidgetSelectionRange &lhs,
+ const QTableWidgetSelectionRange &rhs) noexcept
{ return lhs.m_top == rhs.m_top && lhs.m_left == rhs.m_left
&& lhs.m_bottom == rhs.m_bottom && lhs.m_right == rhs.m_right; };
- friend inline bool operator!=(const QTableWidgetSelectionRange &lhs,
- const QTableWidgetSelectionRange &rhs)
+ friend bool operator!=(const QTableWidgetSelectionRange &lhs,
+ const QTableWidgetSelectionRange &rhs) noexcept
{ return !(lhs == rhs); }
inline int topRow() const { return m_top; }
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index cc94149e84..31e075a788 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -2513,9 +2513,6 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
This signal is emitted when the specified \a item is expanded so that
all of its children are displayed.
- \note This signal will not be emitted if an item changes its state when
- expandAll() is invoked.
-
\sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem()
*/
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 6ad6004030..f3deab05a1 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -92,6 +92,7 @@
#include <private/qthread_p.h>
#include <QtGui/private/qevent_p.h>
+#include <QtGui/private/qeventpoint_p.h>
#include <private/qfont_p.h>
#if QT_CONFIG(action)
#include <private/qaction_p.h>
@@ -1955,7 +1956,10 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
// \a next). This is to ensure that we can tab in and out of compound widgets
// without getting stuck in a tab-loop between parent and child.
QWidget *focusProxy = test->d_func()->deepestFocusProxy();
- const bool canTakeFocus = ((focusProxy ? focusProxy->focusPolicy() : test->focusPolicy())
+ auto effectiveFocusPolicy = [](QWidget *widget) {
+ return widget->isEnabled() ? widget->focusPolicy() : Qt::NoFocus;
+ };
+ const bool canTakeFocus = (effectiveFocusPolicy(focusProxy ? focusProxy : test)
& focus_flag) == focus_flag;
const bool composites = focusProxy ? (next ? focusProxy->isAncestorOf(test)
: test->isAncestorOf(focusProxy))
@@ -2944,7 +2948,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
break;
- QMutableSinglePointEvent::from(we).mutablePoint().setPosition(we.position() + w->pos());
+ QMutableEventPoint::setPosition(we.point(0), we.position() + w->pos());
w = w->parentWidget();
} while (w);
wheel->setAccepted(eventAccepted);
@@ -3149,15 +3153,16 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
w = w->parentWidget();
touchEvent->setTarget(w);
for (int i = 0; i < touchEvent->pointCount(); ++i) {
- auto &pt = QMutableEventPoint::from(touchEvent->point(i));
- pt.setPosition(pt.position() + offset);
+ auto &pt = touchEvent->point(i);
+ QMutableEventPoint::setPosition(pt, pt.position() + offset);
}
}
#ifndef QT_NO_GESTURES
if (!eventAccepted && !gesturePendingWidget.isNull()) {
- // the first widget subscribed to a gesture gets an implicit grab
- d->activateImplicitTouchGrab(gesturePendingWidget, touchEvent);
+ // the first widget subscribed to a gesture gets an implicit grab for all
+ // points, also for events and event points that have not been accepted.
+ d->activateImplicitTouchGrab(gesturePendingWidget, touchEvent, QApplicationPrivate::GrabAllPoints);
}
#endif
@@ -3279,11 +3284,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
res = d->notify_helper(receiver, e);
break;
}
- } else if (receiver->isWindowType()) {
- res = d->notify_helper(receiver, e);
- // We don't call QGuiApplication::notify here, so we need to duplicate the logic
- if (res && e->type() == QEvent::Close)
- d->maybeLastWindowClosed(static_cast<QWindow *>(receiver));
} else {
res = d->notify_helper(receiver, e);
}
@@ -3803,8 +3803,8 @@ bool QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven
bool containsPress = false;
for (int i = 0; i < touchEvent->pointCount(); ++i) {
- auto &pt = QMutableEventPoint::from(touchEvent->point(i));
- pt.setPosition(widget->mapFromGlobal(pt.globalPosition()));
+ auto &pt = touchEvent->point(i);
+ QMutableEventPoint::setPosition(pt, widget->mapFromGlobal(pt.globalPosition()));
if (pt.state() == QEventPoint::State::Pressed)
containsPress = true;
@@ -3846,24 +3846,26 @@ QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice
if (closestTouchPointId == -1 || distance < closestDistance) {
closestTouchPointId = pt.id();
closestDistance = distance;
- closestTarget = static_cast<const QMutableEventPoint &>(pt).target();
+ closestTarget = QMutableEventPoint::target(pt);
}
}
}
return static_cast<QWidget *>(closestTarget);
}
-void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchEvent)
+void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchEvent,
+ ImplicitTouchGrabMode grabMode)
{
if (touchEvent->type() != QEvent::TouchBegin)
return;
// If the widget dispatched the event further (see QGraphicsProxyWidget), then
- // there might already be an implicit grabber. Don't override that.
+ // there might already be an implicit grabber. Don't override that. A widget that
+ // has partially recognized a gesture needs to grab all points.
for (int i = 0; i < touchEvent->pointCount(); ++i) {
- auto &mep = QMutableEventPoint::from(touchEvent->point(i));
- if (!mep.target() && mep.isAccepted())
- mep.setTarget(widget);
+ auto &ep = touchEvent->point(i);
+ if (!QMutableEventPoint::target(ep) && (ep.isAccepted() || grabMode == GrabAllPoints))
+ QMutableEventPoint::setTarget(ep, widget);
}
// TODO setExclusiveGrabber() to be consistent with Qt Quick?
}
@@ -3912,9 +3914,9 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, const QTouchEv
// on touch pads, implicitly grab all touch points
// on touch screens, grab touch points that are redirected to the closest widget
if (device->type() == QInputDevice::DeviceType::TouchPad || usingClosestWidget)
- QMutableEventPoint::from(touchPoint).setTarget(target);
+ QMutableEventPoint::setTarget(touchPoint, target);
} else {
- target = QMutableEventPoint::from(touchPoint).target();
+ target = QMutableEventPoint::target(touchPoint);
if (!target)
continue;
}
@@ -4015,7 +4017,7 @@ void QApplicationPrivate::translateTouchCancel(const QPointingDevice *device, ul
const QPointingDevicePrivate *devPriv = QPointingDevicePrivate::get(device);
for (auto &epd : devPriv->activePoints.values()) {
const auto &pt = epd.eventPoint;
- QObject *target = static_cast<const QMutableEventPoint &>(pt).target();
+ QObject *target = QMutableEventPoint::target(pt);
if (target && target->isWidgetType())
widgetsNeedingCancel.insert(static_cast<QWidget *>(target));
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 6bb1f35d1b..155081fd79 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -248,7 +248,9 @@ public:
QWidget *findClosestTouchPointTarget(const QPointingDevice *device, const QEventPoint &touchPoint);
void appendTouchPoint(const QEventPoint &touchPoint);
void removeTouchPoint(int touchPointId);
- void activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchBeginEvent);
+ enum ImplicitTouchGrabMode { GrabAcceptedPoints, GrabAllPoints };
+ void activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchBeginEvent,
+ ImplicitTouchGrabMode grabMode = GrabAcceptedPoints);
static bool translateRawTouchEvent(QWidget *widget, const QTouchEvent *touchEvent);
static void translateTouchCancel(const QPointingDevice *device, ulong timestamp);
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 044176d141..2867bd9fb1 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -570,12 +570,14 @@ void QLayout::widgetEvent(QEvent *e)
case QEvent::ChildRemoved:
{
QChildEvent *c = (QChildEvent *)e;
- if (c->child()->isWidgetType()) {
+ QObject *child = c->child();
+ QObjectPrivate *op = QObjectPrivate::get(child);
+ if (op->wasWidget) {
#if QT_CONFIG(menubar)
- if (c->child() == d->menubar)
+ if (child == d->menubar)
d->menubar = nullptr;
#endif
- removeWidgetRecursively(this, c->child());
+ removeWidgetRecursively(this, child);
}
}
break;
diff --git a/src/widgets/kernel/qshortcut_widgets.cpp b/src/widgets/kernel/qshortcut_widgets.cpp
index 9e64376fce..8beb4ce5d6 100644
--- a/src/widgets/kernel/qshortcut_widgets.cpp
+++ b/src/widgets/kernel/qshortcut_widgets.cpp
@@ -307,7 +307,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge
continue;
#endif
QAction *a = menu->menuAction();
- if (correctActionContext(context, a, active_window))
+ if (a->isVisible() && a->isEnabled() && correctActionContext(context, a, active_window))
return true;
} else
#endif
diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp
index c354d14f5e..fe34ef5982 100644
--- a/src/widgets/kernel/qsizepolicy.cpp
+++ b/src/widgets/kernel/qsizepolicy.cpp
@@ -317,9 +317,8 @@ void QSizePolicy::setControlType(ControlType type) noexcept
*/
/*!
- \fn size_t qHash(QSizePolicy key, size_t seed = 0)
+ \fn size_t QSizePolicy::qHash(QSizePolicy key, size_t seed = 0)
\since 5.6
- \relates QSizePolicy
Returns the hash value for \a key, using
\a seed to seed the calculation.
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
index 24db99354b..53c7afc906 100644
--- a/src/widgets/kernel/qsizepolicy.h
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -43,14 +43,13 @@
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qalgorithms.h>
+#include <QtCore/qhashfunctions.h>
QT_BEGIN_NAMESPACE
class QVariant;
class QSizePolicy;
-Q_DECL_CONST_FUNCTION inline size_t qHash(QSizePolicy key, size_t seed = 0) noexcept;
-
class Q_WIDGETS_EXPORT QSizePolicy
{
Q_GADGET
@@ -108,9 +107,10 @@ public:
constexpr void setVerticalPolicy(Policy d) noexcept { bits.verPolicy = d; }
void setControlType(ControlType type) noexcept;
+ // ### Qt 7: consider making Policy a QFlags and removing these casts
constexpr Qt::Orientations expandingDirections() const noexcept {
- return ( (verticalPolicy() & int(ExpandFlag)) ? Qt::Vertical : Qt::Orientations() )
- | ( (horizontalPolicy() & int(ExpandFlag)) ? Qt::Horizontal : Qt::Orientations() ) ;
+ return ( (verticalPolicy() & static_cast<Policy>(ExpandFlag)) ? Qt::Vertical : Qt::Orientations() )
+ | ( (horizontalPolicy() & static_cast<Policy>(ExpandFlag)) ? Qt::Horizontal : Qt::Orientations() ) ;
}
constexpr void setHeightForWidth(bool b) noexcept { bits.hfw = b; }
@@ -121,7 +121,7 @@ public:
constexpr bool operator==(const QSizePolicy& s) const noexcept { return data == s.data; }
constexpr bool operator!=(const QSizePolicy& s) const noexcept { return data != s.data; }
- friend Q_DECL_CONST_FUNCTION size_t qHash(QSizePolicy key, size_t seed) noexcept { return qHash(key.data, seed); }
+ friend Q_DECL_CONST_FUNCTION size_t qHash(QSizePolicy key, size_t seed = 0) noexcept { return qHash(key.data, seed); }
operator QVariant() const;
diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp
index c9116fcef6..acc69d098c 100644
--- a/src/widgets/kernel/qtestsupport_widgets.cpp
+++ b/src/widgets/kernel/qtestsupport_widgets.cpp
@@ -46,6 +46,7 @@
#include <QtCore/qthread.h>
#include <QtGui/qtestsupport_gui.h>
#include <QtGui/private/qevent_p.h>
+#include <QtGui/private/qeventpoint_p.h>
QT_BEGIN_NAMESPACE
@@ -100,30 +101,30 @@ QTouchEventWidgetSequence::~QTouchEventWidgetSequence()
QTouchEventWidgetSequence& QTouchEventWidgetSequence::press(int touchId, const QPoint &pt, QWidget *widget)
{
- auto &p = QMutableEventPoint::from(point(touchId));
- p.setGlobalPosition(mapToScreen(widget, pt));
- p.setState(QEventPoint::State::Pressed);
+ auto &p = point(touchId);
+ QMutableEventPoint::setGlobalPosition(p, mapToScreen(widget, pt));
+ QMutableEventPoint::setState(p, QEventPoint::State::Pressed);
return *this;
}
QTouchEventWidgetSequence& QTouchEventWidgetSequence::move(int touchId, const QPoint &pt, QWidget *widget)
{
- auto &p = QMutableEventPoint::from(point(touchId));
- p.setGlobalPosition(mapToScreen(widget, pt));
- p.setState(QEventPoint::State::Updated);
+ auto &p = point(touchId);
+ QMutableEventPoint::setGlobalPosition(p, mapToScreen(widget, pt));
+ QMutableEventPoint::setState(p, QEventPoint::State::Updated);
return *this;
}
QTouchEventWidgetSequence& QTouchEventWidgetSequence::release(int touchId, const QPoint &pt, QWidget *widget)
{
- auto &p = QMutableEventPoint::from(point(touchId));
- p.setGlobalPosition(mapToScreen(widget, pt));
- p.setState(QEventPoint::State::Released);
+ auto &p = point(touchId);
+ QMutableEventPoint::setGlobalPosition(p, mapToScreen(widget, pt));
+ QMutableEventPoint::setState(p, QEventPoint::State::Released);
return *this;
}
QTouchEventWidgetSequence& QTouchEventWidgetSequence::stationary(int touchId)
{
- auto &p = QMutableEventPoint::from(pointOrPreviousPoint(touchId));
- p.setState(QEventPoint::State::Stationary);
+ auto &p = pointOrPreviousPoint(touchId);
+ QMutableEventPoint::setState(p, QEventPoint::State::Stationary);
return *this;
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index e6b49e8c45..80dcadb81f 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -203,7 +203,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
version, QObjectPrivateVersion);
#endif
- isWidget = true;
+ willBeWidget = true; // used in QObject's ctor
memset(high_attributes, 0, sizeof(high_attributes));
#ifdef QWIDGET_EXTRA_DEBUG
@@ -978,6 +978,9 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
{
Q_Q(QWidget);
+ isWidget = true;
+ wasWidget = true;
+
Q_ASSERT_X(q != parentWidget, Q_FUNC_INFO, "Cannot parent a QWidget to itself");
if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
@@ -1101,6 +1104,11 @@ QWindow *QWidgetPrivate::_q_closestWindowHandle() const
QScreen *QWidgetPrivate::associatedScreen() const
{
+#if QT_CONFIG(graphicsview)
+ // embedded widgets never have a screen associated, let QWidget::screen fall back to toplevel
+ if (nearestGraphicsProxyWidget(q_func()))
+ return nullptr;
+#endif
if (auto window = windowHandle(WindowHandleMode::Closest))
return window->screen();
return nullptr;
@@ -1541,6 +1549,8 @@ QWidget::~QWidget()
#if QT_CONFIG(graphicseffect)
delete d->graphicsEffect;
#endif
+
+ d->isWidget = false;
}
int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
@@ -5463,10 +5473,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
(source->d_func());
if (!sourced->context) {
- QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, repaintManager);
+ const QRegion effectRgn(rgn.boundingRect());
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
sourced->context = &context;
if (!sharedPainter) {
- setSystemClip(pdev->paintEngine(), pdev->devicePixelRatio(), rgn.translated(offset));
+ setSystemClip(pdev->paintEngine(), pdev->devicePixelRatio(), effectRgn.translated(offset));
QPainter p(pdev);
p.translate(offset);
context.painter = &p;
@@ -5480,7 +5491,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
}
sharedPainter->save();
sharedPainter->translate(offset);
- setSystemClip(sharedPainter->paintEngine(), sharedPainter->device()->devicePixelRatio(), rgn.translated(offset));
+ setSystemClip(sharedPainter->paintEngine(), sharedPainter->device()->devicePixelRatio(), effectRgn.translated(offset));
graphicsEffect->draw(sharedPainter);
setSystemClip(sharedPainter->paintEngine(), 1, QRegion());
sharedPainter->restore();
@@ -5488,7 +5499,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
sourced->context = nullptr;
if (repaintManager)
- repaintManager->markNeedsFlush(q, rgn, offset);
+ repaintManager->markNeedsFlush(q, effectRgn, offset);
return;
}
@@ -8890,8 +8901,7 @@ bool QWidget::event(QEvent *event)
inputMethodEvent((QInputMethodEvent *) event);
break;
- case QEvent::InputMethodQuery:
- if (testAttribute(Qt::WA_InputMethodEnabled)) {
+ case QEvent::InputMethodQuery: {
QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(event);
Qt::InputMethodQueries queries = query->queries();
for (uint i = 0; i < 32; ++i) {
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index db458be7f1..41f343dfec 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -390,6 +390,7 @@ public:
void invalidateBackingStore(const T &);
QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
+ bool isOverlapped(const QRect &rect) const { return !overlappedRegion(rect, true).isEmpty(); }
void syncBackingStore();
void syncBackingStore(const QRegion &region);
diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp
index 977a746c5a..16ff8ea721 100644
--- a/src/widgets/kernel/qwidgetrepaintmanager.cpp
+++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp
@@ -414,25 +414,6 @@ static bool hasPlatformWindow(QWidget *widget)
return widget && widget->windowHandle() && widget->windowHandle()->handle();
}
-static QList<QRect> getSortedRectsToScroll(const QRegion &region, int dx, int dy)
-{
- QList<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)
@@ -442,14 +423,13 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
return;
QWidget *tlw = q->window();
- QTLWExtra* x = tlw->d_func()->topData();
static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_MOVE") == 0;
- QWidget *pw = q->parentWidget();
- QPoint toplevelOffset = pw->mapTo(tlw, QPoint());
- QWidgetPrivate *pd = pw->d_func();
- QRect clipR(pd->clipRect());
+ QWidget *parentWidget = q->parentWidget();
+ QPoint toplevelOffset = parentWidget->mapTo(tlw, QPoint());
+ QWidgetPrivate *parentPrivate = parentWidget->d_func();
+ const QRect clipR(parentPrivate->clipRect());
const QRect newRect(rect.translated(dx, dy));
QRect destRect = rect.intersected(clipR);
if (destRect.isValid())
@@ -458,60 +438,40 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
const QRect parentRect(rect & clipR);
const bool nativeWithTextureChild = textureChildSeen && hasPlatformWindow(q);
- const bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
+ bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild && sourceRect.isValid()
#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));
+ QRegion parentRegion(effectiveRectFor(parentRect));
if (!extra || !extra->hasMask) {
- parentR -= newRect;
+ parentRegion -= newRect;
} else {
// invalidateBackingStore() excludes anything outside the mask
- parentR += newRect & clipR;
+ parentRegion += newRect & clipR;
}
- pd->invalidateBackingStore(parentR);
+ parentPrivate->invalidateBackingStore(parentRegion);
invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft()));
} else {
-
- QWidgetRepaintManager *repaintManager = x->repaintManager.get();
+ QWidgetRepaintManager *repaintManager = QWidgetPrivate::get(tlw)->maybeRepaintManager();
+ Q_ASSERT(repaintManager);
QRegion childExpose(newRect & clipR);
- QRegion overlappedExpose;
- if (sourceRect.isValid()) {
- overlappedExpose = (overlappedRegion(sourceRect) | overlappedRegion(destRect)) & clipR;
-
- const qreal factor = QHighDpiScaling::factor(q->windowHandle());
- if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
- const QList<QRect> rectsToScroll =
- getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
- for (QRect r : rectsToScroll) {
- if (repaintManager->bltRect(r, dx, dy, pw)) {
- childExpose -= r.translated(dx, dy);
- }
- }
- }
-
- childExpose -= overlappedExpose;
- }
+ if (repaintManager->bltRect(sourceRect, dx, dy, parentWidget))
+ childExpose -= destRect;
- if (!pw->updatesEnabled())
+ if (!parentWidget->updatesEnabled())
return;
const bool childUpdatesEnabled = q->updatesEnabled();
- if (childUpdatesEnabled) {
- if (!overlappedExpose.isEmpty()) {
- overlappedExpose.translate(-data.crect.topLeft());
- invalidateBackingStore(overlappedExpose);
- }
- if (!childExpose.isEmpty()) {
- childExpose.translate(-data.crect.topLeft());
- repaintManager->markDirty(childExpose, q);
- isMoved = true;
- }
+
+ if (childUpdatesEnabled && !childExpose.isEmpty()) {
+ childExpose.translate(-data.crect.topLeft());
+ repaintManager->markDirty(childExpose, q);
+ isMoved = true;
}
QRegion parentExpose(parentRect);
@@ -520,14 +480,14 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft());
if (!parentExpose.isEmpty()) {
- repaintManager->markDirty(parentExpose, pw);
- pd->isMoved = true;
+ repaintManager->markDirty(parentExpose, parentWidget);
+ parentPrivate->isMoved = true;
}
if (childUpdatesEnabled) {
QRegion needsFlush(sourceRect);
needsFlush += destRect;
- repaintManager->markNeedsFlush(pw, needsFlush, toplevelOffset);
+ repaintManager->markNeedsFlush(parentWidget, needsFlush, toplevelOffset);
}
}
}
@@ -537,20 +497,20 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
{
Q_Q(QWidget);
QWidget *tlw = q->window();
- QTLWExtra* x = tlw->d_func()->topData();
- QWidgetRepaintManager *repaintManager = x->repaintManager.get();
+ QWidgetRepaintManager *repaintManager = QWidgetPrivate::get(tlw)->maybeRepaintManager();
if (!repaintManager)
return;
static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_SCROLL") == 0;
- const QRect clipR = clipRect();
- const QRect scrollRect = rect & clipR;
- const bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent);
+ const 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())));
if (!accelerateScroll) {
- if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) {
+ if (overlapped) {
QRegion region(scrollRect);
subtractOpaqueSiblings(region);
invalidateBackingStore(region);
@@ -562,23 +522,12 @@ 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);
-
- const qreal factor = QHighDpiScaling::factor(q->windowHandle());
- if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
- const QList<QRect> rectsToScroll =
- getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
- for (const QRect &r : rectsToScroll) {
- if (repaintManager->bltRect(r, dx, dy, q)) {
- childExpose -= r.translated(dx, dy);
- }
- }
+ if (sourceRect.isValid()) {
+ if (repaintManager->bltRect(sourceRect, dx, dy, q))
+ childExpose -= destRect;
}
- childExpose -= overlappedExpose;
-
if (inDirtyList) {
if (rect == q->rect()) {
dirty.translate(dx, dy);
@@ -595,8 +544,6 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
if (!q->updatesEnabled())
return;
- if (!overlappedExpose.isEmpty())
- invalidateBackingStore(overlappedExpose);
if (!childExpose.isEmpty()) {
repaintManager->markDirty(childExpose, q);
isScrolled = true;
diff --git a/src/widgets/kernel/qwidgetrepaintmanager_p.h b/src/widgets/kernel/qwidgetrepaintmanager_p.h
index 8b792617ec..89f65e05bc 100644
--- a/src/widgets/kernel/qwidgetrepaintmanager_p.h
+++ b/src/widgets/kernel/qwidgetrepaintmanager_p.h
@@ -100,6 +100,9 @@ public:
void moveStaticWidgets(QWidget *reparented);
void removeStaticWidget(QWidget *widget);
QRegion staticContents(QWidget *widget = nullptr, const QRect &withinClipRect = QRect()) const;
+ QRegion dirtyRegion() const { return dirty; }
+ QList<QWidget *> dirtyWidgetList() const { return dirtyWidgets; }
+ bool isDirty() const;
bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);
@@ -121,8 +124,6 @@ private:
void flush();
void flush(QWidget *widget, const QRegion &region, QPlatformTextureList *widgetTextures);
- bool isDirty() const;
-
bool hasStaticContents() const;
void updateStaticContentsSize();
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index ba1230301e..14a2655e35 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -120,6 +120,7 @@ public:
}
bool participatesInLastWindowClosed() const override;
+ bool treatAsVisible() const override;
};
QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
@@ -230,6 +231,7 @@ static inline bool shouldBePropagatedToWidget(QEvent *event)
case QEvent::ChildAdded:
case QEvent::ChildRemoved:
case QEvent::Paint:
+ case QEvent::Close: // Propagated manually in closeEvent
return false;
default:
return true;
@@ -242,15 +244,6 @@ bool QWidgetWindow::event(QEvent *event)
return QWindow::event(event);
switch (event->type()) {
- case QEvent::Close: {
- // The widget might be deleted in the close event handler.
- QPointer<QObject> guard = this;
- handleCloseEvent(static_cast<QCloseEvent *>(event));
- if (guard)
- QWindow::event(event);
- return true;
- }
-
case QEvent::Enter:
case QEvent::Leave:
handleEnterLeaveEvent(event);
@@ -624,7 +617,8 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
receiver = qt_button_down;
else if (popupChild)
receiver = popupChild;
- QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPosition().toPoint(), event->modifiers());
+ const QPoint localPos = receiver->mapFromGlobal(event->globalPosition().toPoint());
+ QContextMenuEvent e(QContextMenuEvent::Mouse, localPos, event->globalPosition().toPoint(), event->modifiers());
QApplication::forwardEvent(receiver, &e, event);
}
#else
@@ -838,7 +832,7 @@ void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
}
}
-void QWidgetWindow::handleCloseEvent(QCloseEvent *event)
+void QWidgetWindow::closeEvent(QCloseEvent *event)
{
Q_D(QWidgetWindow);
bool accepted = m_widget->d_func()->handleClose(d->inClose ? QWidgetPrivate::CloseWithEvent
@@ -860,6 +854,18 @@ bool QWidgetWindowPrivate::participatesInLastWindowClosed() const
return QWindowPrivate::participatesInLastWindowClosed();
}
+bool QWidgetWindowPrivate::treatAsVisible() const
+{
+ Q_Q(const QWidgetWindow);
+
+ // Widget windows may have Qt::WA_DontShowOnScreen, in which case the
+ // QQWidget will be visible, but the corresponding QWindow will not.
+ // Since the lastWindowClosed logic relies on checking whether the
+ // closed window was visible, and if there are any remaining visible
+ // windows, we need to reflect the QWidget state, not the QWindow one.
+ return q->widget()->isVisible();
+}
+
#if QT_CONFIG(wheelevent)
void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index eb2bed26e3..0ad3ec5062 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -83,7 +83,8 @@ public:
protected:
bool event(QEvent *) override;
- void handleCloseEvent(QCloseEvent *);
+ void closeEvent(QCloseEvent *) override;
+
void handleEnterLeaveEvent(QEvent *);
void handleFocusInEvent(QFocusEvent *);
void handleKeyEvent(QKeyEvent *);
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 5b268aa684..43e9c38f07 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -104,9 +104,7 @@ enum Direction {
// from windows style
static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsItemHMargin = 3; // menu item hor text margin
static const int windowsItemVMargin = 8; // menu item ver text margin
-static const int windowsRightBorder = 15; // right border on windows
static const int groupBoxBottomMargin = 0; // space below the groupbox
static const int groupBoxTopMargin = 3;
@@ -1548,34 +1546,36 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
const int margin = int(QStyleHelper::dpiScaled(5, option));
if (!menuItem->text.isEmpty()) {
painter->setFont(menuItem->font);
- proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0), Qt::AlignLeft | Qt::AlignVCenter,
+ proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0),
+ Qt::AlignLeft | Qt::AlignVCenter,
menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
QPalette::Text);
w = menuItem->fontMetrics.horizontalAdvance(menuItem->text) + margin;
}
painter->setPen(shadow.lighter(106));
- bool reverse = menuItem->direction == Qt::RightToLeft;
+ const bool reverse = menuItem->direction == Qt::RightToLeft;
painter->drawLine(menuItem->rect.left() + margin + (reverse ? 0 : w), menuItem->rect.center().y(),
menuItem->rect.right() - margin - (reverse ? w : 0), menuItem->rect.center().y());
painter->restore();
break;
}
- bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
+ const bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
if (selected) {
QRect r = option->rect;
painter->fillRect(r, highlight);
painter->setPen(QPen(highlightOutline));
painter->drawRect(QRectF(r).adjusted(0.5, 0.5, -0.5, -0.5));
}
- bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
- bool checked = menuItem->checked;
- bool sunken = menuItem->state & State_Sunken;
- bool enabled = menuItem->state & State_Enabled;
+ const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ const bool checked = menuItem->checked;
+ const bool sunken = menuItem->state & State_Sunken;
+ const bool enabled = menuItem->state & State_Enabled;
- bool ignoreCheckMark = false;
- const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
+ const int checkColHOffset = QFusionStylePrivate::menuItemHMargin + windowsItemFrame - 1;
+ // icon checkbox's highlight column width
int checkcol = qMax<int>(menuItem->rect.height() * 0.79,
- qMax<int>(menuItem->maxIconWidth, dpiScaled(21, option))); // icon checkbox's highlight column width
+ qMax<int>(menuItem->maxIconWidth, dpiScaled(21, option)));
+ bool ignoreCheckMark = false;
if (
#if QT_CONFIG(combobox)
qobject_cast<const QComboBox*>(widget) ||
@@ -1587,8 +1587,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
// Check, using qreal and QRectF to avoid error accumulation
const qreal boxMargin = dpiScaled(3.5, option);
const qreal boxWidth = checkcol - 2 * boxMargin;
- QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
- QRect checkRect = checkRectF.toRect();
+ QRect checkRect = QRectF(option->rect.left() + boxMargin + checkColHOffset,
+ option->rect.center().y() - boxWidth/2 + 1, boxWidth,
+ boxWidth).toRect();
checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
if (checkable) {
@@ -1598,8 +1599,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::NoPen);
- QPalette::ColorRole textRole = !enabled ? QPalette::Text:
- selected ? QPalette::HighlightedText : QPalette::ButtonText;
+ QPalette::ColorRole textRole = !enabled
+ ? QPalette::Text :
+ selected ? QPalette::HighlightedText
+ : QPalette::ButtonText;
painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
const int adjustment = checkRect.height() * 0.3;
painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment));
@@ -1626,8 +1629,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
}
// Text and icon, ripped from windows style
- bool dis = !(menuItem->state & State_Enabled);
- bool act = menuItem->state & State_Selected;
+ const bool dis = !(menuItem->state & State_Enabled);
+ const bool act = menuItem->state & State_Selected;
const QStyleOption *opt = option;
const QStyleOptionMenuItem *menuitem = menuItem;
@@ -1675,36 +1678,38 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
}
int x, y, w, h;
menuitem->rect.getRect(&x, &y, &w, &h);
- int tab = menuitem->reservedShortcutWidth;
QColor discol;
if (dis) {
discol = menuitem->palette.text().color();
p->setPen(discol);
}
- int xm = checkColHOffset + checkcol + windowsItemHMargin;
- int xpos = menuitem->rect.x() + xm;
+ const int xm = checkColHOffset + checkcol + QFusionStylePrivate::menuItemHMargin;
+ const int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
- QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ const QRect textRect(xpos, y + windowsItemVMargin,
+ w - xm - QFusionStylePrivate::menuRightBorder - menuitem->reservedShortcutWidth + 2,
+ h - 2 * windowsItemVMargin);
+ const QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
QStringView s(menuitem->text);
if (!s.isEmpty()) { // draw text
p->save();
- int t = s.indexOf(QLatin1Char('\t'));
+ const int tabIndex = s.indexOf(QLatin1Char('\t'));
int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
text_flags |= Qt::TextHideMnemonic;
text_flags |= Qt::AlignLeft;
- if (t >= 0) {
+ if (tabIndex >= 0) {
QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
- QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
- const QString textToDraw = s.mid(t + 1).toString();
+ QRect(textRect.topRight(),
+ QPoint(menuitem->rect.right(), textRect.bottom())));
+ const QString textToDraw = s.mid(tabIndex + 1).toString();
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
p->setPen(menuitem->palette.light().color());
p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
p->drawText(vShortcutRect, text_flags, textToDraw);
- s = s.left(t);
+ s = s.left(tabIndex);
}
QFont font = menuitem->font;
// font may not have any "hard" flags set. We override
@@ -1718,23 +1723,24 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
font.setBold(true);
p->setFont(font);
- QString textToDraw = s.left(t).toString();
+ const QFontMetrics fontMetrics(font);
+ const QString textToDraw = fontMetrics.elidedText(s.left(tabIndex).toString(),
+ Qt::ElideMiddle, vTextRect.width());
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
p->setPen(menuitem->palette.light().color());
p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
- textToDraw = menuitem->fontMetrics.elidedText(textToDraw, Qt::ElideMiddle, vTextRect.width());
p->drawText(vTextRect, text_flags, textToDraw);
p->restore();
}
// Arrow
if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- int dim = (menuItem->rect.height() - 4) / 2;
+ const int dim = (menuItem->rect.height() - 4) / 2;
PrimitiveElement arrow;
arrow = option->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
+ const int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
QStyleOptionMenuItem newMI = *menuItem;
@@ -2021,22 +2027,24 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
cachePainter.setPen(d->topShadow());
cachePainter.drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
- // Draw button gradient
- QColor buttonColor = d->buttonColor(option->palette);
- QRect updownRect = upRect.adjusted(0, -2, 0, downRect.height() + 2);
- QLinearGradient gradient = qt_fusion_gradient(updownRect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
+ if (!upRect.isNull()) {
+ // Draw button gradient
+ const QColor buttonColor = d->buttonColor(option->palette);
+ const QRect updownRect = upRect.adjusted(0, -2, 0, downRect.height() + 2);
+ const QLinearGradient gradient = qt_fusion_gradient(updownRect, (isEnabled && option->state & State_MouseOver )
+ ? buttonColor : buttonColor.darker(104));
- // Draw button gradient
- cachePainter.setPen(Qt::NoPen);
- cachePainter.setBrush(gradient);
+ cachePainter.setPen(Qt::NoPen);
+ cachePainter.setBrush(gradient);
- cachePainter.save();
- cachePainter.setClipRect(updownRect);
- cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
- cachePainter.setPen(QPen(d->innerContrastLine()));
- cachePainter.setBrush(Qt::NoBrush);
- cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 2, 2);
- cachePainter.restore();
+ cachePainter.save();
+ cachePainter.setClipRect(updownRect);
+ cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
+ cachePainter.setPen(QPen(d->innerContrastLine()));
+ cachePainter.setBrush(Qt::NoBrush);
+ cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 2, 2);
+ cachePainter.restore();
+ }
if ((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) && upIsActive) {
if (sunken)
@@ -2064,12 +2072,14 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
cachePainter.restore();
}
- // outline the up/down buttons
- cachePainter.setPen(outline);
- if (spinBox->direction == Qt::RightToLeft) {
- cachePainter.drawLine(upRect.right(), upRect.top() - 1, upRect.right(), downRect.bottom() + 1);
- } else {
- cachePainter.drawLine(upRect.left(), upRect.top() - 1, upRect.left(), downRect.bottom() + 1);
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ // buttonSymbols == NoButtons results in 'null' rects
+ // and a tiny rect painted in the corner.
+ cachePainter.setPen(outline);
+ if (spinBox->direction == Qt::RightToLeft)
+ cachePainter.drawLine(upRect.right(), upRect.top() - 1, upRect.right(), downRect.bottom() + 1);
+ else
+ cachePainter.drawLine(upRect.left(), upRect.top() - 1, upRect.left(), downRect.bottom() + 1);
}
if (upIsActive && sunken) {
@@ -3175,22 +3185,22 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
case CT_MenuItem:
if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
int w = size.width(); // Don't rely of QCommonStyle's width calculation here
- int maxpmw = menuItem->maxIconWidth;
- int tabSpacing = 20;
if (menuItem->text.contains(QLatin1Char('\t')))
- w += tabSpacing;
+ w += menuItem->reservedShortcutWidth;
else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin, option);
else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
- QFontMetrics fm(menuItem->font);
+ const QFontMetrics fm(menuItem->font);
QFont fontBold = menuItem->font;
fontBold.setBold(true);
- QFontMetrics fmBold(fontBold);
+ const QFontMetrics fmBold(fontBold);
w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text);
}
const qreal dpi = QStyleHelper::dpi(option);
- const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth, dpi)); // Windows always shows a check column
- w += checkcol;
+ // Windows always shows a check column
+ const int checkcol = qMax<int>(menuItem->maxIconWidth,
+ QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth, dpi));
+ w += checkcol + windowsItemFrame;
w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10, dpi);
newSize.setWidth(w);
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 04c110a662..9301141c07 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1504,24 +1504,19 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent.
- \value PM_TreeViewIndentation The indentation of items in a tree view.
- This enum value has been introduced in Qt 5.4.
+ \value [since 5.4] PM_TreeViewIndentation The indentation of items in a tree view.
\value PM_HeaderDefaultSectionSizeHorizontal The default size of sections
in a horizontal header. This enum value has been introduced in Qt 5.5.
\value PM_HeaderDefaultSectionSizeVertical The default size of sections
in a vertical header. This enum value has been introduced in Qt 5.5.
- \value PM_TitleBarButtonIconSize The size of button icons on a title bar.
- This enum value has been introduced in Qt 5.8.
- \value PM_TitleBarButtonSize The size of buttons on a title bar.
- This enum value has been introduced in Qt 5.8.
+ \value [since 5.8] PM_TitleBarButtonIconSize The size of button icons on a title bar.
+ \value [since 5.8] PM_TitleBarButtonSize The size of buttons on a title bar.
- \value PM_LineEditIconSize The default size for icons in a line edit.
- This enum value has been introduced in Qt 6.2.
+ \value [since 6.2] PM_LineEditIconSize The default size for icons in a line edit.
- \value PM_LineEditIconMargin The margin around icons in a line edit.
- This enum value has been introduced in Qt 6.3.
+ \value [since 6.3] PM_LineEditIconMargin The margin around icons in a line edit.
\value PM_CustomBase Base value for custom pixel metrics. Custom
values must be greater than this value.
@@ -1853,9 +1848,8 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
spinbox mouse clicks.
\value SH_SpinBox_ClickAutoRepeatThreshold Auto-repeat threshold for
spinbox mouse clicks.
- \value SH_SpinBox_SelectOnStep Whether changing the value using
- the buttons or up/down keys automatically selects the text. This enum
- value has been introduced in Qt 6.3.
+ \value [since 6.3] SH_SpinBox_SelectOnStep Whether changing the value using
+ the buttons or up/down keys automatically selects the text.
\value SH_ToolTipLabel_Opacity An integer indicating the opacity for
the tip label, 0 is completely transparent, 255 is completely
@@ -2024,7 +2018,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_Table_AlwaysDrawLeftTopGridLines
Determines if the far left and top grid lines are drawn in a table or
not when the header is hidden. Defaults to false.
- This enum value has been introduced in Qt 6.2.
+ This enum value has been introduced in Qt 6.3.
\sa styleHint()
*/
@@ -2117,23 +2111,15 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SP_MediaSeekBackward Icon indicating that media should seek backward.
\value SP_MediaVolume Icon indicating a volume control.
\value SP_MediaVolumeMuted Icon indicating a muted volume control.
- \value SP_LineEditClearButton Icon for a standard clear button in a QLineEdit. This enum value was added in Qt 5.2.
- \value SP_DialogYesToAllButton Icon for a standard YesToAll button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_DialogNoToAllButton Icon for a standard NoToAll button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_DialogSaveAllButton Icon for a standard SaveAll button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_DialogAbortButton Icon for a standard Abort button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_DialogRetryButton Icon for a standard Retry button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_DialogIgnoreButton Icon for a standard Ignore button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_RestoreDefaultsButton Icon for a standard RestoreDefaults button in a QDialogButtonBox.
- This enum value was added in Qt 5.14.
- \value SP_TabCloseButton Icon for the close button in the tab of a QTabBar.
- This enum value was added in Qt 6.3.
+ \value [since 5.2] SP_LineEditClearButton Icon for a standard clear button in a QLineEdit.
+ \value [since 5.14] SP_DialogYesToAllButton Icon for a standard YesToAll button in a QDialogButtonBox.
+ \value [since 5.14] SP_DialogNoToAllButton Icon for a standard NoToAll button in a QDialogButtonBox.
+ \value [since 5.14] SP_DialogSaveAllButton Icon for a standard SaveAll button in a QDialogButtonBox.
+ \value [since 5.14] SP_DialogAbortButton Icon for a standard Abort button in a QDialogButtonBox.
+ \value [since 5.14] SP_DialogRetryButton Icon for a standard Retry button in a QDialogButtonBox.
+ \value [since 5.14] SP_DialogIgnoreButton Icon for a standard Ignore button in a QDialogButtonBox.
+ \value [since 5.14] SP_RestoreDefaultsButton Icon for a standard RestoreDefaults button in a QDialogButtonBox.
+ \value [since 6.3] SP_TabCloseButton Icon for the close button in the tab of a QTabBar.
\value SP_CustomBase Base value for custom standard pixmaps;
custom values must be greater than this value.
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
deleted file mode 100644
index 44090a54f0..0000000000
--- a/src/widgets/styles/qstyle.qrc
+++ /dev/null
@@ -1,179 +0,0 @@
-<RCC>
- <qresource prefix="/qt-project.org/styles/commonstyle">
- <file>images/cleartext-16.png</file>
- <file>images/cleartext-32.png</file>
- <file>images/filelink-16.png</file>
- <file>images/filelink-32.png</file>
- <file>images/filelink-128.png</file>
- <file>images/file-16.png</file>
- <file>images/file-32.png</file>
- <file>images/file-128.png</file>
- <file>images/newdirectory-16.png</file>
- <file>images/newdirectory-32.png</file>
- <file>images/newdirectory-128.png</file>
- <file>images/parentdir-16.png</file>
- <file>images/parentdir-32.png</file>
- <file>images/parentdir-128.png</file>
- <file>images/dvd-16.png</file>
- <file>images/dvd-32.png</file>
- <file>images/dvd-128.png</file>
- <file>images/cdr-16.png</file>
- <file>images/cdr-32.png</file>
- <file>images/cdr-128.png</file>
- <file>images/floppy-16.png</file>
- <file>images/floppy-32.png</file>
- <file>images/floppy-128.png</file>
- <file>images/harddrive-16.png</file>
- <file>images/harddrive-32.png</file>
- <file>images/harddrive-128.png</file>
- <file>images/trash-16.png</file>
- <file>images/trash-32.png</file>
- <file>images/trash-128.png</file>
- <file>images/networkdrive-16.png</file>
- <file>images/networkdrive-32.png</file>
- <file>images/networkdrive-128.png</file>
- <file>images/computer-16.png</file>
- <file>images/computer-32.png</file>
- <file>images/desktop-16.png</file>
- <file>images/desktop-32.png</file>
- <file>images/dirclosed-16.png</file>
- <file>images/dirclosed-32.png</file>
- <file>images/dirclosed-128.png</file>
- <file>images/dirlink-16.png</file>
- <file>images/dirlink-32.png</file>
- <file>images/dirlink-128.png</file>
- <file>images/diropen-16.png</file>
- <file>images/diropen-32.png</file>
- <file>images/diropen-128.png</file>
- <file>images/left-16.png</file>
- <file>images/left-32.png</file>
- <file>images/left-128.png</file>
- <file>images/right-16.png</file>
- <file>images/right-32.png</file>
- <file>images/right-128.png</file>
- <file>images/up-16.png</file>
- <file>images/up-32.png</file>
- <file>images/up-128.png</file>
- <file>images/down-16.png</file>
- <file>images/down-32.png</file>
- <file>images/down-128.png</file>
- <file>images/filecontents-16.png</file>
- <file>images/filecontents-32.png</file>
- <file>images/filecontents-128.png</file>
- <file>images/fileinfo-16.png</file>
- <file>images/fileinfo-32.png</file>
- <file>images/fileinfo-128.png</file>
- <file>images/viewdetailed-16.png</file>
- <file>images/viewdetailed-32.png</file>
- <file>images/viewdetailed-128.png</file>
- <file>images/viewlist-16.png</file>
- <file>images/viewlist-32.png</file>
- <file>images/viewlist-128.png</file>
- <file>images/fontbitmap-16.png</file>
- <file>images/fonttruetype-16.png</file>
- <file>images/standardbutton-apply-128.png</file>
- <file>images/standardbutton-apply-16.png</file>
- <file>images/standardbutton-apply-32.png</file>
- <file>images/standardbutton-cancel-128.png</file>
- <file>images/standardbutton-cancel-16.png</file>
- <file>images/standardbutton-cancel-32.png</file>
- <file>images/standardbutton-clear-128.png</file>
- <file>images/standardbutton-clear-16.png</file>
- <file>images/standardbutton-clear-32.png</file>
- <file>images/standardbutton-close-128.png</file>
- <file>images/standardbutton-close-16.png</file>
- <file>images/standardbutton-close-32.png</file>
- <file>images/standardbutton-delete-128.png</file>
- <file>images/standardbutton-delete-16.png</file>
- <file>images/standardbutton-delete-32.png</file>
- <file>images/standardbutton-help-128.png</file>
- <file>images/standardbutton-help-16.png</file>
- <file>images/standardbutton-help-32.png</file>
- <file>images/standardbutton-no-128.png</file>
- <file>images/standardbutton-no-16.png</file>
- <file>images/standardbutton-no-32.png</file>
- <file>images/standardbutton-ok-128.png</file>
- <file>images/standardbutton-ok-16.png</file>
- <file>images/standardbutton-ok-32.png</file>
- <file>images/standardbutton-open-128.png</file>
- <file>images/standardbutton-open-16.png</file>
- <file>images/standardbutton-open-32.png</file>
- <file>images/standardbutton-save-128.png</file>
- <file>images/standardbutton-save-16.png</file>
- <file>images/standardbutton-save-32.png</file>
- <file>images/standardbutton-yes-128.png</file>
- <file>images/standardbutton-yes-16.png</file>
- <file>images/standardbutton-yes-32.png</file>
- <file>images/standardbutton-closetab-32.png</file>
- <file>images/standardbutton-closetab-16.png</file>
- <file>images/standardbutton-closetab-down-32.png</file>
- <file>images/standardbutton-closetab-down-16.png</file>
- <file>images/standardbutton-closetab-hover-32.png</file>
- <file>images/standardbutton-closetab-hover-16.png</file>
- <file>images/refresh-24.png</file>
- <file>images/refresh-32.png</file>
- <file>images/stop-24.png</file>
- <file>images/stop-32.png</file>
- <file>images/media-stop-16.png</file>
- <file>images/media-stop-32.png</file>
- <file>images/media-play-16.png</file>
- <file>images/media-play-32.png</file>
- <file>images/media-pause-16.png</file>
- <file>images/media-pause-32.png</file>
- <file>images/media-seek-forward-16.png</file>
- <file>images/media-seek-forward-32.png</file>
- <file>images/media-seek-backward-16.png</file>
- <file>images/media-seek-backward-32.png</file>
- <file>images/media-skip-forward-16.png</file>
- <file>images/media-skip-forward-32.png</file>
- <file>images/media-skip-backward-16.png</file>
- <file>images/media-skip-backward-32.png</file>
- <file>images/media-volume-16.png</file>
- <file>images/media-volume-muted-16.png</file>
- <file>images/fusion_groupbox.png</file>
- <file>images/closedock-10.png</file>
- <file>images/closedock-16.png</file>
- <file>images/closedock-20.png</file>
- <file>images/closedock-32.png</file>
- <file>images/closedock-48.png</file>
- <file>images/closedock-64.png</file>
- <file>images/normalizedockup-10.png</file>
- <file>images/normalizedockup-16.png</file>
- <file>images/normalizedockup-20.png</file>
- <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 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/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 67dfdcb015..06b07d2c4c 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1535,6 +1535,7 @@ QStyleOptionProgressBar::QStyleOptionProgressBar(int version)
minimum(0), maximum(0), progress(0), textAlignment(Qt::AlignLeft), textVisible(false),
invertedAppearance(false), bottomToTop(false)
{
+ state |= QStyle::State_Horizontal;
}
/*!
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 1697832d7f..b799948933 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -1570,39 +1570,53 @@ public:
} while (metaObject != nullptr);
return result;
}
- QString attribute(NodePtr node, const QString& name) const override
+ QString attributeValue(NodePtr node, const QCss::AttributeSelector& aSelector) const override
{
if (isNullNode(node))
return QString();
+ const QString &name = aSelector.name;
QHash<QString, QString> &cache = m_attributeCache[OBJECT_PTR(node)];
QHash<QString, QString>::const_iterator cacheIt = cache.constFind(name);
if (cacheIt != cache.constEnd())
return cacheIt.value();
+ QVariant value;
+ QString valueStr;
QObject *obj = OBJECT_PTR(node);
- QVariant value = obj->property(name.toLatin1());
- if (!value.isValid()) {
- if (name == QLatin1String("class")) {
- QString className = QString::fromLatin1(obj->metaObject()->className());
- if (className.contains(QLatin1Char(':')))
- className.replace(QLatin1Char(':'), QLatin1Char('-'));
- cache[name] = className;
- return className;
- } else if (name == QLatin1String("style")) {
- QWidget *w = qobject_cast<QWidget *>(obj);
- QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : nullptr;
- if (proxy) {
- QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
- cache[name] = styleName;
- return styleName;
+ const int propertyIndex = obj->metaObject()->indexOfProperty(name.toLatin1());
+ if (propertyIndex == -1) {
+ value = obj->property(name.toLatin1()); // might be a dynamic property
+ if (!value.isValid()) {
+ if (name == u"class"_qs) {
+ QString className = QString::fromLatin1(obj->metaObject()->className());
+ if (className.contains(QLatin1Char(':')))
+ className.replace(QLatin1Char(':'), QLatin1Char('-'));
+ valueStr = className;
+ } else if (name == u"style"_qs) {
+ QWidget *w = qobject_cast<QWidget *>(obj);
+ QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : nullptr;
+ if (proxy)
+ valueStr = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
}
}
+ } else {
+ const QMetaProperty property = obj->metaObject()->property(propertyIndex);
+ value = property.read(obj);
+ // support Qt 5 selector syntax, which required the integer enum value
+ if (property.isEnumType()) {
+ bool isNumber;
+ aSelector.value.toInt(&isNumber);
+ if (isNumber)
+ value.convert(QMetaType::fromType<int>());
+ }
+ }
+ if (value.isValid()) {
+ valueStr = (value.userType() == QMetaType::QStringList
+ || value.userType() == QMetaType::QVariantList)
+ ? value.toStringList().join(QLatin1Char(' '))
+ : value.toString();
}
- QString valueStr = (value.userType() == QMetaType::QStringList
- || value.userType() == QMetaType::QVariantList)
- ? value.toStringList().join(QLatin1Char(' '))
- : value.toString();
cache[name] = valueStr;
return valueStr;
}
@@ -3274,7 +3288,6 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
rule.configurePalette(&toolOpt.palette, QPalette::ButtonText, QPalette::Button);
toolOpt.font = rule.font.resolve(toolOpt.font);
toolOpt.rect = rule.borderRect(opt->rect);
- bool customArrow = tool->features & QStyleOptionToolButton::Arrow;
const auto customArrowElement = [tool]{
switch (tool->arrowType) {
case Qt::DownArrow: return PseudoElement_DownArrow;
@@ -3285,9 +3298,29 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
}
return PseudoElement_None;
};
- bool customDropDown = tool->features & QStyleOptionToolButton::MenuButtonPopup;
+ // if arrow/menu/indicators are requested, either draw them using the available rule,
+ // or let the base style draw them; but not both
+ const bool drawArrow = tool->features & QStyleOptionToolButton::Arrow;
+ bool customArrow = drawArrow && hasStyleRule(w, customArrowElement());
+ if (customArrow) {
+ toolOpt.features &= ~QStyleOptionToolButton::Arrow;
+ toolOpt.text = QString(); // we need to draw the arrow and the text ourselves
+ }
+ const bool drawDropDown = tool->features & QStyleOptionToolButton::MenuButtonPopup;
+ bool customDropDown = drawDropDown && hasStyleRule(w, PseudoElement_ToolButtonMenu);
bool customDropDownArrow = false;
- bool customMenuIndicator = !customDropDown && (tool->features & QStyleOptionToolButton::HasMenu);
+ const bool drawMenuIndicator = tool->features & QStyleOptionToolButton::HasMenu;
+ if (customDropDown) {
+ toolOpt.subControls &= ~QStyle::SC_ToolButtonMenu;
+ customDropDownArrow = hasStyleRule(w, PseudoElement_ToolButtonMenuArrow);
+ if (customDropDownArrow)
+ toolOpt.features &= ~(QStyleOptionToolButton::Menu | QStyleOptionToolButton::HasMenu);
+ }
+ bool customMenuIndicator = (!customDropDown && drawMenuIndicator)
+ && hasStyleRule(w, PseudoElement_ToolButtonMenuIndicator);
+ if (customMenuIndicator)
+ toolOpt.features &= ~QStyleOptionToolButton::HasMenu;
+
if (rule.hasNativeBorder()) {
if (tool->subControls & SC_ToolButton) {
//in some case (eg. the button is "auto raised") the style doesn't draw the background
@@ -3301,28 +3334,12 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
if (!(bflags & (State_Sunken | State_On | State_Raised)))
rule.drawBackground(p, toolOpt.rect);
}
- customArrow = customArrow && hasStyleRule(w, customArrowElement());
- if (customArrow)
- toolOpt.features &= ~QStyleOptionToolButton::Arrow;
- customDropDown = customDropDown && hasStyleRule(w, PseudoElement_ToolButtonMenu);
- if (customDropDown) {
- toolOpt.subControls &= ~QStyle::SC_ToolButtonMenu;
- customDropDownArrow = hasStyleRule(w, PseudoElement_ToolButtonMenuArrow);
- if (customDropDownArrow)
- toolOpt.features &= ~(QStyleOptionToolButton::Menu | QStyleOptionToolButton::HasMenu);
- }
- customMenuIndicator = customMenuIndicator && hasStyleRule(w, PseudoElement_ToolButtonMenuIndicator);
- if (customMenuIndicator)
- toolOpt.features &= ~QStyleOptionToolButton::HasMenu;
if (rule.baseStyleCanDraw() && !(tool->features & QStyleOptionToolButton::Arrow)) {
baseStyle()->drawComplexControl(cc, &toolOpt, p, w);
} else {
QWindowsStyle::drawComplexControl(cc, &toolOpt, p, w);
}
-
- if (!customArrow && !customDropDown && !customMenuIndicator)
- return;
} else {
rule.drawRule(p, opt->rect);
toolOpt.rect = rule.contentsRect(opt->rect);
@@ -3332,7 +3349,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
}
const QRect cr = toolOpt.rect;
- if (customDropDown) {
+ if (drawDropDown) {
if (opt->subControls & QStyle::SC_ToolButtonMenu) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
QRect menuButtonRect = subControlRect(CC_ToolButton, opt, QStyle::SC_ToolButtonMenu, w);
@@ -3343,7 +3360,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
baseStyle()->drawPrimitive(PE_IndicatorButtonDropDown, &toolOpt, p, w);
}
- if (customDropDownArrow) {
+ if (customDropDownArrow || drawMenuIndicator) {
QRenderRule arrowRule = renderRule(w, opt, PseudoElement_ToolButtonMenuArrow);
QRect arrowRect = arrowRule.hasGeometry()
? positionRect(w, arrowRule, PseudoElement_ToolButtonMenuArrow, menuButtonRect, toolOpt.direction)
@@ -3356,7 +3373,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
}
}
}
- } else if (customMenuIndicator) {
+ } else if (drawMenuIndicator) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenuIndicator);
QRect r = subRule.hasGeometry()
? positionRect(w, subRule, PseudoElement_ToolButtonMenuIndicator, toolOpt.rect, toolOpt.direction)
@@ -3370,27 +3387,36 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
}
toolOpt.rect = cr;
+ // If we don't have a custom arrow, then the arrow will have been rendered
+ // already by the base style when drawing the label.
if (customArrow) {
const auto arrowElement = customArrowElement();
QRenderRule subRule = renderRule(w, opt, arrowElement);
- QRect r = subRule.hasGeometry() ? positionRect(w, subRule, arrowElement, toolOpt.rect, toolOpt.direction)
- : subRule.contentsRect(toolOpt.rect);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, r);
- } else {
- toolOpt.rect = r;
- const auto arrowElement = [&toolOpt] {
- switch (toolOpt.arrowType) {
- case Qt::DownArrow: return QStyle::PE_IndicatorArrowDown;
- case Qt::UpArrow: return QStyle::PE_IndicatorArrowUp;
- case Qt::LeftArrow: return QStyle::PE_IndicatorArrowLeft;
- case Qt::RightArrow: return QStyle::PE_IndicatorArrowRight;
- case Qt::NoArrow: break;
- }
- return QStyle::PE_IndicatorArrowDown; // never happens
- };
- baseStyle()->drawPrimitive(arrowElement(), &toolOpt, p, w);
+ QRect arrowRect = subRule.hasGeometry() ? positionRect(w, subRule, arrowElement, toolOpt.rect, toolOpt.direction)
+ : subRule.contentsRect(toolOpt.rect);
+
+ switch (toolOpt.toolButtonStyle) {
+ case Qt::ToolButtonIconOnly:
+ break;
+ case Qt::ToolButtonTextOnly:
+ case Qt::ToolButtonTextBesideIcon:
+ case Qt::ToolButtonTextUnderIcon: {
+ // The base style needs to lay out the contents and will render the styled
+ // arrow icons, unless the geometry is defined in the style sheet.
+ toolOpt.text = tool->text;
+ if (!subRule.hasGeometry())
+ toolOpt.features |= QStyleOptionToolButton::Arrow;
+ drawControl(CE_ToolButtonLabel, &toolOpt, p, w);
+ if (!subRule.hasGeometry())
+ return;
+ break;
+ }
+ case Qt::ToolButtonFollowStyle:
+ // QToolButton handles this, so must never happen
+ Q_ASSERT(false);
+ break;
}
+ subRule.drawRule(p, arrowRect);
}
return;
@@ -5053,8 +5079,14 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
if (!rule.hasNativeBorder() || rule.hasBox())
return 0;
break;
+
+ case PM_ScrollView_ScrollBarOverlap:
+ if (!rule.hasNativeBorder() || rule.hasBox())
+ return 0;
+ break;
#endif // QT_CONFIG(scrollbar)
+
case PM_ProgressBarChunkWidth:
subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
if (subRule.hasContentsSize()) {
@@ -5647,6 +5679,10 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi
case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: s = QLatin1String("paint-alternating-row-colors-for-empty-area"); break;
case SH_TitleBar_ShowToolTipsOnButtons: s = QLatin1String("titlebar-show-tooltips-on-buttons"); break;
case SH_Widget_Animation_Duration: s = QLatin1String("widget-animation-duration"); break;
+ case SH_ScrollBar_Transient:
+ if (!rule.hasNativeBorder() || rule.hasBox())
+ return 0;
+ break;
default: break;
}
if (!s.isEmpty() && rule.hasStyleHint(s)) {
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index c1a67c3ce4..c353be5f59 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -103,12 +103,12 @@ static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon)
\list
\li All supported versions of Windows.
- \li All window managers and independent tray implementations for X11 that implement the
- \l{http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.2.html freedesktop.org}
- XEmbed system tray specification.
- \li All X11 desktop environments that implement the D-Bus
+ \li All Linux desktop environments that implement the D-Bus
\l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem}
- specification, including recent versions of KDE and Unity.
+ {StatusNotifierItem specification}, including KDE, Gnome, Xfce, LXQt, and DDE.
+ \li All window managers and independent tray implementations for X11 that implement the
+ \l{http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.2.html}
+ {freedesktop.org XEmbed system tray specification}.
\li All supported versions of \macos.
\endlist
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 4ad8a3b411..627dbaa1d6 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -1232,49 +1232,57 @@ void QAbstractScrollArea::contextMenuEvent(QContextMenuEvent *e)
void QAbstractScrollArea::keyPressEvent(QKeyEvent * e)
{
Q_D(QAbstractScrollArea);
-
+ if (false){
+#ifndef QT_NO_SHORTCUT
+ } else if (e == QKeySequence::MoveToPreviousPage) {
+ d->vbar->triggerAction(QScrollBar::SliderPageStepSub);
+ } else if (e == QKeySequence::MoveToNextPage) {
+ d->vbar->triggerAction(QScrollBar::SliderPageStepAdd);
+#endif
+ } else {
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
- e->ignore();
- return;
- }
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
+ e->ignore();
+ return;
+ }
#endif
- switch (e->key()) {
- case Qt::Key_Up:
- d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
- break;
- case Qt::Key_Down:
- d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
- break;
- case Qt::Key_Left:
+ switch (e->key()) {
+ case Qt::Key_Up:
+ d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
+ break;
+ case Qt::Key_Down:
+ d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
+ break;
+ case Qt::Key_Left:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
- && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) {
- //if we aren't using the hbar or we are already at the leftmost point ignore
- e->ignore();
- return;
- }
+ if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
+ && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) {
+ //if we aren't using the hbar or we are already at the leftmost point ignore
+ e->ignore();
+ return;
+ }
#endif
- d->hbar->triggerAction(
- layoutDirection() == Qt::LeftToRight
- ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
- break;
- case Qt::Key_Right:
+ d->hbar->triggerAction(
+ layoutDirection() == Qt::LeftToRight
+ ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
+ break;
+ case Qt::Key_Right:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
- && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) {
- //if we aren't using the hbar or we are already at the rightmost point ignore
- e->ignore();
- return;
- }
+ if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
+ && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) {
+ //if we aren't using the hbar or we are already at the rightmost point ignore
+ e->ignore();
+ return;
+ }
#endif
- d->hbar->triggerAction(
- layoutDirection() == Qt::LeftToRight
- ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
- break;
- default:
- e->ignore();
- return;
+ d->hbar->triggerAction(
+ layoutDirection() == Qt::LeftToRight
+ ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
+ break;
+ default:
+ e->ignore();
+ return;
+ }
}
e->accept();
}
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 8effcd0f55..fdf5aeeed5 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
-class QAbstractScrollAreaPrivate: public QFramePrivate
+class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
{
Q_DECLARE_PUBLIC(QAbstractScrollArea)
diff --git a/src/widgets/widgets/qcheckbox.cpp b/src/widgets/widgets/qcheckbox.cpp
index 2e9a404157..e50e327091 100644
--- a/src/widgets/widgets/qcheckbox.cpp
+++ b/src/widgets/widgets/qcheckbox.cpp
@@ -122,7 +122,7 @@ public:
setAutoRepeat(), toggle(), pressed(), released(), clicked(), toggled(),
checkState(), and stateChanged().
- \sa QAbstractButton, QRadioButton, {fowler}{GUI Design Handbook: Check Box}
+ \sa QAbstractButton, QRadioButton
*/
/*!
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 5e7ae42ebb..db7bf9c504 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -1042,8 +1042,7 @@ QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent)
of the view(), e.g., by using
\l{QAbstractItemView::}{setSelectionMode()}.
- \sa QLineEdit, QSpinBox, QRadioButton, QButtonGroup,
- {fowler}{GUI Design Handbook: Combo Box, Drop-Down List Box}
+ \sa QLineEdit, QSpinBox, QRadioButton, QButtonGroup
*/
void QComboBoxPrivate::init()
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index af8c172306..19327533b4 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -51,6 +51,7 @@
#include <qlayout.h>
#include <qset.h>
#include <qstyle.h>
+#include <qstylepainter.h>
#if QT_CONFIG(timezone)
#include <QTimeZone>
#endif
@@ -2441,8 +2442,8 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event)
optCombo.state &= ~QStyle::State_Enabled;
}
- QPainter p(this);
- style()->drawComplexControl(QStyle::CC_ComboBox, &optCombo, &p, this);
+ QStylePainter p(this);
+ p.drawComplexControl(QStyle::CC_ComboBox, optCombo);
}
int QDateTimeEditPrivate::absoluteIndex(QDateTimeEdit::Section s, int index) const
diff --git a/src/widgets/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp
index d9f872ac1e..3202527519 100644
--- a/src/widgets/widgets/qdial.cpp
+++ b/src/widgets/widgets/qdial.cpp
@@ -226,7 +226,7 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const
by \l {QAbstractSlider::singleStep} {singleStep}, and
\l {QAbstractSlider::pageStep} {pageStep}.
- \sa QScrollBar, QSpinBox, QSlider, {fowler}{GUI Design Handbook: Slider}, {Sliders Example}
+ \sa QScrollBar, QSpinBox, QSlider, {Sliders Example}
*/
/*!
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 4080a622f0..e08f64a660 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -219,7 +219,7 @@ void QDockWidgetTitleButton::leaveEvent(QEvent *event)
void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
{
- QPainter p(this);
+ QStylePainter p(this);
QStyleOptionToolButton opt;
opt.initFrom(this);
@@ -232,7 +232,7 @@ void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
opt.state |= QStyle::State_On;
if (isDown())
opt.state |= QStyle::State_Sunken;
- style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
+ p.drawPrimitive(QStyle::PE_PanelButtonTool, opt);
} else if (isDown() || isChecked()) {
// no frame, but the icon might have explicit pixmaps for QIcon::On
opt.state |= QStyle::State_On | QStyle::State_Sunken;
@@ -244,7 +244,7 @@ void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
opt.features = QStyleOptionToolButton::None;
opt.arrowType = Qt::NoArrow;
opt.iconSize = dockButtonIconSize();
- style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
+ p.drawComplexControl(QStyle::CC_ToolButton, opt);
}
/******************************************************************************
diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp
index 0090f9b0b9..f5acfe27b8 100644
--- a/src/widgets/widgets/qeffects.cpp
+++ b/src/widgets/widgets/qeffects.cpp
@@ -499,14 +499,12 @@ void QRollEffect::scroll()
+ (2 * totalWidth * (elapsed%duration) + duration)
/ (2 * duration);
// equiv. to int((totalWidth*elapsed) / duration + 0.5)
- done = (currentWidth >= totalWidth);
}
if (currentHeight != totalHeight) {
currentHeight = totalHeight * (elapsed/duration)
+ (2 * totalHeight * (elapsed%duration) + duration)
/ (2 * duration);
// equiv. to int((totalHeight*elapsed) / duration + 0.5)
- done = (currentHeight >= totalHeight);
}
done = (currentHeight >= totalHeight) &&
(currentWidth >= totalWidth);
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 60a1f06764..4a9d510177 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -178,11 +178,28 @@ static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool
return QFontDatabase::Any;
}
+class QFontComboBoxPrivate : public QComboBoxPrivate
+{
+public:
+ inline QFontComboBoxPrivate() { filters = QFontComboBox::AllFonts; }
+
+ QFontComboBox::FontFilters filters;
+ QFont currentFont;
+ QHash<QFontDatabase::WritingSystem, QString> sampleTextForWritingSystem;
+ QHash<QString, QString> sampleTextForFontFamily;
+ QHash<QString, QFont> displayFontForFontFamily;
+
+ void _q_updateModel();
+ void _q_currentChanged(const QString &);
+
+ Q_DECLARE_PUBLIC(QFontComboBox)
+};
+
class QFontFamilyDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- explicit QFontFamilyDelegate(QObject *parent);
+ explicit QFontFamilyDelegate(QObject *parent, QFontComboBoxPrivate *comboP);
// painting
void paint(QPainter *painter,
@@ -195,13 +212,15 @@ public:
const QIcon truetype;
const QIcon bitmap;
QFontDatabase::WritingSystem writingSystem;
+ QFontComboBoxPrivate *comboPrivate;
};
-QFontFamilyDelegate::QFontFamilyDelegate(QObject *parent)
+QFontFamilyDelegate::QFontFamilyDelegate(QObject *parent, QFontComboBoxPrivate *comboP)
: QAbstractItemDelegate(parent),
truetype(QStringLiteral(":/qt-project.org/styles/commonstyle/images/fonttruetype-16.png")),
bitmap(QStringLiteral(":/qt-project.org/styles/commonstyle/images/fontbitmap-16.png")),
- writingSystem(QFontDatabase::Any)
+ writingSystem(QFontDatabase::Any),
+ comboPrivate(comboP)
{
}
@@ -220,6 +239,8 @@ void QFontFamilyDelegate::paint(QPainter *painter,
if (hasLatin)
font = font2;
+ font = comboPrivate->displayFontForFontFamily.value(text, font);
+
QRect r = option.rect;
if (option.state & QStyle::State_Selected) {
@@ -264,10 +285,11 @@ void QFontFamilyDelegate::paint(QPainter *painter,
if (writingSystem != QFontDatabase::Any)
system = writingSystem;
- if (system != QFontDatabase::Any) {
+ const QString sampleText = comboPrivate->sampleTextForFontFamily.value(text, comboPrivate->sampleTextForWritingSystem.value(system));
+ if (system != QFontDatabase::Any || !sampleText.isEmpty()) {
int w = painter->fontMetrics().horizontalAdvance(text + QLatin1String(" "));
painter->setFont(font2);
- QString sample = QFontDatabase::writingSystemSample(system);
+ const QString sample = !sampleText.isEmpty() ? sampleText : QFontDatabase::writingSystemSample(system);
if (option.direction == Qt::RightToLeft)
r.setRight(r.right() - w);
else
@@ -293,24 +315,13 @@ QSize QFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option,
}
-class QFontComboBoxPrivate : public QComboBoxPrivate
-{
-public:
- inline QFontComboBoxPrivate() { filters = QFontComboBox::AllFonts; }
-
- QFontComboBox::FontFilters filters;
- QFont currentFont;
-
- void _q_updateModel();
- void _q_currentChanged(const QString &);
-
- Q_DECLARE_PUBLIC(QFontComboBox)
-};
-
-
void QFontComboBoxPrivate::_q_updateModel()
{
Q_Q(QFontComboBox);
+
+ if (QCoreApplication::closingDown())
+ return;
+
const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts);
const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts);
@@ -367,7 +378,8 @@ void QFontComboBoxPrivate::_q_updateModel()
void QFontComboBoxPrivate::_q_currentChanged(const QString &text)
{
Q_Q(QFontComboBox);
- if (currentFont.families().first() != text) {
+ QStringList families = currentFont.families();
+ if (families.isEmpty() || families.first() != text) {
currentFont.setFamilies(QStringList{text});
emit q->currentFontChanged(currentFont);
}
@@ -418,7 +430,7 @@ QFontComboBox::QFontComboBox(QWidget *parent)
QStringListModel *m = new QStringListModel(this);
setModel(m);
- setItemDelegate(new QFontFamilyDelegate(this));
+ setItemDelegate(new QFontFamilyDelegate(this, d));
QListView *lview = qobject_cast<QListView*>(view());
if (lview)
lview->setUniformItemSizes(true);
@@ -559,6 +571,77 @@ QSize QFontComboBox::sizeHint() const
return sz;
}
+/*!
+ Sets the \a sampleText to show after the font name (when the combo is open) for a given \a writingSystem.
+
+ The sample text given with setSampleTextForFont() has priority.
+
+ \since 6.3
+*/
+void QFontComboBox::setSampleTextForSystem(QFontDatabase::WritingSystem writingSystem, const QString &sampleText)
+{
+ Q_D(QFontComboBox);
+ d->sampleTextForWritingSystem[writingSystem] = sampleText;
+}
+
+
+/*!
+ Returns the sample text to show after the font name (when the combo is open) for a given \a writingSystem.
+
+ \since 6.3
+*/
+QString QFontComboBox::sampleTextForSystem(QFontDatabase::WritingSystem writingSystem) const
+{
+ Q_D(const QFontComboBox);
+ return d->sampleTextForWritingSystem.value(writingSystem);
+}
+
+/*!
+ Sets the \a sampleText to show after the font name (when the combo is open) for a given \a fontFamily.
+
+ The sample text given with this function has priority over the one set with setSampleTextForSystem().
+
+ \since 6.3
+*/
+void QFontComboBox::setSampleTextForFont(const QString &fontFamily, const QString &sampleText)
+{
+ Q_D(QFontComboBox);
+ d->sampleTextForFontFamily[fontFamily] = sampleText;
+}
+
+/*!
+ Returns the sample text to show after the font name (when the combo is open) for a given \a fontFamily.
+
+ \since 6.3
+*/
+QString QFontComboBox::sampleTextForFont(const QString &fontFamily) const
+{
+ Q_D(const QFontComboBox);
+ return d->sampleTextForFontFamily.value(fontFamily);
+}
+
+/*!
+ Sets the \a font to be used to display a given \a fontFamily (when the combo is open).
+
+ \since 6.3
+*/
+void QFontComboBox::setDisplayFont(const QString &fontFamily, const QFont &font)
+{
+ Q_D(QFontComboBox);
+ d->displayFontForFontFamily[fontFamily] = font;
+}
+
+/*!
+ Returns the font (if set) to be used to display a given \a fontFamily (when the combo is open).
+
+ \since 6.3
+*/
+std::optional<QFont> QFontComboBox::displayFont(const QString &fontFamily) const
+{
+ Q_D(const QFontComboBox);
+ return d->displayFontForFontFamily.value(fontFamily, {});
+}
+
QT_END_NAMESPACE
#include "qfontcombobox.moc"
diff --git a/src/widgets/widgets/qfontcombobox.h b/src/widgets/widgets/qfontcombobox.h
index 6c1871dd2d..18b642680a 100644
--- a/src/widgets/widgets/qfontcombobox.h
+++ b/src/widgets/widgets/qfontcombobox.h
@@ -80,6 +80,15 @@ public:
QFont currentFont() const;
QSize sizeHint() const override;
+ void setSampleTextForSystem(QFontDatabase::WritingSystem writingSystem, const QString &sampleText);
+ QString sampleTextForSystem(QFontDatabase::WritingSystem writingSystem) const;
+
+ void setSampleTextForFont(const QString &fontFamily, const QString &sampleText);
+ QString sampleTextForFont(const QString &fontFamily) const;
+
+ void setDisplayFont(const QString &fontFamily, const QFont &font);
+ std::optional<QFont> displayFont(const QString &fontFamily) const;
+
public Q_SLOTS:
void setCurrentFont(const QFont &f);
diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp
index 1661c5c881..b9d79817f8 100644
--- a/src/widgets/widgets/qframe.cpp
+++ b/src/widgets/widgets/qframe.cpp
@@ -44,6 +44,7 @@
#include "qpainter.h"
#include "qstyle.h"
#include "qstyleoption.h"
+#include "qstylepainter.h"
#include "qapplication.h"
#include "qframe_p.h"
@@ -511,8 +512,8 @@ QSize QFrame::sizeHint() const
void QFrame::paintEvent(QPaintEvent *)
{
- QPainter paint(this);
- drawFrame(&paint);
+ QStylePainter p(this);
+ drawFrame(&p);
}
/*!
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index d6a9075712..9b13cfcb9b 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -183,8 +183,7 @@ QLabelPrivate::~QLabelPrivate()
was a button (inheriting from QAbstractButton), triggering the
mnemonic would emulate a button click.
- \sa QLineEdit, QTextEdit, QPixmap, QMovie,
- {fowler}{GUI Design Handbook: Label}
+ \sa QLineEdit, QTextEdit, QPixmap, QMovie
*/
#ifndef QT_NO_PICTURE
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 616e1ae424..dd09d9a686 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -208,7 +208,7 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
Any other key sequence that represents a valid character, will
cause the character to be inserted into the line edit.
- \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
+ \sa QTextEdit, QLabel, QComboBox, {Line Edits Example}
*/
@@ -1805,10 +1805,6 @@ QRect QLineEdit::cursorRect() const
void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
{
Q_D(QLineEdit);
- if (!d->shouldEnableInputMethod()) {
- e->ignore();
- return;
- }
if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
// Clear the edit and reset to normal echo mode while entering input
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 7cffd90aba..5aeea88e4e 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -522,10 +522,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
{
QLayout *topLayout = layout();
- if (topLayout->menuBar() && topLayout->menuBar() != menuBar) {
+ if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
// Reparent corner widgets before we delete the old menu bar.
- QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(topLayout->menuBar());
- if (menuBar) {
+ QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(existingMenuBar);
+ if (oldMenuBar && menuBar) {
// TopLeftCorner widget.
QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
if (cornerWidget)
@@ -535,9 +535,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
if (cornerWidget)
menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
}
- oldMenuBar->hide();
- oldMenuBar->setParent(nullptr);
- oldMenuBar->deleteLater();
+
+ existingMenuBar->hide();
+ existingMenuBar->setParent(nullptr);
+ existingMenuBar->deleteLater();
}
topLayout->setMenuBar(menuBar);
}
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index b5671180a2..3ab8632f80 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -1000,6 +1000,10 @@ void QMdiAreaPrivate::activateWindow(QMdiSubWindow *child)
if (child->isHidden() || child == active)
return;
+
+ if (child->d_func()->isActive && active == nullptr)
+ child->d_func()->isActive = false;
+
child->d_func()->setActive(true);
}
diff --git a/src/widgets/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h
index 043cf92201..8b55cf34cc 100644
--- a/src/widgets/widgets/qmdisubwindow_p.h
+++ b/src/widgets/widgets/qmdisubwindow_p.h
@@ -121,7 +121,7 @@ private:
};
} // namespace QMdi
-class QMdiSubWindowPrivate : public QWidgetPrivate
+class Q_AUTOTEST_EXPORT QMdiSubWindowPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMdiSubWindow)
public:
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 74ac7e799c..264924a628 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -625,6 +625,29 @@ void QMenuPrivate::hideMenu(QMenu *menu)
menu->d_func()->causedPopup.widget = nullptr;
}
+QWindow *QMenuPrivate::transientParentWindow() const
+{
+ Q_Q(const QMenu);
+ if (const QWidget *parent = q->nativeParentWidget()) {
+ if (parent->windowHandle())
+ return parent->windowHandle();
+ }
+
+ if (const QWindow *w = q->windowHandle()) {
+ if (w->transientParent())
+ return w->transientParent();
+ }
+
+ if (causedPopup.widget) {
+ if (const QWidget *w = causedPopup.widget.data()) {
+ if (const QWidget *ww = w->window())
+ return ww->windowHandle();
+ }
+ }
+
+ return nullptr;
+}
+
void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
{
Q_Q(QMenu);
@@ -1053,6 +1076,16 @@ QAction *QMenu::menuAction() const
}
/*!
+ \fn static QMenu *QMenu::menuInAction(const QAction *action)
+
+ Returns the menu contained by \a action, or \nullptr if \a action does not
+ contain a menu.
+
+ In widget applications, actions that contain menus can be used to create menu
+ items with submenus, or inserted into toolbars to create buttons with popup menus.
+*/
+
+/*!
\property QMenu::title
\brief The title of the menu
@@ -1693,8 +1726,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
\b{Important inherited functions:} addAction(), removeAction(), clear(),
addSeparator(), and addMenu().
- \sa QMenuBar, {fowler}{GUI Design Handbook: Menu, Drop-Down and Pop-Up},
- {Qt Widgets - Application Example}, {Menus Example}
+ \sa QMenuBar, {Qt Widgets - Application Example}, {Menus Example}
*/
@@ -2973,6 +3005,8 @@ bool QMenu::event(QEvent *e)
d->sloppyState.reset();
if (d->currentAction)
d->popupAction(d->currentAction, 0, false);
+ if (isWindow() && window() && window()->windowHandle() && !window()->windowHandle()->transientParent())
+ window()->windowHandle()->setTransientParent(d->transientParentWindow());
break;
#if QT_CONFIG(tooltip)
case QEvent::ToolTip:
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 68481308fb..1b14263e6b 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -189,6 +189,8 @@ public:
QAction *actionAt(const QPoint &) const;
QAction *menuAction() const;
+ static QMenu *menuInAction(const QAction *action)
+ { return qobject_cast<QMenu *>(action->menuObject()); }
QString title() const;
void setTitle(const QString &title);
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index ffe956d007..bad9c294f8 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -440,6 +440,7 @@ public:
QMenuCaused causedPopup;
void hideUpToMenuBar();
void hideMenu(QMenu *menu);
+ QWindow *transientParentWindow() const;
//index mappings
inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index afe40361a8..4af9ba09e2 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -684,7 +684,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
\sa QMenu, QShortcut, QAction,
{http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
- {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
+ {Menus Example}
*/
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index aedd4593ec..9ca5bff827 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1616,7 +1616,7 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e)
const QPoint globalPos = QCursor::pos();
pos = d->viewport->mapFromGlobal(globalPos);
QMouseEvent ev(QEvent::MouseMove, pos, d->viewport->mapTo(d->viewport->topLevelWidget(), pos), globalPos,
- Qt::LeftButton, Qt::LeftButton, d->keyboardModifiers);
+ Qt::LeftButton, Qt::LeftButton, QGuiApplication::keyboardModifiers());
mouseMoveEvent(&ev);
}
int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
@@ -1681,7 +1681,6 @@ void QPlainTextEdit::setPlainText(const QString &text)
void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
{
Q_D(QPlainTextEdit);
- d->keyboardModifiers = e->modifiers();
#ifdef QT_KEYPAD_NAVIGATION
switch (e->key()) {
@@ -1832,7 +1831,6 @@ void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e)
Q_D(QPlainTextEdit);
if (!isReadOnly())
d->handleSoftwareInputPanel();
- d->keyboardModifiers = e->modifiers();
#ifdef QT_KEYPAD_NAVIGATION
if (QApplicationPrivate::keypadNavigationEnabled()) {
@@ -1942,7 +1940,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
// keep right margin clean from full-width selection
int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
- - document()->documentMargin();
+ - document()->documentMargin() + cursorWidth();
er.setRight(qMin(er.right(), maxX));
painter.setClipRect(er);
diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h
index 112eb2e4f6..114db01574 100644
--- a/src/widgets/widgets/qplaintextedit_p.h
+++ b/src/widgets/widgets/qplaintextedit_p.h
@@ -155,7 +155,6 @@ public:
qreal pageUpDownLastCursorY = 0;
QPlainTextEdit::LineWrapMode lineWrap = QPlainTextEdit::WidgetWidth;
QTextOption::WrapMode wordWrap = QTextOption::WrapAtWordBoundaryOrAnywhere;
- Qt::KeyboardModifiers keyboardModifiers = {};
int originalOffsetY = 0;
int topLine = 0;
diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp
index e2d4875f54..734384c192 100644
--- a/src/widgets/widgets/qprogressbar.cpp
+++ b/src/widgets/widgets/qprogressbar.cpp
@@ -201,7 +201,7 @@ bool QProgressBarPrivate::repaintRequired() const
example, when using QNetworkAccessManager to download items when
they are unable to determine the size of the item being downloaded.
- \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
+ \sa QProgressDialog
*/
/*!
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index 8d3d472882..cacc0f22d1 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -171,7 +171,7 @@ QT_BEGIN_NAMESPACE
and other API, and QPushButton provides GUI logic.
See QAbstractButton for more information about the API.
- \sa QToolButton, QRadioButton, QCheckBox, {fowler}{GUI Design Handbook: Push Button}
+ \sa QToolButton, QRadioButton, QCheckBox
*/
/*!
@@ -525,6 +525,8 @@ void QPushButton::mouseMoveEvent(QMouseEvent *e)
d->hovering = hit;
}
}
+
+ QAbstractButton::mouseMoveEvent(e);
}
/*!
diff --git a/src/widgets/widgets/qradiobutton.cpp b/src/widgets/widgets/qradiobutton.cpp
index 8e880a3f35..a7992664dc 100644
--- a/src/widgets/widgets/qradiobutton.cpp
+++ b/src/widgets/widgets/qradiobutton.cpp
@@ -118,8 +118,7 @@ void QRadioButtonPrivate::init()
setDown(), isDown(), autoRepeat(), group(), setAutoRepeat(),
toggle(), pressed(), released(), clicked(), and toggled().
- \sa QPushButton, QToolButton, QCheckBox, {fowler}{GUI Design Handbook: Radio Button},
- {Group Box Example}
+ \sa QPushButton, QToolButton, QCheckBox, {Group Box Example}
*/
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index f880240ea7..e8fdadb648 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -203,10 +203,13 @@ void QScrollAreaPrivate::updateScrollBars()
if (vbarpolicy == Qt::ScrollBarAsNeeded) {
int vbarWidth = vbar->sizeHint().width();
QSize m_hfw = m.expandedTo(min).boundedTo(max);
- while (h > m.height() && vbarWidth) {
- --vbarWidth;
- --m_hfw.rwidth();
- h = widget->heightForWidth(m_hfw.width());
+ // is there any point in searching?
+ if (widget->heightForWidth(m_hfw.width() - vbarWidth) <= m.height()) {
+ while (h > m.height() && vbarWidth) {
+ --vbarWidth;
+ --m_hfw.rwidth();
+ h = widget->heightForWidth(m_hfw.width());
+ }
}
max = QSize(m_hfw.width(), qMax(m_hfw.height(), h));
}
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index 8a2ef884d7..bdb646f816 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -44,6 +44,7 @@
#include "qscrollbar.h"
#include "qstyle.h"
#include "qstyleoption.h"
+#include "qstylepainter.h"
#if QT_CONFIG(menu)
#include "qmenu.h"
#endif
@@ -187,7 +188,7 @@ QT_BEGIN_NAMESPACE
Most GUI styles use the pageStep() value to calculate the size of the
slider.
- \sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example}
+ \sa QScrollArea, QSlider, QDial, QSpinBox, {Sliders Example}
*/
bool QScrollBarPrivate::updateHoverControl(const QPoint &pos)
@@ -525,7 +526,7 @@ void QScrollBar::wheelEvent(QWheelEvent *event)
void QScrollBar::paintEvent(QPaintEvent *)
{
Q_D(QScrollBar);
- QPainter p(this);
+ QStylePainter p(this);
QStyleOptionSlider opt;
initStyleOption(&opt);
opt.subControls = QStyle::SC_All;
@@ -536,7 +537,7 @@ void QScrollBar::paintEvent(QPaintEvent *)
} else {
opt.activeSubControls = (QStyle::SubControl)d->hoverControl;
}
- style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this);
+ p.drawComplexControl(QStyle::CC_ScrollBar, opt);
}
/*!
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
index d2eeec494a..ef53d726d9 100644
--- a/src/widgets/widgets/qslider.cpp
+++ b/src/widgets/widgets/qslider.cpp
@@ -46,6 +46,7 @@
#include "qpainter.h"
#include "qstyle.h"
#include "qstyleoption.h"
+#include "qstylepainter.h"
#include "private/qapplication_p.h"
#include "private/qabstractslider_p.h"
#include "qdebug.h"
@@ -155,6 +156,13 @@ void QSlider::initStyleOption(QStyleOptionSlider *option) const
option->pageStep = d->pageStep;
if (d->orientation == Qt::Horizontal)
option->state |= QStyle::State_Horizontal;
+
+ if (d->pressedControl) {
+ option->activeSubControls = d->pressedControl;
+ option->state |= QStyle::State_Sunken;
+ } else {
+ option->activeSubControls = d->hoverControl;
+ }
}
bool QSliderPrivate::updateHoverControl(const QPoint &pos)
@@ -256,7 +264,7 @@ QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
\li End moves to the end (maximum).
\endlist
- \sa QScrollBar, QSpinBox, QDial, {fowler}{GUI Design Handbook: Slider}, {Sliders Example}
+ \sa QScrollBar, QSpinBox, QDial, {Sliders Example}
*/
@@ -310,21 +318,15 @@ QSlider::~QSlider()
void QSlider::paintEvent(QPaintEvent *)
{
Q_D(QSlider);
- QPainter p(this);
+ QStylePainter p(this);
QStyleOptionSlider opt;
initStyleOption(&opt);
opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
if (d->tickPosition != NoTicks)
opt.subControls |= QStyle::SC_SliderTickmarks;
- if (d->pressedControl) {
- opt.activeSubControls = d->pressedControl;
- opt.state |= QStyle::State_Sunken;
- } else {
- opt.activeSubControls = d->hoverControl;
- }
- style()->drawComplexControl(QStyle::CC_Slider, &opt, &p, this);
+ p.drawComplexControl(QStyle::CC_Slider, opt);
}
/*!
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 1c04f02422..7f31a955f6 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1286,16 +1286,18 @@ int QSplitter::count() const
void QSplitter::childEvent(QChildEvent *c)
{
Q_D(QSplitter);
- if (!c->child()->isWidgetType()) {
- if (Q_UNLIKELY(c->type() == QEvent::ChildAdded && qobject_cast<QLayout *>(c->child())))
- qWarning("Adding a QLayout to a QSplitter is not supported.");
- return;
- }
if (c->added()) {
+ if (!c->child()->isWidgetType()) {
+ if (Q_UNLIKELY(qobject_cast<QLayout *>(c->child())))
+ qWarning("Adding a QLayout to a QSplitter is not supported.");
+ return;
+ }
QWidget *w = static_cast<QWidget*>(c->child());
if (!d->blockChildAdd && !w->isWindow() && !d->findWidget(w))
d->insertWidget_helper(d->list.count(), w, false);
} else if (c->polished()) {
+ if (!c->child()->isWidgetType())
+ return;
QWidget *w = static_cast<QWidget*>(c->child());
if (!d->blockChildAdd && !w->isWindow() && d->shouldShowWidget(w))
w->show();
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index d368f6668b..99aae2e13b 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -215,8 +215,7 @@ QRect QStatusBarPrivate::messageRect() const
\image fusion-statusbar-sizegrip.png A status bar shown in the Fusion widget style
- \sa QMainWindow, QStatusTipEvent, {fowler}{GUI Design Handbook:
- Status Bar}, {Qt Widgets - Application Example}
+ \sa QMainWindow, QStatusTipEvent, {Qt Widgets - Application Example}
*/
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 11fa33ca15..376355b0d5 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -42,8 +42,6 @@
#include "qabstractitemdelegate.h"
#endif
#include "qapplication.h"
-#include "qbitmap.h"
-#include "qcursor.h"
#include "qevent.h"
#include "qpainter.h"
#include "qstyle.h"
@@ -1020,6 +1018,11 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
++tab->lastTab;
}
+ if (tabAt(d->mousePosition) == index) {
+ d->hoverIndex = index;
+ d->hoverRect = tabRect(index);
+ }
+
tabInserted(index);
d->autoHideTabs();
return index;
@@ -1104,16 +1107,15 @@ void QTabBar::removeTab(int index)
}
d->refresh();
d->autoHideTabs();
- if (!d->hoverRect.isEmpty()) {
- for (int i = 0; i < d->tabList.count(); ++i) {
- const QRect area = tabRect(i);
- if (area.contains(mapFromGlobal(QCursor::pos()))) {
- d->hoverIndex = i;
- d->hoverRect = area;
- break;
- }
- }
+ if (d->hoverRect.isValid()) {
update(d->hoverRect);
+ d->hoverIndex = tabAt(d->mousePosition);
+ if (d->validIndex(d->hoverIndex)) {
+ d->hoverRect = tabRect(d->hoverIndex);
+ update(d->hoverRect);
+ } else {
+ d->hoverRect = QRect();
+ }
}
tabRemoved(index);
}
@@ -1433,6 +1435,13 @@ void QTabBar::setCurrentIndex(int index)
int oldIndex = d->currentIndex;
if (auto tab = d->at(index)) {
d->currentIndex = index;
+ // If the size hint depends on whether the tab is selected (for instance a style
+ // sheet rule that sets a bold font on the 'selected' tab) then we need to
+ // re-layout the entire tab bar. To minimize the cost, do that only if the
+ // size hint changes for the tab that becomes the current tab (the old curent tab
+ // will most certainly do the same). QTBUG-6905
+ if (tabRect(index).size() != tabSizeHint(index))
+ d->layoutTabs();
update();
d->makeVisible(index);
if (d->validIndex(oldIndex)) {
@@ -1689,33 +1698,29 @@ bool QTabBar::event(QEvent *event)
case QEvent::HoverMove:
case QEvent::HoverEnter: {
QHoverEvent *he = static_cast<QHoverEvent *>(event);
- if (!d->hoverRect.contains(he->position().toPoint())) {
- QRect oldHoverRect = d->hoverRect;
- bool cursorOverTabs = false;
- for (int i = 0; i < d->tabList.count(); ++i) {
- QRect area = tabRect(i);
- if (area.contains(he->position().toPoint())) {
- d->hoverIndex = i;
- d->hoverRect = area;
- cursorOverTabs = true;
- break;
- }
- }
- if (!cursorOverTabs) {
- d->hoverIndex = -1;
+ d->mousePosition = he->position().toPoint();
+ if (!d->hoverRect.contains(d->mousePosition)) {
+ if (d->hoverRect.isValid())
+ update(d->hoverRect);
+ d->hoverIndex = tabAt(d->mousePosition);
+ if (d->validIndex(d->hoverIndex)) {
+ d->hoverRect = tabRect(d->hoverIndex);
+ update(d->hoverRect);
+ } else {
d->hoverRect = QRect();
}
- if (he->oldPos() != QPoint(-1, -1))
- update(oldHoverRect);
- update(d->hoverRect);
}
return true;
}
case QEvent::HoverLeave: {
- QRect oldHoverRect = d->hoverRect;
+ d->mousePosition = {-1, -1};
+ if (d->hoverRect.isValid())
+ update(d->hoverRect);
d->hoverIndex = -1;
d->hoverRect = QRect();
- update(oldHoverRect);
+#if QT_CONFIG(wheelevent)
+ d->accumulatedAngleDelta = QPoint();
+#endif
return true;
}
#if QT_CONFIG(tooltip)
@@ -1789,6 +1794,7 @@ bool QTabBar::event(QEvent *event)
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
+ d->mousePosition = static_cast<QMouseEvent *>(event)->position().toPoint();
d->mouseButtons = static_cast<QMouseEvent *>(event)->buttons();
break;
default:
@@ -2385,10 +2391,57 @@ void QTabBar::wheelEvent(QWheelEvent *event)
{
Q_D(QTabBar);
if (style()->styleHint(QStyle::SH_TabBar_AllowWheelScrolling)) {
- int delta = (qAbs(event->angleDelta().x()) > qAbs(event->angleDelta().y()) ?
- event->angleDelta().x() : event->angleDelta().y());
- int offset = delta > 0 ? -1 : 1;
- d->setCurrentNextEnabledIndex(offset);
+ const bool wheelVertical = qAbs(event->angleDelta().y()) > qAbs(event->angleDelta().x());
+ const bool tabsVertical = verticalTabs(d->shape);
+ if (event->device()->capabilities().testFlag(QInputDevice::Capability::PixelScroll)) {
+ // For wheels/touch pads with pixel precision, scroll the tab bar if
+ // it has the right orientation.
+ int delta = 0;
+ if (tabsVertical == wheelVertical)
+ delta = wheelVertical ? event->pixelDelta().y() : event->pixelDelta().x();
+ if (layoutDirection() == Qt::RightToLeft)
+ delta = -delta;
+ if (delta && d->validIndex(d->lastVisible)) {
+ const int oldScrollOffset = d->scrollOffset;
+ const QRect lastTabRect = d->tabList.at(d->lastVisible)->rect;
+ const QRect scrollRect = d->normalizedScrollRect(d->lastVisible);
+ int scrollRectExtent = scrollRect.right();
+ if (!d->leftB->isVisible())
+ scrollRectExtent += tabsVertical ? d->leftB->height() : d->leftB->width();
+ if (!d->rightB->isVisible())
+ scrollRectExtent += tabsVertical ? d->rightB->height() : d->rightB->width();
+
+ const int maxScrollOffset = qMax((tabsVertical ?
+ lastTabRect.bottom() :
+ lastTabRect.right()) - scrollRectExtent, 0);
+ d->scrollOffset = qBound(0, d->scrollOffset - delta, maxScrollOffset);
+ d->leftB->setEnabled(d->scrollOffset > -scrollRect.left());
+ d->rightB->setEnabled(maxScrollOffset > d->scrollOffset);
+ if (oldScrollOffset != d->scrollOffset) {
+ event->accept();
+ update();
+ return;
+ }
+ }
+ } else {
+ d->accumulatedAngleDelta += event->angleDelta();
+ const int xSteps = d->accumulatedAngleDelta.x() / QWheelEvent::DefaultDeltasPerStep;
+ const int ySteps = d->accumulatedAngleDelta.y() / QWheelEvent::DefaultDeltasPerStep;
+ int offset = 0;
+ if (xSteps > 0 || ySteps > 0) {
+ offset = -1;
+ d->accumulatedAngleDelta = QPoint();
+ } else if (xSteps < 0 || ySteps < 0) {
+ offset = 1;
+ d->accumulatedAngleDelta = QPoint();
+ }
+ const int oldCurrentIndex = d->currentIndex;
+ d->setCurrentNextEnabledIndex(offset);
+ if (oldCurrentIndex != d->currentIndex) {
+ event->accept();
+ return;
+ }
+ }
QWidget::wheelEvent(event);
}
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index eb1339a802..5bc4c15293 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -101,6 +101,10 @@ public:
QRect hoverRect;
QPoint dragStartPosition;
+ QPoint mousePosition = {-1, -1};
+#if QT_CONFIG(wheelevent)
+ QPoint accumulatedAngleDelta;
+#endif
QSize iconSize;
QToolButton* rightB = nullptr; // right or bottom
QToolButton* leftB = nullptr; // left or top
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index 96c3510529..f4e1610fee 100644
--- a/src/widgets/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
@@ -169,8 +169,7 @@ bool QToolButtonPrivate::hasMenu() const
with actions used in other parts of the main window.
\endtable
- \sa QPushButton, QToolBar, QMainWindow, QAction,
- {fowler}{GUI Design Handbook: Push Button}
+ \sa QPushButton, QToolBar, QMainWindow, QAction
*/
/*!
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 76029714d5..ef1158b8ce 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1299,7 +1299,7 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
}
#ifndef QT_NO_SHORTCUT
else if (e == QKeySequence::InsertParagraphSeparator) {
- cursor.insertBlock();
+ insertParagraphSeparator();
e->accept();
goto accept;
} else if (e == QKeySequence::InsertLineSeparator) {
@@ -3198,6 +3198,49 @@ QString QWidgetTextControl::toMarkdown(QTextDocument::MarkdownFeatures features)
}
#endif
+void QWidgetTextControlPrivate::insertParagraphSeparator()
+{
+ // clear blockFormat properties that the user is unlikely to want duplicated:
+ // - don't insert <hr/> automatically
+ // - the next paragraph after a heading should be a normal paragraph
+ // - remove the bottom margin from the last list item before appending
+ // - the next checklist item after a checked item should be unchecked
+ auto blockFmt = cursor.blockFormat();
+ auto charFmt = cursor.charFormat();
+ blockFmt.clearProperty(QTextFormat::BlockTrailingHorizontalRulerWidth);
+ if (blockFmt.hasProperty(QTextFormat::HeadingLevel)) {
+ blockFmt.clearProperty(QTextFormat::HeadingLevel);
+ charFmt = QTextCharFormat();
+ }
+ if (cursor.currentList()) {
+ auto existingFmt = cursor.blockFormat();
+ existingFmt.clearProperty(QTextBlockFormat::BlockBottomMargin);
+ cursor.setBlockFormat(existingFmt);
+ if (blockFmt.marker() == QTextBlockFormat::MarkerType::Checked)
+ blockFmt.setMarker(QTextBlockFormat::MarkerType::Unchecked);
+ }
+
+ // After a blank line, reset block and char formats. I.e. you can end a list,
+ // block quote, etc. by hitting enter twice, and get back to normal paragraph style.
+ if (cursor.block().text().isEmpty() &&
+ !cursor.blockFormat().hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) &&
+ !cursor.blockFormat().hasProperty(QTextFormat::BlockCodeLanguage)) {
+ blockFmt = QTextBlockFormat();
+ const bool blockFmtChanged = (cursor.blockFormat() != blockFmt);
+ charFmt = QTextCharFormat();
+ cursor.setBlockFormat(blockFmt);
+ cursor.setCharFormat(charFmt);
+ // If the user hit enter twice just to get back to default format,
+ // don't actually insert a new block. But if the user then hits enter
+ // yet again, the block format will not change, so we will insert a block.
+ // This is what many word processors do.
+ if (blockFmtChanged)
+ return;
+ }
+
+ cursor.insertBlock(blockFmt, charFmt);
+}
+
void QWidgetTextControlPrivate::append(const QString &text, Qt::TextFormat format)
{
QTextCursor tmp(doc);
@@ -3455,7 +3498,7 @@ void QTextEditMimeData::setup() const
that->setData(QLatin1String("application/vnd.oasis.opendocument.text"), buffer.data());
}
#endif
- that->setText(fragment.toPlainText());
+ that->setText(fragment.toRawText());
fragment = QTextDocumentFragment();
}
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
index cc4f867e8e..c94f859e6f 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -73,8 +73,9 @@ class QAbstractScrollArea;
class QWidgetTextControlPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QWidgetTextControl)
public:
+ Q_DECLARE_PUBLIC(QWidgetTextControl)
+
QWidgetTextControlPrivate();
bool cursorMoveKeyEvent(QKeyEvent *e);
@@ -178,6 +179,7 @@ public:
bool isPreediting() const;
void commitPreedit();
+ void insertParagraphSeparator();
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
QTextDocument *doc;