summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp117
-rw-r--r--src/widgets/widgets/qabstractbutton.h40
-rw-r--r--src/widgets/widgets/qabstractbutton_p.h40
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp177
-rw-r--r--src/widgets/widgets/qabstractscrollarea.h46
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h44
-rw-r--r--src/widgets/widgets/qabstractslider.cpp57
-rw-r--r--src/widgets/widgets/qabstractslider.h40
-rw-r--r--src/widgets/widgets/qabstractslider_p.h40
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp87
-rw-r--r--src/widgets/widgets/qabstractspinbox.h43
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h48
-rw-r--r--src/widgets/widgets/qbuttongroup.cpp48
-rw-r--r--src/widgets/widgets/qbuttongroup.h40
-rw-r--r--src/widgets/widgets/qbuttongroup_p.h40
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp134
-rw-r--r--src/widgets/widgets/qcalendarwidget.h52
-rw-r--r--src/widgets/widgets/qcheckbox.cpp75
-rw-r--r--src/widgets/widgets/qcheckbox.h44
-rw-r--r--src/widgets/widgets/qcombobox.cpp691
-rw-r--r--src/widgets/widgets/qcombobox.h58
-rw-r--r--src/widgets/widgets/qcombobox_p.h92
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.cpp54
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.h40
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp373
-rw-r--r--src/widgets/widgets/qdatetimeedit.h57
-rw-r--r--src/widgets/widgets/qdatetimeedit_p.h84
-rw-r--r--src/widgets/widgets/qdial.cpp48
-rw-r--r--src/widgets/widgets/qdial.h40
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp375
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h42
-rw-r--r--src/widgets/widgets/qdialogbuttonbox_p.h80
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp371
-rw-r--r--src/widgets/widgets/qdockarealayout_p.h56
-rw-r--r--src/widgets/widgets/qdockwidget.cpp354
-rw-r--r--src/widgets/widgets/qdockwidget.h50
-rw-r--r--src/widgets/widgets/qdockwidget_p.h62
-rw-r--r--src/widgets/widgets/qeffects.cpp55
-rw-r--r--src/widgets/widgets/qeffects_p.h40
-rw-r--r--src/widgets/widgets/qfocusframe.cpp48
-rw-r--r--src/widgets/widgets/qfocusframe.h40
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp239
-rw-r--r--src/widgets/widgets/qfontcombobox.h51
-rw-r--r--src/widgets/widgets/qframe.cpp51
-rw-r--r--src/widgets/widgets/qframe.h42
-rw-r--r--src/widgets/widgets/qframe_p.h40
-rw-r--r--src/widgets/widgets/qgroupbox.cpp71
-rw-r--r--src/widgets/widgets/qgroupbox.h40
-rw-r--r--src/widgets/widgets/qkeysequenceedit.cpp208
-rw-r--r--src/widgets/widgets/qkeysequenceedit.h57
-rw-r--r--src/widgets/widgets/qkeysequenceedit_p.h46
-rw-r--r--src/widgets/widgets/qlabel.cpp165
-rw-r--r--src/widgets/widgets/qlabel.h52
-rw-r--r--src/widgets/widgets/qlabel_p.h62
-rw-r--r--src/widgets/widgets/qlcdnumber.cpp88
-rw-r--r--src/widgets/widgets/qlcdnumber.h40
-rw-r--r--src/widgets/widgets/qlineedit.cpp547
-rw-r--r--src/widgets/widgets/qlineedit.h54
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp177
-rw-r--r--src/widgets/widgets/qlineedit_p.h69
-rw-r--r--src/widgets/widgets/qmainwindow.cpp126
-rw-r--r--src/widgets/widgets/qmainwindow.h44
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp892
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h147
-rw-r--r--src/widgets/widgets/qmdiarea.cpp170
-rw-r--r--src/widgets/widgets/qmdiarea.h40
-rw-r--r--src/widgets/widgets/qmdiarea_p.h42
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp117
-rw-r--r--src/widgets/widgets/qmdisubwindow.h41
-rw-r--r--src/widgets/widgets/qmdisubwindow_p.h47
-rw-r--r--src/widgets/widgets/qmenu.cpp392
-rw-r--r--src/widgets/widgets/qmenu.h143
-rw-r--r--src/widgets/widgets/qmenu_mac.mm40
-rw-r--r--src/widgets/widgets/qmenu_p.h48
-rw-r--r--src/widgets/widgets/qmenubar.cpp209
-rw-r--r--src/widgets/widgets/qmenubar.h70
-rw-r--r--src/widgets/widgets/qmenubar_p.h42
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp290
-rw-r--r--src/widgets/widgets/qplaintextedit.h48
-rw-r--r--src/widgets/widgets/qplaintextedit_p.h62
-rw-r--r--src/widgets/widgets/qprogressbar.cpp65
-rw-r--r--src/widgets/widgets/qprogressbar.h40
-rw-r--r--src/widgets/widgets/qpushbutton.cpp68
-rw-r--r--src/widgets/widgets/qpushbutton.h45
-rw-r--r--src/widgets/widgets/qpushbutton_p.h46
-rw-r--r--src/widgets/widgets/qradiobutton.cpp43
-rw-r--r--src/widgets/widgets/qradiobutton.h40
-rw-r--r--src/widgets/widgets/qrubberband.cpp40
-rw-r--r--src/widgets/widgets/qrubberband.h40
-rw-r--r--src/widgets/widgets/qscrollarea.cpp64
-rw-r--r--src/widgets/widgets/qscrollarea.h40
-rw-r--r--src/widgets/widgets/qscrollarea_p.h42
-rw-r--r--src/widgets/widgets/qscrollbar.cpp79
-rw-r--r--src/widgets/widgets/qscrollbar.h40
-rw-r--r--src/widgets/widgets/qscrollbar_p.h40
-rw-r--r--src/widgets/widgets/qsizegrip.cpp56
-rw-r--r--src/widgets/widgets/qsizegrip.h40
-rw-r--r--src/widgets/widgets/qslider.cpp66
-rw-r--r--src/widgets/widgets/qslider.h40
-rw-r--r--src/widgets/widgets/qspinbox.cpp94
-rw-r--r--src/widgets/widgets/qspinbox.h40
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp96
-rw-r--r--src/widgets/widgets/qsplashscreen.h40
-rw-r--r--src/widgets/widgets/qsplitter.cpp125
-rw-r--r--src/widgets/widgets/qsplitter.h40
-rw-r--r--src/widgets/widgets/qsplitter_p.h42
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp47
-rw-r--r--src/widgets/widgets/qstackedwidget.h40
-rw-r--r--src/widgets/widgets/qstatusbar.cpp213
-rw-r--r--src/widgets/widgets/qstatusbar.h40
-rw-r--r--src/widgets/widgets/qtabbar.cpp381
-rw-r--r--src/widgets/widgets/qtabbar.h49
-rw-r--r--src/widgets/widgets/qtabbar_p.h60
-rw-r--r--src/widgets/widgets/qtabwidget.cpp100
-rw-r--r--src/widgets/widgets/qtabwidget.h43
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp137
-rw-r--r--src/widgets/widgets/qtextbrowser.h43
-rw-r--r--src/widgets/widgets/qtextedit.cpp224
-rw-r--r--src/widgets/widgets/qtextedit.h51
-rw-r--r--src/widgets/widgets/qtextedit_p.h59
-rw-r--r--src/widgets/widgets/qtoolbar.cpp213
-rw-r--r--src/widgets/widgets/qtoolbar.h95
-rw-r--r--src/widgets/widgets/qtoolbar_p.h40
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp172
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h40
-rw-r--r--src/widgets/widgets/qtoolbarextension.cpp50
-rw-r--r--src/widgets/widgets/qtoolbarextension_p.h40
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp72
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h40
-rw-r--r--src/widgets/widgets/qtoolbarseparator.cpp40
-rw-r--r--src/widgets/widgets/qtoolbarseparator_p.h40
-rw-r--r--src/widgets/widgets/qtoolbox.cpp44
-rw-r--r--src/widgets/widgets/qtoolbox.h40
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp121
-rw-r--r--src/widgets/widgets/qtoolbutton.h49
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp45
-rw-r--r--src/widgets/widgets/qwidgetanimator_p.h40
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp204
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h59
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp44
-rw-r--r--src/widgets/widgets/qwidgetresizehandler_p.h40
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp253
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h56
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h44
144 files changed, 5453 insertions, 8757 deletions
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index de6741c030..3a5fbe1b90 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "private/qabstractbutton_p.h"
@@ -44,17 +8,20 @@
#endif
#if QT_CONFIG(buttongroup)
#include "qbuttongroup.h"
-#include "private/qapplication_p.h"
#include "private/qbuttongroup_p.h"
#endif
+#include "private/qapplication_p.h"
#include "qabstractbutton_p.h"
#include "qevent.h"
#include "qpainter.h"
#include "qapplication.h"
#include "qstyle.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
+#include <qpa/qplatformtheme.h>
+
+#include <QtCore/qpointer.h>
#include <algorithm>
@@ -215,10 +182,10 @@ QAbstractButton *QAbstractButtonPrivate::queryCheckedButton() const
Q_Q(const QAbstractButton);
QList<QAbstractButton *> buttonList = queryButtonList();
- if (!autoExclusive || buttonList.count() == 1) // no group
+ if (!autoExclusive || buttonList.size() == 1) // no group
return nullptr;
- for (int i = 0; i < buttonList.count(); ++i) {
+ for (int i = 0; i < buttonList.size(); ++i) {
QAbstractButton *b = buttonList.at(i);
if (b->d_func()->checked && b != q)
return b;
@@ -262,7 +229,7 @@ void QAbstractButtonPrivate::moveFocus(int key)
QPoint goal = target.center();
uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
- for (int i = 0; i < buttonList.count(); ++i) {
+ for (int i = 0; i < buttonList.size(); ++i) {
QAbstractButton *button = buttonList.at(i);
if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
(exclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
@@ -345,7 +312,7 @@ void QAbstractButtonPrivate::fixFocusPolicy()
return;
QList<QAbstractButton *> buttonList = queryButtonList();
- for (int i = 0; i < buttonList.count(); ++i) {
+ for (int i = 0; i < buttonList.size(); ++i) {
QAbstractButton *b = buttonList.at(i);
if (!b->isCheckable())
continue;
@@ -525,7 +492,7 @@ void QAbstractButton::setText(const QString &text)
d->sizeHint = QSize();
update();
updateGeometry();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
#endif
@@ -648,12 +615,13 @@ void QAbstractButton::setChecked(bool checked)
if (guard)
d->emitToggled(checked);
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::State s;
- s.checked = true;
- QAccessibleStateChangeEvent event(this, s);
- QAccessible::updateAccessibility(&event);
+#if QT_CONFIG(accessibility)
+ if (guard) {
+ QAccessible::State s;
+ s.checked = true;
+ QAccessibleStateChangeEvent event(this, s);
+ QAccessible::updateAccessibility(&event);
+ }
#endif
}
@@ -939,9 +907,6 @@ bool QAbstractButton::event(QEvent *e)
case QEvent::HoverEnter:
case QEvent::HoverLeave:
case QEvent::ContextMenu:
-#if QT_CONFIG(wheelevent)
- case QEvent::Wheel:
-#endif
return true;
default:
break;
@@ -1043,19 +1008,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
{
Q_D(QAbstractButton);
bool next = true;
- switch (e->key()) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- e->ignore();
- break;
- case Qt::Key_Select:
- case Qt::Key_Space:
- if (!e->isAutoRepeat()) {
- setDown(true);
- repaint();
- d->emitPressed();
- }
- break;
+
+ const auto key = e->key();
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
+ setDown(true);
+ repaint();
+ d->emitPressed();
+ return;
+ }
+
+ switch (key) {
case Qt::Key_Up:
next = false;
Q_FALLTHROUGH();
@@ -1085,7 +1050,7 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
// cleaned up when fixing task 194373. It's here to ensure that we
// keep compatibility outside QAbstractItemView.
d->moveFocus(e->key());
- if (hasFocus()) // nothing happend, propagate
+ if (hasFocus()) // nothing happened, propagate
e->ignore();
} else {
// Prefer parent widget, use this if parent is absent
@@ -1120,15 +1085,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
if (!e->isAutoRepeat())
d->repeatTimer.stop();
- switch (e->key()) {
- case Qt::Key_Select:
- case Qt::Key_Space:
- if (!e->isAutoRepeat() && d->down)
- d->click();
- break;
- default:
- e->ignore();
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
+ d->click();
+ return;
}
+
+ e->ignore();
}
/*!\reimp
diff --git a/src/widgets/widgets/qabstractbutton.h b/src/widgets/widgets/qabstractbutton.h
index ee7378411f..7a1e55abdd 100644
--- a/src/widgets/widgets/qabstractbutton.h
+++ b/src/widgets/widgets/qabstractbutton.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTBUTTON_H
#define QABSTRACTBUTTON_H
diff --git a/src/widgets/widgets/qabstractbutton_p.h b/src/widgets/widgets/qabstractbutton_p.h
index 39e2e399a7..6b6d5a2167 100644
--- a/src/widgets/widgets/qabstractbutton_p.h
+++ b/src/widgets/widgets/qabstractbutton_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTBUTTON_P_H
#define QABSTRACTBUTTON_P_H
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index f7407d7d74..f6f8e8b795 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qabstractscrollarea.h"
@@ -68,6 +32,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\class QAbstractScrollArea
\brief The QAbstractScrollArea widget provides a scrolling area with
@@ -202,7 +168,7 @@ void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPo
}
/*! \internal
- Retuns a list of scroll bar widgets for the given position. The scroll bar
+ Returns a list of scroll-bar widgets for the given position. The scroll bar
itself is not returned.
*/
QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position)
@@ -282,11 +248,11 @@ void QAbstractScrollAreaPrivate::init()
{
Q_Q(QAbstractScrollArea);
viewport = new QWidget(q);
- viewport->setObjectName(QLatin1String("qt_scrollarea_viewport"));
+ viewport->setObjectName("qt_scrollarea_viewport"_L1);
viewport->setBackgroundRole(QPalette::Base);
viewport->setAutoFillBackground(true);
scrollBarContainers[Qt::Horizontal] = new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);
- scrollBarContainers[Qt::Horizontal]->setObjectName(QLatin1String("qt_scrollarea_hcontainer"));
+ scrollBarContainers[Qt::Horizontal]->setObjectName("qt_scrollarea_hcontainer"_L1);
hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;
hbar->setRange(0,0);
scrollBarContainers[Qt::Horizontal]->setVisible(false);
@@ -294,7 +260,7 @@ void QAbstractScrollAreaPrivate::init()
QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(_q_hslide(int)));
QObject::connect(hbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
scrollBarContainers[Qt::Vertical] = new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);
- scrollBarContainers[Qt::Vertical]->setObjectName(QLatin1String("qt_scrollarea_vcontainer"));
+ scrollBarContainers[Qt::Vertical]->setObjectName("qt_scrollarea_vcontainer"_L1);
vbar = scrollBarContainers[Qt::Vertical]->scrollBar;
vbar->setRange(0,0);
scrollBarContainers[Qt::Vertical]->setVisible(false);
@@ -329,22 +295,25 @@ void QAbstractScrollAreaPrivate::layoutChildren()
void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar)
{
Q_Q(QAbstractScrollArea);
- bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, hbar);
+ QStyleOptionSlider barOpt;
+
+ hbar->initStyleOption(&barOpt);
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, hbar);
bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
|| ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
&& hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
+ const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, hbar);
- bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, vbar);
+ vbar->initStyleOption(&barOpt);
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, vbar);
bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
|| ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
&& vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
+ const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, vbar);
QStyleOption opt(0);
opt.initFrom(q);
- const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, hbar);
- const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, vbar);
-
const int hsbExt = hbar->sizeHint().height();
const int vsbExt = vbar->sizeHint().width();
const QPoint extPoint(vsbExt, hsbExt);
@@ -402,7 +371,7 @@ void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrol
#if QT_CONFIG(itemviews)
if ((vscrollOverlap > 0 && needv) || (hscrollOverlap > 0 && needh)) {
const QList<QHeaderView *> headers = q->findChildren<QHeaderView*>();
- if (headers.count() <= 2) {
+ if (headers.size() <= 2) {
for (const QHeaderView *header : headers) {
const QRect geo = header->geometry();
if (header->orientation() == Qt::Vertical && header->isVisible() && QStyle::visualRect(opt.direction, opt.rect, geo).left() <= opt.rect.width() / 2)
@@ -442,8 +411,10 @@ void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrol
viewportRect.adjust(right, top, -left, -bottom);
else
viewportRect.adjust(left, top, -right, -bottom);
+ viewportRect = QStyle::visualRect(opt.direction, opt.rect, viewportRect);
+ viewportRect.translate(-overshoot);
+ viewport->setGeometry(viewportRect); // resize the viewport last
- viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
*needHorizontalScrollbar = needh;
*needVerticalScrollbar = needv;
}
@@ -564,15 +535,13 @@ scrolling range.
QSize QAbstractScrollArea::maximumViewportSize() const
{
Q_D(const QAbstractScrollArea);
- int hsbExt = d->hbar->sizeHint().height();
- int vsbExt = d->vbar->sizeHint().width();
-
int f = 2 * d->frameWidth;
QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
+ // Count the sizeHint of the bar only if it is displayed.
if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
- max.rwidth() -= vsbExt;
+ max.rwidth() -= d->vbar->sizeHint().width();
if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
- max.rheight() -= hsbExt;
+ max.rheight() -= d->hbar->sizeHint().height();
return max;
}
@@ -836,7 +805,7 @@ QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
/*!
Sets the margins around the scrolling area to \a left, \a top, \a
right and \a bottom. This is useful for applications such as
- spreadsheets with "locked" rows and columns. The marginal space is
+ spreadsheets with "locked" rows and columns. The marginal space
is left blank; put widgets in the unused area.
Note that this function is frequently called by QTreeView and
@@ -1131,7 +1100,7 @@ void QAbstractScrollArea::resizeEvent(QResizeEvent *)
This event handler can be reimplemented in a subclass to receive
paint events (passed in \a event), for the viewport() widget.
- \note If you open a painter, make sure to open it on the viewport().
+ \note If you create a QPainter, it must operate on the viewport().
\sa QWidget::paintEvent()
*/
@@ -1230,49 +1199,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();
}
@@ -1366,10 +1343,14 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt(const QPoint &startPos) con
void QAbstractScrollAreaPrivate::flashScrollBars()
{
- bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, hbar);
+ QStyleOptionSlider opt;
+ hbar->initStyleOption(&opt);
+
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, hbar);
if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
hbar->d_func()->flash();
- bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, vbar);
+ vbar->initStyleOption(&opt);
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, vbar);
if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
vbar->d_func()->flash();
}
@@ -1450,9 +1431,9 @@ QSize QAbstractScrollArea::sizeHint() const
if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
const int f = 2 * d->frameWidth;
- const QSize frame( f, f );
- const bool vbarHidden = d->vbar->isHidden() || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
- const bool hbarHidden = d->hbar->isHidden() || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
+ const QSize frame(f, f);
+ const bool vbarHidden = !d->vbar->isVisibleTo(this) || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
+ const bool hbarHidden = !d->vbar->isVisibleTo(this) || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
const QSize scrollbars(vbarHidden ? 0 : d->vbar->sizeHint().width(),
hbarHidden ? 0 : d->hbar->sizeHint().height());
d->sizeHint = frame + scrollbars + viewportSizeHint();
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
index 6d0d8fa6e6..33f4b76444 100644
--- a/src/widgets/widgets/qabstractscrollarea.h
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSCROLLAREA_H
#define QABSTRACTSCROLLAREA_H
@@ -56,8 +20,10 @@ class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame
{
Q_OBJECT
- Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
- Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
+ Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy
+ WRITE setVerticalScrollBarPolicy)
+ Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy
+ WRITE setHorizontalScrollBarPolicy)
Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
public:
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 8effcd0f55..7224d489ce 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSCROLLAREA_P_H
#define QABSTRACTSCROLLAREA_P_H
@@ -63,7 +27,7 @@ QT_BEGIN_NAMESPACE
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
-class QAbstractScrollAreaPrivate: public QFramePrivate
+class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
{
Q_DECLARE_PUBLIC(QAbstractScrollArea)
@@ -116,7 +80,7 @@ class QAbstractScrollAreaFilter : public QObject
Q_OBJECT
public:
QAbstractScrollAreaFilter(QAbstractScrollAreaPrivate *p) : d(p)
- { setObjectName(QLatin1String("qt_abstractscrollarea_filter")); }
+ { setObjectName(QLatin1StringView("qt_abstractscrollarea_filter")); }
bool eventFilter(QObject *o, QEvent *e) override
{ return (o == d->viewport ? d->viewportEvent(e) : false); }
private:
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index a0611565b8..4e65fbac88 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qapplication.h>
#include "qabstractslider.h"
#include "qevent.h"
#include "qabstractslider_p.h"
#include "qdebug.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#include <limits.h>
@@ -107,7 +71,7 @@ QT_BEGIN_NAMESPACE
\row \li \l sliderReleased()
\li the user releases the slider.
\row \li \l actionTriggered()
- \li a slider action was triggerd.
+ \li a slider action was triggered.
\row \li \l rangeChanged()
\li a the range has changed.
\endtable
@@ -534,18 +498,25 @@ void QAbstractSlider::setValue(int value)
value = d->bound(value);
if (d->value == value && d->position == value)
return;
+
+ // delay signal emission until sliderChanged() has been called
+ const bool emitValueChanged = (value != d->value);
d->value = value;
+
if (d->position != value) {
d->position = value;
if (d->pressed)
- emit sliderMoved((d->position = value));
+ emit sliderMoved(d->position);
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(this, d->value);
QAccessible::updateAccessibility(&event);
#endif
sliderChange(SliderValueChange);
- emit valueChanged(value);
+
+ if (emitValueChanged)
+ emit valueChanged(value);
+
}
/*!
diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h
index 7791d30d10..fa2261fda1 100644
--- a/src/widgets/widgets/qabstractslider.h
+++ b/src/widgets/widgets/qabstractslider.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSLIDER_H
#define QABSTRACTSLIDER_H
diff --git a/src/widgets/widgets/qabstractslider_p.h b/src/widgets/widgets/qabstractslider_p.h
index 1b8c76c7ec..db4294e198 100644
--- a/src/widgets/widgets/qabstractslider_p.h
+++ b/src/widgets/widgets/qabstractslider_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSLIDER_P_H
#define QABSTRACTSLIDER_P_H
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index fc01354046..f377275d23 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qplatformdefs.h>
#include <private/qabstractspinbox_p.h>
@@ -58,10 +22,11 @@
#include <qpalette.h>
#include <qstylepainter.h>
#include <qdebug.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
# include <qaccessible.h>
#endif
+#include <QtCore/qpointer.h>
//#define QABSTRACTSPINBOX_QSBDEBUG
#ifdef QABSTRACTSPINBOX_QSBDEBUG
@@ -72,6 +37,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\class QAbstractSpinBox
\brief The QAbstractSpinBox class provides a spinbox and a line edit to
@@ -671,7 +638,8 @@ void QAbstractSpinBox::stepBy(int steps)
} else if (e == AlwaysEmit) {
d->emitSignals(e, old);
}
- selectAll();
+ if (style()->styleHint(QStyle::SH_SpinBox_SelectOnStep, nullptr, this, nullptr))
+ selectAll();
}
/*!
@@ -724,14 +692,14 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
d->edit->setAcceptDrops(false);
if (d->type != QMetaType::UnknownType) {
- connect(d->edit, SIGNAL(textChanged(QString)),
- this, SLOT(_q_editorTextChanged(QString)));
- connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
- this, SLOT(_q_editorCursorPositionChanged(int,int)));
- connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
- this, SLOT(updateMicroFocus()));
- connect(d->edit->d_func()->control, SIGNAL(updateMicroFocus()),
- this, SLOT(updateMicroFocus()));
+ QObjectPrivate::connect(d->edit, &QLineEdit::textChanged,
+ d, &QAbstractSpinBoxPrivate::editorTextChanged);
+ QObjectPrivate::connect(d->edit, &QLineEdit::cursorPositionChanged,
+ d, &QAbstractSpinBoxPrivate::editorCursorPositionChanged);
+ connect(d->edit, &QLineEdit::cursorPositionChanged,
+ this, [this]() { updateMicroFocus(); });
+ connect(d->edit->d_func()->control, &QWidgetLineControl::updateMicroFocus,
+ this, [this]() { updateMicroFocus(); });
}
d->updateEditFieldGeometry();
d->edit->setContextMenuPolicy(Qt::NoContextMenu);
@@ -905,7 +873,7 @@ QSize QAbstractSpinBox::sizeHint() const
int h = d->edit->sizeHint().height();
int w = 0;
QString s;
- QString fixedContent = d->prefix + d->suffix + QLatin1Char(' ');
+ QString fixedContent = d->prefix + d->suffix + u' ';
s = d->textFromValue(d->minimum);
s.truncate(18);
s += fixedContent;
@@ -945,7 +913,7 @@ QSize QAbstractSpinBox::minimumSizeHint() const
int w = 0;
QString s;
- QString fixedContent = d->prefix + QLatin1Char(' ');
+ QString fixedContent = d->prefix + u' ';
s = d->textFromValue(d->minimum);
s.truncate(18);
s += fixedContent;
@@ -1053,7 +1021,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
d->updateState(up, true);
}
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(this, d->value);
QAccessible::updateAccessibility(&event);
#endif
@@ -1095,7 +1063,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
case Qt::Key_U:
if (event->modifiers() & Qt::ControlModifier
- && QGuiApplication::platformName() == QLatin1String("xcb")) { // only X11
+ && QGuiApplication::platformName() == "xcb"_L1) { // only X11
event->accept();
if (!isReadOnly())
clear();
@@ -1269,7 +1237,7 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
killTimer(d->spinClickThresholdTimerId);
d->spinClickThresholdTimerId = -1;
d->effectiveSpinRepeatRate = d->buttonState & Keyboard
- ? QGuiApplication::styleHints()->keyboardAutoRepeatRate()
+ ? QGuiApplication::styleHints()->keyboardAutoRepeatRateF()
: d->spinClickTimerInterval;
d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
doStep = true;
@@ -1543,7 +1511,7 @@ void QAbstractSpinBoxPrivate::emitSignals(EmitPolicy, const QVariant &)
signal.
*/
-void QAbstractSpinBoxPrivate::_q_editorTextChanged(const QString &t)
+void QAbstractSpinBoxPrivate::editorTextChanged(const QString &t)
{
Q_Q(QAbstractSpinBox);
@@ -1573,7 +1541,7 @@ void QAbstractSpinBoxPrivate::_q_editorTextChanged(const QString &t)
the different sections etc.
*/
-void QAbstractSpinBoxPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos)
+void QAbstractSpinBoxPrivate::editorCursorPositionChanged(int oldpos, int newpos)
{
if (!edit->hasSelectedText() && !ignoreCursorPositionChanged && !specialValue()) {
ignoreCursorPositionChanged = true;
@@ -1624,7 +1592,7 @@ void QAbstractSpinBoxPrivate::init()
Q_Q(QAbstractSpinBox);
q->setLineEdit(new QLineEdit(q));
- edit->setObjectName(QLatin1String("qt_spinbox_lineedit"));
+ edit->setObjectName("qt_spinbox_lineedit"_L1);
validator = new QSpinBoxValidator(q, this);
edit->setValidator(validator);
@@ -1684,7 +1652,7 @@ void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false
steps *= 10;
q->stepBy(steps);
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(q, value);
QAccessible::updateAccessibility(&event);
#endif
@@ -1968,7 +1936,7 @@ QVariant QAbstractSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
QSpinBoxValidator::QSpinBoxValidator(QAbstractSpinBox *qp, QAbstractSpinBoxPrivate *dp)
: QValidator(qp), qptr(qp), dptr(dp)
{
- setObjectName(QLatin1String("qt_spinboxvalidator"));
+ setObjectName("qt_spinboxvalidator"_L1);
}
/*!
@@ -1985,7 +1953,7 @@ QValidator::State QSpinBoxValidator::validate(QString &input, int &pos) const
if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
input.prepend(dptr->prefix);
- pos += dptr->prefix.length();
+ pos += dptr->prefix.size();
}
if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
@@ -2075,6 +2043,7 @@ QVariant operator-(const QVariant &arg1, const QVariant &arg2)
dt.setTime(dt.time().addMSecs(msecs));
ret = QVariant(dt);
}
+ break;
}
default: break;
}
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 50c139e066..91d3dcb8fc 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSPINBOX_H
#define QABSTRACTSPINBOX_H
@@ -172,9 +136,6 @@ protected:
QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = nullptr);
private:
- Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_editorCursorPositionChanged(int, int))
-
Q_DECLARE_PRIVATE(QAbstractSpinBox)
Q_DISABLE_COPY(QAbstractSpinBox)
friend class QAccessibleAbstractSpinBox;
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index bfde96372c..4252a01423 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTSPINBOX_P_H
#define QABSTRACTSPINBOX_P_H
@@ -110,8 +74,8 @@ public:
virtual QString textFromValue(const QVariant &n) const;
virtual QVariant valueFromText(const QString &input) const;
- void _q_editorTextChanged(const QString &);
- virtual void _q_editorCursorPositionChanged(int oldpos, int newpos);
+ void editorTextChanged(const QString &);
+ virtual void editorCursorPositionChanged(int oldpos, int newpos);
virtual QStyle::SubControl newHoverControl(const QPoint &pos);
bool updateHoverControl(const QPoint &pos);
@@ -128,7 +92,7 @@ public:
QVariant value, minimum, maximum, singleStep;
QRect hoverRect;
- mutable QString cachedText = QLatin1String("\x01");
+ mutable QString cachedText = { u'\x01' };
mutable QVariant cachedValue;
mutable QSize cachedSizeHint, cachedMinimumSizeHint;
QLineEdit *edit = nullptr;
@@ -138,7 +102,7 @@ public:
int spinClickTimerInterval = 100;
int spinClickThresholdTimerId = -1;
int spinClickThresholdTimerInterval = -1;
- int effectiveSpinRepeatRate = 1;
+ qreal effectiveSpinRepeatRate = 1;
int acceleration = 0;
int wheelDeltaRemainder = 0;
diff --git a/src/widgets/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp
index 8ed343177d..079ef45e90 100644
--- a/src/widgets/widgets/qbuttongroup.cpp
+++ b/src/widgets/widgets/qbuttongroup.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "private/qbuttongroup_p.h"
@@ -50,7 +14,7 @@ void QButtonGroupPrivate::detectCheckedButton()
checkedButton = nullptr;
if (exclusive)
return;
- for (int i = 0; i < buttonList.count(); i++) {
+ for (int i = 0; i < buttonList.size(); i++) {
if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
checkedButton = buttonList.at(i);
return;
@@ -93,8 +57,8 @@ void QButtonGroupPrivate::detectCheckedButton()
In addition, QButtonGroup can map between integers and buttons.
You can assign an integer id to a button with setId(), and
retrieve it with id(). The id of the currently checked button is
- available with checkedId(), and there is an overloaded signal
- buttonClicked() which emits the id of the button. The id \c {-1}
+ available with checkedId(), and there is a signal
+ idClicked() that emits the id of the button. The id \c {-1}
is reserved by QButtonGroup to mean "no such button". The purpose
of the mapping mechanism is to simplify the representation of enum
values in a user interface.
@@ -118,7 +82,7 @@ QButtonGroup::QButtonGroup(QObject *parent)
QButtonGroup::~QButtonGroup()
{
Q_D(QButtonGroup);
- for (int i = 0; i < d->buttonList.count(); ++i)
+ for (int i = 0; i < d->buttonList.size(); ++i)
d->buttonList.at(i)->d_func()->group = nullptr;
}
diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h
index 9154c34e33..2a399e5325 100644
--- a/src/widgets/widgets/qbuttongroup.h
+++ b/src/widgets/widgets/qbuttongroup.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBUTTONGROUP_H
#define QBUTTONGROUP_H
diff --git a/src/widgets/widgets/qbuttongroup_p.h b/src/widgets/widgets/qbuttongroup_p.h
index 148f572373..ffeab3fc0b 100644
--- a/src/widgets/widgets/qbuttongroup_p.h
+++ b/src/widgets/widgets/qbuttongroup_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBUTTONGROUP_P_H
#define QBUTTONGROUP_P_H
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 5f35b85044..034127b4f3 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qcalendarwidget.h"
@@ -63,6 +27,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
enum {
RowCount = 6,
ColumnCount = 7,
@@ -71,13 +37,13 @@ enum {
MinimumDayOffset = 1
};
-namespace {
-
static QString formatNumber(int number, int fieldWidth)
{
- return QString::number(number).rightJustified(fieldWidth, QLatin1Char('0'));
+ return QString::number(number).rightJustified(fieldWidth, u'0');
}
+namespace QtPrivate {
+
class QCalendarDateSectionValidator
{
public:
@@ -105,9 +71,9 @@ protected:
QString QCalendarDateSectionValidator::highlightString(const QString &str, int pos)
{
if (pos == 0)
- return QLatin1String("<b>") + str + QLatin1String("</b>");
- int startPos = str.length() - pos;
- return QStringView{str}.mid(0, startPos) + QLatin1String("<b>") + QStringView{str}.mid(startPos, pos) + QLatin1String("</b>");
+ return "<b>"_L1 + str + "</b>"_L1;
+ int startPos = str.size() - pos;
+ return QStringView{str}.mid(0, startPos) + "<b>"_L1 + QStringView{str}.mid(startPos, pos) + "</b>"_L1;
}
@@ -432,9 +398,11 @@ struct SectionToken {
QCalendarDateSectionValidator *validator;
int repeat;
};
-} // unnamed namespace
-Q_DECLARE_TYPEINFO(SectionToken, Q_PRIMITIVE_TYPE);
-namespace {
+} // namespace QtPrivate
+
+Q_DECLARE_TYPEINFO(QtPrivate::SectionToken, Q_PRIMITIVE_TYPE);
+
+namespace QtPrivate {
class QCalendarDateValidator
{
@@ -544,7 +512,7 @@ void QCalendarDateValidator::setFormat(const QString &format)
clear();
int pos = 0;
- const QLatin1Char quote('\'');
+ const auto quote = u'\'';
bool quoting = false;
QString separator;
while (pos < format.size()) {
@@ -560,13 +528,13 @@ void QCalendarDateValidator::setFormat(const QString &format)
quoting = false;
} else {
QCalendarDateSectionValidator *validator = nullptr;
- if (nextChar == QLatin1Char('d')) {
+ if (nextChar == u'd') {
offset = qMin(4, countRepeat(format, pos));
validator = &m_dayValidator;
- } else if (nextChar == QLatin1Char('M')) {
+ } else if (nextChar == u'M') {
offset = qMin(4, countRepeat(format, pos));
validator = &m_monthValidator;
- } else if (nextChar == QLatin1Char('y')) {
+ } else if (nextChar == u'y') {
offset = qMin(4, countRepeat(format, pos));
validator = &m_yearValidator;
} else {
@@ -761,8 +729,8 @@ bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e)
{
if (m_widget) {
if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
- QKeyEvent* ke = (QKeyEvent*)e;
- if ((ke->text().length() > 0 && ke->text().at(0).isPrint()) || m_dateFrame) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if ((ke->text().size() > 0 && ke->text().at(0).isPrint()) || m_dateFrame) {
if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Select) {
applyDate();
emit editingFinished();
@@ -1640,7 +1608,20 @@ protected:
}
};
-} // unnamed namespace
+} // namespace QtPrivate
+
+using QCalendarDateSectionValidator = QtPrivate::QCalendarDateSectionValidator;
+using QCalendarDayValidator = QtPrivate::QCalendarDayValidator;
+using QCalendarMonthValidator = QtPrivate::QCalendarMonthValidator;
+using QCalendarYearValidator = QtPrivate::QCalendarYearValidator;
+using QCalendarDateValidator = QtPrivate::QCalendarDateValidator;
+using QPrevNextCalButton = QtPrivate::QPrevNextCalButton;
+using QCalendarDelegate = QtPrivate::QCalendarDelegate;
+using QCalToolButton = QtPrivate::QCalToolButton;
+using QCalendarDelegate = QtPrivate::QCalendarDelegate;
+using QCalendarModel = QtPrivate::QCalendarModel;
+using QCalendarView = QtPrivate::QCalendarView;
+using QCalendarTextNavigator = QtPrivate::QCalendarTextNavigator;
class QCalendarWidgetPrivate : public QWidgetPrivate
{
@@ -1758,7 +1739,7 @@ void QCalendarWidgetPrivate::createNavigationBar(QWidget *widget)
{
Q_Q(QCalendarWidget);
navBarBackground = new QWidget(widget);
- navBarBackground->setObjectName(QLatin1String("qt_calendar_navigationbar"));
+ navBarBackground->setObjectName("qt_calendar_navigationbar"_L1);
navBarBackground->setAutoFillBackground(true);
navBarBackground->setBackgroundRole(QPalette::Highlight);
@@ -1819,11 +1800,11 @@ void QCalendarWidgetPrivate::createNavigationBar(QWidget *widget)
monthButton->setFocusPolicy(Qt::NoFocus);
//set names for the header controls.
- prevMonth->setObjectName(QLatin1String("qt_calendar_prevmonth"));
- nextMonth->setObjectName(QLatin1String("qt_calendar_nextmonth"));
- monthButton->setObjectName(QLatin1String("qt_calendar_monthbutton"));
- yearButton->setObjectName(QLatin1String("qt_calendar_yearbutton"));
- yearEdit->setObjectName(QLatin1String("qt_calendar_yearedit"));
+ prevMonth->setObjectName("qt_calendar_prevmonth"_L1);
+ nextMonth->setObjectName("qt_calendar_nextmonth"_L1);
+ monthButton->setObjectName("qt_calendar_monthbutton"_L1);
+ yearButton->setObjectName("qt_calendar_yearbutton"_L1);
+ yearEdit->setObjectName("qt_calendar_yearedit"_L1);
updateMonthMenu();
showMonth(m_model->m_date.year(m_model->m_calendar), m_model->m_date.month(m_model->m_calendar));
@@ -2135,7 +2116,7 @@ QCalendarWidget::QCalendarWidget(QWidget *parent)
d->m_model->m_dayFormats.insert(Qt::Saturday, fmt);
d->m_model->m_dayFormats.insert(Qt::Sunday, fmt);
d->m_view = new QCalendarView(this);
- d->m_view->setObjectName(QLatin1String("qt_calendar_calendarview"));
+ d->m_view->setObjectName("qt_calendar_calendarview"_L1);
d->m_view->setModel(d->m_model);
d->m_model->setView(d->m_view);
d->m_view->setSelectionBehavior(QAbstractItemView::SelectItems);
@@ -2219,7 +2200,7 @@ QSize QCalendarWidget::minimumSizeHint() const
QStyleOption option;
option.initFrom(this);
- const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option) + 1) * 2;
+ const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, this) + 1) * 2;
if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) {
rows = 6;
@@ -2278,7 +2259,7 @@ QSize QCalendarWidget::minimumSizeHint() const
headerW += monthW + buttonDecoMargin;
fm = d->yearButton->fontMetrics();
- headerW += fm.boundingRect(QLatin1String("5555")).width() + buttonDecoMargin;
+ headerW += fm.boundingRect("5555"_L1).width() + buttonDecoMargin;
headerSize = QSize(headerW, headerH);
}
@@ -2511,14 +2492,14 @@ void QCalendarWidget::showToday()
\snippet code/src_gui_widgets_qcalendarwidget.cpp 1
\endtable
- By default, the minimum date is the earliest date that the QDate
- class can handle.
-
When setting a minimum date, the maximumDate and selectedDate
properties are adjusted if the selection range becomes invalid. If
the provided date is not a valid QDate object, the
setMinimumDate() function does nothing.
+ The default minimum date is November 25, 4714 BCE.
+ You can restore this default by calling clearMinimumDate() (since Qt 6.6).
+
\sa setDateRange()
*/
@@ -2547,6 +2528,11 @@ void QCalendarWidget::setMinimumDate(QDate date)
}
}
+void QCalendarWidget::clearMinimumDate()
+{
+ setMinimumDate(QDate::fromJulianDay(1));
+}
+
/*!
\property QCalendarWidget::maximumDate
\brief the maximum date of the currently specified date range.
@@ -2562,14 +2548,14 @@ void QCalendarWidget::setMinimumDate(QDate date)
\snippet code/src_gui_widgets_qcalendarwidget.cpp 2
\endtable
- By default, the maximum date is the last day the QDate class can
- handle.
-
When setting a maximum date, the minimumDate and selectedDate
properties are adjusted if the selection range becomes invalid. If
the provided date is not a valid QDate object, the
setMaximumDate() function does nothing.
+ The default maximum date is December 31, 9999 CE.
+ You can restore this default by calling clearMaximumDate() (since Qt 6.6).
+
\sa setDateRange()
*/
@@ -2598,6 +2584,11 @@ void QCalendarWidget::setMaximumDate(QDate date)
}
}
+void QCalendarWidget::clearMaximumDate()
+{
+ setMaximumDate(QDate(9999, 12, 31));
+}
+
/*!
Defines a date range by setting the minimumDate and maximumDate
properties.
@@ -2882,7 +2873,7 @@ QMap<QDate, QTextCharFormat> QCalendarWidget::dateTextFormat() const
}
/*!
- Returns a QTextCharFormat for \a date. The char format can be be
+ Returns a QTextCharFormat for \a date. The char format can be
empty if the date is not renderd specially.
*/
QTextCharFormat QCalendarWidget::dateTextFormat(QDate date) const
@@ -2948,7 +2939,7 @@ void QCalendarWidget::setDateEditEnabled(bool enable)
\since 4.3
If the calendar widget's \l{dateEditEnabled}{date edit is enabled}, this
- property specifies the amount of time (in millseconds) that the date edit
+ property specifies the amount of time (in milliseconds) that the date edit
remains open after the most recent user input. Once this time has elapsed,
the date specified in the date edit is accepted and the popup is closed.
@@ -3108,6 +3099,7 @@ bool QCalendarWidget::event(QEvent *event)
case QEvent::StyleChange:
d->cachedSizeHint = QSize();
d->m_view->updateGeometry();
+ break;
default:
break;
}
diff --git a/src/widgets/widgets/qcalendarwidget.h b/src/widgets/widgets/qcalendarwidget.h
index bb720a09f0..034c95dd62 100644
--- a/src/widgets/widgets/qcalendarwidget.h
+++ b/src/widgets/widgets/qcalendarwidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCALENDARWIDGET_H
#define QCALENDARWIDGET_H
@@ -57,13 +21,15 @@ class Q_WIDGETS_EXPORT QCalendarWidget : public QWidget
Q_OBJECT
Q_ENUMS(Qt::DayOfWeek)
Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate)
- Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate)
- Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate)
+ Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate RESET clearMinimumDate)
+ Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate RESET clearMaximumDate)
Q_PROPERTY(Qt::DayOfWeek firstDayOfWeek READ firstDayOfWeek WRITE setFirstDayOfWeek)
Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
- Q_PROPERTY(HorizontalHeaderFormat horizontalHeaderFormat READ horizontalHeaderFormat WRITE setHorizontalHeaderFormat)
- Q_PROPERTY(VerticalHeaderFormat verticalHeaderFormat READ verticalHeaderFormat WRITE setVerticalHeaderFormat)
+ Q_PROPERTY(HorizontalHeaderFormat horizontalHeaderFormat READ horizontalHeaderFormat
+ WRITE setHorizontalHeaderFormat)
+ Q_PROPERTY(VerticalHeaderFormat verticalHeaderFormat READ verticalHeaderFormat
+ WRITE setVerticalHeaderFormat)
Q_PROPERTY(bool navigationBarVisible READ isNavigationBarVisible WRITE setNavigationBarVisible)
Q_PROPERTY(bool dateEditEnabled READ isDateEditEnabled WRITE setDateEditEnabled)
Q_PROPERTY(int dateEditAcceptDelay READ dateEditAcceptDelay WRITE setDateEditAcceptDelay)
@@ -102,9 +68,11 @@ public:
QDate minimumDate() const;
void setMinimumDate(QDate date);
+ void clearMinimumDate();
QDate maximumDate() const;
void setMaximumDate(QDate date);
+ void clearMaximumDate();
Qt::DayOfWeek firstDayOfWeek() const;
void setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek);
diff --git a/src/widgets/widgets/qcheckbox.cpp b/src/widgets/widgets/qcheckbox.cpp
index 2e9a404157..88cd603d70 100644
--- a/src/widgets/widgets/qcheckbox.cpp
+++ b/src/widgets/widgets/qcheckbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qcheckbox.h"
#include "qapplication.h"
@@ -45,7 +9,7 @@
#include "qstyle.h"
#include "qstyleoption.h"
#include "qevent.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
@@ -64,7 +28,7 @@ public:
uint tristate : 1;
uint noChange : 1;
uint hovering : 1;
- uint publishedState : 2;
+ Qt::CheckState publishedState : 3;
void init();
};
@@ -95,7 +59,7 @@ public:
\endtable
Whenever a checkbox is checked or cleared, it emits the signal
- stateChanged(). Connect to this signal if you want to trigger an action
+ checkStateChanged(). Connect to this signal if you want to trigger an action
each time the checkbox changes state. You can use isChecked() to query
whether or not a checkbox is checked.
@@ -120,14 +84,21 @@ public:
setPixmap(), accel(), setAccel(), isToggleButton(), setDown(), isDown(),
isOn(), checkState(), autoRepeat(), isExclusiveToggle(), group(),
setAutoRepeat(), toggle(), pressed(), released(), clicked(), toggled(),
- checkState(), and stateChanged().
+ checkState(), and checkStateChanged().
- \sa QAbstractButton, QRadioButton, {fowler}{GUI Design Handbook: Check Box}
+ \sa QAbstractButton, QRadioButton
*/
/*!
\fn void QCheckBox::stateChanged(int state)
+ \deprecated [6.9] Use checkStateChanged(Qt::CheckState) instead.
+*/
+
+/*!
+ \fn void QCheckBox::checkStateChanged(Qt::CheckState state)
+ \since 6.7
+
This signal is emitted whenever the checkbox's state changes, i.e.,
whenever the user checks or unchecks it.
@@ -247,7 +218,7 @@ Qt::CheckState QCheckBox::checkState() const
void QCheckBox::setCheckState(Qt::CheckState state)
{
Q_D(QCheckBox);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
bool noChange = d->noChange;
#endif
if (state == Qt::PartiallyChecked) {
@@ -260,12 +231,17 @@ void QCheckBox::setCheckState(Qt::CheckState state)
setChecked(state != Qt::Unchecked);
d->blockRefresh = false;
d->refresh();
- if ((uint)state != d->publishedState) {
+ if (state != d->publishedState) {
d->publishedState = state;
+ emit checkStateChanged(state);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QT_IGNORE_DEPRECATIONS(
emit stateChanged(state);
+ )
+#endif
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (noChange != d->noChange) {
QAccessible::State s;
s.checkStateMixed = true;
@@ -355,9 +331,14 @@ void QCheckBox::checkStateSet()
Q_D(QCheckBox);
d->noChange = false;
Qt::CheckState state = checkState();
- if ((uint)state != d->publishedState) {
+ if (state != d->publishedState) {
d->publishedState = state;
+ emit checkStateChanged(state);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QT_IGNORE_DEPRECATIONS(
emit stateChanged(state);
+ )
+#endif
}
}
diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h
index bb0f303235..de623b7b9e 100644
--- a/src/widgets/widgets/qcheckbox.h
+++ b/src/widgets/widgets/qcheckbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCHECKBOX_H
#define QCHECKBOX_H
@@ -72,7 +36,11 @@ public:
void setCheckState(Qt::CheckState state);
Q_SIGNALS:
+#if QT_DEPRECATED_SINCE(6, 9)
+ QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_9("Use checkStateChanged() instead")
void stateChanged(int);
+#endif
+ void checkStateChanged(Qt::CheckState);
protected:
bool event(QEvent *e) override;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 4f626f7428..1fe9a8d7be 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qcombobox.h"
@@ -48,7 +12,7 @@
#if QT_CONFIG(tableview)
#include <qtableview.h>
#endif
-#include <qitemdelegate.h>
+#include <qabstractitemdelegate.h>
#include <qmap.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
@@ -81,23 +45,30 @@
# include <private/qeffects_p.h>
#endif
#include <private/qstyle_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
+#include <array>
+
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
QComboBoxPrivate::QComboBoxPrivate()
: QWidgetPrivate(),
shownOnce(false),
duplicatesEnabled(false),
frame(true),
- inserting(false)
+ inserting(false),
+ hidingPopup(false)
{
}
QComboBoxPrivate::~QComboBoxPrivate()
{
+ disconnectModel();
#ifdef Q_OS_MAC
cleanupNativePopup();
#endif
@@ -158,8 +129,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
menuOption.palette.setBrush(QPalette::All, QPalette::Window,
qvariant_cast<QBrush>(index.data(Qt::BackgroundRole)));
}
- menuOption.text = index.model()->data(index, Qt::DisplayRole).toString()
- .replace(QLatin1Char('&'), QLatin1String("&&"));
+ menuOption.text = index.model()->data(index, Qt::DisplayRole).toString().replace(u'&', "&&"_L1);
menuOption.reservedShortcutWidth = 0;
menuOption.maxIconWidth = option.decorationSize.width() + 4;
menuOption.menuRect = option.rect;
@@ -234,7 +204,7 @@ bool QComboMenuDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
}
#if QT_CONFIG(completer)
-void QComboBoxPrivate::_q_completerActivated(const QModelIndex &index)
+void QComboBoxPrivate::completerActivated(const QModelIndex &index)
{
Q_Q(QComboBox);
#if QT_CONFIG(proxymodel)
@@ -260,15 +230,6 @@ void QComboBoxPrivate::_q_completerActivated(const QModelIndex &index)
}
}
#endif
-
-# ifdef QT_KEYPAD_NAVIGATION
- if ( QApplicationPrivate::keypadNavigationEnabled()
- && q->isEditable()
- && q->completer()
- && q->completer()->completionMode() == QCompleter::UnfilteredPopupCompletion ) {
- q->setEditFocus(false);
- }
-# endif // QT_KEYPAD_NAVIGATION
}
#endif // QT_CONFIG(completer)
@@ -283,7 +244,7 @@ void QComboBoxPrivate::updateArrow(QStyle::StateFlag state)
q->update(q->rect());
}
-void QComboBoxPrivate::_q_modelReset()
+void QComboBoxPrivate::modelReset()
{
Q_Q(QComboBox);
if (lineEdit) {
@@ -295,7 +256,7 @@ void QComboBoxPrivate::_q_modelReset()
q->update();
}
-void QComboBoxPrivate::_q_modelDestroyed()
+void QComboBoxPrivate::modelDestroyed()
{
model = QAbstractItemModelPrivate::staticEmptyModel();
}
@@ -398,7 +359,7 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
case QComboBox::AdjustToContents:
case QComboBox::AdjustToContentsOnFirstShow:
if (count == 0) {
- sh.rwidth() = 7 * fm.horizontalAdvance(QLatin1Char('x'));
+ sh.rwidth() = 7 * fm.horizontalAdvance(u'x');
} else {
for (int i = 0; i < count; ++i) {
if (!q->itemIcon(i).isNull()) {
@@ -418,7 +379,7 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
hasIcon = !q->itemIcon(i).isNull();
}
if (minimumContentsLength > 0)
- sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.horizontalAdvance(QLatin1Char('X')) + (hasIcon ? iconSize.width() + 4 : 0)));
+ sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.horizontalAdvance(u'X') + (hasIcon ? iconSize.width() + 4 : 0)));
if (!placeholderText.isEmpty())
sh.setWidth(qMax(sh.width(), fm.boundingRect(placeholderText).width()));
@@ -531,21 +492,27 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView
setLineWidth(1);
}
- setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
-
if (top) {
layout->insertWidget(0, top);
- connect(top, SIGNAL(doScroll(int)), this, SLOT(scrollItemView(int)));
+ connect(top, &QComboBoxPrivateScroller::doScroll,
+ this, &QComboBoxPrivateContainer::scrollItemView);
}
if (bottom) {
layout->addWidget(bottom);
- connect(bottom, SIGNAL(doScroll(int)), this, SLOT(scrollItemView(int)));
+ connect(bottom, &QComboBoxPrivateScroller::doScroll,
+ this, &QComboBoxPrivateContainer::scrollItemView);
}
// Some styles (Mac) have a margin at the top and bottom of the popup.
layout->insertSpacing(0, 0);
layout->addSpacing(0);
- updateTopBottomMargin();
+ updateStyleSettings();
+}
+
+QComboBoxPrivateContainer::~QComboBoxPrivateContainer()
+{
+ disconnect(view, &QAbstractItemView::destroyed,
+ this, &QComboBoxPrivateContainer::viewDestroyed);
}
void QComboBoxPrivateContainer::scrollItemView(int action)
@@ -628,13 +595,13 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
view->removeEventFilter(this);
view->viewport()->removeEventFilter(this);
#if QT_CONFIG(scrollbar)
- disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),
- this, SLOT(updateScrollers()));
- disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
- this, SLOT(updateScrollers()));
+ disconnect(view->verticalScrollBar(), &QScrollBar::valueChanged,
+ this, &QComboBoxPrivateContainer::updateScrollers);
+ disconnect(view->verticalScrollBar(), &QScrollBar::rangeChanged,
+ this, &QComboBoxPrivateContainer::updateScrollers);
#endif
- disconnect(view, SIGNAL(destroyed()),
- this, SLOT(viewDestroyed()));
+ disconnect(view, &QAbstractItemView::destroyed,
+ this, &QComboBoxPrivateContainer::viewDestroyed);
if (isAncestorOf(view))
delete view;
@@ -665,13 +632,13 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
view->setLineWidth(0);
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
#if QT_CONFIG(scrollbar)
- connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),
- this, SLOT(updateScrollers()));
- connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
- this, SLOT(updateScrollers()));
+ connect(view->verticalScrollBar(), &QScrollBar::valueChanged,
+ this, &QComboBoxPrivateContainer::updateScrollers);
+ connect(view->verticalScrollBar(), &QScrollBar::rangeChanged,
+ this, &QComboBoxPrivateContainer::updateScrollers);
#endif
- connect(view, SIGNAL(destroyed()),
- this, SLOT(viewDestroyed()));
+ connect(view, &QAbstractItemView::destroyed,
+ this, &QComboBoxPrivateContainer::viewDestroyed);
}
/*!
@@ -728,14 +695,20 @@ void QComboBoxPrivateContainer::updateTopBottomMargin()
boxLayout->invalidate();
}
+void QComboBoxPrivateContainer::updateStyleSettings()
+{
+ // add scroller arrows if style needs them
+ QStyleOptionComboBox opt = comboStyleOption();
+ view->setMouseTracking(combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
+ combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo));
+ setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
+ updateTopBottomMargin();
+}
+
void QComboBoxPrivateContainer::changeEvent(QEvent *e)
{
- if (e->type() == QEvent::StyleChange) {
- QStyleOptionComboBox opt = comboStyleOption();
- view->setMouseTracking(combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
- combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo));
- setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
- }
+ if (e->type() == QEvent::StyleChange)
+ updateStyleSettings();
QFrame::changeEvent(e);
}
@@ -754,6 +727,7 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
#endif
if (view->currentIndex().isValid() && view->currentIndex().flags().testFlag(Qt::ItemIsEnabled)) {
combo->hidePopup();
+ keyEvent->accept();
emit itemSelected(view->currentIndex());
}
return true;
@@ -763,11 +737,13 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
Q_FALLTHROUGH();
case Qt::Key_F4:
combo->hidePopup();
+ keyEvent->accept();
+ emit itemSelected(view->currentIndex());
return true;
default:
#if QT_CONFIG(shortcut)
- if (keyEvent->matches(QKeySequence::Cancel)) {
- combo->hidePopup();
+ if (keyEvent->matches(QKeySequence::Cancel) && isVisible()) {
+ keyEvent->accept();
return true;
}
#endif
@@ -943,8 +919,11 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
\fn void QComboBox::currentTextChanged(const QString &text)
\since 5.0
- This signal is sent whenever currentText changes. The new value
- is passed as \a text.
+ This signal is emitted whenever currentText changes.
+ The new value is passed as \a text.
+
+ \note It is not emitted, if currentText remains the same,
+ even if currentIndex changes.
*/
/*!
@@ -970,39 +949,34 @@ QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent)
/*!
\class QComboBox
- \brief The QComboBox widget is a combined button and popup list.
+ \brief The QComboBox widget combines a button with a dropdown list.
\ingroup basicwidgets
\inmodule QtWidgets
- \image windows-combobox.png
-
- A QComboBox provides a means of presenting a list of options to the user
- in a way that takes up the minimum amount of screen space.
-
- A combobox is a selection widget that displays the current item,
- and can pop up a list of selectable items. A combobox may be editable,
- allowing the user to modify each item in the list.
-
- Comboboxes can contain pixmaps as well as strings; the
- insertItem() and setItemText() functions are suitably overloaded.
- For editable comboboxes, the function clearEditText() is provided,
+ \table
+ \row
+ \li \inlineimage collapsed_combobox.png
+ \caption Collapsed QCombobox
+ \li
+ \inlineimage expanded_combobox.png
+ \caption Expanded QCombobox
+ \endtable
+
+ \section1 Display Features
+ A QComboBox is a compact way to present a list of options to the user.
+
+ A combobox is a selection widget that shows the current item,
+ and pops up a list of selectable items when clicked. Comboboxes can
+ contain pixmaps as well as strings if the insertItem() and setItemText()
+ functions are suitably overloaded.
+
+ \section1 Editing Features
+ A combobox may be editable, allowing the user to modify each item in the
+ list. For editable comboboxes, the function clearEditText() is provided,
to clear the displayed string without changing the combobox's
contents.
- There are three signals emitted if the current item of a combobox
- changes, currentIndexChanged(), currentTextChanged() and activated().
- currentIndexChanged() and currentTextChanged() are always emitted
- regardless if the change
- was done programmatically or by user interaction, while
- activated() is only emitted when the change is caused by user
- interaction. The highlighted() signal is emitted when the user
- highlights an item in the combobox popup list. All three signals
- exist in two versions, one with a QString argument and one with an
- \c int argument. If the user selects or highlights a pixmap, only
- the \c int signals are emitted. Whenever the text of an editable
- combobox is changed the editTextChanged() signal is emitted.
-
When the user enters a new string in an editable combobox, the
widget may or may not insert it, and it can insert it in several
locations. The default policy is \l InsertAtBottom but you can change
@@ -1025,21 +999,36 @@ QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent)
setCompleter() and whether or not the user can add duplicates
is set with setDuplicatesEnabled().
- QComboBox uses the \l{Model/View Programming}{model/view
- framework} for its popup list and to store its items. By default
- a QStandardItemModel stores the items and a QListView subclass
- displays the popuplist. You can access the model and view directly
- (with model() and view()), but QComboBox also provides functions
- to set and get item data (e.g., setItemData() and itemText()). You
- can also set a new model and view (with setModel() and setView()).
- For the text and icon in the combobox label, the data in the model
- that has the Qt::DisplayRole and Qt::DecorationRole is used. Note
- that you cannot alter the \l{QAbstractItemView::}{SelectionMode}
- of the view(), e.g., by using
+ \section1 Signals
+ There are three signals emitted if the current item of a combobox
+ changes: currentIndexChanged(), currentTextChanged(), and activated().
+ currentIndexChanged() and currentTextChanged() are always emitted
+ regardless if the change
+ was done programmatically or by user interaction, while
+ activated() is only emitted when the change is caused by user
+ interaction. The highlighted() signal is emitted when the user
+ highlights an item in the combobox popup list. All three signals
+ exist in two versions, one with a QString argument and one with an
+ \c int argument. If the user selects or highlights a pixmap, only
+ the \c int signals are emitted. Whenever the text of an editable
+ combobox is changed, the editTextChanged() signal is emitted.
+
+ \section1 Model/View Framework
+
+ QComboBox uses the \l{Model/View Programming}{model/view framework} for its
+ popup list and to store its items. By default a QStandardItemModel stores
+ the items and a QListView subclass displays the popuplist. You can access
+ the model and view directly (with model() and view()), but QComboBox also
+ provides functions to set and get item data, for example, setItemData() and
+ itemText(). You can also set a new model and view (with setModel()
+ and setView()). For the text and icon in the combobox label, the data in
+ the model that has the Qt::DisplayRole and Qt::DecorationRole is used.
+
+ \note You cannot alter the \l{QAbstractItemView::}{SelectionMode}
+ of the view(), for example, 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()
@@ -1073,27 +1062,30 @@ QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer()
Q_Q(QComboBox);
container = new QComboBoxPrivateContainer(new QComboBoxListView(q), q);
+ disconnectModel();
container->itemView()->setModel(model);
+ connectModel();
container->itemView()->setTextElideMode(Qt::ElideMiddle);
updateDelegate(true);
updateLayoutDirection();
updateViewContainerPaletteAndOpacity();
- QObject::connect(container, SIGNAL(itemSelected(QModelIndex)),
- q, SLOT(_q_itemSelected(QModelIndex)));
- QObject::connect(container->itemView()->selectionModel(),
- SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_emitHighlighted(QModelIndex)));
- QObject::connect(container, SIGNAL(resetButton()), q, SLOT(_q_resetButton()));
+ QObjectPrivate::connect(container, &QComboBoxPrivateContainer::itemSelected,
+ this, &QComboBoxPrivate::itemSelected);
+ QObjectPrivate::connect(container->itemView()->selectionModel(),
+ &QItemSelectionModel::currentChanged,
+ this, &QComboBoxPrivate::emitHighlighted);
+ QObjectPrivate::connect(container, &QComboBoxPrivateContainer::resetButton,
+ this, &QComboBoxPrivate::resetButton);
return container;
}
-void QComboBoxPrivate::_q_resetButton()
+void QComboBoxPrivate::resetButton()
{
updateArrow(QStyle::State_None);
}
-void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+void QComboBoxPrivate::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_Q(QComboBox);
if (inserting || topLeft.parent() != root)
@@ -1111,17 +1103,17 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn
lineEdit->setText(text);
updateLineEditGeometry();
} else {
- emit q->currentTextChanged(text);
+ updateCurrentText(text);
}
q->update();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(q, text);
QAccessible::updateAccessibility(&event);
#endif
}
}
-void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
+void QComboBoxPrivate::rowsInserted(const QModelIndex &parent, int start, int end)
{
Q_Q(QComboBox);
if (inserting || parent != root)
@@ -1136,20 +1128,31 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int
// set current index if combo was previously empty and there is no placeholderText
if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid() &&
placeholderText.isEmpty()) {
+#if QT_CONFIG(accessibility)
+ // This might have been called by the model emitting rowInserted(), at which
+ // point the view won't have updated the accessibility bridge yet about its new
+ // dimensions. Do it now so that the change of the selection matches the row
+ // indexes of the accessibility bridge's representation.
+ if (container && container->itemView()) {
+ QAccessibleTableModelChangeEvent event(container->itemView(),
+ QAccessibleTableModelChangeEvent::ModelReset);
+ QAccessible::updateAccessibility(&event);
+ }
+#endif
q->setCurrentIndex(0);
// need to emit changed if model updated index "silently"
} else if (currentIndex.row() != indexBeforeChange) {
q->update();
- _q_emitCurrentIndexChanged(currentIndex);
+ emitCurrentIndexChanged(currentIndex);
}
}
-void QComboBoxPrivate::_q_updateIndexBeforeChange()
+void QComboBoxPrivate::updateIndexBeforeChange()
{
indexBeforeChange = currentIndex.row();
}
-void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
+void QComboBoxPrivate::rowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
{
Q_Q(QComboBox);
if (parent != root)
@@ -1161,6 +1164,12 @@ void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/,
q->updateGeometry();
}
+ // model has removed the last row
+ if (model->rowCount(root) == 0) {
+ setCurrentIndex(QModelIndex());
+ return;
+ }
+
// model has changed the currentIndex
if (currentIndex.row() != indexBeforeChange) {
if (!currentIndex.isValid() && q->count()) {
@@ -1172,7 +1181,7 @@ void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/,
updateLineEditGeometry();
}
q->update();
- _q_emitCurrentIndexChanged(currentIndex);
+ emitCurrentIndexChanged(currentIndex);
}
}
@@ -1281,7 +1290,7 @@ Qt::MatchFlags QComboBoxPrivate::matchFlags() const
}
-void QComboBoxPrivate::_q_editingFinished()
+void QComboBoxPrivate::editingFinished()
{
Q_Q(QComboBox);
if (!lineEdit)
@@ -1313,13 +1322,13 @@ void QComboBoxPrivate::_q_editingFinished()
}
-void QComboBoxPrivate::_q_returnPressed()
+void QComboBoxPrivate::returnPressed()
{
Q_Q(QComboBox);
// The insertion code below does not apply when the policy is QComboBox::NoInsert.
// In case a completer is installed, item activation via the completer is handled
- // in _q_completerActivated(). Otherwise _q_editingFinished() updates the current
+ // in completerActivated(). Otherwise editingFinished() updates the current
// index as appropriate.
if (insertPolicy == QComboBox::NoInsert)
return;
@@ -1377,7 +1386,7 @@ void QComboBoxPrivate::_q_returnPressed()
}
}
-void QComboBoxPrivate::_q_itemSelected(const QModelIndex &item)
+void QComboBoxPrivate::itemSelected(const QModelIndex &item)
{
Q_Q(QComboBox);
if (item != currentIndex) {
@@ -1399,7 +1408,7 @@ void QComboBoxPrivate::emitActivated(const QModelIndex &index)
emit q->textActivated(text);
}
-void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index)
+void QComboBoxPrivate::emitHighlighted(const QModelIndex &index)
{
Q_Q(QComboBox);
if (!index.isValid())
@@ -1409,15 +1418,15 @@ void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index)
emit q->textHighlighted(text);
}
-void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
+void QComboBoxPrivate::emitCurrentIndexChanged(const QModelIndex &index)
{
Q_Q(QComboBox);
const QString text = itemText(index);
emit q->currentIndexChanged(index.row());
// signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here
if (!lineEdit)
- emit q->currentTextChanged(text);
-#ifndef QT_NO_ACCESSIBILITY
+ updateCurrentText(text);
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(q, text);
QAccessible::updateAccessibility(&event);
#endif
@@ -1442,11 +1451,13 @@ QComboBox::~QComboBox()
Q_D(QComboBox);
QT_TRY {
- disconnect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
+ d->disconnectModel();
} QT_CATCH(...) {
; // objects can't throw in destructor
}
+
+ // Dispose of container before QComboBox goes away
+ delete d->container;
}
/*!
@@ -1477,7 +1488,7 @@ void QComboBox::setMaxVisibleItems(int maxItems)
/*!
\property QComboBox::count
- \brief the number of items in the combobox
+ \brief the number of items in the combobox.
By default, for an empty combo box, this property has a value of 0.
*/
@@ -1489,7 +1500,7 @@ int QComboBox::count() const
/*!
\property QComboBox::maxCount
- \brief the maximum number of items allowed in the combobox
+ \brief the maximum number of items allowed in the combobox.
\note If you set the maximum number to be less then the current
amount of items in the combobox, the extra items will be
@@ -1522,7 +1533,7 @@ int QComboBox::maxCount() const
/*!
\property QComboBox::duplicatesEnabled
- \brief whether the user can enter duplicate items into the combobox
+ \brief whether the user can enter duplicate items into the combobox.
Note that it is always possible to programmatically insert duplicate items into the
combobox.
@@ -1568,7 +1579,7 @@ int QComboBox::findData(const QVariant &data, int role, Qt::MatchFlags flags) co
/*!
\property QComboBox::insertPolicy
\brief the policy used to determine where user-inserted items should
- appear in the combobox
+ appear in the combobox.
The default value is \l InsertAtBottom, indicating that new items will appear
at the bottom of the list of items.
@@ -1591,7 +1602,7 @@ void QComboBox::setInsertPolicy(InsertPolicy policy)
/*!
\property QComboBox::sizeAdjustPolicy
\brief the policy describing how the size of the combobox changes
- when the content changes
+ when the content changes.
The default value is \l AdjustToContentsOnFirstShow.
@@ -1682,7 +1693,7 @@ void QComboBox::setIconSize(const QSize &size)
/*!
\property QComboBox::placeholderText
- \brief Sets a \a placeholderText text shown when no valid index is set
+ \brief Sets a \a placeholderText text shown when no valid index is set.
The \a placeholderText will be shown when an invalid index is set. The
text is not accessible in the dropdown list. When this function is called
@@ -1721,7 +1732,7 @@ QString QComboBox::placeholderText() const
/*!
\property QComboBox::editable
- \brief whether the combo box can be edited by the user
+ \brief whether the combo box can be edited by the user.
By default, this property is \c false. The effect of editing depends
on the insert policy.
@@ -1760,6 +1771,8 @@ void QComboBoxPrivate::updateDelegate(bool force)
QIcon QComboBoxPrivate::itemIcon(const QModelIndex &index) const
{
+ if (!index.isValid())
+ return {};
QVariant decoration = model->data(index, Qt::DecorationRole);
if (decoration.userType() == QMetaType::QPixmap)
return QIcon(qvariant_cast<QPixmap>(decoration));
@@ -1830,13 +1843,18 @@ void QComboBox::setLineEdit(QLineEdit *edit)
#endif
if (d->lineEdit->parent() != this)
d->lineEdit->setParent(this);
- connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
- connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
- connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
- connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString)));
- connect(d->lineEdit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateMicroFocus()));
- connect(d->lineEdit, SIGNAL(selectionChanged()), this, SLOT(updateMicroFocus()));
- connect(d->lineEdit->d_func()->control, SIGNAL(updateMicroFocus()), this, SLOT(updateMicroFocus()));
+ QObjectPrivate::connect(d->lineEdit, &QLineEdit::returnPressed,
+ d, &QComboBoxPrivate::returnPressed);
+ QObjectPrivate::connect(d->lineEdit, &QLineEdit::editingFinished,
+ d, &QComboBoxPrivate::editingFinished);
+ connect(d->lineEdit, &QLineEdit::textChanged, this, &QComboBox::editTextChanged);
+ connect(d->lineEdit, &QLineEdit::textChanged, this, &QComboBox::currentTextChanged);
+ QObjectPrivate::connect(d->lineEdit, &QLineEdit::cursorPositionChanged,
+ d, &QComboBoxPrivate::updateMicroFocus);
+ QObjectPrivate::connect(d->lineEdit, &QLineEdit::selectionChanged,
+ d, &QComboBoxPrivate::updateMicroFocus);
+ QObjectPrivate::connect(d->lineEdit->d_func()->control, &QWidgetLineControl::updateMicroFocus,
+ d, &QComboBoxPrivate::updateMicroFocus);
d->lineEdit->setFrame(false);
d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
d->updateFocusPolicy();
@@ -1938,7 +1956,8 @@ void QComboBox::setCompleter(QCompleter *c)
}
d->lineEdit->setCompleter(c);
if (c) {
- connect(c, SIGNAL(activated(QModelIndex)), this, SLOT(_q_completerActivated(QModelIndex)));
+ QObjectPrivate::connect(c, QOverload<const QModelIndex &>::of(&QCompleter::activated),
+ d, &QComboBoxPrivate::completerActivated);
c->setWidget(this);
}
}
@@ -2032,59 +2051,60 @@ void QComboBox::setModel(QAbstractItemModel *model)
if (d->lineEdit && d->lineEdit->completer())
d->lineEdit->completer()->setModel(model);
#endif
- if (d->model) {
- disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
- disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateIndexBeforeChange()));
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateIndexBeforeChange()));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- disconnect(d->model, SIGNAL(modelAboutToBeReset()),
- this, SLOT(_q_updateIndexBeforeChange()));
- disconnect(d->model, SIGNAL(modelReset()),
- this, SLOT(_q_modelReset()));
- if (d->model->QObject::parent() == this)
- delete d->model;
+ d->disconnectModel();
+ if (d->model && d->model->QObject::parent() == this) {
+ delete d->model;
+ d->model = nullptr;
}
d->model = model;
- connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
- connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateIndexBeforeChange()));
- connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateIndexBeforeChange()));
- connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- connect(model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- connect(model, SIGNAL(modelAboutToBeReset()),
- this, SLOT(_q_updateIndexBeforeChange()));
- connect(model, SIGNAL(modelReset()),
- this, SLOT(_q_modelReset()));
-
if (d->container) {
d->container->itemView()->setModel(model);
- connect(d->container->itemView()->selectionModel(),
- SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_emitHighlighted(QModelIndex)), Qt::UniqueConnection);
+ QObjectPrivate::connect(d->container->itemView()->selectionModel(),
+ &QItemSelectionModel::currentChanged,
+ d, &QComboBoxPrivate::emitHighlighted, Qt::UniqueConnection);
}
+ d->connectModel();
+
setRootModelIndex(QModelIndex());
d->trySetValidIndex();
d->modelChanged();
}
+void QComboBoxPrivate::connectModel()
+{
+ if (!model)
+ return;
+
+ modelConnections = {
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ this, &QComboBoxPrivate::dataChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsAboutToBeInserted,
+ this, &QComboBoxPrivate::updateIndexBeforeChange),
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsInserted,
+ this, &QComboBoxPrivate::rowsInserted),
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsAboutToBeRemoved,
+ this, &QComboBoxPrivate::updateIndexBeforeChange),
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsRemoved,
+ this, &QComboBoxPrivate::rowsRemoved),
+ QObjectPrivate::connect(model, &QObject::destroyed,
+ this, &QComboBoxPrivate::modelDestroyed),
+ QObjectPrivate::connect(model, &QAbstractItemModel::modelAboutToBeReset,
+ this, &QComboBoxPrivate::updateIndexBeforeChange),
+ QObjectPrivate::connect(model, &QAbstractItemModel::modelReset,
+ this, &QComboBoxPrivate::modelReset)
+ };
+}
+
+void QComboBoxPrivate::disconnectModel()
+{
+ for (auto &connection : modelConnections)
+ QObject::disconnect(connection);
+}
+
/*!
Returns the root model item index for the items in the combobox.
@@ -2130,7 +2150,7 @@ int QComboBox::currentIndex() const
void QComboBox::setCurrentIndex(int index)
{
Q_D(QComboBox);
- QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
+ QModelIndex mi = index >= 0 ? d->model->index(index, d->modelColumn, d->root) : QModelIndex();
d->setCurrentIndex(mi);
}
@@ -2167,9 +2187,24 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
}
updateLineEditGeometry();
}
- if (indexChanged) {
+ // If the model was reset to an empty one, currentIndex will be invalidated
+ // (because it's a QPersistentModelIndex), but the index change will never
+ // be advertised. So an explicit check for this condition is needed.
+ // The variable used for that check has to be reset when a previously valid
+ // index becomes invalid.
+ const bool modelResetToEmpty = !normalized.isValid() && indexBeforeChange != -1;
+ if (modelResetToEmpty)
+ indexBeforeChange = -1;
+
+ if (indexChanged || modelResetToEmpty) {
+ QItemSelectionModel::SelectionFlags selectionMode = QItemSelectionModel::ClearAndSelect;
+ if (q->view()->selectionBehavior() == QAbstractItemView::SelectRows)
+ selectionMode.setFlag(QItemSelectionModel::Rows);
+ if (auto *model = q->view()->selectionModel())
+ model->setCurrentIndex(currentIndex, selectionMode);
+
q->update();
- _q_emitCurrentIndexChanged(currentIndex);
+ emitCurrentIndexChanged(currentIndex);
}
}
@@ -2298,7 +2333,7 @@ void QComboBox::insertItem(int index, const QIcon &icon, const QString &text, co
if (!values.isEmpty()) d->model->setItemData(item, values);
}
d->inserting = false;
- d->_q_rowsInserted(d->root, index, index);
+ d->rowsInserted(d->root, index, index);
++itemCount;
} else {
d->inserting = false;
@@ -2325,7 +2360,7 @@ void QComboBox::insertItems(int index, const QStringList &list)
if (list.isEmpty())
return;
index = qBound(0, index, count());
- int insertCount = qMin(d->maxCount - index, list.count());
+ int insertCount = qMin(d->maxCount - index, list.size());
if (insertCount <= 0)
return;
// For the common case where we are using the built in QStandardItemModel
@@ -2346,7 +2381,7 @@ void QComboBox::insertItems(int index, const QStringList &list)
d->model->setData(item, list.at(i), Qt::EditRole);
}
d->inserting = false;
- d->_q_rowsInserted(d->root, index, index + insertCount - 1);
+ d->rowsInserted(d->root, index, index + insertCount - 1);
} else {
d->inserting = false;
}
@@ -2456,8 +2491,11 @@ void QComboBox::setView(QAbstractItemView *itemView)
return;
}
- if (itemView->model() != d->model)
+ if (itemView->model() != d->model) {
+ d->disconnectModel();
itemView->setModel(d->model);
+ d->connectModel();
+ }
d->viewContainer()->setItemView(itemView);
}
@@ -2489,12 +2527,13 @@ void QComboBoxPrivate::cleanupNativePopup()
if (!m_platformMenu)
return;
+ m_platformMenu->setVisible(false);
int count = int(m_platformMenu->tag());
for (int i = 0; i < count; ++i)
m_platformMenu->menuItemAt(i)->deleteLater();
delete m_platformMenu;
- m_platformMenu = 0;
+ m_platformMenu = nullptr;
}
/*!
@@ -2526,15 +2565,17 @@ bool QComboBoxPrivate::showNativePopup()
QVariant textVariant = model->data(rowIndex, Qt::EditRole);
item->setText(textVariant.toString());
QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole);
+ const Qt::ItemFlags itemFlags = model->flags(rowIndex);
if (iconVariant.canConvert<QIcon>())
item->setIcon(iconVariant.value<QIcon>());
item->setCheckable(true);
item->setChecked(i == currentIndex);
+ item->setEnabled(itemFlags & Qt::ItemIsEnabled);
if (!currentItem || i == currentIndex)
currentItem = item;
IndexSetter setter = { i, q };
- QObject::connect(item, &QPlatformMenuItem::activated, setter);
+ QObject::connect(item, &QPlatformMenuItem::activated, q, setter);
m_platformMenu->insertMenuItem(item, 0);
m_platformMenu->syncMenuItem(item);
@@ -2549,15 +2590,18 @@ bool QComboBoxPrivate::showNativePopup()
else if (q->testAttribute(Qt::WA_MacMiniSize))
offset = QPoint(-2, 6);
+ [[maybe_unused]] QPointer<QComboBox> guard(q);
const QRect targetRect = QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize());
m_platformMenu->showPopup(tlw, QHighDpi::toNativePixels(targetRect, tlw), currentItem);
#ifdef Q_OS_MACOS
- // The Cocoa popup will swallow any mouse release event.
- // We need to fake one here to un-press the button.
- QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton,
- Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers());
- QCoreApplication::sendEvent(q, &mouseReleased);
+ if (guard) {
+ // The Cocoa popup will swallow any mouse release event.
+ // We need to fake one here to un-press the button.
+ QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), q->mapToGlobal(QPoint(0, 0)),
+ Qt::LeftButton, Qt::MouseButtons(Qt::LeftButton), {});
+ QCoreApplication::sendEvent(q, &mouseReleased);
+ }
#endif
return true;
@@ -2595,22 +2639,6 @@ void QComboBox::showPopup()
return;
#endif // Q_OS_MAC
-#ifdef QT_KEYPAD_NAVIGATION
-#if QT_CONFIG(completer)
- if (QApplicationPrivate::keypadNavigationEnabled() && d->completer) {
- // editable combo box is line edit plus completer
- setEditFocus(true);
- d->completer->complete(); // show popup
- return;
- }
-#endif
-#endif
-
- // set current item and select it
- QItemSelectionModel::SelectionFlags selectionMode = QItemSelectionModel::ClearAndSelect;
- if (view()->selectionBehavior() == QAbstractItemView::SelectRows)
- selectionMode.setFlag(QItemSelectionModel::Rows);
- view()->selectionModel()->setCurrentIndex(d->currentIndex, selectionMode);
QComboBoxPrivateContainer* container = d->viewContainer();
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
@@ -2621,6 +2649,7 @@ void QComboBox::showPopup()
QPoint above = mapToGlobal(listRect.topLeft());
int aboveHeight = above.y() - screen.y();
bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen);
+ const auto listView = qobject_cast<QListView *>(d->viewContainer()->itemView());
{
int listHeight = 0;
@@ -2635,6 +2664,8 @@ void QComboBox::showPopup()
while (!toCheck.isEmpty()) {
QModelIndex parent = toCheck.pop();
for (int i = 0, end = d->model->rowCount(parent); i < end; ++i) {
+ if (listView && listView->isRowHidden(i))
+ continue;
QModelIndex idx = d->model->index(i, d->modelColumn, parent);
if (!idx.isValid())
continue;
@@ -2707,8 +2738,14 @@ void QComboBox::showPopup()
// Position horizontally.
listRect.moveLeft(above.x());
- // Position vertically so the curently selected item lines up
- // with the combo box.
+ // Position vertically so the currently selected item lines up
+ // with the combo box. In order to do that, make sure that the item
+ // view is scrolled to the top first, otherwise calls to view()->visualRect()
+ // will return the geometry the selected item had the last time the popup
+ // was visible (and perhaps scrolled). And this will not match the geometry
+ // it will actually have when we resize the container to fit all the items
+ // further down in this function.
+ view()->scrollToTop();
const QRect currentItemRect = view()->visualRect(view()->currentIndex());
const int offset = listRect.top() - currentItemRect.top();
listRect.moveTop(above.y() + offset - listRect.top());
@@ -2741,13 +2778,15 @@ void QComboBox::showPopup()
QGuiApplication::inputMethod()->reset();
}
- QScrollBar *sb = view()->horizontalScrollBar();
- Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy();
- bool needHorizontalScrollBar = (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn)
- && sb->minimum() < sb->maximum();
- if (needHorizontalScrollBar) {
+ const QScrollBar *sb = view()->horizontalScrollBar();
+ const auto needHorizontalScrollBar = [this, sb]{
+ const Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy();
+ return (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn)
+ && sb->minimum() < sb->maximum();
+ };
+ const bool neededHorizontalScrollBar = needHorizontalScrollBar();
+ if (neededHorizontalScrollBar)
listRect.adjust(0, 0, 0, sb->height());
- }
// Hide the scrollers here, so that the listrect gets the full height of the container
// If the scrollers are truly needed, the later call to container->updateScrollers()
@@ -2790,6 +2829,11 @@ void QComboBox::showPopup()
}
}
container->show();
+ if (!neededHorizontalScrollBar && needHorizontalScrollBar()) {
+ listRect.adjust(0, 0, 0, sb->height());
+ container->setGeometry(listRect);
+ }
+
container->updateScrollers();
view()->setFocus();
@@ -2803,10 +2847,6 @@ void QComboBox::showPopup()
#endif
container->update();
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplicationPrivate::keypadNavigationEnabled())
- view()->setEditFocus(true);
-#endif
if (startTimer) {
container->popupTimer.start();
container->maybeIgnoreMouseButtonRelease = true;
@@ -2826,60 +2866,64 @@ void QComboBox::showPopup()
void QComboBox::hidePopup()
{
Q_D(QComboBox);
- if (d->container && d->container->isVisible()) {
+ if (d->hidingPopup)
+ return;
+ d->hidingPopup = true;
+ // can't use QBoolBlocker on a bitfield
+ auto resetHidingPopup = qScopeGuard([d]{
+ d->hidingPopup = false;
+ });
+
+ if (!d->container || !d->container->isVisible())
+ return;
+
#if QT_CONFIG(effects)
- QSignalBlocker modelBlocker(d->model);
- QSignalBlocker viewBlocker(d->container->itemView());
- QSignalBlocker containerBlocker(d->container);
- // Flash selected/triggered item (if any).
- if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) {
- QItemSelectionModel *selectionModel = view() ? view()->selectionModel() : nullptr;
- if (selectionModel && selectionModel->hasSelection()) {
- QEventLoop eventLoop;
- const QItemSelection selection = selectionModel->selection();
-
- // Deselect item and wait 60 ms.
+ QItemSelectionModel *selectionModel = d->container->itemView()
+ ? d->container->itemView()->selectionModel() : nullptr;
+ // Flash selected/triggered item (if any) before hiding the popup.
+ if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem) &&
+ selectionModel && selectionModel->hasSelection()) {
+ const QItemSelection selection = selectionModel->selection();
+
+ QTimer::singleShot(0, d->container, [d, selection, selectionModel]{
+ QSignalBlocker modelBlocker(d->model);
+ QSignalBlocker viewBlocker(d->container->itemView());
+ QSignalBlocker containerBlocker(d->container);
+
+ // Deselect item and wait 60 ms.
+ selectionModel->select(selection, QItemSelectionModel::Toggle);
+ QTimer::singleShot(60, d->container, [d, selection, selectionModel]{
+ QSignalBlocker modelBlocker(d->model);
+ QSignalBlocker viewBlocker(d->container->itemView());
+ QSignalBlocker containerBlocker(d->container);
selectionModel->select(selection, QItemSelectionModel::Toggle);
- QTimer::singleShot(60, &eventLoop, SLOT(quit()));
- eventLoop.exec();
+ QTimer::singleShot(20, d->container, [d] {
+ d->doHidePopup();
+ });
+ });
+ });
+ } else
+#endif // QT_CONFIG(effects)
+ {
+ d->doHidePopup();
+ }
+}
- // Select item and wait 20 ms.
- selectionModel->select(selection, QItemSelectionModel::Toggle);
- QTimer::singleShot(20, &eventLoop, SLOT(quit()));
- eventLoop.exec();
- }
- }
+void QComboBoxPrivate::doHidePopup()
+{
+ if (container && container->isVisible())
+ container->hide();
- // Fade out.
- bool needFade = style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
- bool didFade = false;
- if (needFade) {
-#if defined(Q_OS_MAC)
- QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
- int at = platformNativeInterface->metaObject()->indexOfMethod("fadeWindow()");
- if (at != -1) {
- QMetaMethod windowFade = platformNativeInterface->metaObject()->method(at);
- windowFade.invoke(platformNativeInterface, Q_ARG(QWindow *, d->container->windowHandle()));
- didFade = true;
- }
+ resetButton();
+}
-#endif // Q_OS_MAC
- // Other platform implementations welcome :-)
- }
- containerBlocker.unblock();
- viewBlocker.unblock();
- modelBlocker.unblock();
+void QComboBoxPrivate::updateCurrentText(const QString &text)
+{
+ if (text == currentText)
+ return;
- if (!didFade)
-#endif // QT_CONFIG(effects)
- // Fade should implicitly hide as well ;-)
- d->container->hide();
- }
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplicationPrivate::keypadNavigationEnabled() && isEditable() && hasFocus())
- setEditFocus(true);
-#endif
- d->_q_resetButton();
+ currentText = text;
+ emit q_func()->currentTextChanged(text);
}
/*!
@@ -2892,7 +2936,7 @@ void QComboBox::clear()
{
Q_D(QComboBox);
d->model->removeRows(0, d->model->rowCount(d->root), d->root);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(this, QString());
QAccessible::updateAccessibility(&event);
#endif
@@ -2906,7 +2950,7 @@ void QComboBox::clearEditText()
Q_D(QComboBox);
if (d->lineEdit)
d->lineEdit->clear();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(this, QString());
QAccessible::updateAccessibility(&event);
#endif
@@ -2920,7 +2964,7 @@ void QComboBox::setEditText(const QString &text)
Q_D(QComboBox);
if (d->lineEdit)
d->lineEdit->setText(text);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleValueChangeEvent event(this, text);
QAccessible::updateAccessibility(&event);
#endif
@@ -2959,7 +3003,10 @@ void QComboBox::changeEvent(QEvent *e)
Q_D(QComboBox);
switch (e->type()) {
case QEvent::StyleChange:
+ if (d->container)
+ d->container->updateStyleSettings();
d->updateDelegate();
+
#ifdef Q_OS_MAC
case QEvent::MacSizeChange:
#endif
@@ -3083,9 +3130,7 @@ bool QComboBox::event(QEvent *event)
break;
#ifdef QT_KEYPAD_NAVIGATION
case QEvent::EnterEditFocus:
- if (!d->lineEdit)
- setEditFocus(false); // We never want edit focus if we are not editable
- else
+ if (d->lineEdit)
d->lineEdit->event(event); //so cursor starts
break;
case QEvent::LeaveEditFocus:
@@ -3132,7 +3177,10 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e)
// viewContainer(), we avoid creating the QComboBoxPrivateContainer.
viewContainer()->initialClickPosition = q->mapToGlobal(e->position().toPoint());
}
+ QPointer<QComboBox> guard = q;
q->showPopup();
+ if (!guard)
+ return;
// The code below ensures that regular mousepress and pick item still works
// If it was not called the viewContainer would ignore event since it didn't have
// a mousePressEvent first.
@@ -3184,7 +3232,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
Move move = NoMove;
int newIndex = currentIndex();
- switch (e->key()) {
+
+ bool pressLikeButton = !d->lineEdit;
+#ifdef QT_KEYPAD_NAVIGATION
+ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
+#endif
+ auto key = e->key();
+ if (pressLikeButton) {
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(key)) {
+ showPopup();
+ return;
+ }
+ }
+
+ switch (key) {
case Qt::Key_Up:
if (e->modifiers() & Qt::ControlModifier)
break; // pass to line edit for auto completion
@@ -3226,12 +3290,6 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
return;
}
break;
- case Qt::Key_Space:
- if (!d->lineEdit) {
- showPopup();
- return;
- }
- break;
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
@@ -3239,13 +3297,6 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
e->ignore();
break;
#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (QApplicationPrivate::keypadNavigationEnabled()
- && (!hasEditFocus() || !d->lineEdit)) {
- showPopup();
- return;
- }
- break;
case Qt::Key_Left:
case Qt::Key_Right:
if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
@@ -3256,14 +3307,22 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
if (!hasEditFocus() || !d->lineEdit)
e->ignore();
} else {
- e->ignore(); // let the surounding dialog have it
+ e->ignore(); // let the surrounding dialog have it
}
break;
#endif
default:
+#if QT_CONFIG(shortcut)
+ if (d->container && d->container->isVisible() && e->matches(QKeySequence::Cancel)) {
+ hidePopup();
+ e->accept();
+ }
+#endif
+
if (!d->lineEdit) {
- if (!e->text().isEmpty())
- d->keyboardSearchString(e->text());
+ const auto text = e->text();
+ if (!text.isEmpty() && text.at(0).isPrint())
+ d->keyboardSearchString(text);
else
e->ignore();
}
@@ -3461,7 +3520,7 @@ QVariant QComboBox::inputMethodQuery(Qt::InputMethodQuery query, const QVariant
/*!
\property QComboBox::frame
- \brief whether the combo box draws itself with a frame
+ \brief whether the combo box draws itself with a frame.
If enabled (the default) the combo box draws itself inside a
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 75dbb1183d..1689d0fa1e 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOMBOBOX_H
#define QCOMBOBOX_H
@@ -62,7 +26,8 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget
Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
Q_PROPERTY(int count READ count)
- Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged USER true)
+ Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged
+ USER true)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
Q_PROPERTY(QVariant currentData READ currentData)
Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
@@ -239,21 +204,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QComboBox)
Q_DISABLE_COPY(QComboBox)
- Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
- Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
- Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange())
- Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
- Q_PRIVATE_SLOT(d_func(), void _q_modelReset())
-#if QT_CONFIG(completer)
- Q_PRIVATE_SLOT(d_func(), void _q_completerActivated(const QModelIndex &index))
-#endif
};
inline void QComboBox::addItem(const QString &atext, const QVariant &auserData)
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 16ded8f1a4..723d637ae2 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOMBOBOX_P_H
#define QCOMBOBOX_P_H
@@ -63,7 +27,6 @@
#include "QtGui/qpainter.h"
#include "QtWidgets/qstyle.h"
#include "QtWidgets/qstyleoption.h"
-#include "QtCore/qpair.h"
#include "QtCore/qtimer.h"
#include "private/qwidget_p.h"
#include "QtCore/qpointer.h"
@@ -85,7 +48,11 @@ class QComboBoxListView : public QListView
{
Q_OBJECT
public:
- QComboBoxListView(QComboBox *cmb = nullptr) : combo(cmb) {}
+ QComboBoxListView(QComboBox *cmb = nullptr) : combo(cmb)
+ {
+ if (cmb)
+ setScreen(cmb->screen());
+ }
protected:
void resizeEvent(QResizeEvent *event) override
@@ -216,12 +183,14 @@ class Q_WIDGETS_EXPORT QComboBoxPrivateContainer : public QFrame
public:
QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent);
+ ~QComboBoxPrivateContainer();
QAbstractItemView *itemView() const;
void setItemView(QAbstractItemView *itemView);
int spacing() const;
int topMargin() const;
int bottomMargin() const { return topMargin(); }
void updateTopBottomMargin();
+ void updateStyleSettings();
QTimer blockMouseReleaseTimer;
QBasicTimer adjustSizeTimer;
@@ -302,7 +271,8 @@ public:
{}
static bool isSeparator(const QModelIndex &index) {
- return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
+ return index.data(Qt::AccessibleDescriptionRole).toString()
+ == QLatin1StringView("separator");
}
static void setSeparator(QAbstractItemModel *model, const QModelIndex &index) {
model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole);
@@ -349,24 +319,25 @@ public:
QComboBoxPrivateContainer* viewContainer();
void updateLineEditGeometry();
Qt::MatchFlags matchFlags() const;
- void _q_editingFinished();
- void _q_returnPressed();
- void _q_complete();
- void _q_itemSelected(const QModelIndex &item);
+ void editingFinished();
+ void returnPressed();
+ void complete();
+ void itemSelected(const QModelIndex &item);
bool contains(const QString &text, int role);
void emitActivated(const QModelIndex &index);
- void _q_emitHighlighted(const QModelIndex &index);
- void _q_emitCurrentIndexChanged(const QModelIndex &index);
- void _q_modelDestroyed();
- void _q_modelReset();
+ void emitHighlighted(const QModelIndex &index);
+ void emitCurrentIndexChanged(const QModelIndex &index);
+ void modelDestroyed();
+ void modelReset();
+ void updateMicroFocus() { q_func()->updateMicroFocus(); } // PMF connect doesn't handle default args
#if QT_CONFIG(completer)
- void _q_completerActivated(const QModelIndex &index);
+ void completerActivated(const QModelIndex &index);
#endif
- void _q_resetButton();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_updateIndexBeforeChange();
- void _q_rowsInserted(const QModelIndex &parent, int start, int end);
- void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
+ void resetButton();
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void updateIndexBeforeChange();
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsRemoved(const QModelIndex &parent, int start, int end);
void updateArrow(QStyle::StateFlag state);
bool updateHoverControl(const QPoint &pos);
void trySetValidIndex();
@@ -386,6 +357,10 @@ public:
void updateViewContainerPaletteAndOpacity();
void updateFocusPolicy();
void showPopupFromMouseEvent(QMouseEvent *e);
+ void doHidePopup();
+ void updateCurrentText(const QString &text);
+ void connectModel();
+ void disconnectModel();
#ifdef Q_OS_MAC
void cleanupNativePopup();
@@ -402,15 +377,17 @@ public:
};
#endif
+ std::array<QMetaObject::Connection, 8> modelConnections;
QAbstractItemModel *model = nullptr;
QLineEdit *lineEdit = nullptr;
- QComboBoxPrivateContainer *container = nullptr;
+ QPointer<QComboBoxPrivateContainer> container;
#ifdef Q_OS_MAC
QPlatformMenu *m_platformMenu = nullptr;
#endif
QPersistentModelIndex currentIndex;
QPersistentModelIndex root;
QString placeholderText;
+ QString currentText;
QRect hoverRect;
QSize iconSize;
mutable QSize minimumSizeHint;
@@ -422,13 +399,14 @@ public:
int minimumContentsLength = 0;
int indexBeforeChange = -1;
int maxVisibleItems = 10;
- int maxCount = std::numeric_limits<int>::max();
+ int maxCount = (std::numeric_limits<int>::max)();
int modelColumn = 0;
int placeholderIndex = -1;
bool shownOnce : 1;
bool duplicatesEnabled : 1;
bool frame : 1;
bool inserting : 1;
+ bool hidingPopup : 1;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp
index 3aa6d9ca29..5c7d2601d9 100644
--- a/src/widgets/widgets/qcommandlinkbutton.cpp
+++ b/src/widgets/widgets/qcommandlinkbutton.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qcommandlinkbutton.h"
#include "qstylepainter.h"
@@ -207,8 +171,8 @@ bool QCommandLinkButtonPrivate::usingVistaStyle() const
Q_Q(const QCommandLinkButton);
//### This is a hack to detect if we are indeed running Vista style themed and not in classic
// When we add api to query for this, we should change this implementation to use it.
- return q->style()->inherits("QWindowsVistaStyle")
- && q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, nullptr) == 0;
+ return q->property("_qt_usingVistaStyle").toBool()
+ && q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, nullptr, q) == 0;
}
void QCommandLinkButtonPrivate::init()
@@ -225,7 +189,7 @@ void QCommandLinkButtonPrivate::init()
q->setIconSize(QSize(20, 20));
QStyleOptionButton opt;
q->initStyleOption(&opt);
- q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink, &opt));
+ q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink, &opt, q));
}
// Calculates the height of the description text based on widget width
@@ -361,9 +325,9 @@ void QCommandLinkButton::paintEvent(QPaintEvent *)
QSize pixmapSize = icon().actualSize(iconSize());
const int vOffset = isDown()
- ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option) : 0;
+ ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this) : 0;
const int hOffset = isDown()
- ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option) : 0;
+ ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this) : 0;
//Draw icon
p.drawControl(QStyle::CE_PushButton, option);
@@ -375,9 +339,9 @@ void QCommandLinkButton::paintEvent(QPaintEvent *)
//Draw title
QColor textColor = palette().buttonText().color();
if (isEnabled() && d->usingVistaStyle()) {
- textColor = QColor(21, 28, 85);
+ textColor = option.palette.buttonText().color();
if (underMouse() && !isDown())
- textColor = QColor(7, 64, 229);
+ textColor = option.palette.brightText().color();
//A simple text color transition
d->currentColor = d->mergedColors(textColor, d->currentColor, 60);
option.palette.setColor(QPalette::ButtonText, d->currentColor);
diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h
index 2a1ae05807..7979b992f4 100644
--- a/src/widgets/widgets/qcommandlinkbutton.h
+++ b/src/widgets/widgets/qcommandlinkbutton.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOMMANDLINKBUTTON_H
#define QCOMMANDLINKBUTTON_H
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index ddab5ea762..01e52b2fa6 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <private/qapplication_p.h>
#include <private/qdatetimeedit_p.h>
@@ -51,9 +15,7 @@
#include <qlayout.h>
#include <qset.h>
#include <qstyle.h>
-#if QT_CONFIG(timezone)
-#include <QTimeZone>
-#endif
+#include <qstylepainter.h>
#include <algorithm>
@@ -68,6 +30,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
// --- QDateTimeEdit ---
/*!
@@ -223,7 +187,9 @@ QDateTimeEdit::QDateTimeEdit(QTime time, QWidget *parent)
\internal
*/
QDateTimeEdit::QDateTimeEdit(const QVariant &var, QMetaType::Type parserType, QWidget *parent)
- : QAbstractSpinBox(*new QDateTimeEditPrivate, parent)
+ : QAbstractSpinBox(*new QDateTimeEditPrivate(parserType == QMetaType::QDateTime
+ ? QTimeZone::LocalTime : QTimeZone::UTC),
+ parent)
{
Q_D(QDateTimeEdit);
d->parserType = parserType;
@@ -241,8 +207,8 @@ QDateTimeEdit::~QDateTimeEdit()
\property QDateTimeEdit::dateTime
\brief The QDateTime that is set in the QDateTimeEdit.
- When setting this property, the new QDateTime is converted to the timespec of
- the QDateTimeEdit, which thus remains unchanged.
+ When setting this property, the new QDateTime is converted to the time system
+ of the QDateTimeEdit, which thus remains unchanged.
By default, this property is set to the start of 2000 CE. It can only be set
to a valid QDateTime value. If any operation causes this property to have an
@@ -253,7 +219,7 @@ QDateTimeEdit::~QDateTimeEdit()
widget's date-range to start and end on the date of the new value of this
property.
- \sa date, time, minimumDateTime, maximumDateTime
+ \sa date, time, minimumDateTime, maximumDateTime, timeZone
*/
QDateTime QDateTimeEdit::dateTime() const
@@ -266,8 +232,8 @@ void QDateTimeEdit::setDateTime(const QDateTime &datetime)
{
Q_D(QDateTimeEdit);
if (datetime.isValid()) {
- QDateTime when = d->convertTimeSpec(datetime);
- Q_ASSERT(when.timeSpec() == d->spec);
+ QDateTime when = d->convertTimeZone(datetime);
+ Q_ASSERT(when.timeRepresentation() == d->timeZone);
d->clearCache();
const QDate date = when.date();
@@ -303,14 +269,10 @@ void QDateTimeEdit::setDate(QDate date)
setDateRange(date, date);
d->clearCache();
- QDateTime when(date, d->value.toTime(), d->spec);
- // The specified time might not exist on the specified day,
- // i.e. the time is in the gap a spring-forward jumps over.
- if (!when.isValid())
- when = QDateTime::fromMSecsSinceEpoch(when.toMSecsSinceEpoch(), d->spec);
+ QDateTime when = d->dateTimeValue(date, d->value.toTime());
Q_ASSERT(when.isValid());
d->setValue(when, EmitIfChanged);
- d->updateTimeSpec();
+ d->updateTimeZone();
}
}
@@ -337,7 +299,7 @@ void QDateTimeEdit::setTime(QTime time)
Q_D(QDateTimeEdit);
if (time.isValid()) {
d->clearCache();
- d->setValue(QDateTime(d->value.toDate(), time, d->spec), EmitIfChanged);
+ d->setValue(d->dateTimeValue(d->value.toDate(), time), EmitIfChanged);
}
}
@@ -394,7 +356,7 @@ void QDateTimeEdit::setMinimumDateTime(const QDateTime &dt)
{
Q_D(QDateTimeEdit);
if (dt.isValid() && dt.date() >= QDATETIMEEDIT_DATE_MIN) {
- const QDateTime m = dt.toTimeSpec(d->spec);
+ const QDateTime m = dt.toTimeZone(d->timeZone);
const QDateTime max = d->maximum.toDateTime();
d->setRange(m, (max > m ? max : m));
}
@@ -436,7 +398,7 @@ void QDateTimeEdit::setMaximumDateTime(const QDateTime &dt)
{
Q_D(QDateTimeEdit);
if (dt.isValid() && dt.date() <= QDATETIMEEDIT_DATE_MAX) {
- const QDateTime m = dt.toTimeSpec(d->spec);
+ const QDateTime m = dt.toTimeZone(d->timeZone);
const QDateTime min = d->minimum.toDateTime();
d->setRange((min < m ? min : m), m);
}
@@ -470,8 +432,8 @@ void QDateTimeEdit::setDateTimeRange(const QDateTime &min, const QDateTime &max)
{
Q_D(QDateTimeEdit);
// FIXME: does none of the range checks applied to setMin/setMax methods !
- const QDateTime minimum = min.toTimeSpec(d->spec);
- const QDateTime maximum = (min > max ? minimum : max.toTimeSpec(d->spec));
+ const QDateTime minimum = min.toTimeZone(d->timeZone);
+ const QDateTime maximum = (min > max ? minimum : max.toTimeZone(d->timeZone));
d->setRange(minimum, maximum);
}
@@ -506,9 +468,8 @@ QDate QDateTimeEdit::minimumDate() const
void QDateTimeEdit::setMinimumDate(QDate min)
{
Q_D(QDateTimeEdit);
- if (min.isValid() && min >= QDATETIMEEDIT_DATE_MIN) {
- setMinimumDateTime(QDateTime(min, d->minimum.toTime(), d->spec));
- }
+ if (min.isValid() && min >= QDATETIMEEDIT_DATE_MIN)
+ setMinimumDateTime(d->dateTimeValue(min, d->minimum.toTime()));
}
void QDateTimeEdit::clearMinimumDate()
@@ -548,7 +509,7 @@ void QDateTimeEdit::setMaximumDate(QDate max)
{
Q_D(QDateTimeEdit);
if (max.isValid())
- setMaximumDateTime(QDateTime(max, d->maximum.toTime(), d->spec));
+ setMaximumDateTime(d->dateTimeValue(max, d->maximum.toTime()));
}
void QDateTimeEdit::clearMaximumDate()
@@ -585,10 +546,8 @@ QTime QDateTimeEdit::minimumTime() const
void QDateTimeEdit::setMinimumTime(QTime min)
{
Q_D(QDateTimeEdit);
- if (min.isValid()) {
- const QDateTime m(d->minimum.toDate(), min, d->spec);
- setMinimumDateTime(m);
- }
+ if (min.isValid())
+ setMinimumDateTime(d->dateTimeValue(d->minimum.toDate(), min));
}
void QDateTimeEdit::clearMinimumTime()
@@ -624,10 +583,8 @@ QTime QDateTimeEdit::maximumTime() const
void QDateTimeEdit::setMaximumTime(QTime max)
{
Q_D(QDateTimeEdit);
- if (max.isValid()) {
- const QDateTime m(d->maximum.toDate(), max, d->spec);
- setMaximumDateTime(m);
- }
+ if (max.isValid())
+ setMaximumDateTime(d->dateTimeValue(d->maximum.toDate(), max));
}
void QDateTimeEdit::clearMaximumTime()
@@ -665,8 +622,8 @@ void QDateTimeEdit::setDateRange(QDate min, QDate max)
{
Q_D(QDateTimeEdit);
if (min.isValid() && max.isValid()) {
- setDateTimeRange(QDateTime(min, d->minimum.toTime(), d->spec),
- QDateTime(max, d->maximum.toTime(), d->spec));
+ setDateTimeRange(d->dateTimeValue(min, d->minimum.toTime()),
+ d->dateTimeValue(max, d->maximum.toTime()));
}
}
@@ -704,8 +661,8 @@ void QDateTimeEdit::setTimeRange(QTime min, QTime max)
{
Q_D(QDateTimeEdit);
if (min.isValid() && max.isValid()) {
- setDateTimeRange(QDateTime(d->minimum.toDate(), min, d->spec),
- QDateTime(d->maximum.toDate(), max, d->spec));
+ setDateTimeRange(d->dateTimeValue(d->minimum.toDate(), min),
+ d->dateTimeValue(d->maximum.toDate(), max));
}
}
@@ -988,10 +945,10 @@ void QDateTimeEdit::setDisplayFormat(const QString &format)
}
} else if (dateShown && !timeShown) {
setTimeRange(QDATETIMEEDIT_TIME_MIN, QDATETIMEEDIT_TIME_MAX);
- d->value = QDateTime(d->value.toDate(), QTime(), d->spec);
+ d->value = d->value.toDate().startOfDay(d->timeZone);
}
d->updateEdit();
- d->_q_editorCursorPositionChanged(-1, 0);
+ d->editorCursorPositionChanged(-1, 0);
}
}
@@ -1027,24 +984,70 @@ void QDateTimeEdit::setCalendarPopup(bool enable)
update();
}
+#if QT_DEPRECATED_SINCE(6, 10)
/*!
\property QDateTimeEdit::timeSpec
- \brief The current timespec used by the date time edit.
\since 4.4
+ \deprecated[6.10] Use QDateTimeEdit::timeZone instead.
+ \brief The current timespec used by the date time edit.
+
+ Since Qt 6.7 this is an indirect accessor for the timeZone property.
+
+ \sa QDateTimeEdit::timeZone
*/
Qt::TimeSpec QDateTimeEdit::timeSpec() const
{
Q_D(const QDateTimeEdit);
- return d->spec;
+ return d->timeZone.timeSpec();
}
void QDateTimeEdit::setTimeSpec(Qt::TimeSpec spec)
{
Q_D(QDateTimeEdit);
- if (spec != d->spec) {
- d->spec = spec;
- d->updateTimeSpec();
+ if (spec != d->timeZone.timeSpec()) {
+ switch (spec) {
+ case Qt::UTC:
+ setTimeZone(QTimeZone::UTC);
+ break;
+ case Qt::LocalTime:
+ setTimeZone(QTimeZone::LocalTime);
+ break;
+ default:
+ qWarning() << "Ignoring attempt to set time-spec" << spec
+ << "which needs ancillary data: see setTimeZone()";
+ return;
+ }
+ }
+}
+#endif // 6.10 deprecation
+
+// TODO: enable user input to control timeZone, when the format includes it.
+/*!
+ \property QDateTimeEdit::timeZone
+ \since 6.7
+ \brief The current timezone used by the datetime editing widget
+
+ If the datetime format in use includes a timezone indicator - that is, a
+ \c{t}, \c{tt}, \c{ttt} or \c{tttt} format specifier - the user's input is
+ re-expressed in this timezone whenever it is parsed, overriding any timezone
+ the user may have specified.
+
+ \sa QDateTimeEdit::displayFormat
+*/
+
+QTimeZone QDateTimeEdit::timeZone() const
+{
+ Q_D(const QDateTimeEdit);
+ return d->timeZone;
+}
+
+void QDateTimeEdit::setTimeZone(const QTimeZone &zone)
+{
+ Q_D(QDateTimeEdit);
+ if (zone != d->timeZone) {
+ d->timeZone = zone;
+ d->updateTimeZone();
}
}
@@ -1062,9 +1065,9 @@ QSize QDateTimeEdit::sizeHint() const
int h = d->edit->sizeHint().height();
int w = 0;
QString s;
- s = d->textFromValue(d->minimum) + QLatin1Char(' ');
+ s = d->textFromValue(d->minimum) + u' ';
w = qMax<int>(w, fm.horizontalAdvance(s));
- s = d->textFromValue(d->maximum) + QLatin1Char(' ');
+ s = d->textFromValue(d->maximum) + u' ';
w = qMax<int>(w, fm.horizontalAdvance(s));
if (d->specialValueText.size()) {
s = d->specialValueText;
@@ -1328,6 +1331,7 @@ void QDateTimeEdit::focusInEvent(QFocusEvent *event)
case Qt::ActiveWindowFocusReason:
if (oldHasHadFocus)
return;
+ break;
case Qt::ShortcutFocusReason:
case Qt::TabFocusReason:
default:
@@ -1420,7 +1424,7 @@ void QDateTimeEdit::stepBy(int steps)
d->updateCache(d->value, d->displayText());
d->setSelected(d->currentSectionIndex);
- d->updateTimeSpec();
+ d->updateTimeZone();
}
/*!
@@ -1479,15 +1483,11 @@ void QDateTimeEdit::fixup(QString &input) const
int copy = d->edit->cursorPosition();
QDateTime value = d->validateAndInterpret(input, copy, state, true);
- /*
- String was valid, but the datetime still is not; use the time that
- has the same distance from epoch.
- CorrectToPreviousValue correction is handled by QAbstractSpinBox.
- */
- if (!value.isValid() && d->correctionMode == QAbstractSpinBox::CorrectToNearestValue) {
- value = QDateTime::fromMSecsSinceEpoch(value.toMSecsSinceEpoch(), value.timeSpec());
+ // CorrectToPreviousValue correction is handled by QAbstractSpinBox.
+ // The value might not match the input if the input represents a date-time
+ // skipped over by its time representation, such as a spring-forward.
+ if (d->correctionMode == QAbstractSpinBox::CorrectToNearestValue)
input = textFromDateTime(value);
- }
}
@@ -1511,7 +1511,7 @@ QDateTimeEdit::StepEnabled QDateTimeEdit::stepEnabled() const
if (d->wrapping)
return StepEnabled(StepUpEnabled | StepDownEnabled);
// 3 cases. date, time, datetime. each case look
- // at just the relavant component.
+ // at just the relevant component.
QVariant max, min, val;
if (!(d->sections & DateSections_Mask)) {
// time only, no date
@@ -1628,7 +1628,7 @@ QTimeEdit::QTimeEdit(QWidget *parent)
*/
QTimeEdit::QTimeEdit(QTime time, QWidget *parent)
- : QDateTimeEdit(time, QMetaType::QTime, parent)
+ : QDateTimeEdit(time.isValid() ? time : QDATETIMEEDIT_TIME_MIN, QMetaType::QTime, parent)
{
connect(this, &QTimeEdit::timeChanged, this, &QTimeEdit::userTimeChanged);
}
@@ -1698,7 +1698,7 @@ QDateEdit::QDateEdit(QWidget *parent)
*/
QDateEdit::QDateEdit(QDate date, QWidget *parent)
- : QDateTimeEdit(date, QMetaType::QDate, parent)
+ : QDateTimeEdit(date.isValid() ? date : QDATETIMEEDIT_DATE_INITIAL, QMetaType::QDate, parent)
{
connect(this, &QDateEdit::dateChanged, this, &QDateEdit::userDateChanged);
}
@@ -1734,65 +1734,42 @@ QDateEdit::~QDateEdit()
*/
-QDateTimeEditPrivate::QDateTimeEditPrivate()
- : QDateTimeParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit, QCalendar())
+QDateTimeEditPrivate::QDateTimeEditPrivate(const QTimeZone &zone)
+ : QDateTimeParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit, QCalendar()),
+ timeZone(zone)
{
- hasHadFocus = false;
- formatExplicitlySet = false;
- cacheGuard = false;
fixday = true;
type = QMetaType::QDateTime;
- sections = { };
- cachedDay = -1;
currentSectionIndex = FirstSectionIndex;
first.pos = 0;
- calendarPopup = false;
- minimum = QDATETIMEEDIT_COMPAT_DATE_MIN.startOfDay();
- maximum = QDATETIMEEDIT_DATE_MAX.endOfDay();
- arrowState = QStyle::State_None;
- monthCalendar = nullptr;
+ minimum = QDATETIMEEDIT_COMPAT_DATE_MIN.startOfDay(timeZone);
+ maximum = QDATETIMEEDIT_DATE_MAX.endOfDay(timeZone);
readLocaleSettings();
+}
-#ifdef QT_KEYPAD_NAVIGATION
- focusOnButton = false;
-#endif
+QDateTime QDateTimeEditPrivate::convertTimeZone(const QDateTime &datetime)
+{
+ return datetime.toTimeZone(timeZone);
}
-QDateTime QDateTimeEditPrivate::convertTimeSpec(const QDateTime &datetime)
+QDateTime QDateTimeEditPrivate::dateTimeValue(QDate date, QTime time) const
{
- Q_ASSERT(value.toDateTime().timeSpec() == spec);
- switch (spec) {
- case Qt::UTC:
- return datetime.toUTC();
- case Qt::LocalTime:
- return datetime.toLocalTime();
- case Qt::OffsetFromUTC:
- return datetime.toOffsetFromUtc(value.toDateTime().offsetFromUtc());
- case Qt::TimeZone:
-#if QT_CONFIG(timezone)
- return datetime.toTimeZone(value.toDateTime().timeZone());
-#else
- qWarning("QDateTimeEdit: Internal: enable timezone feature to support Qt::TimeZone");
- return datetime;
-#endif
- }
- Q_UNREACHABLE();
+ return QDateTime(date, time, timeZone);
}
-// FIXME: architecturaly incompatible with OffsetFromUTC or TimeZone as spec (QTBUG-80417).
-void QDateTimeEditPrivate::updateTimeSpec()
+void QDateTimeEditPrivate::updateTimeZone()
{
- minimum = minimum.toDateTime().toTimeSpec(spec);
- maximum = maximum.toDateTime().toTimeSpec(spec);
- value = value.toDateTime().toTimeSpec(spec);
+ minimum = minimum.toDateTime().toTimeZone(timeZone);
+ maximum = maximum.toDateTime().toTimeZone(timeZone);
+ value = value.toDateTime().toTimeZone(timeZone);
// time zone changes can lead to 00:00:00 becomes 01:00:00 and 23:59:59 becomes 00:59:59 (invalid range)
const bool dateShown = (sections & QDateTimeEdit::DateSections_Mask);
if (!dateShown) {
if (minimum.toTime() >= maximum.toTime()){
- minimum = value.toDate().startOfDay(spec);
- maximum = value.toDate().endOfDay(spec);
+ minimum = value.toDate().startOfDay(timeZone);
+ maximum = value.toDate().endOfDay(timeZone);
}
}
}
@@ -1827,6 +1804,27 @@ void QDateTimeEditPrivate::updateEdit()
}
}
+QDateTime QDateTimeEditPrivate::getMinimum() const
+{
+ if (keyboardTracking)
+ return minimum.toDateTime();
+
+ if (timeZone.timeSpec() == Qt::LocalTime)
+ return QDateTimeParser::getMinimum();
+
+ return QDATETIMEEDIT_DATE_MIN.startOfDay(timeZone);
+}
+
+QDateTime QDateTimeEditPrivate::getMaximum() const
+{
+ if (keyboardTracking)
+ return maximum.toDateTime();
+
+ if (timeZone.timeSpec() == Qt::LocalTime)
+ return QDateTimeParser::getMaximum();
+
+ return QDATETIMEEDIT_DATE_MAX.endOfDay(timeZone);
+}
/*!
\internal
@@ -1872,7 +1870,7 @@ int QDateTimeEditPrivate::sectionAt(int pos) const
const int textSize = text.size();
if (textSize - pos < separators.last().size() + 1) {
if (separators.last().size() == 0) {
- return sectionNodes.count() - 1;
+ return sectionNodes.size() - 1;
}
return (pos == textSize ? LastSectionIndex : NoSectionIndex);
}
@@ -1958,7 +1956,7 @@ int QDateTimeEditPrivate::nextPrevSection(int current, bool forward) const
void QDateTimeEditPrivate::clearSection(int index)
{
- const QLatin1Char space(' ');
+ const auto space = u' ';
int cursorPos = edit->cursorPosition();
const QSignalBlocker blocker(edit);
QString t = edit->text();
@@ -2039,8 +2037,10 @@ QDateTime QDateTimeEditPrivate::validateAndInterpret(QString &input, int &positi
StateNode tmp = parse(input, position, value.toDateTime(), fixup);
// Take note of any corrections imposed during parsing:
input = m_text;
- // Impose this widget's spec:
- tmp.value = tmp.value.toTimeSpec(spec);
+ // TODO: if the format specifies time-zone, update timeZone to match the
+ // parsed text; but we're in const context, so can't - QTBUG-118393.
+ // Impose this widget's time system:
+ tmp.value = tmp.value.toTimeZone(timeZone);
// ... but that might turn a valid datetime into an invalid one:
if (!tmp.value.isValid() && tmp.state == Acceptable)
tmp.state = Intermediate;
@@ -2086,7 +2086,7 @@ QString QDateTimeEditPrivate::textFromValue(const QVariant &f) const
QVariant QDateTimeEditPrivate::valueFromText(const QString &f) const
{
Q_Q(const QDateTimeEdit);
- return q->dateTimeFromText(f).toTimeSpec(spec);
+ return q->dateTimeFromText(f).toTimeZone(timeZone);
}
@@ -2113,30 +2113,59 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c
v = q->dateTimeFromText(str);
int val = getDigit(v, sectionIndex);
- val += steps;
-
const int min = absoluteMin(sectionIndex);
const int max = absoluteMax(sectionIndex, value.toDateTime());
- if (val < min) {
- val = (wrapping ? max - (min - val) + 1 : min);
- } else if (val > max) {
- val = (wrapping ? min + val - max - 1 : max);
+ if (sn.type & DayOfWeekSectionMask) {
+ // Must take locale's first day of week into account when *not*
+ // wrapping; min and max don't help us.
+#ifndef QT_ALWAYS_WRAP_WEEKDAY // (documentation, not an actual define)
+ if (!wrapping) {
+ /* It's not clear this is ever really a desirable behavior.
+
+ It refuses to step backwards from the first day of the week or
+ forwards from the day before, only allowing day-of-week stepping
+ from start to end of one week. That's strictly what non-wrapping
+ behavior must surely mean, when put in locale-neutral terms.
+
+ It is, however, likely that users would prefer the "more natural"
+ behavior of cycling through the week.
+ */
+ const int first = int(locale().firstDayOfWeek()); // Mon = 1 through 7 = Sun
+ val = qBound(val < first ? first - 7 : first,
+ val + steps,
+ val < first ? first - 1 : first + 6);
+ } else
+#endif
+ {
+ val += steps;
+ }
+
+ // Restore to range from 1 through 7:
+ val = val % 7;
+ if (val <= 0)
+ val += 7;
+ } else {
+ val += steps;
+ const int span = max - min + 1;
+ if (val < min)
+ val = wrapping ? val + span : min;
+ else if (val > max)
+ val = wrapping ? val - span : max;
}
const int oldDay = v.date().day(calendar);
- setDigit(v, sectionIndex, val);
/*
- Stepping into a daylight saving time that doesn't exist,
- so use the time that has the same distance from epoch.
+ Stepping into a daylight saving time that doesn't exist (setDigit() is
+ true when date and time are valid, even if the date-time returned
+ isn't), so use the time that has the same distance from epoch.
*/
- if (!v.isValid()) {
- auto msecsSinceEpoch = v.toMSecsSinceEpoch();
+ if (setDigit(v, sectionIndex, val) && getDigit(v, sectionIndex) != val
+ && sn.type & HourSectionMask && steps < 0) {
// decreasing from e.g 3am to 2am would get us back to 3am, but we want 1am
- if (steps < 0 && sn.type & HourSectionMask)
- msecsSinceEpoch -= 3600 * 1000;
- v = QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch, v.timeSpec());
+ auto msecsSinceEpoch = v.toMSecsSinceEpoch() - 3600 * 1000;
+ v = QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch, v.timeRepresentation());
}
// if this sets year or month it will make
// sure that days are lowered if needed.
@@ -2144,7 +2173,8 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c
const QDateTime minimumDateTime = minimum.toDateTime();
const QDateTime maximumDateTime = maximum.toDateTime();
// changing one section should only modify that section, if possible
- if (sn.type != AmPmSection && (v < minimumDateTime || v > maximumDateTime)) {
+ if (sn.type != AmPmSection && !(sn.type & DayOfWeekSectionMask)
+ && (v < minimumDateTime || v > maximumDateTime)) {
const int localmin = getDigit(minimumDateTime, sectionIndex);
const int localmax = getDigit(maximumDateTime, sectionIndex);
@@ -2231,8 +2261,7 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c
}
}
- const QDateTime ret = bound(v, value, steps).toDateTime().toTimeSpec(spec);
- return ret;
+ return bound(v, value, steps).toDateTime().toTimeZone(timeZone);
}
/*!
@@ -2268,7 +2297,7 @@ void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
\internal
*/
-void QDateTimeEditPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos)
+void QDateTimeEditPrivate::editorCursorPositionChanged(int oldpos, int newpos)
{
if (ignoreCursorPositionChanged || specialValue())
return;
@@ -2326,7 +2355,7 @@ void QDateTimeEditPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos
currentSectionIndex = s;
Q_ASSERT_X(currentSectionIndex < sectionNodes.size(),
- "QDateTimeEditPrivate::_q_editorCursorPositionChanged()",
+ "QDateTimeEditPrivate::editorCursorPositionChanged()",
qPrintable(QString::fromLatin1("Internal error (%1 %2)").
arg(currentSectionIndex).
arg(sectionNodes.size())));
@@ -2419,8 +2448,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
@@ -2450,7 +2479,7 @@ void QDateTimeEditPrivate::interpret(EmitPolicy ep)
|| currentSectionIndex < 0
|| !(fieldInfo(currentSectionIndex) & AllowPartial))) {
setValue(value, ep);
- updateTimeSpec();
+ updateTimeZone();
} else {
QAbstractSpinBoxPrivate::interpret(ep);
}
@@ -2491,25 +2520,25 @@ void QDateTimeEditPrivate::init(const QVariant &var)
Q_Q(QDateTimeEdit);
switch (var.userType()) {
case QMetaType::QDate:
- value = var.toDate().startOfDay();
- updateTimeSpec();
+ value = var.toDate().startOfDay(timeZone);
+ updateTimeZone();
q->setDisplayFormat(defaultDateFormat);
if (sectionNodes.isEmpty()) // ### safeguard for broken locale
- q->setDisplayFormat(QLatin1String("dd/MM/yyyy"));
+ q->setDisplayFormat("dd/MM/yyyy"_L1);
break;
case QMetaType::QDateTime:
value = var;
- updateTimeSpec();
+ updateTimeZone();
q->setDisplayFormat(defaultDateTimeFormat);
if (sectionNodes.isEmpty()) // ### safeguard for broken locale
- q->setDisplayFormat(QLatin1String("dd/MM/yyyy hh:mm:ss"));
+ q->setDisplayFormat("dd/MM/yyyy hh:mm:ss"_L1);
break;
case QMetaType::QTime:
- value = QDateTime(QDATETIMEEDIT_DATE_INITIAL, var.toTime());
- updateTimeSpec();
+ value = dateTimeValue(QDATETIMEEDIT_DATE_INITIAL, var.toTime());
+ updateTimeZone();
q->setDisplayFormat(defaultTimeFormat);
if (sectionNodes.isEmpty()) // ### safeguard for broken locale
- q->setDisplayFormat(QLatin1String("hh:mm:ss"));
+ q->setDisplayFormat("hh:mm:ss"_L1);
break;
default:
Q_ASSERT_X(0, "QDateTimeEditPrivate::init", "Internal error");
@@ -2584,7 +2613,7 @@ void QDateTimeEditPrivate::updateEditFieldGeometry()
QVariant QDateTimeEditPrivate::getZeroVariant() const
{
Q_ASSERT(type == QMetaType::QDateTime);
- return QDateTime(QDATETIMEEDIT_DATE_INITIAL, QTime(), spec);
+ return QDATETIMEEDIT_DATE_INITIAL.startOfDay(timeZone);
}
void QDateTimeEditPrivate::setRange(const QVariant &min, const QVariant &max)
@@ -2613,7 +2642,7 @@ void QDateTimeEditPrivate::initCalendarPopup(QCalendarWidget *cw)
Q_Q(QDateTimeEdit);
if (!monthCalendar) {
monthCalendar = new QCalendarPopup(q, cw, calendar);
- monthCalendar->setObjectName(QLatin1String("qt_datetimedit_calendar"));
+ monthCalendar->setObjectName("qt_datetimedit_calendar"_L1);
QObject::connect(monthCalendar, SIGNAL(newDateSelected(QDate)), q, SLOT(setDate(QDate)));
QObject::connect(monthCalendar, SIGNAL(hidingCalendar(QDate)), q, SLOT(setDate(QDate)));
QObject::connect(monthCalendar, SIGNAL(activated(QDate)), q, SLOT(setDate(QDate)));
diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h
index a1d9be1088..f7c0dd7374 100644
--- a/src/widgets/widgets/qdatetimeedit.h
+++ b/src/widgets/widgets/qdatetimeedit.h
@@ -1,47 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATETIMEEDIT_H
#define QDATETIMEEDIT_H
#include <QtWidgets/qtwidgetsglobal.h>
-#include <QtCore/qdatetime.h>
+#include <QtCore/qtimezone.h>
#include <QtCore/qcalendar.h>
#include <QtCore/qvariant.h>
#include <QtWidgets/qabstractspinbox.h>
@@ -61,8 +25,10 @@ class Q_WIDGETS_EXPORT QDateTimeEdit : public QAbstractSpinBox
Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged USER true)
Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged)
Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged)
- Q_PROPERTY(QDateTime maximumDateTime READ maximumDateTime WRITE setMaximumDateTime RESET clearMaximumDateTime)
- Q_PROPERTY(QDateTime minimumDateTime READ minimumDateTime WRITE setMinimumDateTime RESET clearMinimumDateTime)
+ Q_PROPERTY(QDateTime maximumDateTime READ maximumDateTime WRITE setMaximumDateTime
+ RESET clearMaximumDateTime)
+ Q_PROPERTY(QDateTime minimumDateTime READ minimumDateTime WRITE setMinimumDateTime
+ RESET clearMinimumDateTime)
Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate RESET clearMaximumDate)
Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate RESET clearMinimumDate)
Q_PROPERTY(QTime maximumTime READ maximumTime WRITE setMaximumTime RESET clearMaximumTime)
@@ -73,7 +39,10 @@ class Q_WIDGETS_EXPORT QDateTimeEdit : public QAbstractSpinBox
Q_PROPERTY(bool calendarPopup READ calendarPopup WRITE setCalendarPopup)
Q_PROPERTY(int currentSectionIndex READ currentSectionIndex WRITE setCurrentSectionIndex)
Q_PROPERTY(int sectionCount READ sectionCount)
+#if QT_DEPRECATED_SINCE(6, 10)
Q_PROPERTY(Qt::TimeSpec timeSpec READ timeSpec WRITE setTimeSpec)
+#endif
+ Q_PROPERTY(QTimeZone timeZone READ timeZone WRITE setTimeZone)
public:
enum Section { // a sub-type of QDateTimeParser's like-named enum.
NoSection = 0x0000,
@@ -159,8 +128,14 @@ public:
bool calendarPopup() const;
void setCalendarPopup(bool enable);
+#if QT_DEPRECATED_SINCE(6, 10)
+ QT_DEPRECATED_VERSION_X_6_10("Use timeZone() instead")
Qt::TimeSpec timeSpec() const;
+ QT_DEPRECATED_VERSION_X_6_10("Use setTimeZone() instead")
void setTimeSpec(Qt::TimeSpec spec);
+#endif
+ QTimeZone timeZone() const;
+ void setTimeZone(const QTimeZone &zone);
QSize sizeHint() const override;
diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h
index dd0f6b251c..215ee75bfe 100644
--- a/src/widgets/widgets/qdatetimeedit_p.h
+++ b/src/widgets/widgets/qdatetimeedit_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATETIMEEDIT_P_H
#define QDATETIMEEDIT_P_H
@@ -53,6 +17,8 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include <QtCore/qcalendar.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qtimezone.h>
#include "QtWidgets/qcalendarwidget.h"
#include "QtWidgets/qspinbox.h"
#include "QtWidgets/qtoolbutton.h"
@@ -62,6 +28,7 @@
#include "private/qdatetimeparser_p.h"
#include "qdebug.h"
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +37,7 @@ class Q_AUTOTEST_EXPORT QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, p
{
Q_DECLARE_PUBLIC(QDateTimeEdit)
public:
- QDateTimeEditPrivate();
+ QDateTimeEditPrivate(const QTimeZone &zone = QTimeZone::LocalTime);
void init(const QVariant &var);
void readLocaleSettings();
@@ -83,7 +50,7 @@ public:
void emitSignals(EmitPolicy ep, const QVariant &old) override;
QString textFromValue(const QVariant &f) const override;
QVariant valueFromText(const QString &f) const override;
- void _q_editorCursorPositionChanged(int oldpos, int newpos) override;
+ void editorCursorPositionChanged(int oldpos, int newpos) override;
void interpret(EmitPolicy ep) override;
void clearCache() const override;
QStyle::SubControl newHoverControl(const QPoint &pos) override;
@@ -94,22 +61,8 @@ public:
// Override QDateTimeParser:
QString displayText() const override { return edit->text(); }
- QDateTime getMinimum() const override
- {
- if (keyboardTracking)
- return minimum.toDateTime();
- if (spec != Qt::LocalTime)
- return QDateTime(QDATETIMEEDIT_DATE_MIN.startOfDay(spec));
- return QDateTimeParser::getMinimum();
- }
- QDateTime getMaximum() const override
- {
- if (keyboardTracking)
- return maximum.toDateTime();
- if (spec != Qt::LocalTime)
- return QDateTime(QDATETIMEEDIT_DATE_MIN.startOfDay(spec));
- return QDateTimeParser::getMaximum();
- }
+ QDateTime getMinimum() const override;
+ QDateTime getMaximum() const override;
QLocale locale() const override { return q_func()->locale(); }
int cursorPosition() const override { return edit ? edit->cursorPosition() : -1; }
@@ -123,9 +76,10 @@ public:
void updateCache(const QVariant &val, const QString &str) const;
- QDateTime convertTimeSpec(const QDateTime &datetime);
- void updateTimeSpec();
+ QDateTime convertTimeZone(const QDateTime &datetime);
+ void updateTimeZone();
QString valueToText(const QVariant &var) const { return textFromValue(var); }
+ QDateTime dateTimeValue(QDate date, QTime time) const;
void _q_resetButton();
void updateArrow(QStyle::StateFlag state);
@@ -140,20 +94,20 @@ public:
void initCalendarPopup(QCalendarWidget *cw = nullptr);
void positionCalendarPopup();
- QDateTimeEdit::Sections sections;
- mutable bool cacheGuard;
+ QDateTimeEdit::Sections sections = {};
+ mutable bool cacheGuard = false;
QString defaultDateFormat, defaultTimeFormat, defaultDateTimeFormat, unreversedFormat;
mutable QVariant conflictGuard;
- bool hasHadFocus, formatExplicitlySet, calendarPopup;
- QStyle::StateFlag arrowState;
- QCalendarPopup *monthCalendar;
+ bool hasHadFocus = false, formatExplicitlySet = false, calendarPopup = false;
+ QStyle::StateFlag arrowState = QStyle::State_None;
+ QCalendarPopup *monthCalendar = nullptr;
#ifdef QT_KEYPAD_NAVIGATION
- bool focusOnButton;
+ bool focusOnButton = false;
#endif
- Qt::TimeSpec spec = Qt::LocalTime;
+ QTimeZone timeZone;
};
diff --git a/src/widgets/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp
index 594fe0a779..14e96f8dc3 100644
--- a/src/widgets/widgets/qdial.cpp
+++ b/src/widgets/widgets/qdial.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdial.h"
@@ -52,7 +16,7 @@
#include <qslider.h>
#include <private/qabstractslider_p.h>
#include <private/qmath_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#include <qmath.h>
@@ -94,6 +58,8 @@ int QDialPrivate::bound(int val) const
if (wrapping) {
if ((val >= minimum) && (val <= maximum))
return val;
+ if (minimum == maximum)
+ return minimum;
val = minimum + ((val - minimum) % (maximum - minimum));
if (val < minimum)
val += maximum - minimum;
@@ -222,11 +188,11 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const
If you are using the mouse wheel to adjust the dial, the increment
value is determined by the lesser value of
- \l{QApplication::wheelScrollLines()} {wheelScrollLines} multipled
+ \l{QApplication::wheelScrollLines()} {wheelScrollLines} multiplied
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/qdial.h b/src/widgets/widgets/qdial.h
index 9abea5bf45..af08a41048 100644
--- a/src/widgets/widgets/qdial.h
+++ b/src/widgets/widgets/qdial.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDIAL_H
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index 560eeab433..30ace89fa8 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qhash.h>
#include <QtWidgets/qpushbutton.h>
@@ -50,6 +14,9 @@
#include <QtGui/qaction.h>
#include "qdialogbuttonbox.h"
+#include "qdialogbuttonbox_p.h"
+
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@@ -89,7 +56,7 @@ QT_BEGIN_NAMESPACE
the buttons (or button texts) yourself and add them to the button box,
specifying their role.
- \snippet dialogs/extension/finddialog.cpp 1
+ \snippet dialogs/dialogs.cpp buttonbox
Alternatively, QDialogButtonBox provides several standard buttons (e.g. OK, Cancel, Save)
that you can use. They exist as flags so you can OR them together in the constructor.
@@ -147,39 +114,25 @@ QT_BEGIN_NAMESPACE
\sa QMessageBox, QPushButton, QDialog
*/
-
-class QDialogButtonBoxPrivate : public QWidgetPrivate
+QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
+ : orientation(orient), buttonLayout(nullptr), center(false)
{
- Q_DECLARE_PUBLIC(QDialogButtonBox)
-
-public:
- QDialogButtonBoxPrivate(Qt::Orientation orient);
-
- QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
- QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
-
- Qt::Orientation orientation;
- QDialogButtonBox::ButtonLayout layoutPolicy;
- QBoxLayout *buttonLayout;
- bool internalRemove;
- bool center;
+ struct EventFilter : public QObject
+ {
+ EventFilter(QDialogButtonBoxPrivate *d) : d(d) {};
+
+ bool eventFilter(QObject *obj, QEvent *event) override
+ {
+ QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);
+ return button ? d->handleButtonShowAndHide(button, event) : false;
+ }
- void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
+ private:
+ QDialogButtonBoxPrivate *d;
- void layoutButtons();
- void initLayout();
- void resetLayout();
- QPushButton *createButton(QDialogButtonBox::StandardButton button, bool doLayout = true);
- void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role, bool doLayout = true);
- void _q_handleButtonDestroyed();
- void _q_handleButtonClicked();
- void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
- void retranslateStrings();
-};
+ };
-QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
- : orientation(orient), buttonLayout(nullptr), internalRemove(false), center(false)
-{
+ filter.reset(new EventFilter(this));
}
void QDialogButtonBoxPrivate::initLayout()
@@ -213,7 +166,6 @@ void QDialogButtonBoxPrivate::initLayout()
void QDialogButtonBoxPrivate::resetLayout()
{
- //delete buttonLayout;
initLayout();
layoutButtons();
}
@@ -221,8 +173,8 @@ void QDialogButtonBoxPrivate::resetLayout()
void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *> &buttonList,
bool reverse)
{
- int start = reverse ? buttonList.count() - 1 : 0;
- int end = reverse ? -1 : buttonList.count();
+ int start = reverse ? buttonList.size() - 1 : 0;
+ int end = reverse ? -1 : buttonList.size();
int step = reverse ? -1 : 1;
for (int i = start; i != end; i += step) {
@@ -237,6 +189,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
Q_Q(QDialogButtonBox);
const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
+ QBoolBlocker blocker(ignoreShowAndHide);
for (int i = buttonLayout->count() - 1; i >= 0; --i) {
QLayoutItem *item = buttonLayout->takeAt(i);
if (QWidget *widget = item->widget())
@@ -329,16 +282,20 @@ void QDialogButtonBoxPrivate::layoutButtons()
++currentLayout;
}
- QWidget *lastWidget = nullptr;
- q->setFocusProxy(nullptr);
+ QWidgetList layoutWidgets;
for (int i = 0; i < buttonLayout->count(); ++i) {
- QLayoutItem *item = buttonLayout->itemAt(i);
- if (QWidget *widget = item->widget()) {
- if (lastWidget)
- QWidget::setTabOrder(lastWidget, widget);
- else
- q->setFocusProxy(widget);
- lastWidget = widget;
+ if (auto *widget = buttonLayout->itemAt(i)->widget())
+ layoutWidgets << widget;
+ }
+
+ q->setFocusProxy(nullptr);
+ if (!layoutWidgets.isEmpty()) {
+ QWidget *prev = layoutWidgets.constLast();
+ for (QWidget *here : layoutWidgets) {
+ QWidget::setTabOrder(prev, here);
+ prev = here;
+ if (auto *pushButton = qobject_cast<QPushButton *>(prev); pushButton && pushButton->isDefault())
+ q->setFocusProxy(pushButton);
}
}
@@ -347,7 +304,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
}
QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardButton sbutton,
- bool doLayout)
+ LayoutRule layoutRule)
{
Q_Q(QDialogButtonBox);
int icon = 0;
@@ -422,7 +379,7 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
if (Q_UNLIKELY(role == QPlatformDialogHelper::InvalidRole))
qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
else
- addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), doLayout);
+ addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), layoutRule);
#if QT_CONFIG(shortcut)
const QKeySequence standardShortcut = QGuiApplicationPrivate::platformTheme()->standardButtonShortcut(sbutton);
if (!standardShortcut.isEmpty())
@@ -432,23 +389,36 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
}
void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
- bool doLayout)
+ LayoutRule layoutRule, AddRule addRule)
{
- Q_Q(QDialogButtonBox);
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_handleButtonClicked()));
- QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
buttonLists[role].append(button);
- if (doLayout)
+ switch (addRule) {
+ case AddRule::Connect:
+ QObjectPrivate::connect(button, &QAbstractButton::clicked,
+ this, &QDialogButtonBoxPrivate::handleButtonClicked);
+ QObjectPrivate::connect(button, &QAbstractButton::destroyed,
+ this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
+ button->installEventFilter(filter.get());
+ break;
+ case AddRule::SkipConnect:
+ break;
+ }
+
+ switch (layoutRule) {
+ case LayoutRule::DoLayout:
layoutButtons();
+ break;
+ case LayoutRule::SkipLayout:
+ break;
+ }
}
void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardButtons buttons)
{
uint i = QDialogButtonBox::FirstButton;
while (i <= QDialogButtonBox::LastButton) {
- if (i & buttons) {
- createButton(QDialogButtonBox::StandardButton(i), false);
- }
+ if (i & buttons)
+ createButton(QDialogButtonBox::StandardButton(i), LayoutRule::SkipLayout);
i = i << 1;
}
layoutButtons();
@@ -456,13 +426,10 @@ void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardBu
void QDialogButtonBoxPrivate::retranslateStrings()
{
- typedef QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator Iterator;
-
- const Iterator end = standardButtonHash.end();
- for (Iterator it = standardButtonHash.begin(); it != end; ++it) {
- const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(it.value());
+ for (auto &&[key, value] : std::as_const(standardButtonHash).asKeyValueRange()) {
+ const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(value);
if (!text.isEmpty())
- it.key()->setText(text);
+ key->setText(text);
}
}
@@ -518,6 +485,14 @@ QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, Qt::Orientation orie
*/
QDialogButtonBox::~QDialogButtonBox()
{
+ Q_D(QDialogButtonBox);
+
+ d->ignoreShowAndHide = true;
+
+ // QObjectPrivate::connect requires explicit disconnect in destructor
+ // otherwise the connection may kick in on child destruction and reach
+ // the parent's destroyed private object
+ d->disconnectAll();
}
/*!
@@ -672,31 +647,42 @@ void QDialogButtonBox::clear()
d->standardButtonHash.clear();
for (int i = 0; i < NRoles; ++i) {
QList<QAbstractButton *> &list = d->buttonLists[i];
- while (list.count()) {
+ while (list.size()) {
QAbstractButton *button = list.takeAt(0);
- QObject::disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
+ QObjectPrivate::disconnect(button, &QAbstractButton::destroyed,
+ d, &QDialogButtonBoxPrivate::handleButtonDestroyed);
delete button;
}
}
}
/*!
- Returns a list of all the buttons that have been added to the button box.
+ Returns a list of all buttons that have been added to the button box.
\sa buttonRole(), addButton(), removeButton()
*/
QList<QAbstractButton *> QDialogButtonBox::buttons() const
{
Q_D(const QDialogButtonBox);
+ return d->allButtons();
+}
+
+QList<QAbstractButton *> QDialogButtonBoxPrivate::visibleButtons() const
+{
QList<QAbstractButton *> finalList;
- for (int i = 0; i < NRoles; ++i) {
- const QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j)
+ for (int i = 0; i < QDialogButtonBox::NRoles; ++i) {
+ const QList<QAbstractButton *> &list = buttonLists[i];
+ for (int j = 0; j < list.size(); ++j)
finalList.append(list.at(j));
}
return finalList;
}
+QList<QAbstractButton *> QDialogButtonBoxPrivate::allButtons() const
+{
+ return visibleButtons() << hiddenButtons.keys();
+}
+
/*!
Returns the button role for the specified \a button. This function returns
\l InvalidRole if \a button is \nullptr or has not been added to the button box.
@@ -708,12 +694,12 @@ QDialogButtonBox::ButtonRole QDialogButtonBox::buttonRole(QAbstractButton *butto
Q_D(const QDialogButtonBox);
for (int i = 0; i < NRoles; ++i) {
const QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j) {
+ for (int j = 0; j < list.size(); ++j) {
if (list.at(j) == button)
return ButtonRole(i);
}
}
- return InvalidRole;
+ return d->hiddenButtons.value(button, InvalidRole);
}
/*!
@@ -724,27 +710,45 @@ QDialogButtonBox::ButtonRole QDialogButtonBox::buttonRole(QAbstractButton *butto
void QDialogButtonBox::removeButton(QAbstractButton *button)
{
Q_D(QDialogButtonBox);
+ d->removeButton(button, QDialogButtonBoxPrivate::RemoveReason::ManualRemove);
+}
+/*!
+ \internal
+ Removes \param button.
+ \param reason determines the behavior following the removal:
+ \list
+ \li \c ManualRemove disconnects all signals and removes the button from standardButtonHash.
+ \li \c HideEvent keeps connections alive, standard buttons remain in standardButtonHash.
+ \li \c Destroyed removes the button from standardButtonHash. Signals remain untouched, because
+ the button might already be only a QObject, the destructor of which handles disconnecting.
+ \endlist
+ */
+void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveReason reason)
+{
if (!button)
return;
- // Remove it from the standard button hash first and then from the roles
- d->standardButtonHash.remove(reinterpret_cast<QPushButton *>(button));
- for (int i = 0; i < NRoles; ++i) {
- QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j) {
- if (list.at(j) == button) {
- list.takeAt(j);
- if (!d->internalRemove) {
- disconnect(button, SIGNAL(clicked()), this, SLOT(_q_handleButtonClicked()));
- disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
- }
- break;
- }
- }
- }
- if (!d->internalRemove)
+ // Remove button from hidden buttons and roles
+ hiddenButtons.remove(button);
+ for (int i = 0; i < QDialogButtonBox::NRoles; ++i)
+ buttonLists[i].removeOne(button);
+
+ switch (reason) {
+ case RemoveReason::ManualRemove:
button->setParent(nullptr);
+ QObjectPrivate::disconnect(button, &QAbstractButton::clicked,
+ this, &QDialogButtonBoxPrivate::handleButtonClicked);
+ QObjectPrivate::disconnect(button, &QAbstractButton::destroyed,
+ this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
+ button->removeEventFilter(filter.get());
+ Q_FALLTHROUGH();
+ case RemoveReason::Destroyed:
+ standardButtonHash.remove(reinterpret_cast<QPushButton *>(button));
+ break;
+ case RemoveReason::HideEvent:
+ break;
+ }
}
/*!
@@ -814,7 +818,7 @@ void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
{
Q_D(QDialogButtonBox);
// Clear out all the old standard buttons, then recreate them.
- qDeleteAll(d->standardButtonHash.keys());
+ qDeleteAll(d->standardButtonHash.keyBegin(), d->standardButtonHash.keyEnd());
d->standardButtonHash.clear();
d->createStandardButtons(buttons);
@@ -856,7 +860,7 @@ QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButto
return d->standardButtonHash.value(static_cast<QPushButton *>(button));
}
-void QDialogButtonBoxPrivate::_q_handleButtonClicked()
+void QDialogButtonBoxPrivate::handleButtonClicked()
{
Q_Q(QDialogButtonBox);
if (QAbstractButton *button = qobject_cast<QAbstractButton *>(q->sender())) {
@@ -890,20 +894,51 @@ void QDialogButtonBoxPrivate::_q_handleButtonClicked()
}
}
-void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
+void QDialogButtonBoxPrivate::handleButtonDestroyed()
+{
+ Q_Q(QDialogButtonBox);
+ if (QObject *object = q->sender())
+ removeButton(reinterpret_cast<QAbstractButton *>(object), RemoveReason::Destroyed);
+}
+
+bool QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton *button, QEvent *event)
{
Q_Q(QDialogButtonBox);
- if (QObject *object = q->sender()) {
- QBoolBlocker skippy(internalRemove);
- q->removeButton(reinterpret_cast<QAbstractButton *>(object));
+
+ const QEvent::Type type = event->type();
+
+ if ((type != QEvent::HideToParent && type != QEvent::ShowToParent) || ignoreShowAndHide)
+ return false;
+
+ switch (type) {
+ case QEvent::HideToParent: {
+ const QDialogButtonBox::ButtonRole role = q->buttonRole(button);
+ if (role != QDialogButtonBox::ButtonRole::InvalidRole) {
+ removeButton(button, RemoveReason::HideEvent);
+ hiddenButtons.insert(button, role);
+ layoutButtons();
+ }
+ break;
}
+ case QEvent::ShowToParent:
+ if (hiddenButtons.contains(button)) {
+ const auto role = hiddenButtons.take(button);
+ addButton(button, role, LayoutRule::DoLayout, AddRule::SkipConnect);
+ if (role == QDialogButtonBox::AcceptRole)
+ ensureFirstAcceptIsDefault();
+ }
+ break;
+ default: break;
+ }
+
+ return false;
}
/*!
\property QDialogButtonBox::centerButtons
\brief whether the buttons in the button box are centered
- By default, this property is \c false. This behavior is appopriate
+ By default, this property is \c false. This behavior is appropriate
for most types of dialogs. A notable exception is message boxes
on most platforms (e.g. Windows), where the button box is
centered horizontally.
@@ -954,36 +989,80 @@ void QDialogButtonBox::changeEvent(QEvent *event)
}
}
+void QDialogButtonBoxPrivate::ensureFirstAcceptIsDefault()
+{
+ Q_Q(QDialogButtonBox);
+ const QList<QAbstractButton *> &acceptRoleList = buttonLists[QDialogButtonBox::AcceptRole];
+ QPushButton *firstAcceptButton = acceptRoleList.isEmpty()
+ ? nullptr
+ : qobject_cast<QPushButton *>(acceptRoleList.at(0));
+
+ if (!firstAcceptButton)
+ return;
+
+ bool hasDefault = false;
+ QWidget *dialog = nullptr;
+ QWidget *p = q;
+ while (p && !p->isWindow()) {
+ p = p->parentWidget();
+ if ((dialog = qobject_cast<QDialog *>(p)))
+ break;
+ }
+
+ QWidget *parent = dialog ? dialog : q;
+ Q_ASSERT(parent);
+
+ const auto pushButtons = parent->findChildren<QPushButton *>();
+ for (QPushButton *pushButton : pushButtons) {
+ if (pushButton->isDefault() && pushButton != firstAcceptButton) {
+ hasDefault = true;
+ break;
+ }
+ }
+ if (!hasDefault && firstAcceptButton) {
+ firstAcceptButton->setDefault(true);
+ // When the QDialogButtonBox is focused, and it doesn't have an
+ // explicit focus widget, it will transfer focus to its focus
+ // proxy, which is the first button in the layout. This behavior,
+ // combined with the behavior that QPushButtons in a QDialog will
+ // by default have their autoDefault set to true, results in the
+ // focus proxy/first button stealing the default button status
+ // immediately when the button box is focused, which is not what
+ // we want. Account for this by explicitly making the firstAcceptButton
+ // focused as well, unless an explicit focus widget has been set, or
+ // a dialog child has Qt::StrongFocus.
+ if (dialog && !(QWidgetPrivate::get(dialog)->hasChildWithFocusPolicy(Qt::StrongFocus, q)
+ || dialog->focusWidget()))
+ firstAcceptButton->setFocus();
+ }
+}
+
+void QDialogButtonBoxPrivate::disconnectAll()
+{
+ Q_Q(QDialogButtonBox);
+ const auto buttons = q->findChildren<QAbstractButton *>();
+ for (auto *button : buttons)
+ button->disconnect(q);
+}
+
/*!
\reimp
*/
bool QDialogButtonBox::event(QEvent *event)
{
Q_D(QDialogButtonBox);
- if (event->type() == QEvent::Show) {
- QList<QAbstractButton *> acceptRoleList = d->buttonLists[AcceptRole];
- QPushButton *firstAcceptButton = acceptRoleList.isEmpty() ? 0 : qobject_cast<QPushButton *>(acceptRoleList.at(0));
- bool hasDefault = false;
- QWidget *dialog = nullptr;
- QWidget *p = this;
- while (p && !p->isWindow()) {
- p = p->parentWidget();
- if ((dialog = qobject_cast<QDialog *>(p)))
- break;
- }
+ switch (event->type()) {
+ case QEvent::Show:
+ d->ensureFirstAcceptIsDefault();
+ break;
- const auto pbs = (dialog ? dialog : this)->findChildren<QPushButton *>();
- for (QPushButton *pb : pbs) {
- if (pb->isDefault() && pb != firstAcceptButton) {
- hasDefault = true;
- break;
- }
- }
- if (!hasDefault && firstAcceptButton)
- firstAcceptButton->setDefault(true);
- }else if (event->type() == QEvent::LanguageChange) {
+ case QEvent::LanguageChange:
d->retranslateStrings();
+ break;
+
+ default: break;
}
+
return QWidget::event(event);
}
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
index 46a1d616d7..d967494d0d 100644
--- a/src/widgets/widgets/qdialogbuttonbox.h
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDIALOGBUTTONBOX_H
#define QDIALOGBUTTONBOX_H
@@ -156,8 +120,6 @@ protected:
private:
Q_DISABLE_COPY(QDialogButtonBox)
Q_DECLARE_PRIVATE(QDialogButtonBox)
- Q_PRIVATE_SLOT(d_func(), void _q_handleButtonClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_handleButtonDestroyed())
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDialogButtonBox::StandardButtons)
diff --git a/src/widgets/widgets/qdialogbuttonbox_p.h b/src/widgets/widgets/qdialogbuttonbox_p.h
new file mode 100644
index 0000000000..c3d7e03489
--- /dev/null
+++ b/src/widgets/widgets/qdialogbuttonbox_p.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QDIALOGBUTTONBOX_P_H
+#define QDIALOGBUTTONBOX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qwidget_p.h>
+#include <qdialogbuttonbox.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QDialogButtonBoxPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QDialogButtonBox)
+
+public:
+ enum class RemoveReason {
+ HideEvent,
+ ManualRemove,
+ Destroyed,
+ };
+ enum class LayoutRule {
+ DoLayout,
+ SkipLayout,
+ };
+ enum class AddRule {
+ Connect,
+ SkipConnect,
+ };
+
+ QDialogButtonBoxPrivate(Qt::Orientation orient);
+
+ QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
+ QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
+ QHash<QAbstractButton *, QDialogButtonBox::ButtonRole> hiddenButtons;
+
+ Qt::Orientation orientation;
+ QDialogButtonBox::ButtonLayout layoutPolicy;
+ QBoxLayout *buttonLayout;
+ std::unique_ptr<QObject> filter;
+ bool center;
+ bool ignoreShowAndHide = false;
+
+ void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
+
+ void removeButton(QAbstractButton *button, RemoveReason reason);
+ void layoutButtons();
+ void initLayout();
+ void resetLayout();
+ QPushButton *createButton(QDialogButtonBox::StandardButton button,
+ LayoutRule layoutRule = LayoutRule::DoLayout);
+ void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
+ LayoutRule layoutRule = LayoutRule::DoLayout,
+ AddRule addRule = AddRule::Connect);
+ void handleButtonDestroyed();
+ void handleButtonClicked();
+ bool handleButtonShowAndHide(QAbstractButton *button, QEvent *event);
+ void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
+ void ensureFirstAcceptIsDefault();
+ void retranslateStrings();
+ void disconnectAll();
+ QList<QAbstractButton *> allButtons() const;
+ QList<QAbstractButton *> visibleButtons() const;
+ QDialogButtonBox::ButtonRole buttonRole(QAbstractButton *button) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDIALOGBUTTONBOX_P_H
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 7776ae6613..da0e987171 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "QtWidgets/qapplication.h"
#include "QtWidgets/qwidget.h"
@@ -60,6 +24,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaDockWidgets, "qt.widgets.dockwidgets");
+
// qmainwindow.cpp
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
@@ -125,7 +91,7 @@ bool QDockAreaLayoutItem::skip() const
return widgetItem->isEmpty();
if (subinfo != nullptr) {
- for (int i = 0; i < subinfo->item_list.count(); ++i) {
+ for (int i = 0; i < subinfo->item_list.size(); ++i) {
if (!subinfo->item_list.at(i).skip())
return false;
}
@@ -205,6 +171,38 @@ QDockAreaLayoutItem
return *this;
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem *item)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ return item ? dbg << *item : dbg << "QDockAreaLayoutItem(0x0)";
+}
+
+QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem &item)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "QDockAreaLayoutItem(" << static_cast<const void *>(&item) << "->";
+ if (item.widgetItem) {
+ QWidget *widget = item.widgetItem->widget();
+ if (auto *dockWidget = qobject_cast<QDockWidget *>(widget)) {
+ dbg << "widgetItem(" << dockWidget << ")";
+ } else if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) {
+ dbg << "widgetItem(" << groupWindow << "->(" << groupWindow->dockWidgets() << "))";
+ } else {
+ dbg << "widgetItem(" << widget << ")";
+ }
+ } else if (item.subinfo) {
+ dbg << "subInfo(" << item.subinfo << "->(" << item.subinfo->item_list << ")";
+ } else if (item.placeHolderItem) {
+ dbg << "placeHolderItem(" << item.placeHolderItem << ")";
+ }
+ dbg << ")";
+ return dbg;
+}
+#endif // QT_NO_DEBUG_STREAM
+
/******************************************************************************
** QDockAreaLayoutInfo
*/
@@ -886,7 +884,7 @@ static int separatorMoveHelper(QList<QLayoutStruct> &list, int index, int delta,
delta = growlimit;
int d = 0;
- for (int i = index + 1; d < delta && i < list.count(); ++i)
+ for (int i = index + 1; d < delta && i < list.size(); ++i)
d += shrink(list[i], delta - d);
delta = d;
d = 0;
@@ -894,7 +892,7 @@ static int separatorMoveHelper(QList<QLayoutStruct> &list, int index, int delta,
d += grow(list[i], delta - d);
} else if (delta < 0) {
int growlimit = 0;
- for (int i = index + 1; i < list.count(); ++i) {
+ for (int i = index + 1; i < list.size(); ++i) {
const QLayoutStruct &ls = list.at(i);
if (ls.empty)
continue;
@@ -912,7 +910,7 @@ static int separatorMoveHelper(QList<QLayoutStruct> &list, int index, int delta,
d += shrink(list[i], -delta - d);
delta = -d;
d = 0;
- for (int i = index + 1; d < -delta && i < list.count(); ++i)
+ for (int i = index + 1; d < -delta && i < list.size(); ++i)
d += grow(list[i], -delta - d);
}
@@ -983,12 +981,12 @@ void QDockAreaLayoutInfo::unnest(int index)
QDockAreaLayoutItem &item = item_list[index];
if (item.subinfo == nullptr)
return;
- if (item.subinfo->item_list.count() > 1)
+ if (item.subinfo->item_list.size() > 1)
return;
- if (item.subinfo->item_list.count() == 0) {
+ if (item.subinfo->item_list.size() == 0) {
item_list.removeAt(index);
- } else if (item.subinfo->item_list.count() == 1) {
+ } else if (item.subinfo->item_list.size() == 1) {
QDockAreaLayoutItem &child = item.subinfo->item_list.first();
if (child.widgetItem != nullptr) {
item.widgetItem = child.widgetItem;
@@ -1008,7 +1006,7 @@ void QDockAreaLayoutInfo::remove(const QList<int> &path)
{
Q_ASSERT(!path.isEmpty());
- if (path.count() > 1) {
+ if (path.size() > 1) {
const int index = path.first();
QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != nullptr);
@@ -1020,6 +1018,14 @@ void QDockAreaLayoutInfo::remove(const QList<int> &path)
}
}
+void QDockAreaLayoutInfo::remove(QWidget *widget)
+{
+ const QList<int> path = indexOf(widget);
+ if (path.isEmpty())
+ return;
+ remove(path);
+}
+
QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
{
Q_ASSERT(!path.isEmpty());
@@ -1028,7 +1034,7 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
if (index < 0)
index = -index - 1;
- if (path.count() > 1) {
+ if (path.size() > 1) {
QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != nullptr);
return item.subinfo->plug(path.mid(1));
@@ -1047,7 +1053,7 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path)
Q_ASSERT(!path.isEmpty());
const int index = path.first();
- if (path.count() > 1) {
+ if (path.size() > 1) {
QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != nullptr);
return item.subinfo->unplug(path.mid(1));
@@ -1124,6 +1130,21 @@ static QRect dockedGeometry(QWidget *widget)
return result;
}
+bool QDockAreaLayoutInfo::hasGapItem(const QList<int> &path) const
+{
+ // empty path has no gap item
+ if (path.isEmpty())
+ return false;
+
+ // Index -1 isn't a gap
+ // Index out of range points at a position to be created. That isn't a gap either.
+ const int index = path.constFirst();
+ if (index < 0 || index >= item_list.count())
+ return false;
+
+ return item_list[index].flags & QDockAreaLayoutItem::GapItem;
+}
+
bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
{
Q_ASSERT(!path.isEmpty());
@@ -1135,9 +1156,7 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid
index = -index - 1;
}
-// dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString());
-
- if (path.count() > 1) {
+ if (path.size() > 1) {
QDockAreaLayoutItem &item = item_list[index];
if (item.subinfo == nullptr
@@ -1219,12 +1238,14 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid
break;
}
} else {
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
continue;
- Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
+ Q_ASSERT_X(!(item.flags & QDockAreaLayoutItem::GapItem),
+ "QDockAreaLayoutInfo::insertGap", "inserting two gaps after each other");
space += item.size - pick(o, item.minimumSize());
+ qCDebug(lcQpaDockWidgets) << "Item space:" << item.flags << this;
}
}
@@ -1249,15 +1270,14 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid
// finally, insert the gap
item_list.insert(index, gap_item);
-
-// dump(qDebug() << "insertGap() after:" << index << tabIndex, *this, QString());
+ qCDebug(lcQpaDockWidgets) << "Insert gap after:" << index << this;
return true;
}
QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget)
{
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
continue;
@@ -1284,9 +1304,9 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path)
int index = path.first();
if (index < 0)
index = -index - 1;
- if (index >= item_list.count())
+ if (index >= item_list.size())
return this;
- if (path.count() == 1 || item_list[index].subinfo == nullptr)
+ if (path.size() == 1 || item_list[index].subinfo == nullptr)
return this;
return item_list[index].subinfo->info(path.mid(1));
}
@@ -1341,7 +1361,7 @@ QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const
Q_ASSERT(!path.isEmpty());
const int index = path.first();
- if (path.count() > 1) {
+ if (path.size() > 1) {
const QDockAreaLayoutItem &item = item_list.at(index);
Q_ASSERT(item.subinfo != nullptr);
return item.subinfo->itemRect(path.mid(1));
@@ -1374,7 +1394,7 @@ QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const
Q_ASSERT(!path.isEmpty());
const int index = path.first();
- if (path.count() > 1) {
+ if (path.size() > 1) {
const QDockAreaLayoutItem &item = item_list.at(index);
Q_ASSERT(item.subinfo != nullptr);
return item.subinfo->separatorRect(path.mid(1));
@@ -1599,7 +1619,7 @@ QRegion QDockAreaLayoutInfo::separatorRegion() const
return result;
#endif
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
@@ -1629,7 +1649,7 @@ void QDockAreaLayoutInfo::paintSeparators(QPainter *p, QWidget *widget,
return;
#endif
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
@@ -1714,7 +1734,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
{
Q_ASSERT(!path.isEmpty());
const int index = path.first();
- if (path.count() > 1) {
+ if (path.size() > 1) {
const QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != nullptr);
return item.subinfo->item(path.mid(1));
@@ -1724,7 +1744,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const
{
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.placeHolderItem != nullptr)
continue;
@@ -1741,7 +1761,7 @@ QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const
QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index)
{
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
QDockAreaLayoutItem &item = item_list[i];
if (item.placeHolderItem != nullptr)
continue;
@@ -1764,9 +1784,29 @@ QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index)
return nullptr;
}
+// Add a dock widget or dock widget group window to the item list
+void QDockAreaLayoutInfo::add(QWidget *widget)
+{
+ // Do not add twice
+ if (!indexOf(widget).isEmpty())
+ return;
+
+ if (auto *dockWidget = qobject_cast<QDockWidget *>(widget)) {
+ item_list.append(QDockAreaLayoutItem(new QDockWidgetItem(dockWidget)));
+ return;
+ }
+
+ if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) {
+ item_list.append(QDockAreaLayoutItem(new QDockWidgetGroupWindowItem(groupWindow)));
+ return;
+ }
+
+ qFatal("Coding error. Add supports only QDockWidget and QDockWidgetGroupWindow");
+}
+
void QDockAreaLayoutInfo::deleteAllLayoutItems()
{
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
QDockAreaLayoutItem &item= item_list[i];
if (item.subinfo) {
item.subinfo->deleteAllLayoutItems();
@@ -1786,7 +1826,7 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
// write the index in item_list of the widget that's currently on top.
quintptr id = currentTabId();
int index = -1;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
if (tabId(item_list.at(i)) == id) {
index = i;
break;
@@ -1799,9 +1839,9 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
stream << (uchar) SequenceMarker;
}
- stream << (uchar) o << int(item_list.count());
+ stream << (uchar) o << int(item_list.size());
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.widgetItem != nullptr) {
stream << (uchar) WidgetMarker;
@@ -1897,7 +1937,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
}
QDockWidget *widget = nullptr;
- for (int j = 0; j < widgets.count(); ++j) {
+ for (int j = 0; j < widgets.size(); ++j) {
if (widgets.at(j)->objectName() == name) {
widget = widgets.takeAt(j);
break;
@@ -1957,6 +1997,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
if (testing) {
//was it is not really added to the layout, we need to delete the object here
delete item.widgetItem;
+ item.widgetItem = nullptr;
}
}
} else if (nextMarker == SequenceMarker) {
@@ -1983,7 +2024,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
}
#if QT_CONFIG(tabbar)
- if (!testing && tabbed && index >= 0 && index < item_list.count()) {
+ if (!testing && tabbed && index >= 0 && index < item_list.size()) {
updateTabBar();
setCurrentTabId(tabId(item_list.at(index)));
}
@@ -2003,7 +2044,7 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
}
int j = 0;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
@@ -2022,14 +2063,20 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
break;
QWidget *sepWidget;
- if (j < separatorWidgets.size() && separatorWidgets.at(j)) {
+ if (j < separatorWidgets.size()) {
sepWidget = separatorWidgets.at(j);
+ if (!sepWidget) {
+ qWarning("QDockAreaLayoutInfo::updateSeparatorWidgets: null separator widget");
+ sepWidget = mainWindowLayout()->getSeparatorWidget();
+ separatorWidgets[j] = sepWidget;
+ }
} else {
sepWidget = mainWindowLayout()->getSeparatorWidget();
separatorWidgets.append(sepWidget);
}
j++;
+ Q_ASSERT(sepWidget);
sepWidget->raise();
QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
@@ -2042,7 +2089,6 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
separatorWidgets[k]->hide();
}
separatorWidgets.resize(j);
- Q_ASSERT(separatorWidgets.size() == j);
}
/*! \internal
@@ -2055,7 +2101,7 @@ void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent)
if (tabBar)
tabBar->setParent(parent);
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.flags & QDockAreaLayoutItem::GapItem)
continue;
@@ -2095,7 +2141,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const
const quintptr oldCurrentId = currentTabId();
int tab_idx = 0;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.skip())
continue;
@@ -2160,7 +2206,7 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape)
if (tabBar != nullptr)
tabBar->setShape(static_cast<QTabBar::Shape>(shape));
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
QDockAreaLayoutItem &item = item_list[i];
if (item.subinfo != nullptr)
item.subinfo->setTabBarShape(shape);
@@ -2192,7 +2238,7 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const
result.insert(tabBar);
}
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.subinfo != nullptr)
result += item.subinfo->usedTabBars();
@@ -2206,13 +2252,13 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const
QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const
{
QSet<QWidget*> result;
- const int numSeparatorWidgets = separatorWidgets.count();
+ const int numSeparatorWidgets = separatorWidgets.size();
result.reserve(numSeparatorWidgets);
for (int i = 0; i < numSeparatorWidgets; ++i)
result << separatorWidgets.at(i);
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
const QDockAreaLayoutItem &item = item_list.at(i);
if (item.subinfo != nullptr)
result += item.subinfo->usedSeparatorWidgets();
@@ -2259,7 +2305,7 @@ int QDockAreaLayoutInfo::tabIndexToListIndex(int tabIndex) const
{
Q_ASSERT(tabbed && tabBar);
quintptr data = qvariant_cast<quintptr>(tabBar->tabData(tabIndex));
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
if (tabId(item_list.at(i)) == data)
return i;
}
@@ -2429,23 +2475,7 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const
const QDockAreaLayoutInfo &info = docks[i];
if (info.isEmpty()) {
- QRect r;
- switch (i) {
- case QInternal::LeftDock:
- r = QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height());
- break;
- case QInternal::RightDock:
- r = QRect(rect.right() - EmptyDropAreaSize, rect.top(),
- EmptyDropAreaSize, rect.height());
- break;
- case QInternal::TopDock:
- r = QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize);
- break;
- case QInternal::BottomDock:
- r = QRect(rect.left(), rect.bottom() - EmptyDropAreaSize,
- rect.width(), EmptyDropAreaSize);
- break;
- }
+ const QRect r = gapRect(static_cast<QInternal::DockPosition>(i));
if (r.contains(pos)) {
if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) {
//in case of ForceTabbedDocks, we pass -1 in order to force the gap to be tabbed
@@ -2461,6 +2491,43 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const
return QList<int>();
}
+QRect QDockAreaLayout::gapRect(QInternal::DockPosition dockPos) const
+{
+ Q_ASSERT_X(mainWindow, "QDockAreaLayout::gapRect", "Called without valid mainWindow pointer.");
+
+ // Determine gap size depending on MainWindow size (QTBUG-101657)
+ const QSize gapSize = (mainWindow->size()/2).boundedTo(QSize(EmptyDropAreaSize, EmptyDropAreaSize));
+
+ // Warn if main window is too small to create proper docks.
+ // Do not fail because this can be triggered by a user making MainWindow too small
+ if (mainWindow->height() < (2 * sep)) {
+ qCWarning(lcQpaDockWidgets,
+ "QDockAreaLayout::gapRect: Main window height %i is too small. Docking will not be possible.",
+ mainWindow->height());
+
+ }
+ if (mainWindow->width() < (2 * sep)) {
+ qCWarning(lcQpaDockWidgets,
+ "QDockAreaLayout::gapRect: Main window width %i is too small. Docking will not be possible.",
+ mainWindow->width());
+ }
+
+ // Calculate rectangle of requested dock
+ switch (dockPos) {
+ case QInternal::LeftDock:
+ return QRect(rect.left(), rect.top(), gapSize.width(), rect.height());
+ case QInternal::RightDock:
+ return QRect(rect.right() - gapSize.width(), rect.top(), gapSize.width(), rect.height());
+ case QInternal::TopDock:
+ return QRect(rect.left(), rect.top(), rect.width(), gapSize.height());
+ case QInternal::BottomDock:
+ return QRect(rect.left(), rect.bottom() - gapSize.height(), rect.width(), gapSize.height());
+ case QInternal::DockCount:
+ break;
+ }
+ return QRect();
+}
+
QList<int> QDockAreaLayout::findSeparator(const QPoint &pos) const
{
QList<int> result;
@@ -2502,7 +2569,7 @@ QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path)
const int index = path.first();
Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- if (path.count() == 1)
+ if (path.size() == 1)
return &docks[index];
return docks[index].info(path.mid(1));
@@ -2557,7 +2624,7 @@ QRect QDockAreaLayout::separatorRect(const QList<int> &path) const
const int index = path.first();
Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- if (path.count() == 1)
+ if (path.size() == 1)
return separatorRect(index);
else
return docks[index].separatorRect(path.mid(1));
@@ -2607,7 +2674,7 @@ void QDockAreaLayout::removePlaceHolder(const QString &name)
if (!index.isEmpty())
remove(index);
const auto groups =
- mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups) {
index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
if (!index.isEmpty()) {
@@ -2914,7 +2981,8 @@ void QDockAreaLayout::clear()
centralWidgetRect = QRect();
}
-QSize QDockAreaLayout::sizeHint() const
+template<typename SizePMF, typename CenterPMF>
+QSize QDockAreaLayout::size_helper(SizePMF sizeFn, CenterPMF centerFn) const
{
int left_sep = 0;
int right_sep = 0;
@@ -2928,11 +2996,12 @@ QSize QDockAreaLayout::sizeHint() const
bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
}
- QSize left = docks[QInternal::LeftDock].sizeHint() + QSize(left_sep, 0);
- QSize right = docks[QInternal::RightDock].sizeHint() + QSize(right_sep, 0);
- QSize top = docks[QInternal::TopDock].sizeHint() + QSize(0, top_sep);
- QSize bottom = docks[QInternal::BottomDock].sizeHint() + QSize(0, bottom_sep);
- QSize center = centralWidgetItem == nullptr ? QSize(0, 0) : centralWidgetItem->sizeHint();
+ const QSize left = (docks[QInternal::LeftDock].*sizeFn)() + QSize(left_sep, 0);
+ const QSize right = (docks[QInternal::RightDock].*sizeFn)() + QSize(right_sep, 0);
+ const QSize top = (docks[QInternal::TopDock].*sizeFn)() + QSize(0, top_sep);
+ const QSize bottom = (docks[QInternal::BottomDock].*sizeFn)() + QSize(0, bottom_sep);
+ const QSize center = centralWidgetItem == nullptr
+ ? QSize(0, 0) : (centralWidgetItem->*centerFn)();
int row1 = top.width();
int row2 = left.width() + center.width() + right.width();
@@ -2964,54 +3033,24 @@ QSize QDockAreaLayout::sizeHint() const
return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
}
-QSize QDockAreaLayout::minimumSize() const
+QSize QDockAreaLayout::sizeHint() const
{
- int left_sep = 0;
- int right_sep = 0;
- int top_sep = 0;
- int bottom_sep = 0;
-
- if (centralWidgetItem != nullptr) {
- left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
- right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
- top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
- bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
- }
-
- QSize left = docks[QInternal::LeftDock].minimumSize() + QSize(left_sep, 0);
- QSize right = docks[QInternal::RightDock].minimumSize() + QSize(right_sep, 0);
- QSize top = docks[QInternal::TopDock].minimumSize() + QSize(0, top_sep);
- QSize bottom = docks[QInternal::BottomDock].minimumSize() + QSize(0, bottom_sep);
- QSize center = centralWidgetItem == nullptr ? QSize(0, 0) : centralWidgetItem->minimumSize();
-
- int row1 = top.width();
- int row2 = left.width() + center.width() + right.width();
- int row3 = bottom.width();
- int col1 = left.height();
- int col2 = top.height() + center.height() + bottom.height();
- int col3 = right.height();
-
- if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
- row1 += left.width();
- else
- col1 += top.height();
-
- if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
- row1 += right.width();
- else
- col3 += top.height();
+ return size_helper(&QDockAreaLayoutInfo::sizeHint, &QLayoutItem::sizeHint);
+}
- if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
- row3 += left.width();
- else
- col1 += bottom.height();
+QSize QDockAreaLayout::minimumSize() const
+{
+ return size_helper(&QDockAreaLayoutInfo::minimumSize, &QLayoutItem::minimumSize);
+}
- if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
- row3 += right.width();
- else
- col3 += bottom.height();
+/*!
+ \internal
- return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
+ Returns the smallest size that doesn't change the size of any of the dock areas.
+*/
+QSize QDockAreaLayout::minimumStableSize() const
+{
+ return size_helper(&QDockAreaLayoutInfo::size, &QLayoutItem::minimumSize);
}
/*! \internal
@@ -3022,10 +3061,10 @@ QSize QDockAreaLayout::minimumSize() const
*/
QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
{
- QScreen *screen;
+ QScreen *screen = nullptr;
if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1)
screen = QGuiApplication::screenAt(rect.topLeft());
- else
+ if (!screen)
screen = widget->screen();
const QRect screenRect = screen->geometry();
@@ -3045,7 +3084,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
{
QDockAreaLayoutItem *item = nullptr;
const auto groups =
- mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
if (!index.isEmpty()) {
@@ -3083,7 +3122,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do
{
QLayoutItem *dockWidgetItem = new QDockWidgetItem(dockWidget);
QDockAreaLayoutInfo &info = docks[pos];
- if (orientation == info.o || info.item_list.count() <= 1) {
+ if (orientation == info.o || info.item_list.size() <= 1) {
// empty dock areas, or dock areas containing exactly one widget can have their orientation
// switched.
info.o = orientation;
@@ -3129,11 +3168,11 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
const QList<int> &sizes, Qt::Orientation o)
{
- if (Q_UNLIKELY(docks.count() != sizes.count())) {
+ if (Q_UNLIKELY(docks.size() != sizes.size())) {
qWarning("QMainWidget::resizeDocks: size of the lists are not the same");
return;
}
- int count = docks.count();
+ int count = docks.size();
fallbackToSizeHints = false;
for (int i = 0; i < count; ++i) {
QList<int> path = indexOf(docks[i]);
@@ -3153,7 +3192,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
if (!info->tabbed && info->o == o) {
info->item_list[path.constLast()].size = size;
int totalSize = 0;
- for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) {
+ for (const QDockAreaLayoutItem &item : std::as_const(info->item_list)) {
if (!item.skip()) {
if (totalSize != 0)
totalSize += sep;
@@ -3246,7 +3285,7 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or
int delta = 0;
int index = separator.last();
- if (separator.count() > 1) {
+ if (separator.size() > 1) {
QDockAreaLayoutInfo *info = this->info(separator);
delta = pick(info->o, dest - origin);
if (delta != 0)
@@ -3298,7 +3337,7 @@ int QDockAreaLayoutInfo::separatorMove(const QList<int> &separator, const QPoint
#if QT_CONFIG(tabbar)
// Sets the correct positions for the separator widgets
-// Allocates new sepearator widgets with getSeparatorWidget
+// Allocates new separator widgets with getSeparatorWidget
void QDockAreaLayout::updateSeparatorWidgets() const
{
int j = 0;
@@ -3311,12 +3350,18 @@ void QDockAreaLayout::updateSeparatorWidgets() const
QWidget *sepWidget;
if (j < separatorWidgets.size()) {
sepWidget = separatorWidgets.at(j);
+ if (!sepWidget) {
+ qWarning("QDockAreaLayout::updateSeparatorWidgets: null separator widget");
+ sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
+ separatorWidgets[j] = sepWidget;
+ }
} else {
sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
separatorWidgets.append(sepWidget);
}
j++;
+ Q_ASSERT(sepWidget);
sepWidget->raise();
QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
@@ -3387,7 +3432,7 @@ QSet<QTabBar*> QDockAreaLayout::usedTabBars() const
QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
{
QSet<QWidget*> result;
- const int numSeparators = separatorWidgets.count();
+ const int numSeparators = separatorWidgets.size();
result.reserve(numSeparators);
for (int i = 0; i < numSeparators; ++i)
result << separatorWidgets.at(i);
@@ -3405,7 +3450,7 @@ QRect QDockAreaLayout::gapRect(const QList<int> &path) const
if (info == nullptr)
return QRect();
int index = path.last();
- if (index < 0 || index >= info->item_list.count())
+ if (index < 0 || index >= info->item_list.size())
return QRect();
return info->itemRect(index, true);
}
diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h
index 171147c254..aa39bf9913 100644
--- a/src/widgets/widgets/qdockarealayout_p.h
+++ b/src/widgets/widgets/qdockarealayout_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDOCKAREALAYOUT_P_H
#define QDOCKAREALAYOUT_P_H
@@ -54,7 +18,6 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include "QtWidgets/qlayout.h"
#include "QtCore/qlist.h"
-#include "QtCore/qpair.h"
#include "QtCore/qrect.h"
QT_REQUIRE_CONFIG(dockwidget);
@@ -84,7 +47,7 @@ class QTabBar;
// A path indetifies uniquely one object in this tree, the first number being the side and all the following
// indexes into the QDockAreaLayoutInfo::item_list.
-struct QDockAreaLayoutItem
+struct Q_AUTOTEST_EXPORT QDockAreaLayoutItem
{
enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
@@ -109,6 +72,10 @@ struct QDockAreaLayoutItem
int pos;
int size;
uint flags;
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_AUTOTEST_EXPORT QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem &item);
+ friend Q_AUTOTEST_EXPORT QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem *item);
+#endif
};
class Q_AUTOTEST_EXPORT QPlaceHolderItem
@@ -141,6 +108,7 @@ public:
QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
TabMode tabMode) const;
void remove(const QList<int> &path);
+ void remove(QWidget *widget);
void unnest(int index);
void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
#if QT_CONFIG(tabbar)
@@ -168,6 +136,7 @@ public:
void clear();
bool isEmpty() const;
+ bool hasGapItem(const QList<int> &path) const;
bool onlyHasPlaceholders() const;
bool hasFixedSize() const;
QList<int> findSeparator(const QPoint &pos) const;
@@ -187,6 +156,7 @@ public:
QLayoutItem *itemAt(int *x, int index) const;
QLayoutItem *takeAt(int *x, int index);
+ void add(QWidget *widget);
void deleteAllLayoutItems();
QMainWindowLayout *mainWindowLayout() const;
@@ -235,7 +205,7 @@ public:
QRect centralWidgetRect;
QDockAreaLayout(QMainWindow *win);
QDockAreaLayoutInfo docks[4];
- int sep; // separator extent
+ int sep; // margin between a dock widget and its frame
bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the separator is moved by user)
mutable QList<QWidget *> separatorWidgets;
@@ -271,6 +241,9 @@ public:
QSize sizeHint() const;
QSize minimumSize() const;
+ QSize minimumStableSize() const;
+ template<typename SizePMF, typename CenterPMF>
+ QSize size_helper(SizePMF sizeFn, CenterPMF centerFn) const;
void addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget, Qt::Orientation orientation);
bool restoreDockWidget(QDockWidget *dockWidget);
@@ -299,6 +272,7 @@ public:
void setGrid(QList<QLayoutStruct> *ver_struct_list, QList<QLayoutStruct> *hor_struct_list);
QRect gapRect(const QList<int> &path) const;
+ QRect gapRect(QInternal::DockPosition dockPos) const;
void keepSize(QDockWidget *w);
#if QT_CONFIG(tabbar)
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 548078098c..706306000c 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdockwidget.h"
@@ -56,11 +20,14 @@
#include <private/qstylesheetstyle_p.h>
#include <qpa/qplatformtheme.h>
+#include <private/qhighdpiscaling_p.h>
#include "qdockwidget_p.h"
#include "qmainwindowlayout_p.h"
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp
// qmainwindow.cpp
@@ -152,7 +119,7 @@ bool QDockWidgetTitleButton::event(QEvent *event)
{
switch (event->type()) {
case QEvent::StyleChange:
- case QEvent::ScreenChangeInternal:
+ case QEvent::DevicePixelRatioChange:
m_iconSize = -1;
break;
default:
@@ -161,33 +128,12 @@ bool QDockWidgetTitleButton::event(QEvent *event)
return QAbstractButton::event(event);
}
-static inline bool isWindowsStyle(const QStyle *style)
-{
- // Note: QStyleSheetStyle inherits QWindowsStyle
- const QStyle *effectiveStyle = style;
-
-#if QT_CONFIG(style_stylesheet)
- if (style->inherits("QStyleSheetStyle"))
- effectiveStyle = static_cast<const QStyleSheetStyle *>(style)->baseStyle();
-#endif
-#if !defined(QT_NO_STYLE_PROXY)
- if (style->inherits("QProxyStyle"))
- effectiveStyle = static_cast<const QProxyStyle *>(style)->baseStyle();
-#endif
-
- return effectiveStyle->inherits("QWindowsStyle");
-}
-
QSize QDockWidgetTitleButton::dockButtonIconSize() const
{
if (m_iconSize < 0) {
m_iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
- // Dock Widget title buttons on Windows where historically limited to size 10
- // (from small icon size 16) since only a 10x10 XPM was provided.
- // Adding larger pixmaps to the icons thus caused the icons to grow; limit
- // this to qpiScaled(10) here.
- if (isWindowsStyle(style()))
- m_iconSize = qMin((10 * logicalDpiX()) / 96, m_iconSize);
+ if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this))
+ m_iconSize = (m_iconSize * 5) / 8; // 16 -> 10
}
return QSize(m_iconSize, m_iconSize);
}
@@ -219,21 +165,23 @@ void QDockWidgetTitleButton::leaveEvent(QEvent *event)
void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
{
- QPainter p(this);
+ QStylePainter p(this);
QStyleOptionToolButton opt;
opt.initFrom(this);
opt.state |= QStyle::State_AutoRaise;
- if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this))
- {
+ if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this)) {
if (isEnabled() && underMouse() && !isChecked() && !isDown())
opt.state |= QStyle::State_Raised;
if (isChecked())
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;
}
opt.icon = icon();
@@ -242,7 +190,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);
}
/******************************************************************************
@@ -283,8 +231,10 @@ bool QDockWidgetLayout::wmSupportsNativeWindowDeco()
#if defined(Q_OS_ANDROID)
return false;
#else
- static const bool xcb = !QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive);
- return !xcb;
+ static const bool xcb = !QGuiApplication::platformName().compare("xcb"_L1, Qt::CaseInsensitive);
+ static const bool wayland =
+ QGuiApplication::platformName().startsWith("wayland"_L1, Qt::CaseInsensitive);
+ return !(xcb || wayland);
#endif
}
@@ -308,7 +258,7 @@ void QDockWidgetLayout::addItem(QLayoutItem*)
QLayoutItem *QDockWidgetLayout::itemAt(int index) const
{
int cnt = 0;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
QLayoutItem *item = item_list.at(i);
if (item == nullptr)
continue;
@@ -321,7 +271,7 @@ QLayoutItem *QDockWidgetLayout::itemAt(int index) const
QLayoutItem *QDockWidgetLayout::takeAt(int index)
{
int j = 0;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
QLayoutItem *item = item_list.at(i);
if (item == nullptr)
continue;
@@ -338,7 +288,7 @@ QLayoutItem *QDockWidgetLayout::takeAt(int index)
int QDockWidgetLayout::count() const
{
int result = 0;
- for (int i = 0; i < item_list.count(); ++i) {
+ for (int i = 0; i < item_list.size(); ++i) {
if (item_list.at(i))
++result;
}
@@ -657,13 +607,14 @@ void QDockWidgetPrivate::init()
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
QAbstractButton *button = new QDockWidgetTitleButton(q);
- button->setObjectName(QLatin1String("qt_dockwidget_floatbutton"));
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel()));
+ button->setObjectName("qt_dockwidget_floatbutton"_L1);
+ QObjectPrivate::connect(button, &QAbstractButton::clicked,
+ this, &QDockWidgetPrivate::toggleTopLevel);
layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button);
button = new QDockWidgetTitleButton(q);
- button->setObjectName(QLatin1String("qt_dockwidget_closebutton"));
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
+ button->setObjectName("qt_dockwidget_closebutton"_L1);
+ QObject::connect(button, &QAbstractButton::clicked, q, &QDockWidget::close);
layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);
font = QApplication::font("QDockWidgetTitle");
@@ -674,8 +625,8 @@ void QDockWidgetPrivate::init()
toggleViewAction->setMenuRole(QAction::NoRole);
fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
toggleViewAction->setText(fixedWindowTitle);
- QObject::connect(toggleViewAction, SIGNAL(triggered(bool)),
- q, SLOT(_q_toggleView(bool)));
+ QObjectPrivate::connect(toggleViewAction, &QAction::triggered,
+ this, &QDockWidgetPrivate::toggleView);
#endif
updateButtons();
@@ -710,7 +661,7 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
option->verticalTitleBar = l->verticalTitleBar;
}
-void QDockWidgetPrivate::_q_toggleView(bool b)
+void QDockWidgetPrivate::toggleView(bool b)
{
Q_Q(QDockWidget);
if (b == q->isHidden()) {
@@ -740,7 +691,7 @@ void QDockWidgetPrivate::updateButtons()
= qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
button->setVisible(canFloat && !hideButtons);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
//: Accessible name for button undocking a dock widget (floating state)
button->setAccessibleName(QDockWidget::tr("Float"));
button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
@@ -749,7 +700,7 @@ void QDockWidgetPrivate::updateButtons()
= qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
button->setVisible(canClose && !hideButtons);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
//: Accessible name for button closing a dock widget
button->setAccessibleName(QDockWidget::tr("Close"));
button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
@@ -758,7 +709,7 @@ void QDockWidgetPrivate::updateButtons()
layout->invalidate();
}
-void QDockWidgetPrivate::_q_toggleTopLevel()
+void QDockWidgetPrivate::toggleTopLevel()
{
Q_Q(QDockWidget);
q->setFloating(!q->isFloating());
@@ -784,6 +735,8 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
state = new QDockWidgetPrivate::DragState;
state->pressPos = pos;
+ state->globalPressPos = q->mapToGlobal(pos);
+ state->widgetInitialPos = q->isFloating() ? q->pos() : q->mapToGlobal(QPoint(0, 0));
state->dragging = false;
state->widgetItem = nullptr;
state->ownWidgetItem = false;
@@ -797,7 +750,7 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
tabbed widgets, and false if the dock widget should always be dragged
alone.
*/
-void QDockWidgetPrivate::startDrag(bool group)
+void QDockWidgetPrivate::startDrag(DragScope scope)
{
Q_Q(QDockWidget);
@@ -807,12 +760,16 @@ void QDockWidgetPrivate::startDrag(bool group)
QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q);
Q_ASSERT(layout != nullptr);
- state->widgetItem = layout->unplug(q, group);
+#if QT_CONFIG(draganddrop)
+ bool wasFloating = q->isFloating();
+#endif
+
+ state->widgetItem = layout->unplug(q, scope);
if (state->widgetItem == nullptr) {
- /* I have a QMainWindow parent, but I was never inserted with
+ /* Dock widget has a QMainWindow parent, but was never inserted with
QMainWindow::addDockWidget, so the QMainWindowLayout has no
- widget item for me. :( I have to create it myself, and then
- delete it if I don't get dropped into a dock area. */
+ widget item for it. It will be newly created and deleted if it doesn't
+ get dropped into a dock area. */
QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
if (floatingTab && !q->isFloating())
state->widgetItem = new QDockWidgetGroupWindowItem(floatingTab);
@@ -825,6 +782,20 @@ void QDockWidgetPrivate::startDrag(bool group)
layout->restore();
state->dragging = true;
+
+#if QT_CONFIG(draganddrop)
+ if (QMainWindowLayout::needsPlatformDrag()) {
+ Qt::DropAction result =
+ layout->performPlatformWidgetDrag(state->widgetItem, state->pressPos);
+ if (result == Qt::IgnoreAction && !wasFloating) {
+ layout->revert(state->widgetItem);
+ delete state;
+ state = nullptr;
+ } else {
+ endDrag(QDockWidgetPrivate::EndDragMode::LocationChange);
+ }
+ }
+#endif
}
/*! \internal
@@ -832,7 +803,7 @@ void QDockWidgetPrivate::startDrag(bool group)
The \a abort parameter specifies that it ends because of programmatic state
reset rather than mouse release event.
*/
-void QDockWidgetPrivate::endDrag(bool abort)
+void QDockWidgetPrivate::endDrag(EndDragMode mode)
{
Q_Q(QDockWidget);
Q_ASSERT(state != nullptr);
@@ -844,7 +815,11 @@ void QDockWidgetPrivate::endDrag(bool abort)
Q_ASSERT(mainWindow != nullptr);
QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
- if (abort || !mwLayout->plug(state->widgetItem)) {
+ // if mainWindow is being deleted in an ongoing drag, make it a no-op instead of crashing
+ if (!mwLayout)
+ return;
+
+ if (mode == EndDragMode::Abort || !mwLayout->plug(state->widgetItem)) {
if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
// This QDockWidget will now stay in the floating state.
if (state->ownWidgetItem) {
@@ -866,8 +841,21 @@ void QDockWidgetPrivate::endDrag(bool abort)
if (q->isFloating()) { // Might not be floating when dragging a QDockWidgetGroupWindow
undockedGeometry = q->geometry();
#if QT_CONFIG(tabwidget)
- tabPosition = mwLayout->tabPosition(mainWindow->dockWidgetArea(q));
+ // is the widget located within the mainwindow?
+ const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(q);
+ if (area != Qt::NoDockWidgetArea) {
+ tabPosition = mwLayout->tabPosition(area);
+ } else if (auto dwgw = qobject_cast<QDockWidgetGroupWindow *>(q->parent())) {
+ // DockWidget wasn't found in one of the docks within mainwindow
+ // => derive tabPosition from parent
+ tabPosition = mwLayout->tabPosition(toDockWidgetArea(dwgw->layoutInfo()->dockPos));
+ }
#endif
+ // Reparent, if the drag was out of a dock widget group window
+ if (mode == EndDragMode::LocationChange) {
+ if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(q->parentWidget()))
+ groupWindow->reparent(q);
+ }
}
q->activateWindow();
} else {
@@ -881,9 +869,25 @@ void QDockWidgetPrivate::endDrag(bool abort)
state = nullptr;
}
+Qt::DockWidgetArea QDockWidgetPrivate::toDockWidgetArea(QInternal::DockPosition pos)
+{
+ switch (pos) {
+ case QInternal::LeftDock: return Qt::LeftDockWidgetArea;
+ case QInternal::RightDock: return Qt::RightDockWidgetArea;
+ case QInternal::TopDock: return Qt::TopDockWidgetArea;
+ case QInternal::BottomDock: return Qt::BottomDockWidgetArea;
+ default: break;
+ }
+ return Qt::NoDockWidgetArea;
+}
+
void QDockWidgetPrivate::setResizerActive(bool active)
{
Q_Q(QDockWidget);
+ const auto *dwLayout = qobject_cast<QDockWidgetLayout *>(layout);
+ if (dwLayout->nativeWindowDeco(q->isFloating()))
+ return;
+
if (active && !resizer)
resizer = new QWidgetResizeHandler(q);
if (resizer)
@@ -946,13 +950,22 @@ bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event)
if (event->button() == Qt::LeftButton && titleArea.contains(event->position().toPoint()) &&
hasFeature(this, QDockWidget::DockWidgetFloatable)) {
- _q_toggleTopLevel();
+ toggleTopLevel();
return true;
}
}
return false;
}
+bool QDockWidgetPrivate::isTabbed() const
+{
+ Q_Q(const QDockWidget);
+ QDockWidget *that = const_cast<QDockWidget *>(q);
+ auto *mwLayout = qt_mainwindow_layout_from_dock(that);
+ Q_ASSERT(mwLayout);
+ return mwLayout->isDockWidgetTabbed(q);
+}
+
bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
{
bool ret = false;
@@ -970,23 +983,71 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
&& mwlayout->pluggingWidget == nullptr
&& (event->position().toPoint() - state->pressPos).manhattanLength()
> QApplication::startDragDistance()) {
- startDrag();
- q->grabMouse();
- ret = true;
+
+#ifdef Q_OS_MACOS
+ if (windowHandle() && !q->isFloating()) {
+ // When using native widgets on mac, we have not yet been successful in
+ // starting a drag on an NSView that belongs to one window (QMainWindow),
+ // but continue the drag on another (QDockWidget). This is what happens if
+ // we try to make this widget floating during a drag. So as a fall back
+ // solution, we simply make this widget floating instead, when we would
+ // otherwise start a drag.
+ q->setFloating(true);
+ } else
+#endif
+ {
+ const DragScope scope = isTabbed() ? DragScope::Group : DragScope::Widget;
+ startDrag(scope);
+ q->grabMouse();
+ ret = true;
+ }
}
}
- if (state->dragging && !state->nca) {
+ if (state && state->dragging && !state->nca) {
QMargins windowMargins = q->window()->windowHandle()->frameMargins();
QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top());
- QPoint pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
+
+ // TODO maybe use QScreen API (if/when available) to simplify the below code.
+ const QScreen *orgWdgScreen = QGuiApplication::screenAt(state->widgetInitialPos);
+ const QScreen *screenFrom = QGuiApplication::screenAt(state->globalPressPos);
+ const QScreen *screenTo = QGuiApplication::screenAt(event->globalPosition().toPoint());
+ const QScreen *wdgScreen = q->screen();
+
+ QPoint pos;
+ if (Q_LIKELY(screenFrom && screenTo && wdgScreen && orgWdgScreen)) {
+ const QPoint nativeWdgOrgPos = QHighDpiScaling::mapPositionToNative(
+ state->widgetInitialPos, orgWdgScreen->handle());
+ const QPoint nativeTo = QHighDpiScaling::mapPositionToNative(
+ event->globalPosition().toPoint(), screenTo->handle());
+ const QPoint nativeFrom = QHighDpiScaling::mapPositionToNative(state->globalPressPos,
+ screenFrom->handle());
+
+ // Calculate new nativePos based on startPos + mouse delta move.
+ const QPoint nativeNewPos = nativeWdgOrgPos + (nativeTo - nativeFrom);
+ pos = QHighDpiScaling::mapPositionFromNative(nativeNewPos, wdgScreen->handle())
+ - windowMarginOffset;
+ } else {
+ // Fallback in the unlikely case that source and target screens could not be established
+ qCDebug(lcQpaDockWidgets)
+ << "QDockWidget failed to find relevant screen info. screenFrom:" << screenFrom
+ << "screenTo:" << screenTo << " wdgScreen:" << wdgScreen << "orgWdgScreen"
+ << orgWdgScreen;
+ pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
+ }
+
+ // If the newly floating dock widget has got a native title bar,
+ // offset the position by the native title bar's height or width
+ const int dx = q->geometry().x() - q->x();
+ const int dy = q->geometry().y() - q->y();
+ pos.rx() += dx;
+ pos.ry() += dy;
QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
if (floatingTab && !q->isFloating())
floatingTab->move(pos);
else
q->move(pos);
-
if (state && !state->ctrlDrag)
mwlayout->hover(state->widgetItem, event->globalPosition().toPoint());
@@ -1000,9 +1061,15 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
bool QDockWidgetPrivate::mouseReleaseEvent(QMouseEvent *event)
{
#if QT_CONFIG(mainwindow)
+#if QT_CONFIG(draganddrop)
+ // if we are peforming a platform drag ignore the release here and end the drag when the actual
+ // drag ends.
+ if (QMainWindowLayout::needsPlatformDrag())
+ return false;
+#endif
if (event->button() == Qt::LeftButton && state && !state->nca) {
- endDrag();
+ endDrag(EndDragMode::LocationChange);
return true; //filter out the event
}
@@ -1041,26 +1108,25 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
break;
state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
(!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
- startDrag();
+ startDrag(DragScope::Group);
break;
case QEvent::NonClientAreaMouseMove:
if (state == nullptr || !state->dragging)
break;
-#ifndef Q_OS_MAC
- if (state->nca) {
- endDrag();
- }
+#if !defined(Q_OS_MAC) && !defined(Q_OS_WASM)
+ if (state->nca)
+ endDrag(EndDragMode::LocationChange);
#endif
break;
case QEvent::NonClientAreaMouseButtonRelease:
-#ifdef Q_OS_MAC
+#if defined(Q_OS_MAC) || defined(Q_OS_WASM)
if (state)
- endDrag();
+ endDrag(EndDragMode::LocationChange);
#endif
break;
case QEvent::NonClientAreaMouseButtonDblClick:
- _q_toggleTopLevel();
+ toggleTopLevel();
break;
default:
break;
@@ -1126,10 +1192,10 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
return; // this dockwidget can't be redocked
}
- bool wasFloating = q->isFloating();
+ const bool wasFloating = q->isFloating();
if (wasFloating) // Prevent repetitive unplugging from nested invocations (QTBUG-42818)
unplug = false;
- bool hidden = q->isHidden();
+ const bool hidden = q->isHidden();
if (q->isVisible())
q->hide();
@@ -1147,8 +1213,12 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
flags |= Qt::FramelessWindowHint;
}
- if (unplug)
+#if QT_CONFIG(draganddrop)
+ // If we are performing a platform drag the flag is not needed and we want to avoid recreating
+ // the platform window when it would be removed later
+ if (unplug && !QMainWindowLayout::needsPlatformDrag())
flags |= Qt::X11BypassWindowManagerHint;
+#endif
q->setWindowFlags(flags);
@@ -1219,15 +1289,18 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
on whether it is docked; a docked QDockWidget has no frame and a smaller title
bar.
- \sa QMainWindow, {Dock Widgets Example}
+ \note On macOS, if the QDockWidget has a native window handle (for example,
+ if winId() is called on it or the child widget), then due to a limitation it will not be
+ possible to drag the dock widget when undocking. Starting the drag will undock
+ the dock widget, but a second drag will be needed to move the dock widget itself.
+
+ \sa QMainWindow
*/
/*!
\enum QDockWidget::DockWidgetFeature
- \value DockWidgetClosable The dock widget can be closed. On some systems the dock
- widget always has a close button when it's floating
- (for example on MacOS 10.5).
+ \value DockWidgetClosable The dock widget can be closed.
\value DockWidgetMovable The dock widget can be moved between docks
by the user.
\value DockWidgetFloatable The dock widget can be detached from the
@@ -1359,9 +1432,12 @@ QDockWidget::DockWidgetFeatures QDockWidget::features() const
\property QDockWidget::floating
\brief whether the dock widget is floating
- A floating dock widget is presented to the user as an independent
- window "on top" of its parent QMainWindow, instead of being
- docked in the QMainWindow.
+ A floating dock widget is presented to the user as a single, independent
+ window "on top" of its parent QMainWindow, instead of being docked
+ either in the QMainWindow, or in a group of tabbed dock widgets.
+
+ Floating dock widgets can be individually positioned and resized, both
+ programmatically or by mouse interaction.
By default, this property is \c true.
@@ -1375,7 +1451,7 @@ void QDockWidget::setFloating(bool floating)
// the initial click of a double-click may have started a drag...
if (d->state != nullptr)
- d->endDrag(true);
+ d->endDrag(QDockWidgetPrivate::EndDragMode::Abort);
QRect r = d->undockedGeometry;
// Keep position when undocking for the first time.
@@ -1430,8 +1506,14 @@ void QDockWidget::changeEvent(QEvent *event)
QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
switch (event->type()) {
- case QEvent::ModifiedChange:
case QEvent::WindowTitleChange:
+ if (isFloating() && windowHandle() && d->topData() && windowHandle()->isVisible()) {
+ // From QWidget::setWindowTitle(): Propagate window title without signal emission
+ d->topData()->caption = windowHandle()->title();
+ d->setWindowTitle_helper(windowHandle()->title());
+ }
+ Q_FALLTHROUGH();
+ case QEvent::ModifiedChange:
update(layout->titleArea());
#ifndef QT_NO_ACTION
d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
@@ -1457,8 +1539,14 @@ void QDockWidget::closeEvent(QCloseEvent *event)
{
Q_D(QDockWidget);
if (d->state)
- d->endDrag(true);
- QWidget::closeEvent(event);
+ d->endDrag(QDockWidgetPrivate::EndDragMode::Abort);
+
+ // For non-closable widgets, don't allow closing, except when the mainwindow
+ // is hidden, as otherwise an application wouldn't be able to be shut down.
+ const QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
+ const bool canClose = (d->features & DockWidgetClosable)
+ || (!win || !win->isVisible());
+ event->setAccepted(canClose);
}
/*! \reimp */
@@ -1534,7 +1622,7 @@ bool QDockWidget::event(QEvent *event)
bool onTop = false;
if (win != nullptr) {
const QObjectList &siblings = win->children();
- onTop = siblings.count() > 0 && siblings.last() == (QObject*)this;
+ onTop = siblings.size() > 0 && siblings.last() == (QObject*)this;
}
#if QT_CONFIG(tabbar)
if (!isFloating() && layout != nullptr && onTop)
@@ -1648,6 +1736,10 @@ QAction * QDockWidget::toggleViewAction() const
invisible). This happens when the widget is hidden or shown, as
well as when it is docked in a tabbed dock area and its tab
becomes selected or unselected.
+
+ \note The signal can differ from QWidget::isVisible(). This can be the case, if
+ a dock widget is minimized or tabified and associated to a non-selected or
+ inactive tab.
*/
/*!
@@ -1729,6 +1821,26 @@ QWidget *QDockWidget::titleBarWidget() const
return layout->widgetForRole(QDockWidgetLayout::TitleBar);
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QDockWidget *dockWidget)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+
+ if (!dockWidget) {
+ dbg << "QDockWidget(0x0)";
+ return dbg;
+ }
+
+ dbg << "QDockWidget(" << static_cast<const void *>(dockWidget);
+ dbg << "->(ObjectName=" << dockWidget->objectName();
+ dbg << "; floating=" << dockWidget->isFloating();
+ dbg << "; features=" << dockWidget->features();
+ dbg << ";))";
+ return dbg;
+}
+#endif // QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
#include "qdockwidget.moc"
diff --git a/src/widgets/widgets/qdockwidget.h b/src/widgets/widgets/qdockwidget.h
index 69c5a6447a..2efa1d3c2f 100644
--- a/src/widgets/widgets/qdockwidget.h
+++ b/src/widgets/widgets/qdockwidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICDOCKWIDGET_H
#define QDYNAMICDOCKWIDGET_H
@@ -56,7 +20,7 @@ class Q_WIDGETS_EXPORT QDockWidget : public QWidget
{
Q_OBJECT
- Q_PROPERTY(bool floating READ isFloating WRITE setFloating)
+ Q_PROPERTY(bool floating READ isFloating WRITE setFloating NOTIFY topLevelChanged)
Q_PROPERTY(DockWidgetFeatures features READ features WRITE setFeatures NOTIFY featuresChanged)
Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas
WRITE setAllowedAreas NOTIFY allowedAreasChanged)
@@ -100,6 +64,10 @@ public:
inline bool isAreaAllowed(Qt::DockWidgetArea area) const
{ return (allowedAreas() & area) == area; }
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QDockWidget *dockWidget);
+#endif
+
#ifndef QT_NO_ACTION
QAction *toggleViewAction() const;
#endif
@@ -108,7 +76,7 @@ Q_SIGNALS:
void featuresChanged(QDockWidget::DockWidgetFeatures features);
void topLevelChanged(bool topLevel);
void allowedAreasChanged(Qt::DockWidgetAreas allowedAreas);
- void visibilityChanged(bool visible);
+ void visibilityChanged(bool visible); // ### Qt7: Deprecate this. Better listen to hide/show events
void dockLocationChanged(Qt::DockWidgetArea area);
protected:
@@ -121,8 +89,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QDockWidget)
Q_DISABLE_COPY(QDockWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
- Q_PRIVATE_SLOT(d_func(), void _q_toggleTopLevel())
friend class QDockAreaLayout;
friend class QDockWidgetItem;
friend class QMainWindowLayout;
diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h
index ca9bf9dfcc..fa936599c6 100644
--- a/src/widgets/widgets/qdockwidget_p.h
+++ b/src/widgets/widgets/qdockwidget_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICDOCKWIDGET_P_H
#define QDYNAMICDOCKWIDGET_P_H
@@ -77,6 +41,8 @@ class QDockWidgetPrivate : public QWidgetPrivate
struct DragState {
QPoint pressPos;
+ QPoint globalPressPos;
+ QPoint widgetInitialPos;
bool dragging;
QLayoutItem *widgetItem;
bool ownWidgetItem;
@@ -85,11 +51,22 @@ class QDockWidgetPrivate : public QWidgetPrivate
};
public:
+ enum class DragScope {
+ Group,
+ Widget
+ };
+
+ enum class EndDragMode {
+ LocationChange,
+ Abort
+ };
+
void init();
- void _q_toggleView(bool); // private slot
- void _q_toggleTopLevel(); // private slot
+ void toggleView(bool);
+ void toggleTopLevel();
void updateButtons();
+ static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos);
#if QT_CONFIG(tabwidget)
QTabWidget::TabPosition tabPosition = QTabWidget::North;
@@ -119,8 +96,8 @@ public:
void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
void nonClientAreaMouseEvent(QMouseEvent *event);
void initDrag(const QPoint &pos, bool nca);
- void startDrag(bool group = true);
- void endDrag(bool abort = false);
+ void startDrag(DragScope scope);
+ void endDrag(EndDragMode mode);
void moveEvent(QMoveEvent *event);
void recalculatePressPos(QResizeEvent *event);
@@ -129,6 +106,7 @@ public:
void setResizerActive(bool active);
bool isAnimating() const;
+ bool isTabbed() const;
private:
QWidgetResizeHandler *resizer = nullptr;
diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp
index 0090f9b0b9..74ac24a2b0 100644
--- a/src/widgets/widgets/qeffects.cpp
+++ b/src/widgets/widgets/qeffects.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qapplication.h"
#include "qdebug.h"
@@ -151,7 +115,7 @@ void QAlphaWidget::run(int time)
qApp->installEventFilter(this);
widget->setWindowOpacity(0.0);
widget->show();
- connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
+ connect(&anim, &QTimer::timeout, this, &QAlphaWidget::render);
anim.start(1);
#else
//This is roughly equivalent to calling setVisible(true) without actually showing the widget
@@ -174,7 +138,7 @@ void QAlphaWidget::run(int time)
show();
setEnabled(false);
- connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
+ connect(&anim, &QTimer::timeout, this, &QAlphaWidget::render);
anim.start(1);
} else {
duration = 0;
@@ -207,7 +171,7 @@ bool QAlphaWidget::eventFilter(QObject *o, QEvent *e)
break;
case QEvent::KeyPress: {
#ifndef QT_NO_SHORTCUT
- QKeyEvent *ke = (QKeyEvent*)e;
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
if (ke->matches(QKeySequence::Cancel)) {
showWidget = false;
} else
@@ -328,6 +292,7 @@ void QAlphaWidget::alphaBlend()
back_data += bpl;
front_data += bpl;
}
+ break;
}
default:
break;
@@ -464,7 +429,7 @@ void QRollEffect::run(int time)
duration = qMin(qMax(dist/3, 50), 120);
}
- connect(&anim, SIGNAL(timeout()), this, SLOT(scroll()));
+ connect(&anim, &QTimer::timeout, this, &QRollEffect::scroll);
move(widget->geometry().x(),widget->geometry().y());
resize(qMin(currentWidth, totalWidth), qMin(currentHeight, totalHeight));
@@ -499,14 +464,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);
@@ -555,7 +518,7 @@ void QRollEffect::scroll()
}
}
-/*!
+/*
Scroll widget \a w in \a time ms. \a orient may be 1 (vertical), 2
(horizontal) or 3 (diagonal).
*/
@@ -578,7 +541,7 @@ void qScrollEffect(QWidget* w, QEffects::DirFlags orient, int time)
q_roll->run(time);
}
-/*!
+/*
Fade in widget \a w in \a time ms.
*/
void qFadeEffect(QWidget* w, int time)
diff --git a/src/widgets/widgets/qeffects_p.h b/src/widgets/widgets/qeffects_p.h
index 92f459651f..794ef030a0 100644
--- a/src/widgets/widgets/qeffects_p.h
+++ b/src/widgets/widgets/qeffects_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QEFFECTS_P_H
#define QEFFECTS_P_H
diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp
index 47ac8a5568..d66faedbac 100644
--- a/src/widgets/widgets/qfocusframe.cpp
+++ b/src/widgets/widgets/qfocusframe.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfocusframe.h"
#include "qstyle.h"
@@ -88,8 +52,8 @@ void QFocusFramePrivate::updateSize()
QStyleOption opt;
q->initStyleOption(&opt);
- int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &opt),
- hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &opt);
+ int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &opt, q),
+ hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &opt, q);
QPoint pos(widget->x(), widget->y());
if (q->parentWidget() != widget->parentWidget())
pos = widget->parentWidget()->mapTo(q->parentWidget(), pos);
@@ -265,8 +229,8 @@ QFocusFrame::paintEvent(QPaintEvent *)
QStylePainter p(this);
QStyleOption option;
initStyleOption(&option);
- const int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option);
- const int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option);
+ const int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option, this);
+ const int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, this);
QWidgetPrivate *wd = qt_widget_private(d->widget);
QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2);
p.setClipRect(rect);
diff --git a/src/widgets/widgets/qfocusframe.h b/src/widgets/widgets/qfocusframe.h
index 8f6b7dd067..a281b0dbe3 100644
--- a/src/widgets/widgets/qfocusframe.h
+++ b/src/widgets/widgets/qfocusframe.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFOCUSFRAME_H
#define QFOCUSFRAME_H
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 60a1f06764..c80687c7ed 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -1,46 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfontcombobox.h"
+#include <qabstractitemdelegate.h>
+#include <qaccessible.h>
#include <qstringlistmodel.h>
-#include <qitemdelegate.h>
#include <qlistview.h>
#include <qpainter.h>
#include <qevent.h>
@@ -48,8 +13,12 @@
#include <private/qcombobox_p.h>
#include <qdebug.h>
+#include <array>
+
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
{
switch (script) {
@@ -134,7 +103,7 @@ static QFontDatabase::WritingSystem writingSystemFromLocale()
static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
{
- QList<QFontDatabase::WritingSystem> writingSystems = QFontDatabase::writingSystems(font.families().first());
+ QList<QFontDatabase::WritingSystem> writingSystems = QFontDatabase::writingSystems(font.families().constFirst());
// qDebug() << font.families().first() << writingSystems;
// this just confuses the algorithm below. Vietnamese is Latin with lots of special chars
@@ -166,23 +135,39 @@ static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool
return system;
}
- if (writingSystems.count() == 1 && system > QFontDatabase::Cyrillic)
+ if (writingSystems.size() == 1 && system > QFontDatabase::Cyrillic)
return system;
- if (writingSystems.count() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese)
+ if (writingSystems.size() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese)
return system;
- if (writingSystems.count() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean)
+ if (writingSystems.size() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean)
return system;
return QFontDatabase::Any;
}
+class QFontComboBoxPrivate : public QComboBoxPrivate
+{
+public:
+ QFontComboBox::FontFilters filters = QFontComboBox::AllFonts;
+ QFont currentFont;
+ QHash<QFontDatabase::WritingSystem, QString> sampleTextForWritingSystem;
+ QHash<QString, QString> sampleTextForFontFamily;
+ QHash<QString, QFont> displayFontForFontFamily;
+ std::array<QMetaObject::Connection, 2> connections;
+
+ void updateModel();
+ void 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 +180,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 +207,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 +253,11 @@ void QFontFamilyDelegate::paint(QPainter *painter,
if (writingSystem != QFontDatabase::Any)
system = writingSystem;
- if (system != QFontDatabase::Any) {
- int w = painter->fontMetrics().horizontalAdvance(text + QLatin1String(" "));
+ const QString sampleText = comboPrivate->sampleTextForFontFamily.value(text, comboPrivate->sampleTextForWritingSystem.value(system));
+ if (system != QFontDatabase::Any || !sampleText.isEmpty()) {
+ int w = painter->fontMetrics().horizontalAdvance(text + " "_L1);
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 +283,13 @@ QSize QFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option,
}
-class QFontComboBoxPrivate : public QComboBoxPrivate
+void QFontComboBoxPrivate::updateModel()
{
-public:
- inline QFontComboBoxPrivate() { filters = QFontComboBox::AllFonts; }
-
- QFontComboBox::FontFilters filters;
- QFont currentFont;
-
- void _q_updateModel();
- void _q_currentChanged(const QString &);
-
- Q_DECLARE_PUBLIC(QFontComboBox)
-};
+ Q_Q(QFontComboBox);
+ if (QCoreApplication::closingDown())
+ return;
-void QFontComboBoxPrivate::_q_updateModel()
-{
- Q_Q(QFontComboBox);
const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts);
const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts);
@@ -320,29 +299,28 @@ void QFontComboBoxPrivate::_q_updateModel()
QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(q->view()->itemDelegate());
QFontDatabase::WritingSystem system = delegate ? delegate->writingSystem : QFontDatabase::Any;
- QStringList list = QFontDatabase::families(system);
+ const QStringList list = QFontDatabase::families(system);
QStringList result;
int offset = 0;
QFontInfo fi(currentFont);
- for (int i = 0; i < list.size(); ++i) {
- if (QFontDatabase::isPrivateFamily(list.at(i)))
+ for (const auto &family : list) {
+ if (QFontDatabase::isPrivateFamily(family))
continue;
if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) {
- if (bool(filters & QFontComboBox::ScalableFonts) != QFontDatabase::isSmoothlyScalable(list.at(i)))
+ if (bool(filters & QFontComboBox::ScalableFonts) != QFontDatabase::isSmoothlyScalable(family))
continue;
}
if ((filters & spacingMask) && (filters & spacingMask) != spacingMask) {
- if (bool(filters & QFontComboBox::MonospacedFonts) != QFontDatabase::isFixedPitch(list.at(i)))
+ if (bool(filters & QFontComboBox::MonospacedFonts) != QFontDatabase::isFixedPitch(family))
continue;
}
- result += list.at(i);
- if (list.at(i) == fi.family() || list.at(i).startsWith(fi.family() + QLatin1String(" [")))
- offset = result.count() - 1;
+ result += family;
+ if (family == fi.family() || family.startsWith(fi.family() + " ["_L1))
+ offset = result.size() - 1;
}
- list = result;
//we need to block the signals so that the model doesn't emit reset
//this prevents the current index from changing
@@ -350,10 +328,17 @@ void QFontComboBoxPrivate::_q_updateModel()
///TODO: we should finda way to avoid blocking signals and have a real update of the model
{
const QSignalBlocker blocker(m);
- m->setStringList(list);
+ m->setStringList(result);
+ // Since the modelReset signal is blocked the view will not emit an accessibility event
+ #if QT_CONFIG(accessibility)
+ if (QAccessible::isActive()) {
+ QAccessibleTableModelChangeEvent accessibleEvent(q->view(), QAccessibleTableModelChangeEvent::ModelReset);
+ QAccessible::updateAccessibility(&accessibleEvent);
+ }
+ #endif
}
- if (list.isEmpty()) {
+ if (result.isEmpty()) {
if (currentFont != QFont()) {
currentFont = QFont();
emit q->currentFontChanged(currentFont);
@@ -364,10 +349,11 @@ void QFontComboBoxPrivate::_q_updateModel()
}
-void QFontComboBoxPrivate::_q_currentChanged(const QString &text)
+void QFontComboBoxPrivate::currentChanged(const QString &text)
{
Q_Q(QFontComboBox);
- if (currentFont.families().first() != text) {
+ const QStringList families = currentFont.families();
+ if (families.isEmpty() || families.first() != text) {
currentFont.setFamilies(QStringList{text});
emit q->currentFontChanged(currentFont);
}
@@ -403,7 +389,7 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text)
\image windowsvista-fontcombobox.png Screenshot of QFontComboBox on Windows Vista
- \sa QComboBox, QFont, QFontInfo, QFontMetrics, QFontDatabase, {Character Map Example}
+ \sa QComboBox, QFont, QFontInfo, QFontMetrics, QFontDatabase
*/
/*!
@@ -418,17 +404,18 @@ 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);
setWritingSystem(QFontDatabase::Any);
- connect(this, SIGNAL(currentTextChanged(QString)),
- this, SLOT(_q_currentChanged(QString)));
-
- connect(qApp, SIGNAL(fontDatabaseChanged()),
- this, SLOT(_q_updateModel()));
+ d->connections = {
+ QObjectPrivate::connect(this, &QFontComboBox::currentTextChanged,
+ d, &QFontComboBoxPrivate::currentChanged),
+ QObjectPrivate::connect(qApp, &QGuiApplication::fontDatabaseChanged,
+ d, &QFontComboBoxPrivate::updateModel),
+ };
}
@@ -437,6 +424,9 @@ QFontComboBox::QFontComboBox(QWidget *parent)
*/
QFontComboBox::~QFontComboBox()
{
+ Q_D(const QFontComboBox);
+ for (const QMetaObject::Connection &connection : d->connections)
+ QObject::disconnect(connection);
}
/*!
@@ -455,7 +445,7 @@ void QFontComboBox::setWritingSystem(QFontDatabase::WritingSystem script)
QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(view()->itemDelegate());
if (delegate)
delegate->writingSystem = script;
- d->_q_updateModel();
+ d->updateModel();
}
QFontDatabase::WritingSystem QFontComboBox::writingSystem() const
@@ -491,7 +481,7 @@ void QFontComboBox::setFontFilters(FontFilters filters)
{
Q_D(QFontComboBox);
d->filters = filters;
- d->_q_updateModel();
+ d->updateModel();
}
QFontComboBox::FontFilters QFontComboBox::fontFilters() const
@@ -517,8 +507,8 @@ void QFontComboBox::setCurrentFont(const QFont &font)
Q_D(QFontComboBox);
if (font != d->currentFont) {
d->currentFont = font;
- d->_q_updateModel();
- if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
+ d->updateModel();
+ if (d->currentFont == font) { //else the signal has already be emitted by updateModel
emit currentFontChanged(d->currentFont);
}
}
@@ -555,10 +545,81 @@ QSize QFontComboBox::sizeHint() const
{
QSize sz = QComboBox::sizeHint();
QFontMetrics fm(font());
- sz.setWidth(fm.horizontalAdvance(QLatin1Char('m'))*14);
+ sz.setWidth(fm.horizontalAdvance(u'm') * 14);
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..9c5432b332 100644
--- a/src/widgets/widgets/qfontcombobox.h
+++ b/src/widgets/widgets/qfontcombobox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFONTCOMBOBOX_H
#define QFONTCOMBOBOX_H
@@ -80,6 +44,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);
@@ -92,8 +65,6 @@ protected:
private:
Q_DISABLE_COPY(QFontComboBox)
Q_DECLARE_PRIVATE(QFontComboBox)
- Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateModel())
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QFontComboBox::FontFilters)
diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp
index 1661c5c881..db8dc20be2 100644
--- a/src/widgets/widgets/qframe.cpp
+++ b/src/widgets/widgets/qframe.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qframe.h"
#include "qbitmap.h"
@@ -44,6 +8,7 @@
#include "qpainter.h"
#include "qstyle.h"
#include "qstyleoption.h"
+#include "qstylepainter.h"
#include "qapplication.h"
#include "qframe_p.h"
@@ -463,9 +428,9 @@ int QFrame::frameWidth() const
\brief the frame's rectangle
The frame's rectangle is the rectangle the frame is drawn in. By
- default, this is the entire widget. Setting the rectangle does
- does \e not cause a widget update. The frame rectangle is
- automatically adjusted when the widget changes size.
+ default, this is the entire widget. Setting the rectangle \e doesn't
+ cause a widget update. The frame rectangle is automatically adjusted
+ when the widget changes size.
If you set the rectangle to a null rectangle (for example,
QRect(0, 0, 0, 0)), then the resulting frame rectangle is
@@ -511,8 +476,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/qframe.h b/src/widgets/widgets/qframe.h
index 144003bc0e..0c8a6f81d1 100644
--- a/src/widgets/widgets/qframe.h
+++ b/src/widgets/widgets/qframe.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFRAME_H
#define QFRAME_H
@@ -123,6 +87,8 @@ private:
Q_DECLARE_PRIVATE(QFrame)
};
+Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QFrame::Shape, QFrame::Shadow)
+
QT_END_NAMESPACE
#endif // QFRAME_H
diff --git a/src/widgets/widgets/qframe_p.h b/src/widgets/widgets/qframe_p.h
index 817d33b1f1..a45f5735dd 100644
--- a/src/widgets/widgets/qframe_p.h
+++ b/src/widgets/widgets/qframe_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFRAME_P_H
#define QFRAME_P_H
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 8945139115..eb37599382 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qgroupbox.h"
@@ -50,12 +14,15 @@
#include "qstyle.h"
#include "qstyleoption.h"
#include "qstylepainter.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#include <private/qwidget_p.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
#include "qdebug.h"
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@@ -166,9 +133,9 @@ void QGroupBoxPrivate::click()
widgets). The following example shows how we can set up a
QGroupBox with a layout:
- \snippet widgets/groupbox/window.cpp 2
+ \snippet code/src_gui_widgets_qgroupbox.cpp Set up QGroupBox with layout
- \sa QButtonGroup, {Group Box Example}
+ \sa QButtonGroup
*/
@@ -234,7 +201,7 @@ void QGroupBox::setTitle(const QString &title)
update();
updateGeometry();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
#endif
@@ -360,7 +327,10 @@ bool QGroupBox::event(QEvent *e)
return true;
case QEvent::KeyPress: {
QKeyEvent *k = static_cast<QKeyEvent*>(e);
- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) {
d->pressedControl = QStyle::SC_GroupBoxCheckBox;
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
return true;
@@ -369,7 +339,10 @@ bool QGroupBox::event(QEvent *e)
}
case QEvent::KeyRelease: {
QKeyEvent *k = static_cast<QKeyEvent*>(e);
- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) {
bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
|| d->pressedControl == QStyle::SC_GroupBoxCheckBox);
d->pressedControl = QStyle::SC_None;
@@ -488,12 +461,12 @@ QSize QGroupBox::minimumSizeHint() const
QFontMetrics metrics(fontMetrics());
- int baseWidth = metrics.horizontalAdvance(d->title) + metrics.horizontalAdvance(QLatin1Char(' '));
+ int baseWidth = metrics.horizontalAdvance(d->title) + metrics.horizontalAdvance(u' ');
int baseHeight = metrics.height();
if (d->checkable) {
- baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth, &option);
- baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &option);
- baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight, &option));
+ baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth, &option, this);
+ baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &option, this);
+ baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight, &option, this));
}
QSize size = style()->sizeFromContents(QStyle::CT_GroupBox, &option, QSize(baseWidth, baseHeight), this);
@@ -637,7 +610,7 @@ void QGroupBox::setChecked(bool b)
update();
d->checked = b;
d->_q_setChildrenEnabled(b);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::State st;
st.checked = true;
QAccessibleStateChangeEvent e(this, st);
diff --git a/src/widgets/widgets/qgroupbox.h b/src/widgets/widgets/qgroupbox.h
index f3ed35b7fb..dd4a5b8a93 100644
--- a/src/widgets/widgets/qgroupbox.h
+++ b/src/widgets/widgets/qgroupbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QGROUPBOX_H
#define QGROUPBOX_H
diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp
index 97ee915037..65ed7a465a 100644
--- a/src/widgets/widgets/qkeysequenceedit.cpp
+++ b/src/widgets/widgets/qkeysequenceedit.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Ivan Komissarov.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Ivan Komissarov.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qkeysequenceedit.h"
#include "qkeysequenceedit_p.h"
@@ -55,9 +19,17 @@ void QKeySequenceEditPrivate::init()
lineEdit = new QLineEdit(q);
lineEdit->setObjectName(QStringLiteral("qt_keysequenceedit_lineedit"));
+ lineEdit->setClearButtonEnabled(false);
+ q->connect(lineEdit, &QLineEdit::textChanged, q, [q](const QString& text) {
+ // Clear the shortcut if the user clicked on the clear icon
+ if (text.isEmpty())
+ q->clear();
+ });
+
keyNum = 0;
prevKey = -1;
releaseTimer = 0;
+ finishingKeyCombinations = {Qt::Key_Tab, Qt::Key_Backtab};
QVBoxLayout *layout = new QVBoxLayout(q);
layout->setContentsMargins(0, 0, 0, 0);
@@ -73,8 +45,6 @@ void QKeySequenceEditPrivate::init()
q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_MacShowFocusRect, true);
q->setAttribute(Qt::WA_InputMethodEnabled, false);
-
- // TODO: add clear button
}
int QKeySequenceEditPrivate::translateModifiers(Qt::KeyboardModifiers state, const QString &text)
@@ -167,6 +137,9 @@ QKeySequenceEdit::~QKeySequenceEdit()
\brief This property contains the currently chosen key sequence.
The shortcut can be changed by the user or via setter function.
+
+ \note If the QKeySequence is longer than the maximumSequenceLength
+ property, the key sequence is truncated.
*/
QKeySequence QKeySequenceEdit::keySequence() const
{
@@ -175,6 +148,89 @@ QKeySequence QKeySequenceEdit::keySequence() const
return d->keySequence;
}
+/*!
+ \property QKeySequenceEdit::clearButtonEnabled
+ \brief Whether the key sequence edit displays a clear button when it is not
+ empty.
+
+ If enabled, the key sequence edit displays a trailing \e clear button when
+ it contains some text, otherwise the line edit does not show a clear button
+ (the default).
+
+ \since 6.4
+*/
+void QKeySequenceEdit::setClearButtonEnabled(bool enable)
+{
+ Q_D(QKeySequenceEdit);
+
+ d->lineEdit->setClearButtonEnabled(enable);
+}
+
+bool QKeySequenceEdit::isClearButtonEnabled() const
+{
+ Q_D(const QKeySequenceEdit);
+
+ return d->lineEdit->isClearButtonEnabled();
+}
+
+/*!
+ \property QKeySequenceEdit::maximumSequenceLength
+ \brief The maximum sequence length.
+
+ The maximum number of key sequences a user can enter. The value needs to
+ be between 1 and 4, with 4 being the default.
+
+ \since 6.5
+*/
+qsizetype QKeySequenceEdit::maximumSequenceLength() const
+{
+ Q_D(const QKeySequenceEdit);
+ return d->maximumSequenceLength;
+}
+
+void QKeySequenceEdit::setMaximumSequenceLength(qsizetype count)
+{
+ Q_D(QKeySequenceEdit);
+
+ if (count < 1 || count > QKeySequencePrivate::MaxKeyCount) {
+ qWarning("QKeySequenceEdit: maximumSequenceLength %lld is out of range (1..%d)",
+ qlonglong(count), QKeySequencePrivate::MaxKeyCount);
+ return;
+ }
+ d->maximumSequenceLength = int(count);
+ if (d->keyNum > count) {
+ for (qsizetype i = d->keyNum; i < count; ++i)
+ d->key[i] = QKeyCombination::fromCombined(0);
+ d->keyNum = count;
+ d->rebuildKeySequence();
+ }
+}
+
+/*!
+ \property QKeySequenceEdit::finishingKeyCombinations
+ \brief The list of key combinations that finish editing the key sequences.
+
+ Any combination in the list will finish the editing of key sequences.
+ All other key combinations can be recorded as part of a key sequence. By
+ default, Qt::Key_Tab and Qt::Key_Backtab will finish recording the key
+ sequence.
+
+ \since 6.5
+*/
+void QKeySequenceEdit::setFinishingKeyCombinations(const QList<QKeyCombination> &finishingKeyCombinations)
+{
+ Q_D(QKeySequenceEdit);
+
+ d->finishingKeyCombinations = finishingKeyCombinations;
+}
+
+QList<QKeyCombination> QKeySequenceEdit::finishingKeyCombinations() const
+{
+ Q_D(const QKeySequenceEdit);
+
+ return d->finishingKeyCombinations;
+}
+
void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence)
{
Q_D(QKeySequenceEdit);
@@ -184,16 +240,24 @@ void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence)
if (d->keySequence == keySequence)
return;
- d->keySequence = keySequence;
+ const auto desiredCount = keySequence.count();
+ if (desiredCount > d->maximumSequenceLength) {
+ qWarning("QKeySequenceEdit: setting a key sequence of length %d "
+ "when maximumSequenceLength is %d, truncating.",
+ desiredCount, d->maximumSequenceLength);
+ }
- d->key[0] = d->key[1] = d->key[2] = d->key[3] = QKeyCombination::fromCombined(0);
- d->keyNum = keySequence.count();
+ d->keyNum = std::min(desiredCount, d->maximumSequenceLength);
for (int i = 0; i < d->keyNum; ++i)
d->key[i] = keySequence[i];
+ for (int i = d->keyNum; i < QKeySequencePrivate::MaxKeyCount; ++i)
+ d->key[i] = QKeyCombination::fromCombined(0);
- d->lineEdit->setText(keySequence.toString(QKeySequence::NativeText));
+ d->rebuildKeySequence();
- emit keySequenceChanged(keySequence);
+ d->lineEdit->setText(d->keySequence.toString(QKeySequence::NativeText));
+
+ emit keySequenceChanged(d->keySequence);
}
/*!
@@ -218,13 +282,23 @@ void QKeySequenceEdit::clear()
*/
bool QKeySequenceEdit::event(QEvent *e)
{
+ Q_D(const QKeySequenceEdit);
+
switch (e->type()) {
case QEvent::Shortcut:
return true;
case QEvent::ShortcutOverride:
e->accept();
return true;
- default :
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (!d->finishingKeyCombinations.contains(ke->keyCombination())) {
+ keyPressEvent(ke);
+ return true;
+ }
+ }
+ break;
+ default:
break;
}
@@ -238,6 +312,11 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e)
{
Q_D(QKeySequenceEdit);
+ if (d->finishingKeyCombinations.contains(e->keyCombination())) {
+ d->finishEditing();
+ return;
+ }
+
int nextKey = e->key();
if (d->prevKey == -1) {
@@ -261,26 +340,27 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e)
return;
}
- if (d->keyNum >= QKeySequencePrivate::MaxKeyCount)
+ if (d->keyNum >= d->maximumSequenceLength)
return;
if (e->modifiers() & Qt::ShiftModifier) {
- QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
- int pkTotal = possibleKeys.count();
+ const QList<QKeyCombination> possibleKeys = QKeyMapper::possibleKeys(e);
+ int pkTotal = possibleKeys.size();
if (!pkTotal)
return;
bool found = false;
for (int i = 0; i < possibleKeys.size(); ++i) {
- if (possibleKeys.at(i) - nextKey == int(e->modifiers())
- || (possibleKeys.at(i) == nextKey && e->modifiers() == Qt::ShiftModifier)) {
- nextKey = possibleKeys.at(i);
+ const int key = possibleKeys.at(i).toCombined();
+ if (key - nextKey == int(e->modifiers())
+ || (key == nextKey && e->modifiers() == Qt::ShiftModifier)) {
+ nextKey = key;
found = true;
break;
}
}
// Use as fallback
if (!found)
- nextKey = possibleKeys.first();
+ nextKey = possibleKeys.first().toCombined();
} else {
nextKey |= d->translateModifiers(e->modifiers(), e->text());
}
@@ -289,10 +369,9 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e)
d->key[d->keyNum] = QKeyCombination::fromCombined(nextKey);
d->keyNum++;
- QKeySequence key(d->key[0], d->key[1], d->key[2], d->key[3]);
- d->keySequence = key;
- QString text = key.toString(QKeySequence::NativeText);
- if (d->keyNum < QKeySequencePrivate::MaxKeyCount) {
+ d->rebuildKeySequence();
+ QString text = d->keySequence.toString(QKeySequence::NativeText);
+ if (d->keyNum < d->maximumSequenceLength) {
//: This text is an "unfinished" shortcut, expands like "Ctrl+A, ..."
text = tr("%1, ...").arg(text);
}
@@ -308,7 +387,7 @@ void QKeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
Q_D(QKeySequenceEdit);
if (d->prevKey == e->key()) {
- if (d->keyNum < QKeySequencePrivate::MaxKeyCount)
+ if (d->keyNum < d->maximumSequenceLength)
d->releaseTimer = startTimer(1000);
else
d->finishEditing();
@@ -330,6 +409,17 @@ void QKeySequenceEdit::timerEvent(QTimerEvent *e)
QWidget::timerEvent(e);
}
+/*!
+ \reimp
+*/
+void QKeySequenceEdit::focusOutEvent(QFocusEvent *e)
+{
+ Q_D(QKeySequenceEdit);
+ if (e->reason() != Qt::PopupFocusReason)
+ d->finishEditing();
+ QWidget::focusOutEvent(e);
+}
+
QT_END_NAMESPACE
#include "moc_qkeysequenceedit.cpp"
diff --git a/src/widgets/widgets/qkeysequenceedit.h b/src/widgets/widgets/qkeysequenceedit.h
index 85d76f14a3..db0c4c80dd 100644
--- a/src/widgets/widgets/qkeysequenceedit.h
+++ b/src/widgets/widgets/qkeysequenceedit.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Ivan Komissarov.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Ivan Komissarov.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QKEYSEQUENCEEDIT_H
#define QKEYSEQUENCEEDIT_H
@@ -52,7 +16,11 @@ class QKeySequenceEditPrivate;
class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget
{
Q_OBJECT
- Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence NOTIFY keySequenceChanged USER true)
+ Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence
+ NOTIFY keySequenceChanged USER true)
+ Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled)
+ Q_PROPERTY(qsizetype maximumSequenceLength READ maximumSequenceLength WRITE setMaximumSequenceLength)
+ Q_PROPERTY(QList<QKeyCombination> finishingKeyCombinations READ finishingKeyCombinations WRITE setFinishingKeyCombinations)
public:
explicit QKeySequenceEdit(QWidget *parent = nullptr);
@@ -60,10 +28,18 @@ public:
~QKeySequenceEdit();
QKeySequence keySequence() const;
+ qsizetype maximumSequenceLength() const;
+
+ void setClearButtonEnabled(bool enable);
+ bool isClearButtonEnabled() const;
+
+ void setFinishingKeyCombinations(const QList<QKeyCombination> &finishingKeyCombinations);
+ QList<QKeyCombination> finishingKeyCombinations() const;
public Q_SLOTS:
void setKeySequence(const QKeySequence &keySequence);
void clear();
+ void setMaximumSequenceLength(qsizetype count);
Q_SIGNALS:
void editingFinished();
@@ -76,6 +52,7 @@ protected:
void keyPressEvent(QKeyEvent *) override;
void keyReleaseEvent(QKeyEvent *) override;
void timerEvent(QTimerEvent *) override;
+ void focusOutEvent(QFocusEvent *) override;
private:
Q_DISABLE_COPY(QKeySequenceEdit)
diff --git a/src/widgets/widgets/qkeysequenceedit_p.h b/src/widgets/widgets/qkeysequenceedit_p.h
index 8cd58de68f..bdf3bfe788 100644
--- a/src/widgets/widgets/qkeysequenceedit_p.h
+++ b/src/widgets/widgets/qkeysequenceedit_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Ivan Komissarov.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Ivan Komissarov.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QKEYSEQUENCEEDIT_P_H
#define QKEYSEQUENCEEDIT_P_H
@@ -72,13 +36,17 @@ public:
int translateModifiers(Qt::KeyboardModifiers state, const QString &text);
void resetState();
void finishEditing();
+ void rebuildKeySequence()
+ { keySequence = QKeySequence(key[0], key[1], key[2], key[3]); }
QLineEdit *lineEdit;
QKeySequence keySequence;
int keyNum;
+ int maximumSequenceLength = QKeySequencePrivate::MaxKeyCount;
QKeyCombination key[QKeySequencePrivate::MaxKeyCount];
int prevKey;
int releaseTimer;
+ QList<QKeyCombination> finishingKeyCombinations;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 377f2967cf..f4155de0a0 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpainter.h"
#include "qevent.h"
@@ -54,22 +18,24 @@
#include "private/qstylesheetstyle_p.h"
#include <qmath.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
QLabelPrivate::QLabelPrivate()
: QFramePrivate(),
sh(),
msh(),
text(),
- pixmap(nullptr),
- scaledpixmap(nullptr),
- cachedimage(nullptr),
+ pixmap(),
+ scaledpixmap(),
+ cachedimage(),
#ifndef QT_NO_PICTURE
- picture(nullptr),
+ picture(),
#endif
#if QT_CONFIG(movie)
movie(),
@@ -183,14 +149,13 @@ 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
/*!
\fn QPicture QLabel::picture(Qt::ReturnByValueConstant) const
- \obsolete Use the overload without argument instead.
+ \deprecated Use the overload without argument instead.
\since 5.15
Returns the label's picture.
@@ -339,7 +304,7 @@ void QLabel::setText(const QString &text)
d->updateLabel();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (accessibleName().isEmpty()) {
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
@@ -376,12 +341,9 @@ void QLabel::setPixmap(const QPixmap &pixmap)
Q_D(QLabel);
if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) {
d->clearContents();
- d->pixmap = new QPixmap(pixmap);
+ d->pixmap = pixmap;
}
- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
- d->pixmap->setMask(*((QBitmap *)d->pixmap));
-
d->updateLabel();
}
@@ -396,7 +358,7 @@ QPixmap QLabel::pixmap() const
/*!
\fn QPixmap QLabel::pixmap(Qt::ReturnByValueConstant) const
- \obsolete Use the overload without argument instead.
+ \deprecated Use the overload without argument instead.
\since 5.15
Returns the label's pixmap.
@@ -424,7 +386,7 @@ void QLabel::setPicture(const QPicture &picture)
{
Q_D(QLabel);
d->clearContents();
- d->picture = new QPicture(picture);
+ d->picture = picture;
d->updateLabel();
}
@@ -604,7 +566,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const
if (pixmap && !pixmap->isNull()) {
br = pixmap->rect();
- br.setSize(br.size() / pixmap->devicePixelRatio());
+ br.setSize(pixmap->deviceIndependentSize().toSize());
#ifndef QT_NO_PICTURE
} else if (picture && !picture->isNull()) {
br = picture->boundingRect();
@@ -612,7 +574,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const
#if QT_CONFIG(movie)
} else if (movie && !movie->currentPixmap().isNull()) {
br = movie->currentPixmap().rect();
- br.setSize(br.size() / movie->currentPixmap().devicePixelRatio());
+ br.setSize(movie->currentPixmap().deviceIndependentSize().toSize());
#endif
} else if (isTextLabel) {
int align = QStyle::visualAlignment(textDirection(), QFlag(this->align));
@@ -620,7 +582,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const
int m = indent;
if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
- m = fm.horizontalAdvance(QLatin1Char('x')) - margin*2;
+ m = fm.horizontalAdvance(u'x') - margin*2;
if (m > 0) {
if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
hextra += m;
@@ -1129,17 +1091,19 @@ void QLabel::paintEvent(QPaintEvent *)
#endif
if (d->pixmap && !d->pixmap->isNull()) {
QPixmap pix;
- if (d->scaledcontents) {
- QSize scaledSize = cr.size() * devicePixelRatio();
+ const qreal dpr = devicePixelRatio();
+ if (d->scaledcontents || dpr != d->pixmap->devicePixelRatio()) {
+ QSize scaledSize = d->scaledcontents ? (cr.size() * dpr)
+ : (d->pixmap->size() * (dpr / d->pixmap->devicePixelRatio()));
if (!d->scaledpixmap || d->scaledpixmap->size() != scaledSize) {
if (!d->cachedimage)
- d->cachedimage = new QImage(d->pixmap->toImage());
- delete d->scaledpixmap;
+ d->cachedimage = d->pixmap->toImage();
+ d->scaledpixmap.reset();
QImage scaledImage =
d->cachedimage->scaled(scaledSize,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- d->scaledpixmap = new QPixmap(QPixmap::fromImage(std::move(scaledImage)));
- d->scaledpixmap->setDevicePixelRatio(devicePixelRatio());
+ d->scaledpixmap = QPixmap::fromImage(std::move(scaledImage));
+ d->scaledpixmap->setDevicePixelRatio(dpr);
}
pix = *d->scaledpixmap;
} else
@@ -1207,12 +1171,14 @@ void QLabel::setBuddy(QWidget *buddy)
Q_D(QLabel);
if (d->buddy)
- disconnect(d->buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted()));
+ QObjectPrivate::disconnect(d->buddy, &QObject::destroyed,
+ d, &QLabelPrivate::buddyDeleted);
d->buddy = buddy;
if (buddy)
- connect(buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted()));
+ QObjectPrivate::connect(buddy, &QObject::destroyed,
+ d, &QLabelPrivate::buddyDeleted);
if (d->isTextLabel) {
if (d->shortcutId)
@@ -1248,14 +1214,14 @@ void QLabelPrivate::updateShortcut()
// But then we do want to hide the ampersands, so we can't use shortcutId.
hasShortcut = false;
- if (!text.contains(QLatin1Char('&')))
+ if (!text.contains(u'&'))
return;
hasShortcut = true;
shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
}
-void QLabelPrivate::_q_buddyDeleted()
+void QLabelPrivate::buddyDeleted()
{
Q_Q(QLabel);
q->setBuddy(nullptr);
@@ -1264,7 +1230,7 @@ void QLabelPrivate::_q_buddyDeleted()
#endif // QT_NO_SHORTCUT
#if QT_CONFIG(movie)
-void QLabelPrivate::_q_movieUpdated(const QRect& rect)
+void QLabelPrivate::movieUpdated(const QRect &rect)
{
Q_Q(QLabel);
if (movie && movie->isValid()) {
@@ -1287,12 +1253,12 @@ void QLabelPrivate::_q_movieUpdated(const QRect& rect)
}
}
-void QLabelPrivate::_q_movieResized(const QSize& size)
+void QLabelPrivate::movieResized(const QSize &size)
{
Q_Q(QLabel);
- q->update(); //we need to refresh the whole background in case the new size is smaler
+ q->update(); //we need to refresh the whole background in case the new size is smaller
valid_hints = false;
- _q_movieUpdated(QRect(QPoint(0,0), size));
+ movieUpdated(QRect(QPoint(0,0), size));
q->updateGeometry();
}
@@ -1314,8 +1280,10 @@ void QLabel::setMovie(QMovie *movie)
return;
d->movie = movie;
- connect(movie, SIGNAL(resized(QSize)), this, SLOT(_q_movieResized(QSize)));
- connect(movie, SIGNAL(updated(QRect)), this, SLOT(_q_movieUpdated(QRect)));
+ d->movieConnections = {
+ QObjectPrivate::connect(movie, &QMovie::resized, d, &QLabelPrivate::movieResized),
+ QObjectPrivate::connect(movie, &QMovie::updated, d, &QLabelPrivate::movieUpdated),
+ };
// Assume that if the movie is running,
// resize/update signals will come soon enough
@@ -1339,15 +1307,11 @@ void QLabelPrivate::clearContents()
hasShortcut = false;
#ifndef QT_NO_PICTURE
- delete picture;
- picture = nullptr;
+ picture.reset();
#endif
- delete scaledpixmap;
- scaledpixmap = nullptr;
- delete cachedimage;
- cachedimage = nullptr;
- delete pixmap;
- pixmap = nullptr;
+ scaledpixmap.reset();
+ cachedimage.reset();
+ pixmap.reset();
text.clear();
Q_Q(QLabel);
@@ -1357,10 +1321,8 @@ void QLabelPrivate::clearContents()
shortcutId = 0;
#endif
#if QT_CONFIG(movie)
- if (movie) {
- QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
- QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
- }
+ for (const auto &conn : std::as_const(movieConnections))
+ QObject::disconnect(conn);
movie = nullptr;
#endif
#ifndef QT_NO_CURSOR
@@ -1493,10 +1455,8 @@ void QLabel::setScaledContents(bool enable)
return;
d->scaledcontents = enable;
if (!enable) {
- delete d->scaledpixmap;
- d->scaledpixmap = nullptr;
- delete d->cachedimage;
- d->cachedimage = nullptr;
+ d->scaledpixmap.reset();
+ d->cachedimage.reset();
}
update(contentsRect());
}
@@ -1523,7 +1483,7 @@ QRect QLabelPrivate::documentRect() const
: q->layoutDirection(), QFlag(this->align));
int m = indent;
if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
- m = q->fontMetrics().horizontalAdvance(QLatin1Char('x')) / 2 - margin;
+ m = q->fontMetrics().horizontalAdvance(u'x') / 2 - margin;
if (m > 0) {
if (align & Qt::AlignLeft)
cr.setLeft(cr.left() + m);
@@ -1565,11 +1525,11 @@ void QLabelPrivate::ensureTextPopulated() const
int from = 0;
bool found = false;
QTextCursor cursor;
- while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
+ while (!(cursor = control->document()->find(("&"_L1), from)).isNull()) {
cursor.deleteChar(); // remove the ampersand
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
from = cursor.position();
- if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
+ if (!found && cursor.selectedText() != "&"_L1) { //not a second &
found = true;
shortcutCursor = cursor;
}
@@ -1622,12 +1582,12 @@ void QLabelPrivate::ensureTextControl() const
control->setOpenExternalLinks(openExternalLinks);
control->setPalette(q->palette());
control->setFocus(q->hasFocus());
- QObject::connect(control, SIGNAL(updateRequest(QRectF)),
- q, SLOT(update()));
- QObject::connect(control, SIGNAL(linkHovered(QString)),
- q, SLOT(_q_linkHovered(QString)));
- QObject::connect(control, SIGNAL(linkActivated(QString)),
- q, SIGNAL(linkActivated(QString)));
+ QObject::connect(control, &QWidgetTextControl::updateRequest,
+ q, qOverload<>(&QLabel::update));
+ QObject::connect(control, &QWidgetTextControl::linkActivated,
+ q, &QLabel::linkActivated);
+ QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
+ this, &QLabelPrivate::linkHovered);
textLayoutDirty = true;
textDirty = true;
}
@@ -1643,7 +1603,7 @@ void QLabelPrivate::sendControlEvent(QEvent *e)
control->processEvent(e, -layoutRect().topLeft(), q);
}
-void QLabelPrivate::_q_linkHovered(const QString &anchor)
+void QLabelPrivate::linkHovered(const QString &anchor)
{
Q_Q(QLabel);
#ifndef QT_NO_CURSOR
@@ -1674,7 +1634,7 @@ QRectF QLabelPrivate::layoutRect() const
if (!control)
return cr;
ensureTextLayouted();
- // Caculate y position manually
+ // Calculate y position manually
qreal rh = control->document()->documentLayout()->documentSize().height();
qreal yo = 0;
if (align & Qt::AlignVCenter)
@@ -1694,15 +1654,10 @@ QPoint QLabelPrivate::layoutPoint(const QPoint& p) const
#ifndef QT_NO_CONTEXTMENU
QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
{
- if (!control || effectiveTextFormat == Qt::PlainText)
+ if (!control)
return nullptr;
const QPoint p = layoutPoint(pos);
- QString linkToCopy = control->document()->documentLayout()->anchorAt(p);
-
- if (linkToCopy.isEmpty())
- return nullptr;
-
return control->createStandardContextMenu(p, q_func());
}
#endif
diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h
index 05fb39e0fa..3749ec366a 100644
--- a/src/widgets/widgets/qlabel.h
+++ b/src/widgets/widgets/qlabel.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLABEL_H
#define QLABEL_H
@@ -64,7 +28,8 @@ class Q_WIDGETS_EXPORT QLabel : public QFrame
Q_PROPERTY(int margin READ margin WRITE setMargin)
Q_PROPERTY(int indent READ indent WRITE setIndent)
Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags
+ WRITE setTextInteractionFlags)
Q_PROPERTY(bool hasSelectedText READ hasSelectedText)
Q_PROPERTY(QString selectedText READ selectedText)
@@ -165,15 +130,6 @@ protected:
private:
Q_DISABLE_COPY(QLabel)
Q_DECLARE_PRIVATE(QLabel)
-#if QT_CONFIG(movie)
- Q_PRIVATE_SLOT(d_func(), void _q_movieUpdated(const QRect&))
- Q_PRIVATE_SLOT(d_func(), void _q_movieResized(const QSize&))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_linkHovered(const QString &))
-
-#ifndef QT_NO_SHORTCUT
- Q_PRIVATE_SLOT(d_func(), void _q_buddyDeleted())
-#endif
friend class QTipLabel;
friend class QMessageBoxPrivate;
friend class QBalloonTip;
diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h
index d26bbf6a7f..fb6ccb04eb 100644
--- a/src/widgets/widgets/qlabel_p.h
+++ b/src/widgets/widgets/qlabel_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLABEL_P_H
#define QLABEL_P_H
@@ -69,6 +33,11 @@
#include "qmenu.h"
#endif
+#include <QtCore/qpointer.h>
+
+#include <array>
+#include <optional>
+
QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QLabelPrivate : public QFramePrivate
@@ -84,12 +53,12 @@ public:
QSize sizeForWidth(int w) const;
#if QT_CONFIG(movie)
- void _q_movieUpdated(const QRect&);
- void _q_movieResized(const QSize&);
+ void movieUpdated(const QRect &rect);
+ void movieResized(const QSize &size);
#endif
#ifndef QT_NO_SHORTCUT
void updateShortcut();
- void _q_buddyDeleted();
+ void buddyDeleted();
#endif
inline bool needTextControl() const {
Q_Q(const QLabel);
@@ -104,7 +73,7 @@ public:
void ensureTextControl() const;
void sendControlEvent(QEvent *e);
- void _q_linkHovered(const QString &link);
+ void linkHovered(const QString &link);
QRectF layoutRect() const;
QRect documentRect() const;
@@ -117,14 +86,15 @@ public:
mutable QSize sh;
mutable QSize msh;
QString text;
- QPixmap *pixmap;
- QPixmap *scaledpixmap;
- QImage *cachedimage;
+ std::optional<QPixmap> pixmap;
+ std::optional<QPixmap> scaledpixmap;
+ std::optional<QImage> cachedimage;
#ifndef QT_NO_PICTURE
- QPicture *picture;
+ std::optional<QPicture> picture;
#endif
#if QT_CONFIG(movie)
QPointer<QMovie> movie;
+ std::array<QMetaObject::Connection, 2> movieConnections;
#endif
mutable QWidgetTextControl *control;
mutable QTextCursor shortcutCursor;
diff --git a/src/widgets/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp
index 929b57a1e1..3a65b06415 100644
--- a/src/widgets/widgets/qlcdnumber.cpp
+++ b/src/widgets/widgets/qlcdnumber.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlcdnumber.h"
@@ -105,7 +69,7 @@ public:
Incidentally, QLCDNumber is the very oldest part of Qt, tracing
its roots back to a BASIC program on the \l{Sinclair Spectrum}{Sinclair Spectrum}.
- \sa QLabel, QFrame, {Digital Clock Example}, {Tetrix Example}
+ \sa QLabel, QFrame
*/
/*!
@@ -179,25 +143,25 @@ static QString int2string(int num, int base, int ndigits, bool *oflow)
} while (n != 0);
len = ndigits - len;
if (len > 0)
- s += QString(len, QLatin1Char(' '));
- s += QLatin1String(p);
+ s += QString(len, u' ');
+ s += QLatin1StringView(p);
}
break;
}
if (negative) {
- for (int i=0; i<(int)s.length(); i++) {
- if (s[i] != QLatin1Char(' ')) {
+ for (int i=0; i<(int)s.size(); i++) {
+ if (s[i] != u' ') {
if (i != 0) {
- s[i-1] = QLatin1Char('-');
+ s[i-1] = u'-';
} else {
- s.insert(0, QLatin1Char('-'));
+ s.insert(0, u'-');
}
break;
}
}
}
if (oflow)
- *oflow = (int)s.length() > ndigits;
+ *oflow = (int)s.size() > ndigits;
return s;
}
@@ -217,15 +181,15 @@ static QString double2string(double num, int base, int ndigits, bool *oflow)
int nd = ndigits;
do {
s = QString::asprintf("%*.*g", ndigits, nd, num);
- int i = s.indexOf(QLatin1Char('e'));
- if (i > 0 && s[i+1]==QLatin1Char('+')) {
- s[i] = QLatin1Char(' ');
- s[i+1] = QLatin1Char('e');
+ qsizetype i = s.indexOf(u'e');
+ if (i > 0 && s[i+1]==u'+') {
+ s[i] = u' ';
+ s[i+1] = u'e';
}
- } while (nd-- && (int)s.length() > ndigits);
+ } while (nd-- && (int)s.size() > ndigits);
}
if (oflow)
- *oflow = (int)s.length() > ndigits;
+ *oflow = (int)s.size() > ndigits;
return s;
}
@@ -408,9 +372,9 @@ void QLCDNumber::setDigitCount(int numDigits)
}
if (d->digitStr.isNull()) { // from constructor
d->ndigits = numDigits;
- d->digitStr.fill(QLatin1Char(' '), d->ndigits);
+ d->digitStr.fill(u' ', d->ndigits);
d->points.fill(0, d->ndigits);
- d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
+ d->digitStr[d->ndigits - 1] = u'0'; // "0" is the default number
} else {
bool doDisplay = d->ndigits == 0;
if (numDigits == d->ndigits) // no change
@@ -420,7 +384,7 @@ void QLCDNumber::setDigitCount(int numDigits)
if (numDigits > d->ndigits) { // expand
dif = numDigits - d->ndigits;
QString buf;
- buf.fill(QLatin1Char(' '), dif);
+ buf.fill(u' ', dif);
d->digitStr.insert(0, buf);
d->points.resize(numDigits);
for (i=numDigits-1; i>=dif; i--)
@@ -432,7 +396,7 @@ void QLCDNumber::setDigitCount(int numDigits)
d->digitStr = d->digitStr.right(numDigits);
QBitArray tmpPoints = d->points;
d->points.resize(numDigits);
- for (i=0; i<(int)numDigits; i++)
+ for (i=0; i<numDigits; i++)
d->points.setBit(i, tmpPoints.testBit(i+dif));
}
d->ndigits = numDigits;
@@ -715,25 +679,25 @@ void QLCDNumberPrivate::internalSetString(const QString& s)
Q_Q(QLCDNumber);
QString buffer(ndigits, QChar());
int i;
- int len = s.length();
+ int len = s.size();
QBitArray newPoints(ndigits);
if (!smallPoint) {
if (len == ndigits)
buffer = s;
else
- buffer = s.right(ndigits).rightJustified(ndigits, QLatin1Char(' '));
+ buffer = s.right(ndigits).rightJustified(ndigits, u' ');
} else {
int index = -1;
bool lastWasPoint = true;
newPoints.clearBit(0);
for (i=0; i<len; i++) {
- if (s[i] == QLatin1Char('.')) {
+ if (s[i] == u'.') {
if (lastWasPoint) { // point already set for digit?
if (index == ndigits - 1) // no more digits
break;
index++;
- buffer[index] = QLatin1Char(' '); // 2 points in a row, add space
+ buffer[index] = u' '; // 2 points in a row, add space
}
newPoints.setBit(index); // set decimal point
lastWasPoint = true;
@@ -753,7 +717,7 @@ void QLCDNumberPrivate::internalSetString(const QString& s)
newPoints.testBit(i));
}
for(i=0; i<ndigits-index-1; i++) {
- buffer[i] = QLatin1Char(' ');
+ buffer[i] = u' ';
newPoints.clearBit(i);
}
}
@@ -1159,7 +1123,7 @@ void QLCDNumberPrivate::drawSegment(const QPoint &pos, char segmentNo, QPainter
/*!
\property QLCDNumber::segmentStyle
- \brief the style of the LCDNumber
+ \brief the style of the LCDNumber.
\table
\header \li Style \li Result
diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h
index 644c39eaf3..bcd0623d02 100644
--- a/src/widgets/widgets/qlcdnumber.h
+++ b/src/widgets/widgets/qlcdnumber.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLCDNUMBER_H
#define QLCDNUMBER_H
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index a308f92f9d..8909ac80d9 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlineedit.h"
#include "qlineedit_p.h"
@@ -71,7 +35,7 @@
#endif
#include <private/qwidgettextcontrol_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#if QT_CONFIG(itemviews)
@@ -83,10 +47,9 @@
#include "private/qapplication_p.h"
#include "private/qshortcutmap_p.h"
#include "qkeysequence.h"
-#define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus) \
- && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \
+#define ACCEL_KEY(k) (!QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) \
&& !QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(k) ? \
- QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
+ u'\t' + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
#else
#define ACCEL_KEY(k) QString()
#endif
@@ -98,6 +61,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
Initialize \a option with the values from this QLineEdit. This method
is useful for subclasses when they need a QStyleOptionFrame, but don't want
@@ -135,54 +100,66 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
\image windows-lineedit.png
- A line edit allows the user to enter and edit a single line of
- plain text with a useful collection of editing functions,
- including undo and redo, cut and paste, and drag and drop (see
- \l setDragEnabled()).
+ A line edit allows users to enter and edit a single line of
+ plain text with useful editing functions, including undo and redo, cut and
+ paste, and drag and drop.
By changing the echoMode() of a line edit, it can also be used as
- a "write-only" field, for inputs such as passwords.
-
- The length of the text can be constrained to maxLength(). The text
- can be arbitrarily constrained using a validator() or an
- inputMask(), or both. When switching between a validator and an input mask
- on the same line edit, it is best to clear the validator or input mask to
- prevent undefined behavior.
+ a write-only field for inputs such as passwords.
- A related class is QTextEdit which allows multi-line, rich text
+ QTextEdit is a related class that allows multi-line, rich text
editing.
- You can change the text with setText() or insert(). The text is
- retrieved with text(); the displayed text (which may be different,
- see \l{EchoMode}) is retrieved with displayText(). Text can be
- selected with setSelection() or selectAll(), and the selection can
- be cut(), copy()ied and paste()d. The text can be aligned with
- setAlignment().
-
- When the text changes the textChanged() signal is emitted; when
- the text changes other than by calling setText() the textEdited()
- signal is emitted; when the cursor is moved the
- cursorPositionChanged() signal is emitted; and when the Return or
- Enter key is pressed the returnPressed() signal is emitted.
-
- When editing is finished, either because the line edit lost focus
- or Return/Enter is pressed the editingFinished() signal is
- emitted.
-
- Note that if there is a validator set on the line edit, the
- returnPressed()/editingFinished() signals will only be emitted if
- the validator returns QValidator::Acceptable.
-
- By default, QLineEdits have a frame as specified by platform
- style guides; you can turn it off by calling
- setFrame(false).
-
- The default key bindings are described below. The line edit also
- provides a context menu (usually invoked by a right mouse click)
- that presents some of these editing options.
+ \section1 Constraining Text
+
+ Use \l maxLength to define the maximum permitted length of a text. You can
+ use a \l inputMask and \l setValidator() to further constrain the text
+ content.
+
+ \section1 Editing Text
+
+ You can change the text with setText() or insert(). Use text() to retrieve
+ the text and displayText() to retrieve the displayed text (which may be
+ different, see \l{EchoMode}). You can select the text with setSelection() or
+ selectAll(), and you can cut(), copy(), and paste() the selection. To align
+ the text, use setAlignment().
+
+ When the text changes, the textChanged() signal is emitted. When the text
+ changes in some other way than by calling setText(), the textEdited() signal
+ is emitted. When the cursor is moved, the cursorPositionChanged() signal is
+ emitted. And when the Return or Enter key is selected, the returnPressed()
+ signal is emitted.
+
+ When text editing is finished, either because the line edit lost focus
+ or Return/Enter was selected, the editingFinished() signal is emitted.
+
+ If the line edit focus is lost without any text changes, the
+ editingFinished() signal won't be emitted.
+
+ If there is a validator set on the line edit, the
+ returnPressed()/editingFinished() signals will only be emitted if the
+ validator returns QValidator::Acceptable.
+
+ For more information on the many ways that QLineEdit can be used, see
+ \l {Line Edits Example}, which also provides a selection of line edit
+ examples that show the effects of various properties and validators on the
+ input and output supplied by the user.
+
+ \section1 Setting a Frame
+
+ By default, QLineEdits have a frame as specified in the platform
+ style guides. You can turn the frame off by calling setFrame(false).
+
+ \section1 Default Key Bindings
+
+ The table below describes the default key bindings.
+
+ \note The line edit also provides a context menu (usually invoked by a
+ right-click) that presents some of the editing options listed below.
+
\target desc
\table
- \header \li Keypress \li Action
+ \header \li Keystroke \li Action
\row \li Left Arrow \li Moves the cursor one character to the left.
\row \li Shift+Left Arrow \li Moves and selects text one character to the left.
\row \li Right Arrow \li Moves the cursor one character to the right.
@@ -193,7 +170,7 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
\row \li Ctrl+Backspace \li Deletes the word to the left of the cursor.
\row \li Delete \li Deletes the character to the right of the cursor.
\row \li Ctrl+Delete \li Deletes the word to the right of the cursor.
- \row \li Ctrl+A \li Select all.
+ \row \li Ctrl+A \li Selects all.
\row \li Ctrl+C \li Copies the selected text to the clipboard.
\row \li Ctrl+Insert \li Copies the selected text to the clipboard.
\row \li Ctrl+K \li Deletes to the end of the line.
@@ -205,10 +182,10 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
\row \li Ctrl+Y \li Redoes the last undone operation.
\endtable
- Any other key sequence that represents a valid character, will
- cause the character to be inserted into the line edit.
+ Any other keystroke 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}
*/
@@ -264,13 +241,11 @@ QLineEdit::QLineEdit(QWidget* parent)
}
/*!
- Constructs a line edit containing the text \a contents.
+ Constructs a line edit containing the text \a contents as a child of
+ \a parent.
- The cursor position is set to the end of the line and the maximum
- text length to 32767 characters.
-
- The \a parent and argument is sent to the QWidget
- constructor.
+ The cursor position is set to the end of the line and the maximum text
+ length to 32767 characters.
\sa text(), setMaxLength()
*/
@@ -294,10 +269,10 @@ QLineEdit::~QLineEdit()
/*!
\property QLineEdit::text
- \brief the line edit's text.
+ \brief The line edit's text.
Setting this property clears the selection, clears the undo/redo
- history, moves the cursor to the end of the line and resets the
+ history, moves the cursor to the end of the line, and resets the
\l modified property to false. The text is not validated when
inserted with setText().
@@ -323,7 +298,7 @@ void QLineEdit::setText(const QString& text)
\since 4.7
\property QLineEdit::placeholderText
- \brief the line edit's placeholder text.
+ \brief The line edit's placeholder text.
Setting this property makes the line edit display a grayed-out
placeholder text as long as the line edit is empty.
@@ -355,12 +330,12 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText)
/*!
\property QLineEdit::displayText
- \brief the displayed text.
+ \brief The displayed text.
- If \l echoMode is \l Normal this returns the same as text(); if
- \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of
- platform-dependent password mask characters text().length() in size,
- e.g. "******"; if \l EchoMode is \l NoEcho returns an empty string, "".
+ If \l echoMode is \l Normal, this returns the same as text(). If
+ \l EchoMode is \l Password or \l PasswordEchoOnEdit, it returns a string of
+ platform-dependent password mask characters (e.g. "******"). If \l EchoMode
+ is \l NoEcho, it returns an empty string.
By default, this property contains an empty string.
@@ -376,12 +351,12 @@ QString QLineEdit::displayText() const
/*!
\property QLineEdit::maxLength
- \brief the maximum permitted length of the text.
+ \brief The maximum permitted length of the text.
If the text is too long, it is truncated at the limit.
- If truncation occurs any selected text will be unselected, the
- cursor position is set to 0 and the first part of the string is
+ If truncation occurs, any selected text will be unselected, the
+ cursor position is set to 0, and the first part of the string is
shown.
If the line edit has an input mask, the mask defines the maximum
@@ -406,10 +381,10 @@ void QLineEdit::setMaxLength(int maxLength)
/*!
\property QLineEdit::frame
- \brief whether the line edit draws itself with a frame.
+ \brief Whether the line edit draws itself with a frame.
- If enabled (the default) the line edit draws itself inside a
- frame, otherwise the line edit draws itself without any frame.
+ If enabled (the default), the line edit draws itself inside a
+ frame. Otherwise, the line edit draws itself without any frame.
*/
bool QLineEdit::hasFrame() const
{
@@ -469,9 +444,9 @@ QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
\property QLineEdit::clearButtonEnabled
\brief Whether the line edit displays a clear button when it is not empty.
- If enabled, the line edit displays a trailing \e clear button when it contains
- some text, otherwise the line edit does not show a clear button (the
- default).
+ If enabled, the line edit displays a trailing \uicontrol clear button when
+ it contains some text. Otherwise, the line edit does not show a
+ \uicontrol clear button (the default).
\sa addAction(), removeAction()
\since 5.2
@@ -488,13 +463,13 @@ void QLineEdit::setClearButtonEnabled(bool enable)
if (enable) {
QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this);
clearAction->setEnabled(!isReadOnly());
- clearAction->setObjectName(QLatin1String(clearButtonActionNameC));
+ clearAction->setObjectName(QLatin1StringView(clearButtonActionNameC));
int flags = QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText;
auto widgetAction = d->addAction(clearAction, nullptr, QLineEdit::TrailingPosition, flags);
widgetAction->setVisible(!text().isEmpty());
} else {
- QAction *clearAction = findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+ QAction *clearAction = findChild<QAction *>(QLatin1StringView(clearButtonActionNameC));
Q_ASSERT(clearAction);
d->removeAction(clearAction);
delete clearAction;
@@ -507,7 +482,7 @@ void QLineEdit::setClearButtonEnabled(bool enable)
bool QLineEdit::isClearButtonEnabled() const
{
#if QT_CONFIG(action)
- return findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+ return findChild<QAction *>(QLatin1StringView(clearButtonActionNameC));
#else
return false;
#endif
@@ -535,9 +510,8 @@ void QLineEdit::setFrame(bool enable)
password should be kept secret.
\value Password Display platform-dependent password mask characters instead
of the characters actually entered.
- \value PasswordEchoOnEdit Display characters as they are entered
- while editing otherwise display characters as with
- \c Password.
+ \value PasswordEchoOnEdit Display characters only while they are entered.
+ Otherwise, display characters as with \c Password.
\sa setEchoMode(), echoMode()
*/
@@ -545,13 +519,13 @@ void QLineEdit::setFrame(bool enable)
/*!
\property QLineEdit::echoMode
- \brief the line edit's echo mode.
+ \brief The line edit's echo mode.
The echo mode determines how the text entered in the line edit is
displayed (or echoed) to the user.
The most common setting is \l Normal, in which the text entered by the
- user is displayed verbatim, but QLineEdit also supports modes that allow
+ user is displayed verbatim. QLineEdit also supports modes that allow
the entered text to be suppressed or obscured: these include \l NoEcho,
\l Password and \l PasswordEchoOnEdit.
@@ -608,15 +582,15 @@ const QValidator * QLineEdit::validator() const
value during editing, but will be prevented from editing the text to a
value that \a v validates as \l{QValidator::}{Invalid}.
- This allows you to constrain the text that shall finally be entered when editing is
- done, while leaving users with enough freedom to edit the text from one valid state
- to another.
+ This allows you to constrain the text that will be stored when editing is
+ done while leaving users with enough freedom to edit the text from one valid
+ state to another.
- If \a v == 0, setValidator() removes the current input validator.
- The initial setting is to have no input validator (i.e. any input
- is accepted up to maxLength()).
+ To remove the current input validator, pass \c nullptr. The initial setting
+ is to have no input validator (any input is accepted up to maxLength()).
- \sa validator(), hasAcceptableInput(), QIntValidator, QDoubleValidator, QRegularExpressionValidator
+ \sa validator(), hasAcceptableInput(), QIntValidator, QDoubleValidator,
+ QRegularExpressionValidator
*/
void QLineEdit::setValidator(const QValidator *v)
@@ -638,8 +612,7 @@ void QLineEdit::setValidator(const QValidator *v)
use the QSortFilterProxyModel to ensure that the QCompleter's model contains
only valid entries.
- If \a c == 0, setCompleter() removes the current completer, effectively
- disabling auto completion.
+ To remove the completer and disable auto-completion, pass a \c nullptr.
\sa QCompleter
*/
@@ -649,7 +622,7 @@ void QLineEdit::setCompleter(QCompleter *c)
if (c == d->control->completer())
return;
if (d->control->completer()) {
- disconnect(d->control->completer(), nullptr, this, nullptr);
+ d->disconnectCompleter();
d->control->completer()->setWidget(nullptr);
if (d->control->completer()->parent() == this)
delete d->control->completer();
@@ -659,12 +632,8 @@ void QLineEdit::setCompleter(QCompleter *c)
return;
if (c->widget() == nullptr)
c->setWidget(this);
- if (hasFocus()) {
- QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
- this, SLOT(setText(QString)));
- QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
- this, SLOT(_q_completionHighlighted(QString)));
- }
+ if (hasFocus())
+ d->connectCompleter();
}
/*!
@@ -697,7 +666,7 @@ QSize QLineEdit::sizeHint() const
int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2 * QLineEditPrivate::verticalMargin
+ tm.top() + tm.bottom()
+ d->topmargin + d->bottommargin;
- int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2 * QLineEditPrivate::horizontalMargin
+ int w = fm.horizontalAdvance(u'x') * 17 + 2 * QLineEditPrivate::horizontalMargin
+ tm.left() + tm.right()
+ d->leftmargin + d->rightmargin; // "some"
QStyleOptionFrame opt;
@@ -732,7 +701,7 @@ QSize QLineEdit::minimumSizeHint() const
/*!
\property QLineEdit::cursorPosition
- \brief the current cursor position for this line edit.
+ \brief The current cursor position for this line edit.
Setting the cursor position causes a repaint when appropriate.
@@ -765,7 +734,7 @@ int QLineEdit::cursorPositionAt(const QPoint &pos)
/*!
\property QLineEdit::alignment
- \brief the alignment of the line edit.
+ \brief The alignment of the line edit.
Both horizontal and vertical alignment is allowed here, Qt::AlignJustify
will map to Qt::AlignLeft.
@@ -790,9 +759,9 @@ void QLineEdit::setAlignment(Qt::Alignment alignment)
/*!
- Moves the cursor forward \a steps characters. If \a mark is true
- each character moved over is added to the selection; if \a mark is
- false the selection is cleared.
+ Moves the cursor forward \a steps characters. If \a mark is true,
+ each character moved over is added to the selection. If \a mark is
+ false, the selection is cleared.
\sa cursorBackward()
*/
@@ -805,9 +774,9 @@ void QLineEdit::cursorForward(bool mark, int steps)
/*!
- Moves the cursor back \a steps characters. If \a mark is true each
- character moved over is added to the selection; if \a mark is
- false the selection is cleared.
+ Moves the cursor back \a steps characters. If \a mark is true, each
+ character moved over is added to the selection. If \a mark is
+ false, the selection is cleared.
\sa cursorForward()
*/
@@ -844,9 +813,9 @@ void QLineEdit::cursorWordBackward(bool mark)
/*!
If no text is selected, deletes the character to the left of the
- text cursor and moves the cursor one position to the left. If any
+ text cursor, and moves the cursor one position to the left. If any
text is selected, the cursor is moved to the beginning of the
- selected text and the selected text is deleted.
+ selected text, and the selected text is deleted.
\sa del()
*/
@@ -859,7 +828,7 @@ void QLineEdit::backspace()
/*!
If no text is selected, deletes the character to the right of the
text cursor. If any text is selected, the cursor is moved to the
- beginning of the selected text and the selected text is deleted.
+ beginning of the selected text, and the selected text is deleted.
\sa backspace()
*/
@@ -873,7 +842,7 @@ void QLineEdit::del()
/*!
Moves the text cursor to the beginning of the line unless it is
already there. If \a mark is true, text is selected towards the
- first position; otherwise, any selected text is unselected if the
+ first position. Otherwise, any selected text is unselected if the
cursor is moved.
\sa end()
@@ -888,7 +857,7 @@ void QLineEdit::home(bool mark)
/*!
Moves the text cursor to the end of the line unless it is already
there. If \a mark is true, text is selected towards the last
- position; otherwise, any selected text is unselected if the cursor
+ position. Otherwise, any selected text is unselected if the cursor
is moved.
\sa home()
@@ -903,14 +872,14 @@ void QLineEdit::end(bool mark)
/*!
\property QLineEdit::modified
- \brief whether the line edit's contents has been modified by the user.
+ \brief Whether the line edit's contents has been modified by the user.
The modified flag is never read by QLineEdit; it has a default value
of false and is changed to true whenever the user changes the line
edit's contents.
This is useful for things that need to provide a default value but
- do not start out knowing what the default should be (perhaps it
+ do not start out knowing what the default should be (for example, it
depends on other fields on the form). Start the line edit without
the best default, and when the default is known, if modified()
returns \c false (the user hasn't entered any text), insert the
@@ -933,10 +902,10 @@ void QLineEdit::setModified(bool modified)
/*!
\property QLineEdit::hasSelectedText
- \brief whether there is any text selected.
+ \brief Whether there is any text selected.
hasSelectedText() returns \c true if some or all of the text has been
- selected by the user; otherwise returns \c false.
+ selected by the user. Otherwise, it returns \c false.
By default, this property is \c false.
@@ -952,9 +921,9 @@ bool QLineEdit::hasSelectedText() const
/*!
\property QLineEdit::selectedText
- \brief the selected text.
+ \brief The selected text.
- If there is no selected text this property's value is
+ If there is no selected text, this property's value is
an empty string.
By default, this property contains an empty string.
@@ -970,7 +939,7 @@ QString QLineEdit::selectedText() const
/*!
Returns the index of the first selected character in the
- line edit or -1 if no text is selected.
+ line edit (or -1 if no text is selected).
\sa selectedText()
\sa selectionEnd()
@@ -985,7 +954,7 @@ int QLineEdit::selectionStart() const
/*!
Returns the index of the character directly after the selection
- in the line edit or -1 if no text is selected.
+ in the line edit (or -1 if no text is selected).
\since 5.10
\sa selectedText()
@@ -1039,7 +1008,7 @@ void QLineEdit::setSelection(int start, int length)
/*!
\property QLineEdit::undoAvailable
- \brief whether undo is available.
+ \brief Whether undo is available.
Undo becomes available once the user has modified the text in the line edit.
@@ -1054,10 +1023,10 @@ bool QLineEdit::isUndoAvailable() const
/*!
\property QLineEdit::redoAvailable
- \brief whether redo is available.
+ \brief Whether redo is available.
Redo becomes available once the user has performed one or more undo operations
- on text in the line edit.
+ on the text in the line edit.
By default, this property is \c false.
*/
@@ -1070,7 +1039,7 @@ bool QLineEdit::isRedoAvailable() const
/*!
\property QLineEdit::dragEnabled
- \brief whether the lineedit starts a drag if the user presses and
+ \brief Whether the line edit starts a drag if the user presses and
moves the mouse on some selected text.
Dragging is disabled by default.
@@ -1090,17 +1059,18 @@ void QLineEdit::setDragEnabled(bool b)
/*!
\property QLineEdit::cursorMoveStyle
- \brief the movement style of cursor in this line edit.
+ \brief The movement style of the cursor in this line edit.
\since 4.8
- When this property is set to Qt::VisualMoveStyle, the line edit will use visual
- movement style. Pressing the left arrow key will always cause the cursor to move
- left, regardless of the text's writing direction. The same behavior applies to
- right arrow key.
+ When this property is set to Qt::VisualMoveStyle, the line edit will use a
+ visual movement style. Using the left arrow key will always cause the
+ cursor to move left, regardless of the text's writing direction. The same
+ behavior applies to the right arrow key.
- When the property is Qt::LogicalMoveStyle (the default), within a LTR text block,
- increase cursor position when pressing left arrow key, decrease cursor position
- when pressing the right arrow key. If the text block is right to left, the opposite
+ When the property is set to Qt::LogicalMoveStyle (the default), within a
+ left-to-right (LTR) text block, using the left arrow key will increase
+ the cursor position, whereas using the right arrow key will decrease the
+ cursor position. If the text block is right-to-left (RTL), the opposite
behavior applies.
*/
@@ -1118,7 +1088,7 @@ void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style)
/*!
\property QLineEdit::acceptableInput
- \brief whether the input satisfies the inputMask and the
+ \brief Whether the input satisfies the inputMask and the
validator.
By default, this property is \c true.
@@ -1132,11 +1102,11 @@ bool QLineEdit::hasAcceptableInput() const
}
/*!
+ \since 4.5
Sets the margins around the text inside the frame to have the
sizes \a left, \a top, \a right, and \a bottom.
- \since 4.5
- See also textMargins().
+ \sa textMargins()
*/
void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
{
@@ -1147,7 +1117,7 @@ void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
\since 4.6
Sets the \a margins around the text inside the frame.
- See also textMargins().
+ \sa textMargins()
*/
void QLineEdit::setTextMargins(const QMargins &margins)
{
@@ -1173,41 +1143,47 @@ QMargins QLineEdit::textMargins() const
\property QLineEdit::inputMask
\brief The validation input mask.
- If no mask is set, inputMask() returns an empty string.
-
Sets the QLineEdit's validation mask. Validators can be used
- instead of, or in conjunction with masks; see setValidator().
+ instead of, or in conjunction with masks; see setValidator(). The default is
+ an empty string, which means that no input mask is used.
- Unset the mask and return to normal QLineEdit operation by passing
- an empty string ("").
+ To unset the mask and return to normal QLineEdit operation, pass an empty
+ string.
- The input mask is an input template string. It can contain the following elements:
+ The input mask is an input template string. It can contain the following
+ elements:
\table
- \row \li Mask Characters \li Defines the \l {QChar::} {Category} of input characters
- that are considered valid in this position
- \row \li Meta Characters \li Various special meanings
- \row \li Separators \li All other characters are regarded as immutable separators
+ \row \li Mask Characters \li Defines the \l {QChar::} {Category} of input
+ characters that are considered valid in this position.
+ \row \li Meta Characters \li Various special meanings (see details below).
+ \row \li Separators \li All other characters are regarded as immutable
+ separators.
\endtable
- The following table shows the mask and meta characters that can be used in an input mask.
+ The following table shows the mask and meta characters that can be used in
+ an input mask.
\table
\header \li Mask Character \li Meaning
- \row \li \c A \li character of the Letter category required, such as A-Z, a-z.
- \row \li \c a \li character of the Letter category permitted but not required.
- \row \li \c N \li character of the Letter or Number category required, such as
- A-Z, a-z, 0-9.
- \row \li \c n \li character of the Letter or Number category permitted but not required.
+ \row \li \c A \li Character of the Letter category required, such as A-Z,
+ a-z.
+ \row \li \c a \li Character of the Letter category permitted but not
+ required.
+ \row \li \c N \li Character of the Letter or Number category required, such
+ as A-Z, a-z, 0-9.
+ \row \li \c n \li Character of the Letter or Number category permitted but
+ not required.
\row \li \c X \li Any non-blank character required.
\row \li \c x \li Any non-blank character permitted but not required.
- \row \li \c 9 \li character of the Number category required, e.g 0-9.
- \row \li \c 0 \li character of the Number category permitted but not required.
- \row \li \c D \li character of the Number category and larger than zero required,
- such as 1-9
- \row \li \c d \li character of the Number category and larger than zero permitted but not
- required, such as 1-9.
- \row \li \c # \li character of the Number category, or plus/minus sign permitted but not
+ \row \li \c 9 \li Character of the Number category required, such as 0-9.
+ \row \li \c 0 \li Character of the Number category permitted but not
required.
+ \row \li \c D \li Character of the Number category and larger than zero
+ required, such as 1-9.
+ \row \li \c d \li Character of the Number category and larger than zero
+ permitted but not required, such as 1-9.
+ \row \li \c # \li Character of the Number category, or plus/minus sign
+ permitted but not required.
\row \li \c H \li Hexadecimal character required. A-F, a-f, 0-9.
\row \li \c h \li Hexadecimal character permitted but not required.
\row \li \c B \li Binary character required. 0-1.
@@ -1216,11 +1192,11 @@ QMargins QLineEdit::textMargins() const
\row \li \c > \li All following alphabetic characters are uppercased.
\row \li \c < \li All following alphabetic characters are lowercased.
\row \li \c ! \li Switch off case conversion.
- \row \li \c {;c} \li Terminates the input mask and sets the \e{blank} character to \e{c}.
+ \row \li \c {;c} \li Terminates the input mask and sets the \e{blank}
+ character to \e{c}.
\row \li \c {[ ] { }} \li Reserved.
- \row \li \tt{\\} \li Use \tt{\\} to escape the special
- characters listed above to use them as
- separators.
+ \row \li \tt{\\} \li Use \tt{\\} to escape the special characters listed
+ above to use them as separators.
\endtable
When created or cleared, the line edit will be filled with a copy of the
@@ -1233,7 +1209,7 @@ QMargins QLineEdit::textMargins() const
unmodified content can be read using displayText().
The hasAcceptableInput() method returns false if the current content of the
- line edit does not fulfil the requirements of the input mask.
+ line edit does not fulfill the requirements of the input mask.
Examples:
\table
@@ -1264,8 +1240,10 @@ void QLineEdit::setInputMask(const QString &inputMask)
}
/*!
- Selects all the text (i.e. highlights it) and moves the cursor to
- the end. This is useful when a default value has been inserted
+ Selects all the text (highlights it) and moves the cursor to
+ the end.
+
+ \note This is useful when a default value has been inserted
because if the user types before clicking on the widget, the
selected text will be deleted.
@@ -1293,7 +1271,7 @@ void QLineEdit::deselect()
/*!
Deletes any selected text, inserts \a newText, and validates the
- result. If it is valid, it sets it as the new contents of the line
+ result. If it is valid, it sets the new text as the new contents of the line
edit.
\sa setText(), clear()
@@ -1342,7 +1320,7 @@ void QLineEdit::redo()
/*!
\property QLineEdit::readOnly
- \brief whether the line edit is read only.
+ \brief Whether the line edit is read-only.
In read-only mode, the user can still copy the text to the
clipboard, or drag and drop the text (if echoMode() is \l Normal),
@@ -1375,7 +1353,7 @@ void QLineEdit::setReadOnly(bool enable)
QEvent event(QEvent::ReadOnlyChange);
QCoreApplication::sendEvent(this, &event);
update();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::State changedState;
changedState.readOnly = true;
QAccessibleStateChangeEvent ev(this, changedState);
@@ -1465,7 +1443,10 @@ bool QLineEdit::event(QEvent * e)
#endif
//d->separate();
} else if (e->type() == QEvent::WindowActivate) {
- QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
+ QTimer::singleShot(0, this, [this]() {
+ Q_D(QLineEdit);
+ d->handleWindowActivate();
+ });
#ifndef QT_NO_SHORTCUT
} else if (e->type() == QEvent::ShortcutOverride) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
@@ -1481,6 +1462,8 @@ bool QLineEdit::event(QEvent * e)
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
d->setCursorVisible(true);
}
+ } else if (e->type() == QEvent::Hide) {
+ d->control->setBlinkingCursorEnabled(false);
#if QT_CONFIG(action)
} else if (e->type() == QEvent::ActionRemoved) {
d->removeAction(static_cast<QActionEvent *>(e)->action());
@@ -1645,7 +1628,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
if (d->control->composeMode()) {
int preeditPos = d->control->cursor();
int posInPreedit = position - d->control->cursor();
- int preeditLength = d->control->preeditAreaText().length();
+ int preeditLength = d->control->preeditAreaText().size();
bool positionOnPreedit = false;
if (posInPreedit >= 0 && posInPreedit <= preeditLength)
@@ -1681,8 +1664,9 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
/*!
\fn void QLineEdit::returnPressed()
- This signal is emitted when the Return or Enter key is pressed.
- Note that if there is a validator() or inputMask() set on the line
+ This signal is emitted when the Return or Enter key is used.
+
+ \note If there is a validator() or inputMask() set on the line
edit, the returnPressed() signal will only be emitted if the input
follows the inputMask() and the validator() returns
QValidator::Acceptable.
@@ -1691,41 +1675,39 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
/*!
\fn void QLineEdit::editingFinished()
- This signal is emitted when the Return or Enter key is pressed, or
- if the line edit loses focus and its contents have changed since the
- last time this signal was emitted.
+ This signal is emitted when the Return or Enter key is used, or if the line
+ edit loses focus and its contents have changed since the last time this
+ signal was emitted.
- Note that if there is a validator() or
- inputMask() set on the line edit and enter/return is pressed, the
- editingFinished() signal will only be emitted if the input follows
- the inputMask() and the validator() returns QValidator::Acceptable.
+ \note If there is a validator() or inputMask() set on the line edit and
+ enter/return is used, the editingFinished() signal will only be emitted
+ if the input follows the inputMask() and the validator() returns
+ QValidator::Acceptable.
*/
/*!
\fn void QLineEdit::inputRejected()
\since 5.12
- This signal is emitted when the user presses a key that is not
- considered to be acceptable input. For example, if a key press
- results in a validator's validate() call to return Invalid.
- Another case is when trying to enter in more characters beyond the
- maximum length of the line edit.
+ This signal is emitted when the user uses a key that is not
+ considered to be valid input. For example, if using a key results in a
+ validator's \l {QValidator::validate()}{validate()} call to return
+ \l {QValidator::Invalid}{Invalid}. Another case is when trying
+ to enter more characters beyond the maximum length of the line edit.
- Note: This signal will still be emitted in a case where part of
- the text is accepted but not all of it is. For example, if there
- is a maximum length set and the clipboard text is longer than the
- maximum length when it is pasted.
+ \note This signal will still be emitted when only a part of the text is
+ accepted. For example, if there is a maximum length set and the clipboard
+ text is longer than the maximum length when it is pasted.
*/
/*!
Converts the given key press \a event into a line edit action.
- If Return or Enter is pressed and the current text is valid (or
+ If Return or Enter is used and the current text is valid (or
can be \l{QValidator::fixup()}{made valid} by the
validator), the signal returnPressed() is emitted.
- The default key bindings are listed in the class's detailed
- description.
+ \sa {Default Key Bindings}
*/
void QLineEdit::keyPressEvent(QKeyEvent *event)
@@ -1774,26 +1756,26 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
}
#endif
d->control->processKeyEvent(event);
- if (event->isAccepted()) {
- if (layoutDirection() != d->control->layoutDirection())
- setLayoutDirection(d->control->layoutDirection());
+ if (event->isAccepted())
d->control->updateCursorBlinking();
- }
}
/*!
\reimp
*/
-void QLineEdit::keyReleaseEvent(QKeyEvent *)
+void QLineEdit::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QLineEdit);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel();
d->control->updateCursorBlinking();
+ QWidget::keyReleaseEvent(e);
}
/*!
\since 4.4
- Returns a rectangle that includes the lineedit cursor.
+ Returns a rectangle that includes the line edit cursor.
*/
QRect QLineEdit::cursorRect() const
{
@@ -1806,10 +1788,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
@@ -1841,6 +1819,22 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
*/
QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
+#ifdef Q_OS_ANDROID
+ // QTBUG-61652
+ if (property == Qt::ImEnterKeyType) {
+ QWidget *next = nextInFocusChain();
+ while (next && next != this && next->focusPolicy() == Qt::NoFocus)
+ next = next->nextInFocusChain();
+ if (next) {
+ const auto nextYPos = next->mapToGlobal(QPoint(0, 0)).y();
+ const auto currentYPos = mapToGlobal(QPoint(0, 0)).y();
+ if (currentYPos < nextYPos)
+ // Set EnterKey to KeyNext type only if the next widget
+ // in the focus chain is below current QLineEdit
+ return Qt::EnterKeyNext;
+ }
+ }
+#endif
return inputMethodQuery(property, QVariant());
}
@@ -1850,12 +1844,15 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property, QVariant arg
{
Q_D(const QLineEdit);
switch(property) {
+ case Qt::ImEnabled:
+ return isEnabled() && !isReadOnly();
case Qt::ImCursorRectangle:
return d->cursorRect();
case Qt::ImAnchorRectangle:
return d->adjustedControlRect(d->control->anchorRect());
case Qt::ImFont:
return font();
+ case Qt::ImAbsolutePosition:
case Qt::ImCursorPosition: {
const QPointF pt = argument.toPointF();
if (!pt.isNull())
@@ -1906,8 +1903,11 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
d->control->moveCursor(d->control->nextMaskBlank(0));
else if (!d->control->hasSelectedText())
selectAll();
+ else
+ updateMicroFocus();
} else if (e->reason() == Qt::MouseFocusReason) {
d->clickCausedFocus = 1;
+ updateMicroFocus();
}
#ifdef QT_KEYPAD_NAVIGATION
if (!QApplicationPrivate::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) {
@@ -1925,10 +1925,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
#if QT_CONFIG(completer)
if (d->control->completer()) {
d->control->completer()->setWidget(this);
- QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
- this, SLOT(setText(QString)));
- QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
- this, SLOT(_q_completionHighlighted(QString)));
+ d->connectCompleter();
}
#endif
update();
@@ -1967,9 +1964,8 @@ void QLineEdit::focusOutEvent(QFocusEvent *e)
d->control->setCancelText(QString());
#endif
#if QT_CONFIG(completer)
- if (d->control->completer()) {
- QObject::disconnect(d->control->completer(), nullptr, this, nullptr);
- }
+ if (d->control->completer())
+ d->disconnectCompleter();
#endif
QWidget::focusOutEvent(e);
}
@@ -1990,21 +1986,28 @@ void QLineEdit::paintEvent(QPaintEvent *)
p.setClipRect(r);
QFontMetrics fm = fontMetrics();
+ int fmHeight = 0;
+ if (d->shouldShowPlaceholderText())
+ fmHeight = fm.boundingRect(d->placeholderText).height();
+ else
+ fmHeight = fm.boundingRect(d->control->text() + d->control->preeditAreaText()).height();
+ fmHeight = qMax(fmHeight, fm.height());
+
Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment));
switch (va & Qt::AlignVertical_Mask) {
case Qt::AlignBottom:
- d->vscroll = r.y() + r.height() - fm.height() - QLineEditPrivate::verticalMargin;
+ d->vscroll = r.y() + r.height() - fmHeight - QLineEditPrivate::verticalMargin;
break;
case Qt::AlignTop:
d->vscroll = r.y() + QLineEditPrivate::verticalMargin;
break;
default:
//center
- d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
+ d->vscroll = r.y() + (r.height() - fmHeight + 1) / 2;
break;
}
QRect lineRect(r.x() + QLineEditPrivate::horizontalMargin, d->vscroll,
- r.width() - 2 * QLineEditPrivate::horizontalMargin, fm.height());
+ r.width() - 2 * QLineEditPrivate::horizontalMargin, fmHeight);
if (d->shouldShowPlaceholderText()) {
if (!d->placeholderText.isEmpty()) {
@@ -2088,12 +2091,12 @@ void QLineEdit::paintEvent(QPaintEvent *)
// Asian users see an IM selection text as cursor on candidate
// selection phase of input method, so the ordinary cursor should be
// invisible if we have a preedit string. another condition is when inputmask
- // isn't empty,we don't need draw cursor,because cursor and character overlaping
+ // isn't empty,we don't need draw cursor,because cursor and character overlapping
// area is white.
if (d->cursorVisible && !d->control->isReadOnly() && d->control->inputMask().isEmpty())
flags |= QWidgetLineControl::DrawCursor;
- d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth, &panel));
+ d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth, &panel, this));
d->control->draw(&p, topLeft, r, flags);
}
@@ -2105,7 +2108,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
{
Q_D(QLineEdit);
- if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
+ if (!d->control->isReadOnly() && e->mimeData()->hasFormat("text/plain"_L1)) {
e->acceptProposedAction();
d->control->moveCursor(d->xToPos(e->position().toPoint().x()), false);
d->cursorVisible = true;
@@ -2149,13 +2152,13 @@ void QLineEdit::dropEvent(QDropEvent* e)
if (e->source() == this) {
if (e->dropAction() == Qt::MoveAction) {
if (selStart > oldSelStart && selStart <= oldSelEnd)
- setSelection(oldSelStart, str.length());
+ setSelection(oldSelStart, str.size());
else if (selStart > oldSelEnd)
- setSelection(selStart - str.length(), str.length());
+ setSelection(selStart - str.size(), str.size());
else
- setSelection(selStart, str.length());
+ setSelection(selStart, str.size());
} else {
- setSelection(selStart, str.length());
+ setSelection(selStart, str.size());
}
}
} else {
@@ -2172,10 +2175,10 @@ void QLineEdit::dropEvent(QDropEvent* e)
createStandardContextMenu().
If you do not want the line edit to have a context menu, you can set
- its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
- customize the context menu, reimplement this function. If you want
- to extend the standard context menu, reimplement this function, call
- createStandardContextMenu() and extend the menu returned.
+ its \l contextMenuPolicy to Qt::NoContextMenu. To customize the context
+ menu, reimplement this function. To extend the standard context menu,
+ reimplement this function, call createStandardContextMenu(), and extend the
+ menu returned.
\snippet code/src_gui_widgets_qlineedit.cpp 0
@@ -2192,14 +2195,7 @@ void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
}
}
-static inline void setActionIcon(QAction *action, const QString &name)
-{
- const QIcon icon = QIcon::fromTheme(name);
- if (!icon.isNull())
- action->setIcon(icon);
-}
-
-/*! This function creates the standard context menu which is shown
+/*! Creates the standard context menu, which is shown
when the user clicks on the line edit with the right mouse
button. It is called from the default contextMenuEvent() handler.
The popup menu's ownership is transferred to the caller.
@@ -2209,19 +2205,19 @@ QMenu *QLineEdit::createStandardContextMenu()
{
Q_D(QLineEdit);
QMenu *popup = new QMenu(this);
- popup->setObjectName(QLatin1String("qt_edit_menu"));
+ popup->setObjectName("qt_edit_menu"_L1);
QAction *action = nullptr;
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
action->setEnabled(d->control->isUndoAvailable());
setActionIcon(action, QStringLiteral("edit-undo"));
- connect(action, SIGNAL(triggered()), SLOT(undo()));
+ connect(action, &QAction::triggered, this, &QLineEdit::undo);
action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
action->setEnabled(d->control->isRedoAvailable());
setActionIcon(action, QStringLiteral("edit-redo"));
- connect(action, SIGNAL(triggered()), SLOT(redo()));
+ connect(action, &QAction::triggered, this, &QLineEdit::redo);
popup->addSeparator();
}
@@ -2232,20 +2228,20 @@ QMenu *QLineEdit::createStandardContextMenu()
action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
setActionIcon(action, QStringLiteral("edit-cut"));
- connect(action, SIGNAL(triggered()), SLOT(cut()));
+ connect(action, &QAction::triggered, this, &QLineEdit::cut);
}
action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
action->setEnabled(d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
setActionIcon(action, QStringLiteral("edit-copy"));
- connect(action, SIGNAL(triggered()), SLOT(copy()));
+ connect(action, &QAction::triggered, this, &QLineEdit::copy);
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
action->setEnabled(!d->control->isReadOnly() && !QGuiApplication::clipboard()->text().isEmpty());
setActionIcon(action, QStringLiteral("edit-paste"));
- connect(action, SIGNAL(triggered()), SLOT(paste()));
+ connect(action, &QAction::triggered, this, &QLineEdit::paste);
}
#endif
@@ -2253,7 +2249,8 @@ QMenu *QLineEdit::createStandardContextMenu()
action = popup->addAction(QLineEdit::tr("Delete"));
action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
setActionIcon(action, QStringLiteral("edit-delete"));
- connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
+ connect(action, &QAction::triggered,
+ d->control, &QWidgetLineControl::_q_deleteSelected);
}
if (!popup->isEmpty())
@@ -2263,7 +2260,7 @@ QMenu *QLineEdit::createStandardContextMenu()
action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
setActionIcon(action, QStringLiteral("edit-select-all"));
d->selectAllAction = action;
- connect(action, SIGNAL(triggered()), SLOT(selectAll()));
+ connect(action, &QAction::triggered, this, &QLineEdit::selectAll);
if (!d->control->isReadOnly() && QGuiApplication::styleHints()->useRtlExtensions()) {
popup->addSeparator();
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index b4f6641b86..8955a67895 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLINEEDIT_H
#define QLINEEDIT_H
@@ -250,20 +214,6 @@ private:
#endif
Q_DISABLE_COPY(QLineEdit)
Q_DECLARE_PRIVATE(QLineEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate())
- Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int))
-#if QT_CONFIG(completer)
- Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(const QString &))
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
- Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_clearButtonClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_controlEditingFinished())
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index a5ac6a2211..fdd6a3aa4f 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlineedit.h"
#include "qlineedit_p.h"
@@ -51,7 +15,7 @@
# include "qwidgetaction.h"
#endif
#include "qclipboard.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#ifndef QT_NO_IM
@@ -110,8 +74,25 @@ QRect QLineEditPrivate::cursorRect() const
}
#if QT_CONFIG(completer)
+void QLineEditPrivate::connectCompleter()
+{
+ Q_Q(const QLineEdit);
+ QObject::connect(control->completer(), qOverload<const QString &>(&QCompleter::activated),
+ q, &QLineEdit::setText);
+ QObjectPrivate::connect(control->completer(), qOverload<const QString &>(&QCompleter::highlighted),
+ this, &QLineEditPrivate::completionHighlighted);
+}
-void QLineEditPrivate::_q_completionHighlighted(const QString &newText)
+void QLineEditPrivate::disconnectCompleter()
+{
+ Q_Q(const QLineEdit);
+ QObject::disconnect(control->completer(), qOverload<const QString &>(&QCompleter::activated),
+ q, &QLineEdit::setText);
+ QObjectPrivate::disconnect(control->completer(), qOverload<const QString &>(&QCompleter::highlighted),
+ this, &QLineEditPrivate::completionHighlighted);
+}
+
+void QLineEditPrivate::completionHighlighted(const QString &newText)
{
Q_Q(QLineEdit);
if (control->completer()->completionMode() != QCompleter::InlineCompletion) {
@@ -132,14 +113,14 @@ void QLineEditPrivate::_q_completionHighlighted(const QString &newText)
#endif // QT_CONFIG(completer)
-void QLineEditPrivate::_q_handleWindowActivate()
+void QLineEditPrivate::handleWindowActivate()
{
Q_Q(QLineEdit);
if (!q->hasFocus() && control->hasSelectedText())
control->deselect();
}
-void QLineEditPrivate::_q_textEdited(const QString &text)
+void QLineEditPrivate::textEdited(const QString &text)
{
Q_Q(QLineEdit);
edited = true;
@@ -151,7 +132,7 @@ void QLineEditPrivate::_q_textEdited(const QString &text)
#endif
}
-void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
+void QLineEditPrivate::cursorPositionChanged(int from, int to)
{
Q_Q(QLineEdit);
q->update();
@@ -159,14 +140,14 @@ void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
}
#ifdef QT_KEYPAD_NAVIGATION
-void QLineEditPrivate::_q_editFocusChange(bool e)
+void QLineEditPrivate::editFocusChange(bool e)
{
Q_Q(QLineEdit);
q->setEditFocus(e);
}
#endif
-void QLineEditPrivate::_q_selectionChanged()
+void QLineEditPrivate::selectionChanged()
{
Q_Q(QLineEdit);
if (control->preeditAreaText().isEmpty()) {
@@ -179,14 +160,14 @@ void QLineEditPrivate::_q_selectionChanged()
}
emit q->selectionChanged();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextSelectionEvent ev(q, control->selectionStart(), control->selectionEnd());
ev.setCursorPosition(control->cursorPosition());
QAccessible::updateAccessibility(&ev);
#endif
}
-void QLineEditPrivate::_q_updateNeeded(const QRect &rect)
+void QLineEditPrivate::updateNeeded(const QRect &rect)
{
q_func()->update(adjustedControlRect(rect));
}
@@ -194,45 +175,51 @@ void QLineEditPrivate::_q_updateNeeded(const QRect &rect)
void QLineEditPrivate::init(const QString& txt)
{
Q_Q(QLineEdit);
+
+ const auto qUpdateMicroFocus = [q]()
+ {
+ q->updateMicroFocus();
+ };
control = new QWidgetLineControl(txt);
control->setParent(q);
control->setFont(q->font());
- QObject::connect(control, SIGNAL(textChanged(QString)),
- q, SIGNAL(textChanged(QString)));
- QObject::connect(control, SIGNAL(textEdited(QString)),
- q, SLOT(_q_textEdited(QString)));
- QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
- q, SLOT(_q_cursorPositionChanged(int,int)));
- QObject::connect(control, SIGNAL(selectionChanged()),
- q, SLOT(_q_selectionChanged()));
- QObject::connect(control, SIGNAL(editingFinished()),
- q, SLOT(_q_controlEditingFinished()));
+ QObject::connect(control, &QWidgetLineControl::textChanged,
+ q, &QLineEdit::textChanged);
+ QObjectPrivate::connect(control, &QWidgetLineControl::textEdited,
+ this, &QLineEditPrivate::textEdited);
+ QObjectPrivate::connect(control, &QWidgetLineControl::cursorPositionChanged,
+ this, &QLineEditPrivate::cursorPositionChanged);
+ QObjectPrivate::connect(control, &QWidgetLineControl::selectionChanged,
+ this, &QLineEditPrivate::selectionChanged);
+ QObjectPrivate::connect(control, &QWidgetLineControl::editingFinished,
+ this, &QLineEditPrivate::controlEditingFinished);
#ifdef QT_KEYPAD_NAVIGATION
- QObject::connect(control, SIGNAL(editFocusChange(bool)),
- q, SLOT(_q_editFocusChange(bool)));
+ QObject::connect(control, &QWidgetLineControl::editFocusChange,
+ this, &QLineEditPrivate::editFocusChange);
#endif
- QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
- q, SLOT(updateMicroFocus()));
+ QObject::connect(control, &QWidgetLineControl::cursorPositionChanged,
+ q, qUpdateMicroFocus);
- QObject::connect(control, SIGNAL(textChanged(QString)),
- q, SLOT(updateMicroFocus()));
+ QObject::connect(control, &QWidgetLineControl::textChanged,
+ q, qUpdateMicroFocus);
- QObject::connect(control, SIGNAL(updateMicroFocus()),
- q, SLOT(updateMicroFocus()));
+ QObject::connect(control, &QWidgetLineControl::updateMicroFocus,
+ q, qUpdateMicroFocus);
// for now, going completely overboard with updates.
- QObject::connect(control, SIGNAL(selectionChanged()),
- q, SLOT(update()));
+ QObject::connect(control, &QWidgetLineControl::selectionChanged,
+ q, qOverload<>(&QLineEdit::update));
- QObject::connect(control, SIGNAL(selectionChanged()),
- q, SLOT(updateMicroFocus()));
+ QObject::connect(control, &QWidgetLineControl::selectionChanged,
+ q, qUpdateMicroFocus);
- QObject::connect(control, SIGNAL(displayTextChanged(QString)),
- q, SLOT(update()));
+ QObject::connect(control, &QWidgetLineControl::displayTextChanged,
+ q, qOverload<>(&QLineEdit::update));
- QObject::connect(control, SIGNAL(updateNeeded(QRect)),
- q, SLOT(_q_updateNeeded(QRect)));
- QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected()));
+ QObjectPrivate::connect(control, &QWidgetLineControl::updateNeeded,
+ this, &QLineEditPrivate::updateNeeded);
+ QObject::connect(control, &QWidgetLineControl::inputRejected,
+ q, &QLineEdit::inputRejected);
QStyleOptionFrame opt;
q->initStyleOption(&opt);
@@ -315,7 +302,7 @@ bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
if ( control->composeMode() ) {
int tmp_cursor = xToPos(e->position().toPoint().x());
int mousePos = tmp_cursor - control->cursor();
- if ( mousePos < 0 || mousePos > control->preeditAreaText().length() )
+ if ( mousePos < 0 || mousePos > control->preeditAreaText().size() )
mousePos = -1;
if (mousePos >= 0) {
@@ -418,8 +405,9 @@ void QLineEditIconButton::setHideWithText(bool hide)
void QLineEditIconButton::onAnimationFinished()
{
- if (shouldHideWithText() && isVisible() && !m_wasHidden) {
+ if (shouldHideWithText() && isVisible() && m_fadingOut) {
hide();
+ m_fadingOut = false;
// Invalidate previous geometry to take into account new size of side widgets
if (auto le = lineEditPrivate())
@@ -429,7 +417,7 @@ void QLineEditIconButton::onAnimationFinished()
void QLineEditIconButton::animateShow(bool visible)
{
- m_wasHidden = visible;
+ m_fadingOut = !visible;
if (shouldHideWithText() && !isVisible()) {
show();
@@ -444,7 +432,7 @@ void QLineEditIconButton::animateShow(bool visible)
void QLineEditIconButton::startOpacityAnimation(qreal endValue)
{
- QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"));
+ QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"), this);
connect(animation, &QPropertyAnimation::finished, this, &QLineEditIconButton::onAnimationFinished);
animation->setDuration(160);
@@ -471,7 +459,7 @@ static void displayWidgets(const QLineEditPrivate::SideWidgetEntryList &widgets,
}
#endif
-void QLineEditPrivate::_q_textChanged(const QString &text)
+void QLineEditPrivate::textChanged(const QString &text)
{
if (hasSideWidgets()) {
const int newTextSize = text.size();
@@ -486,16 +474,16 @@ void QLineEditPrivate::_q_textChanged(const QString &text)
}
}
-void QLineEditPrivate::_q_clearButtonClicked()
+void QLineEditPrivate::clearButtonClicked()
{
Q_Q(QLineEdit);
if (!q->text().isEmpty()) {
q->clear();
- _q_textEdited(QString());
+ textEdited(QString());
}
}
-void QLineEditPrivate::_q_controlEditingFinished()
+void QLineEditPrivate::controlEditingFinished()
{
Q_Q(QLineEdit);
edited = false;
@@ -508,7 +496,7 @@ QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters()
Q_Q(const QLineEdit);
SideWidgetParameters result;
result.iconSize = q->style()->pixelMetric(QStyle::PM_LineEditIconSize, nullptr, q);
- result.margin = result.iconSize / 4;
+ result.margin = q->style()->pixelMetric(QStyle::PM_LineEditIconMargin, nullptr, q);
result.widgetWidth = result.iconSize + 6;
result.widgetHeight = result.iconSize + 2;
return result;
@@ -589,7 +577,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE
if (!newAction)
return nullptr;
if (!hasSideWidgets()) { // initial setup.
- QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ QObjectPrivate::connect(q, &QLineEdit::textChanged,
+ this, &QLineEditPrivate::textChanged);
lastTextSize = q->text().size();
}
QWidget *w = nullptr;
@@ -605,7 +594,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE
toolButton->setIcon(newAction->icon());
toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0);
if (flags & SideWidgetClearButton) {
- QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(_q_clearButtonClicked()));
+ QObjectPrivate::connect(toolButton, &QToolButton::clicked,
+ this, &QLineEditPrivate::clearButtonClicked);
#if QT_CONFIG(animation)
// The clear button is handled only by this widget. The button should be really
@@ -668,7 +658,8 @@ void QLineEditPrivate::removeAction(QAction *action)
delete entry.widget;
positionSideWidgets();
if (!hasSideWidgets()) // Last widget, remove connection
- QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ QObjectPrivate::connect(q, &QLineEdit::textChanged,
+ this, &QLineEditPrivate::textChanged);
q->update();
}
#endif // QT_CONFIG(action)
@@ -679,10 +670,18 @@ static int effectiveTextMargin(int defaultMargin, const QLineEditPrivate::SideWi
if (widgets.empty())
return defaultMargin;
- return defaultMargin + (parameters.margin + parameters.widgetWidth) *
- int(std::count_if(widgets.begin(), widgets.end(),
+ const auto visibleSideWidgetCount = std::count_if(widgets.begin(), widgets.end(),
[](const QLineEditPrivate::SideWidgetEntry &e) {
- return e.widget->isVisibleTo(e.widget->parentWidget()); }));
+#if QT_CONFIG(toolbutton) && QT_CONFIG(animation)
+ // a button that's fading out doesn't get any space
+ if (auto* iconButton = qobject_cast<QLineEditIconButton*>(e.widget))
+ return iconButton->needsSpace();
+
+#endif
+ return e.widget->isVisibleTo(e.widget->parentWidget());
+ });
+
+ return defaultMargin + (parameters.margin + parameters.widgetWidth) * visibleSideWidgetCount;
}
QMargins QLineEditPrivate::effectiveTextMargins() const
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index de9b9c1636..3737ac8fe6 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLINEEDIT_P_H
#define QLINEEDIT_P_H
@@ -95,6 +59,11 @@ public:
bool shouldHideWithText() const;
void setHideWithText(bool hide);
+ bool needsSpace() const {
+ if (m_fadingOut)
+ return false;
+ return isVisibleTo(parentWidget());
+ }
#endif
protected:
@@ -118,7 +87,7 @@ private:
#if QT_CONFIG(animation)
bool m_hideWithText = false;
- bool m_wasHidden = false;
+ bool m_fadingOut = false;
#endif
};
@@ -221,25 +190,27 @@ public:
QRect adjustedContentsRect() const;
- void _q_handleWindowActivate();
- void _q_textEdited(const QString &);
- void _q_cursorPositionChanged(int, int);
+ void handleWindowActivate();
+ void textEdited(const QString &);
+ void cursorPositionChanged(int, int);
#ifdef QT_KEYPAD_NAVIGATION
- void _q_editFocusChange(bool);
+ void editFocusChange(bool);
#endif
- void _q_selectionChanged();
- void _q_updateNeeded(const QRect &);
+ void selectionChanged();
+ void updateNeeded(const QRect &);
#if QT_CONFIG(completer)
- void _q_completionHighlighted(const QString &);
+ void connectCompleter();
+ void disconnectCompleter();
+ void completionHighlighted(const QString &);
#endif
QPoint mousePressPos;
#if QT_CONFIG(draganddrop)
QBasicTimer dndTimer;
void drag();
#endif
- void _q_textChanged(const QString &);
- void _q_clearButtonClicked();
- void _q_controlEditingFinished();
+ void textChanged(const QString &);
+ void clearButtonClicked();
+ void controlEditingFinished();
QMargins textMargins; // use effectiveTextMargins() in case of icon.
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 4e7f04de6c..4534058d45 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//#define QT_EXPERIMENTAL_CLIENT_DECORATIONS
@@ -61,6 +25,7 @@
#include <qstyle.h>
#include <qdebug.h>
#include <qpainter.h>
+#include <qmimedata.h>
#include <private/qwidget_p.h>
#if QT_CONFIG(toolbar)
@@ -72,6 +37,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QMainWindowPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMainWindow)
@@ -82,7 +49,7 @@ public:
, useUnifiedToolBar(false)
#endif
{ }
- QMainWindowLayout *layout;
+ QPointer<QMainWindowLayout> layout;
QSize iconSize;
bool explicitIconSize;
Qt::ToolButtonStyle toolButtonStyle;
@@ -93,7 +60,7 @@ public:
static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
{
- return mainWindow ? mainWindow->d_func()->layout : static_cast<QMainWindowLayout *>(nullptr);
+ return mainWindow ? mainWindow->d_func()->layout.data() : static_cast<QMainWindowLayout *>(nullptr);
}
};
@@ -157,6 +124,7 @@ void QMainWindowPrivate::init()
const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, nullptr, q);
iconSize = QSize(metric, metric);
q->setAttribute(Qt::WA_Hover);
+ q->setAcceptDrops(true);
}
/*
@@ -213,9 +181,6 @@ void QMainWindowPrivate::init()
\image mainwindowlayout.png
- \note Creating a main window without a central widget is not supported.
- You must have a central widget even if it is just a placeholder.
-
\section1 Creating Main Window Components
A central widget will typically be a standard Qt widget such
@@ -315,9 +280,7 @@ void QMainWindowPrivate::init()
is the position and size (relative to the size of the main window)
of the toolbars and dock widgets that are stored.
- \sa QMenuBar, QToolBar, QStatusBar, QDockWidget,
- {Qt Widgets - Application Example}, {Dock Widgets Example},
- {MDI Example}, {SDI Example}, {Menus Example}
+ \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Menus Example}
*/
/*!
@@ -522,10 +485,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 +498,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);
}
@@ -614,7 +578,7 @@ void QMainWindow::setStatusBar(QStatusBar *statusbar)
/*!
Returns the central widget for the main window. This function
- returns zero if the central widget has not been set.
+ returns \nullptr if the central widget has not been set.
\sa setCentralWidget()
*/
@@ -949,10 +913,10 @@ void QMainWindow::setDockNestingEnabled(bool enabled)
\since 4.2
If this property is set to false, dock areas containing tabbed dock widgets
- display horizontal tabs, simmilar to Visual Studio.
+ display horizontal tabs, similar to Visual Studio.
If this property is set to true, then the right and left dock areas display vertical
- tabs, simmilar to KDevelop.
+ tabs, similar to KDevelop.
This property should be set before any dock widgets are added to the main window.
*/
@@ -1159,21 +1123,8 @@ void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
{
- QList<QDockWidget*> ret;
- const QDockAreaLayoutInfo *info = d_func()->layout->layoutState.dockAreaLayout.info(dockwidget);
- if (info && info->tabbed && info->tabBar) {
- for(int i = 0; i < info->item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = info->item_list.at(i);
- if (item.widgetItem) {
- if (QDockWidget *dock = qobject_cast<QDockWidget*>(item.widgetItem->widget())) {
- if (dock != dockwidget) {
- ret += dock;
- }
- }
- }
- }
- }
- return ret;
+ Q_D(const QMainWindow);
+ return d->layout ? d->layout->tabifiedDockWidgets(dockwidget) : QList<QDockWidget *>();
}
#endif // QT_CONFIG(tabbar)
@@ -1218,7 +1169,7 @@ Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
resized such that the yellowWidget is twice as big as the blueWidget
If some widgets are grouped in tabs, only one widget per group should be
- specified. Widgets not in the list might be changed to repect the constraints.
+ specified. Widgets not in the list might be changed to respect the constraints.
*/
void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
const QList<int> &sizes, Qt::Orientation orientation)
@@ -1255,6 +1206,7 @@ QByteArray QMainWindow::saveState(int version) const
{
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << QMainWindowLayout::VersionMarker;
stream << version;
d_func()->layout->saveState(stream);
@@ -1283,6 +1235,7 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
return false;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
int marker, v;
stream >> marker;
stream >> v;
@@ -1332,6 +1285,28 @@ bool QMainWindow::event(QEvent *event)
if (!d->explicitIconSize)
setIconSize(QSize());
break;
+#if QT_CONFIG(draganddrop)
+ case QEvent::DragEnter:
+ case QEvent::Drop:
+ if (!d->layout->draggingWidget)
+ break;
+ event->accept();
+ return true;
+ case QEvent::DragMove: {
+ if (!d->layout->draggingWidget)
+ break;
+ auto dragMoveEvent = static_cast<QDragMoveEvent *>(event);
+ d->layout->hover(d->layout->draggingWidget,
+ mapToGlobal(dragMoveEvent->position()).toPoint());
+ event->accept();
+ return true;
+ }
+ case QEvent::DragLeave:
+ if (!d->layout->draggingWidget)
+ break;
+ d->layout->hover(d->layout->draggingWidget, pos() - QPoint(-1, -1));
+ return true;
+#endif
default:
break;
}
@@ -1361,8 +1336,15 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool enabled)
Q_D(QMainWindow);
d->useUnifiedToolBar = enabled;
- createWinId();
+ // The unified toolbar is drawn by the macOS style with a transparent background.
+ // To ensure a suitable surface format is used we need to first create backing
+ // QWindow so we have something to update the surface format on, and then let
+ // QWidget know about the translucency, which it will propagate to the surface.
+ setAttribute(Qt::WA_NativeWindow);
+ setAttribute(Qt::WA_TranslucentBackground, enabled);
+
+ d->create(); // Create first, before querying the platform window
using namespace QNativeInterface::Private;
if (auto *platformWindow = dynamic_cast<QCocoaWindow*>(window()->windowHandle()->handle()))
platformWindow->setContentBorderEnabled(enabled);
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
index fd1bf0b225..a050093417 100644
--- a/src/widgets/widgets/qmainwindow.h
+++ b/src/widgets/widgets/qmainwindow.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICMAINWINDOW_H
#define QDYNAMICMAINWINDOW_H
@@ -75,7 +39,8 @@ class Q_WIDGETS_EXPORT QMainWindow : public QWidget
#endif // QT_CONFIG(dockwidget)
Q_PROPERTY(DockOptions dockOptions READ dockOptions WRITE setDockOptions)
#if QT_CONFIG(toolbar)
- Q_PROPERTY(bool unifiedTitleAndToolBarOnMac READ unifiedTitleAndToolBarOnMac WRITE setUnifiedTitleAndToolBarOnMac)
+ Q_PROPERTY(bool unifiedTitleAndToolBarOnMac READ unifiedTitleAndToolBarOnMac
+ WRITE setUnifiedTitleAndToolBarOnMac)
#endif
public:
@@ -213,6 +178,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QMainWindow)
Q_DISABLE_COPY(QMainWindow)
+ friend class QDockWidgetGroupWindow;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QMainWindow::DockOptions)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 59e2e4e57a..db17e50d5c 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qmainwindowlayout_p.h"
@@ -60,6 +24,10 @@
#endif
#include <qapplication.h>
+#if QT_CONFIG(draganddrop)
+#include <qdrag.h>
+#endif
+#include <qmimedata.h>
#if QT_CONFIG(statusbar)
#include <qstatusbar.h>
#endif
@@ -82,8 +50,12 @@
#include <private/qlayoutengine_p.h>
#include <private/qwidgetresizehandler_p.h>
+#include <QScopedValueRollback>
+
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
/******************************************************************************
@@ -100,14 +72,14 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayoutItem &item, QStri
<< "pos: " << item.pos << " size:" << item.size
<< " gap:" << (item.flags & QDockAreaLayoutItem::GapItem)
<< " keepSize:" << (item.flags & QDockAreaLayoutItem::KeepSize) << '\n';
- indent += QLatin1String(" ");
+ indent += " "_L1;
if (item.widgetItem != nullptr) {
qout << indent << "widget: "
<< item.widgetItem->widget()->metaObject()->className()
<< " \"" << item.widgetItem->widget()->windowTitle() << "\"\n";
} else if (item.subinfo != nullptr) {
qout << indent << "subinfo:\n";
- dumpLayout(qout, *item.subinfo, indent + QLatin1String(" "));
+ dumpLayout(qout, *item.subinfo, indent + " "_L1);
} else if (item.placeHolderItem != nullptr) {
QRect r = item.placeHolderItem->topLevelRect;
qout << indent << "placeHolder: "
@@ -138,11 +110,11 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QSt
#endif
<< '\n';
- indent += QLatin1String(" ");
+ indent += " "_L1;
- for (int i = 0; i < layout.item_list.count(); ++i) {
+ for (int i = 0; i < layout.item_list.size(); ++i) {
qout << indent << "Item: " << i << '\n';
- dumpLayout(qout, layout.item_list.at(i), indent + QLatin1String(" "));
+ dumpLayout(qout, layout.item_list.at(i), indent + " "_L1);
}
}
@@ -155,13 +127,13 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayout &layout)
<< layout.rect.height() << '\n';
qout << "TopDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::TopDock], QLatin1String(" "));
+ dumpLayout(qout, layout.docks[QInternal::TopDock], " "_L1);
qout << "LeftDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::LeftDock], QLatin1String(" "));
+ dumpLayout(qout, layout.docks[QInternal::LeftDock], " "_L1);
qout << "RightDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::RightDock], QLatin1String(" "));
+ dumpLayout(qout, layout.docks[QInternal::RightDock], " "_L1);
qout << "BottomDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::BottomDock], QLatin1String(" "));
+ dumpLayout(qout, layout.docks[QInternal::BottomDock], " "_L1);
}
QDebug operator<<(QDebug debug, const QDockAreaLayout &layout)
@@ -179,18 +151,57 @@ QDebug operator<<(QDebug debug, const QMainWindowLayout *layout)
return debug;
}
+// Use this to dump item lists of all populated main window docks.
+// Use DUMP macro inside QMainWindowLayout
+#if 0
+static void dumpItemLists(const QMainWindowLayout *layout, const char *function, const char *comment)
+{
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const auto &list = layout->layoutState.dockAreaLayout.docks[i].item_list;
+ if (list.isEmpty())
+ continue;
+ qDebug() << function << comment << "Dock" << i << list;
+ }
+}
+#define DUMP(comment) dumpItemLists(this, __FUNCTION__, comment)
+#endif // 0
+
#endif // QT_CONFIG(dockwidget) && !defined(QT_NO_DEBUG)
-/******************************************************************************
- ** QDockWidgetGroupWindow
- */
-// QDockWidgetGroupWindow is the floating window containing several QDockWidgets floating together.
-// (QMainWindow::GroupedDragging feature)
-// QDockWidgetGroupLayout is the layout of that window and use a QDockAreaLayoutInfo to layout
-// the QDockWidgets inside it.
-// If there is only one QDockWidgets, or all QDockWidgets are tabbed together, it is equivalent
-// of a floating QDockWidget (the title of the QDockWidget is the title of the window). But if there
-// are nested QDockWidget, an additional title bar is there.
+
+/*!
+ \internal
+ QDockWidgetGroupWindow is a floating window, containing several QDockWidgets floating together.
+ This requires QMainWindow::GroupedDragging to be enabled.
+ QDockWidgets floating jointly in a QDockWidgetGroupWindow are considered to be docked.
+ Their \c isFloating property is \c false.
+ QDockWidget children of a QDockWidgetGroupWindow are either:
+ \list
+ \li tabbed (as long as Qt is compiled with the \c tabbar feature), or
+ \li arranged next to each other, equivalent to the default on a main window dock.
+ \endlist
+
+ QDockWidgetGroupWindow uses QDockWidgetGroupLayout to lay out its QDockWidget children.
+ It stores layout information in a QDockAreaLayoutInfo, including temporary spacer items
+ and rubber bands.
+
+ If its QDockWidget children are tabbed, the QDockWidgetGroupWindow shows the active QDockWidget's
+ title as its own window title.
+
+ QDockWidgetGroupWindow is designed to hold more than one QDockWidget.
+ A QDockWidgetGroupWindow with only one QDockWidget child may occur only temporarily
+ \list
+ \li in its construction phase, or
+ \li during a hover: While QDockWidget A is hovered over B, B is converted into a QDockWidgetGroupWindow.
+ \endlist
+
+ A QDockWidgetGroupWindow with only one QDockWidget child must never get focus, be dragged or dropped.
+ To enforce this restriction, QDockWidgetGrouWindow will remove itself after its second QDockWidget
+ child has been removed. It will make its last QDockWidget child a single, floating QDockWidget.
+ Eventually, the empty QDockWidgetGroupWindow will call deleteLater() on itself.
+*/
+
+
#if QT_CONFIG(dockwidget)
class QDockWidgetGroupLayout : public QLayout,
public QMainWindowLayoutSeparatorHelper<QDockWidgetGroupLayout>
@@ -294,7 +305,6 @@ bool QDockWidgetGroupWindow::event(QEvent *e)
#if QT_CONFIG(tabbar)
// Forward the close to the QDockWidget just as if its close button was pressed
if (QDockWidget *dw = activeTabbedDockWidget()) {
- e->ignore();
dw->close();
adjustFlags();
}
@@ -328,6 +338,7 @@ bool QDockWidgetGroupWindow::event(QEvent *e)
case QEvent::Resize:
updateCurrentGapRect();
emit resized();
+ break;
default:
break;
}
@@ -401,7 +412,7 @@ QDockWidget *QDockWidgetGroupWindow::activeTabbedDockWidget() const
}
}
if (!dw) {
- for (int i = 0; !dw && i < info->item_list.count(); ++i) {
+ for (int i = 0; !dw && i < info->item_list.size(); ++i) {
const QDockAreaLayoutItem &item = info->item_list.at(i);
if (item.skip())
continue;
@@ -420,22 +431,24 @@ QDockWidget *QDockWidgetGroupWindow::activeTabbedDockWidget() const
*/
void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
{
- if (!layoutInfo()->isEmpty()) {
+ const QDockAreaLayoutInfo *info = layoutInfo();
+ if (!info->isEmpty()) {
show(); // It might have been hidden,
return;
}
// There might still be placeholders
- if (!layoutInfo()->item_list.isEmpty()) {
+ if (!info->item_list.isEmpty()) {
hide();
return;
}
// Make sure to reparent the possibly floating or hidden QDockWidgets to the parent
- const auto dockWidgets = findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly);
- for (QDockWidget *dw : dockWidgets) {
- bool wasFloating = dw->isFloating();
- bool wasHidden = dw->isHidden();
+ const auto dockWidgetsList = dockWidgets();
+ for (QDockWidget *dw : dockWidgetsList) {
+ const bool wasFloating = dw->isFloating();
+ const bool wasHidden = dw->isHidden();
dw->setParent(parentWidget());
+ qCDebug(lcQpaDockWidgets) << "Reparented:" << dw << "to" << parentWidget() << "by" << this;
if (wasFloating) {
dw->setFloating(true);
} else {
@@ -444,20 +457,35 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
qt_mainwindow_layout(static_cast<QMainWindow *>(parentWidget()));
Qt::DockWidgetArea area = ml->dockWidgetArea(this);
if (area == Qt::NoDockWidgetArea)
- area = Qt::LeftDockWidgetArea;
+ area = Qt::LeftDockWidgetArea; // FIXME: DockWidget doesn't save original docking area
static_cast<QMainWindow *>(parentWidget())->addDockWidget(area, dw);
+ qCDebug(lcQpaDockWidgets) << "Redocked to Mainwindow:" << area << dw << "by" << this;
}
if (!wasHidden)
dw->show();
}
-#if QT_CONFIG(tabbar)
- const auto tabBars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly);
- for (QTabBar *tb : tabBars)
- tb->setParent(parentWidget());
-#endif
deleteLater();
}
+/*!
+ \internal
+ \return \c true if the group window has at least one visible QDockWidget child,
+ otherwise false.
+ */
+bool QDockWidgetGroupWindow::hasVisibleDockWidgets() const
+{
+ const auto &children = findChildren<QDockWidget *>(Qt::FindChildrenRecursively);
+ for (auto child : children) {
+ // WA_WState_Visible is set on the dock widget, associated to the active tab
+ // and unset on all others.
+ // WA_WState_Hidden is set if the dock widgets have been explicitly hidden.
+ // This is the relevant information to check (equivalent to !child->isHidden()).
+ if (!child->testAttribute(Qt::WA_WState_Hidden))
+ return true;
+ }
+ return false;
+}
+
/*! \internal
Sets the flags of this window in accordance to the capabilities of the dock widgets
*/
@@ -506,7 +534,7 @@ void QDockWidgetGroupWindow::adjustFlags()
m_removedFrameSize = QSize();
}
- show(); // setWindowFlags hides the window
+ setVisible(hasVisibleDockWidgets());
}
QWidget *titleBarOf = top ? top : parentWidget();
@@ -567,8 +595,12 @@ bool QDockWidgetGroupWindow::hover(QLayoutItem *widgetItem, const QPoint &mouseP
auto newGapPos = newState.gapIndex(mousePos, nestingEnabled, tabMode);
Q_ASSERT(!newGapPos.isEmpty());
- if (newGapPos == currentGapPos)
- return false; // gap is already there
+
+ // Do not insert a new gap item, if the current position already is a gap,
+ // or if the group window contains one
+ if (newGapPos == currentGapPos || newState.hasGapItem(newGapPos))
+ return false;
+
currentGapPos = newGapPos;
newState.insertGap(currentGapPos, widgetItem);
newState.fitItems();
@@ -615,6 +647,108 @@ void QDockWidgetGroupWindow::apply()
layoutInfo()->apply(false);
}
+void QDockWidgetGroupWindow::childEvent(QChildEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::ChildRemoved:
+ if (auto *dockWidget = qobject_cast<QDockWidget *>(event->child()))
+ dockWidget->removeEventFilter(this);
+ destroyIfSingleItemLeft();
+ break;
+ case QEvent::ChildAdded:
+ if (auto *dockWidget = qobject_cast<QDockWidget *>(event->child()))
+ dockWidget->installEventFilter(this);
+ break;
+ default:
+ break;
+ }
+}
+
+bool QDockWidgetGroupWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ auto *dockWidget = qobject_cast<QDockWidget *>(obj);
+ if (!dockWidget)
+ return QWidget::eventFilter(obj, event);
+
+ switch (event->type()) {
+ case QEvent::Close:
+ // We don't want closed dock widgets in a floating tab
+ // => dock it to the main dock, before closing;
+ reparent(dockWidget);
+ dockWidget->setFloating(false);
+ break;
+
+ case QEvent::Hide:
+ // if the dock widget is not an active tab, it is hidden anyway.
+ // if it is the active tab, hide the whole group.
+ if (dockWidget->isVisible())
+ hide();
+ break;
+
+ default:
+ break;
+ }
+ return QWidget::eventFilter(obj, event);
+}
+
+void QDockWidgetGroupWindow::destroyIfSingleItemLeft()
+{
+ const auto &dockWidgets = this->dockWidgets();
+
+ // Handle only the last dock
+ if (dockWidgets.count() != 1)
+ return;
+
+ auto *lastDockWidget = dockWidgets.at(0);
+
+ // If the last remaining dock widget is not in the group window's item_list,
+ // a group window is being docked on a main window docking area.
+ // => don't interfere
+ if (layoutInfo()->indexOf(lastDockWidget).isEmpty())
+ return;
+
+ auto *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
+ QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
+
+ // Unplug the last remaining dock widget and hide the group window, to avoid flickering
+ mwLayout->unplug(lastDockWidget, QDockWidgetPrivate::DragScope::Widget);
+ lastDockWidget->setGeometry(geometry());
+ hide();
+
+ // Get the layout info for the main window dock, where dock widgets need to go
+ QDockAreaLayoutInfo &parentInfo = mwLayout->layoutState.dockAreaLayout.docks[layoutInfo()->dockPos];
+
+ // Re-parent last dock widget
+ reparent(lastDockWidget);
+
+ // the group window could still have placeholder items => clear everything
+ layoutInfo()->item_list.clear();
+
+ // remove the group window and the dock's item_list pointing to it.
+ parentInfo.remove(this);
+ destroyOrHideIfEmpty();
+}
+
+void QDockWidgetGroupWindow::reparent(QDockWidget *dockWidget)
+{
+ // reparent a dockWidget to the main window
+ // - remove it from the floating dock's layout info
+ // - insert it to the main dock's layout info
+ // Finally, set draggingDock to nullptr, since the drag is finished.
+ auto *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
+ Q_ASSERT(mainWindow);
+ QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
+ Q_ASSERT(mwLayout);
+ QDockAreaLayoutInfo &parentInfo = mwLayout->layoutState.dockAreaLayout.docks[layoutInfo()->dockPos];
+ dockWidget->removeEventFilter(this);
+ parentInfo.add(dockWidget);
+ layoutInfo()->remove(dockWidget);
+ const bool wasFloating = dockWidget->isFloating();
+ const bool wasVisible = dockWidget->isVisible();
+ dockWidget->setParent(mainWindow);
+ dockWidget->setFloating(wasFloating);
+ dockWidget->setVisible(wasVisible);
+}
#endif
/******************************************************************************
@@ -675,6 +809,31 @@ QSize QMainWindowLayoutState::minimumSize() const
return result;
}
+/*!
+ \internal
+
+ Returns whether the layout fits into the main window.
+*/
+bool QMainWindowLayoutState::fits() const
+{
+ Q_ASSERT(mainWindow);
+
+ QSize size;
+
+#if QT_CONFIG(dockwidget)
+ size = dockAreaLayout.minimumStableSize();
+#endif
+
+#if QT_CONFIG(toolbar)
+ size.rwidth() += toolBarAreaLayout.docks[QInternal::LeftDock].rect.width();
+ size.rwidth() += toolBarAreaLayout.docks[QInternal::RightDock].rect.width();
+ size.rheight() += toolBarAreaLayout.docks[QInternal::TopDock].rect.height();
+ size.rheight() += toolBarAreaLayout.docks[QInternal::BottomDock].rect.height();
+#endif
+
+ return size.width() <= mainWindow->width() && size.height() <= mainWindow->height();
+}
+
void QMainWindowLayoutState::apply(bool animated)
{
#if QT_CONFIG(toolbar)
@@ -1056,7 +1215,7 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const
dockAreaLayout.saveState(stream);
#if QT_CONFIG(tabbar)
const QList<QDockWidgetGroupWindow *> floatingTabs =
- mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *floating : floatingTabs) {
if (floating->layoutInfo()->isEmpty())
@@ -1171,10 +1330,12 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
}
QDataStream ds(copy);
+ ds.setVersion(_stream.version());
if (!checkFormat(ds))
return false;
QDataStream stream(copy);
+ stream.setVersion(_stream.version());
while (!stream.atEnd()) {
uchar marker;
@@ -1200,7 +1361,7 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
if (info == nullptr) {
continue;
}
- info->item_list.append(QDockAreaLayoutItem(new QDockWidgetItem(w)));
+ info->add(w);
}
}
}
@@ -1210,8 +1371,9 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
{
auto dockWidgets = allMyDockWidgets(mainWindow);
QDockWidgetGroupWindow* floatingTab = qt_mainwindow_layout(mainWindow)->createTabbedDockWindow();
- *floatingTab->layoutInfo() = QDockAreaLayoutInfo(&dockAreaLayout.sep, QInternal::LeftDock,
- Qt::Horizontal, QTabBar::RoundedSouth, mainWindow);
+ *floatingTab->layoutInfo() = QDockAreaLayoutInfo(
+ &dockAreaLayout.sep, QInternal::LeftDock, // FIXME: DockWidget doesn't save original docking area
+ Qt::Horizontal, QTabBar::RoundedSouth, mainWindow);
QRect geometry;
stream >> geometry;
QDockAreaLayoutInfo *info = floatingTab->layoutInfo();
@@ -1269,17 +1431,18 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
#if QT_CONFIG(toolbar)
-static inline void validateToolBarArea(Qt::ToolBarArea &area)
+static constexpr Qt::ToolBarArea validateToolBarArea(Qt::ToolBarArea area)
{
switch (area) {
case Qt::LeftToolBarArea:
case Qt::RightToolBarArea:
case Qt::TopToolBarArea:
case Qt::BottomToolBarArea:
- break;
+ return area;
default:
- area = Qt::TopToolBarArea;
+ break;
}
+ return Qt::TopToolBarArea;
}
static QInternal::DockPosition toDockPos(Qt::ToolBarArea area)
@@ -1315,7 +1478,7 @@ static inline Qt::ToolBarArea toToolBarArea(int pos)
void QMainWindowLayout::addToolBarBreak(Qt::ToolBarArea area)
{
- validateToolBarArea(area);
+ area = validateToolBarArea(area);
layoutState.toolBarAreaLayout.addToolBarBreak(toDockPos(area));
if (savedState.isValid())
@@ -1369,7 +1532,7 @@ void QMainWindowLayout::addToolBar(Qt::ToolBarArea area,
QToolBar *toolbar,
bool)
{
- validateToolBarArea(area);
+ area = validateToolBarArea(area);
// let's add the toolbar to the layout
addChildWidget(toolbar);
QLayoutItem *item = layoutState.toolBarAreaLayout.addToolBar(toDockPos(area), toolbar);
@@ -1464,23 +1627,46 @@ static QInternal::DockPosition toDockPos(Qt::DockWidgetArea area)
return QInternal::DockCount;
}
-static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
+inline static Qt::DockWidgetArea toDockWidgetArea(int pos)
{
- switch (pos) {
- case QInternal::LeftDock : return Qt::LeftDockWidgetArea;
- case QInternal::RightDock : return Qt::RightDockWidgetArea;
- case QInternal::TopDock : return Qt::TopDockWidgetArea;
- case QInternal::BottomDock : return Qt::BottomDockWidgetArea;
- default:
- break;
- }
-
- return Qt::NoDockWidgetArea;
+ return QDockWidgetPrivate::toDockWidgetArea(static_cast<QInternal::DockPosition>(pos));
}
-inline static Qt::DockWidgetArea toDockWidgetArea(int pos)
+// Checks if QDockWidgetGroupWindow or QDockWidget can be plugged the area indicated by path.
+// Returns false if called with invalid widget type or if compiled without dockwidget support.
+static bool isAreaAllowed(QWidget *widget, const QList<int> &path)
{
- return toDockWidgetArea(static_cast<QInternal::DockPosition>(pos));
+ Q_ASSERT_X((path.size() > 1), "isAreaAllowed", "invalid path size");
+ const Qt::DockWidgetArea area = toDockWidgetArea(path[1]);
+
+ // Read permissions directly from a single dock widget
+ if (QDockWidget *dw = qobject_cast<QDockWidget *>(widget)) {
+ const bool allowed = dw->isAreaAllowed(area);
+ if (!allowed)
+ qCDebug(lcQpaDockWidgets) << "No permission for single DockWidget" << widget << "to dock on" << area;
+ return allowed;
+ }
+
+ // Read permissions from a DockWidgetGroupWindow depending on its DockWidget children
+ if (QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(widget)) {
+ const QList<QDockWidget *> children = dwgw->findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly);
+
+ if (children.size() == 1) {
+ // Group window has a single child => read its permissions
+ const bool allowed = children.at(0)->isAreaAllowed(area);
+ if (!allowed)
+ qCDebug(lcQpaDockWidgets) << "No permission for DockWidgetGroupWindow" << widget << "to dock on" << area;
+ return allowed;
+ } else {
+ // Group window has more than one or no children => dock it anywhere
+ qCDebug(lcQpaDockWidgets) << "DockWidgetGroupWindow" << widget << "has" << children.size() << "children:";
+ qCDebug(lcQpaDockWidgets) << children;
+ qCDebug(lcQpaDockWidgets) << "DockWidgetGroupWindow" << widget << "can dock at" << area << "and anywhere else.";
+ return true;
+ }
+ }
+ qCDebug(lcQpaDockWidgets) << "Docking requested for invalid widget type (coding error)." << widget << area;
+ return false;
}
void QMainWindowLayout::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
@@ -1498,6 +1684,25 @@ Qt::DockWidgetArea QMainWindowLayout::corner(Qt::Corner corner) const
return layoutState.dockAreaLayout.corners[corner];
}
+// Returns the rectangle of a dockWidgetArea
+// if max is true, the maximum possible rectangle for dropping is returned
+// the current visible rectangle otherwise
+QRect QMainWindowLayout::dockWidgetAreaRect(const Qt::DockWidgetArea area, DockWidgetAreaSize size) const
+{
+ const QInternal::DockPosition dockPosition = toDockPos(area);
+
+ // Called with invalid dock widget area
+ if (dockPosition == QInternal::DockCount) {
+ qCDebug(lcQpaDockWidgets) << "QMainWindowLayout::dockWidgetAreaRect called with" << area;
+ return QRect();
+ }
+
+ const QDockAreaLayout dl = layoutState.dockAreaLayout;
+
+ // Return maximum or visible rectangle
+ return (size == Maximum) ? dl.gapRect(dockPosition) : dl.docks[dockPosition].rect;
+}
+
void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area,
QDockWidget *dockwidget,
Qt::Orientation orientation)
@@ -1527,6 +1732,7 @@ bool QMainWindowLayout::restoreDockWidget(QDockWidget *dockwidget)
#if QT_CONFIG(tabbar)
void QMainWindowLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
{
+ applyRestoredState();
addChildWidget(second);
layoutState.dockAreaLayout.tabifyDockWidget(first, second);
emit second->dockLocationChanged(dockWidgetArea(first));
@@ -1546,9 +1752,9 @@ void QMainWindowLayout::setDocumentMode(bool enabled)
_documentMode = enabled;
// Update the document mode for all tab bars
- for (QTabBar *bar : qAsConst(usedTabBars))
+ for (QTabBar *bar : std::as_const(usedTabBars))
bar->setDocumentMode(_documentMode);
- for (QTabBar *bar : qAsConst(unusedTabBars))
+ for (QTabBar *bar : std::as_const(unusedTabBars))
bar->setDocumentMode(_documentMode);
}
@@ -1580,7 +1786,7 @@ void QMainWindowLayout::setTabShape(QTabWidget::TabShape tabShape)
QTabWidget::TabPosition QMainWindowLayout::tabPosition(Qt::DockWidgetArea area) const
{
- const auto dockPos = toDockPos(area);
+ const QInternal::DockPosition dockPos = toDockPos(area);
if (dockPos < QInternal::DockCount)
return tabPositions[dockPos];
qWarning("QMainWindowLayout::tabPosition called with out-of-bounds value '%d'", int(area));
@@ -1609,19 +1815,7 @@ void QMainWindowLayout::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::Ta
updateTabBarShapes();
}
-static inline QTabBar::Shape tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position)
-{
- const bool rounded = (shape == QTabWidget::Rounded);
- if (position == QTabWidget::North)
- return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth;
- if (position == QTabWidget::South)
- return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth;
- if (position == QTabWidget::East)
- return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast;
- if (position == QTabWidget::West)
- return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest;
- return QTabBar::RoundedNorth;
-}
+QTabBar::Shape _q_tb_tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position);
#endif // QT_CONFIG(tabwidget)
void QMainWindowLayout::updateTabBarShapes()
@@ -1647,7 +1841,7 @@ void QMainWindowLayout::updateTabBarShapes()
for (int i = 0; i < QInternal::DockCount; ++i) {
#if QT_CONFIG(tabwidget)
QTabWidget::TabPosition pos = verticalTabsEnabled ? vertical[i] : tabPositions[i];
- QTabBar::Shape shape = tabBarShapeFrom(_tabShape, pos);
+ QTabBar::Shape shape = _q_tb_tabBarShapeFrom(_tabShape, pos);
#else
QTabBar::Shape shape = verticalTabsEnabled ? vertical[i] : QTabBar::RoundedSouth;
#endif
@@ -1660,6 +1854,7 @@ void QMainWindowLayout::splitDockWidget(QDockWidget *after,
QDockWidget *dockwidget,
Qt::Orientation orientation)
{
+ applyRestoredState();
addChildWidget(dockwidget);
layoutState.dockAreaLayout.splitDockWidget(after, dockwidget, orientation);
emit dockwidget->dockLocationChanged(dockWidgetArea(after));
@@ -1684,10 +1879,15 @@ void QMainWindowLayout::keepSize(QDockWidget *w)
// Handle custom tooltip, and allow to drag tabs away.
class QMainWindowTabBar : public QTabBar
{
+ Q_OBJECT
QMainWindow *mainWindow;
QPointer<QDockWidget> draggingDock; // Currently dragging (detached) dock widget
public:
QMainWindowTabBar(QMainWindow *parent);
+ ~QMainWindowTabBar();
+ QDockWidget *dockAt(int index) const;
+ QList<QDockWidget *> dockWidgets() const;
+ bool contains(const QDockWidget *dockWidget) const;
protected:
bool event(QEvent *e) override;
void mouseReleaseEvent(QMouseEvent*) override;
@@ -1695,12 +1895,55 @@ protected:
};
+QMainWindowTabBar *QMainWindowLayout::findTabBar(const QDockWidget *dockWidget) const
+{
+ for (auto *bar : usedTabBars) {
+ Q_ASSERT(qobject_cast<QMainWindowTabBar *>(bar));
+ auto *tabBar = static_cast<QMainWindowTabBar *>(bar);
+ if (tabBar->contains(dockWidget))
+ return tabBar;
+ }
+ return nullptr;
+}
+
QMainWindowTabBar::QMainWindowTabBar(QMainWindow *parent)
: QTabBar(parent), mainWindow(parent)
{
setExpanding(false);
}
+QList<QDockWidget *> QMainWindowTabBar::dockWidgets() const
+{
+ QList<QDockWidget *> docks;
+ for (int i = 0; i < count(); ++i) {
+ if (QDockWidget *dock = dockAt(i))
+ docks << dock;
+ }
+ return docks;
+}
+
+bool QMainWindowTabBar::contains(const QDockWidget *dockWidget) const
+{
+ for (int i = 0; i < count(); ++i) {
+ if (dockAt(i) == dockWidget)
+ return true;
+ }
+ return false;
+}
+
+QDockWidget *QMainWindowTabBar::dockAt(int index) const
+{
+ QMainWindowTabBar *that = const_cast<QMainWindowTabBar *>(this);
+ QMainWindowLayout* mlayout = qt_mainwindow_layout(mainWindow);
+ QDockAreaLayoutInfo *info = mlayout->dockInfo(that);
+ if (!info)
+ return nullptr;
+ const int itemIndex = info->tabIndexToListIndex(index);
+ Q_ASSERT(itemIndex >= 0 && itemIndex < info->item_list.count());
+ const QDockAreaLayoutItem &item = info->item_list.at(itemIndex);
+ return item.widgetItem ? qobject_cast<QDockWidget *>(item.widgetItem->widget()) : nullptr;
+}
+
void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
{
// The QTabBar handles the moving (reordering) of tabs.
@@ -1714,13 +1957,8 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
offset *= 3;
QRect r = rect().adjusted(-offset, -offset, offset, offset);
if (d->dragInProgress && !r.contains(e->position().toPoint()) && d->validIndex(d->pressedIndex)) {
- QMainWindowLayout* mlayout = qt_mainwindow_layout(mainWindow);
- QDockAreaLayoutInfo *info = mlayout->dockInfo(this);
- Q_ASSERT(info);
- int idx = info->tabIndexToListIndex(d->pressedIndex);
- const QDockAreaLayoutItem &item = info->item_list.at(idx);
- if (item.widgetItem
- && (draggingDock = qobject_cast<QDockWidget *>(item.widgetItem->widget()))) {
+ draggingDock = dockAt(d->pressedIndex);
+ if (draggingDock) {
// We should drag this QDockWidget away by unpluging it.
// First cancel the QTabBar's internal move
d->moveTabFinished(d->pressedIndex);
@@ -1733,7 +1971,7 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock));
QDockWidgetLayout *dwlayout = static_cast<QDockWidgetLayout *>(draggingDock->layout());
dockPriv->initDrag(dwlayout->titleArea().center(), true);
- dockPriv->startDrag(false);
+ dockPriv->startDrag(QDockWidgetPrivate::DragScope::Widget);
if (dockPriv->state)
dockPriv->state->ctrlDrag = e->modifiers() & Qt::ControlModifier;
}
@@ -1751,13 +1989,28 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
QTabBar::mouseMoveEvent(e);
}
+QMainWindowTabBar::~QMainWindowTabBar()
+{
+ if (!mainWindow || mainWindow == parentWidget())
+ return;
+
+ // tab bar is not parented to the main window
+ // => can only be a dock widget group window
+ // => remove itself from used and unused tab bar containers
+ auto *mwLayout = qt_mainwindow_layout(mainWindow);
+ if (!mwLayout)
+ return;
+ mwLayout->unusedTabBars.removeOne(this);
+ mwLayout->usedTabBars.remove(this);
+}
+
void QMainWindowTabBar::mouseReleaseEvent(QMouseEvent *e)
{
if (draggingDock && e->button() == Qt::LeftButton) {
QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock));
- if (dockPriv->state && dockPriv->state->dragging) {
- dockPriv->endDrag();
- }
+ if (dockPriv->state && dockPriv->state->dragging)
+ dockPriv->endDrag(QDockWidgetPrivate::EndDragMode::LocationChange);
+
draggingDock = nullptr;
}
QTabBar::mouseReleaseEvent(e);
@@ -1781,9 +2034,31 @@ bool QMainWindowTabBar::event(QEvent *e)
return true;
}
+QList<QDockWidget *> QMainWindowLayout::tabifiedDockWidgets(const QDockWidget *dockWidget) const
+{
+ const auto *bar = findTabBar(dockWidget);
+ if (!bar)
+ return {};
+
+ QList<QDockWidget *> buddies = bar->dockWidgets();
+ // Return only other dock widgets associated with dockWidget in a tab bar.
+ // If dockWidget is alone in a tab bar, return an empty list.
+ buddies.removeOne(dockWidget);
+ return buddies;
+}
+
+bool QMainWindowLayout::isDockWidgetTabbed(const QDockWidget *dockWidget) const
+{
+ // A single dock widget in a tab bar is not considered to be tabbed.
+ // This is to make sure, we don't drag an empty QDockWidgetGroupWindow around.
+ // => only consider tab bars with two or more tabs.
+ const auto *bar = findTabBar(dockWidget);
+ return bar && bar->count() > 1;
+}
+
QTabBar *QMainWindowLayout::getTabBar()
{
- if (!usedTabBars.isEmpty()) {
+ if (!usedTabBars.isEmpty() && !isInRestoreState) {
/*
If dock widgets have been removed and added while the main window was
hidden, then the layout hasn't been activated yet, and tab bars from empty
@@ -1819,7 +2094,7 @@ QWidget *QMainWindowLayout::getSeparatorWidget()
result = new QWidget(parentWidget());
result->setAttribute(Qt::WA_MouseNoMask, true);
result->setAutoFillBackground(false);
- result->setObjectName(QLatin1String("qt_qmainwindow_extended_splitter"));
+ result->setObjectName("qt_qmainwindow_extended_splitter"_L1);
}
usedSeparatorWidgets.insert(result);
return result;
@@ -1835,7 +2110,7 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget)
if (info)
return info;
const auto groups =
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ parent()->findChildren<QDockWidgetGroupWindow*>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups) {
info = dwgw->layoutInfo()->info(widget);
if (info)
@@ -1955,9 +2230,37 @@ QLayoutItem *QMainWindowLayout::takeAt(int index)
return nullptr;
}
+
+/*!
+ \internal
+
+ restoredState stores what we earlier read from storage, but it couldn't
+ be applied as the mainwindow wasn't large enough (yet) to fit the state.
+ Usually, the restored state would be applied lazily in setGeometry below.
+ However, if the mainwindow's layout is modified (e.g. by a call to tabify or
+ splitDockWidgets), then we have to forget the restored state as it might contain
+ dangling pointers (QDockWidgetLayoutItem has a copy constructor that copies the
+ layout item pointer, and splitting or tabify might have to delete some of those
+ layout structures).
+
+ Functions that might result in the QMainWindowLayoutState storing dangling pointers
+ have to call this function first, so that the restoredState becomes the actual state
+ first, and is forgotten afterwards.
+*/
+void QMainWindowLayout::applyRestoredState()
+{
+ if (restoredState) {
+ layoutState = *restoredState;
+ restoredState.reset();
+ discardRestoredStateTimer.stop();
+ }
+}
+
void QMainWindowLayout::setGeometry(const QRect &_r)
{
- if (savedState.isValid())
+ // Check if the state is valid, and avoid replacing it again if it is currently used
+ // in applyState
+ if (savedState.isValid() || (restoredState && isInApplyState))
return;
QRect r = _r;
@@ -1974,11 +2277,47 @@ void QMainWindowLayout::setGeometry(const QRect &_r)
r.setBottom(sbr.top() - 1);
}
+ if (restoredState) {
+ /*
+ The main window was hidden and was going to be maximized or full-screened when
+ the state was restored. The state might have been for a larger window size than
+ the current size (in _r), and the window might still be in the process of being
+ shown and transitioning to the final size (there's no reliable way of knowing
+ this across different platforms). Try again with the restored state.
+ */
+ layoutState = *restoredState;
+ if (restoredState->fits()) {
+ restoredState.reset();
+ discardRestoredStateTimer.stop();
+ } else {
+ /*
+ Try again in the next setGeometry call, but discard the restored state
+ after 150ms without any further tries. That's a reasonably short amount of
+ time during which we can expect the windowing system to either have completed
+ showing the window, or resized the window once more (which then restarts the
+ timer in timerEvent).
+ If the windowing system is done, then the user won't have had a chance to
+ change the layout interactively AND trigger another resize.
+ */
+ discardRestoredStateTimer.start(150, this);
+ }
+ }
+
layoutState.rect = r;
+
layoutState.fitLayout();
applyState(layoutState, false);
}
+void QMainWindowLayout::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == discardRestoredStateTimer.timerId()) {
+ discardRestoredStateTimer.stop();
+ restoredState.reset();
+ }
+ QLayout::timerEvent(e);
+}
+
void QMainWindowLayout::addItem(QLayoutItem *)
{ qWarning("QMainWindowLayout::addItem: Please use the public QMainWindow API instead"); }
@@ -2104,7 +2443,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget);
// Let's remove the widget from any possible group window
const auto groups =
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ parent()->findChildren<QDockWidgetGroupWindow*>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups) {
if (dwgw == currentHoveredFloat)
continue;
@@ -2134,7 +2473,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
#if QT_CONFIG(dockwidget)
// Let's remove the widget from any possible group window
const auto groups =
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ parent()->findChildren<QDockWidgetGroupWindow*>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
if (!path.isEmpty())
@@ -2334,7 +2673,7 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay
#endif // QT_CONFIG(dockwidget)
pluggingWidget = nullptr;
- setObjectName(mainwindow->objectName() + QLatin1String("_layout"));
+ setObjectName(mainwindow->objectName() + "_layout"_L1);
}
QMainWindowLayout::~QMainWindowLayout()
@@ -2409,7 +2748,6 @@ static bool unplugGroup(QMainWindowLayout *layout, QLayoutItem **item,
return false;
// The QDockWidget is part of a group of tab and we need to unplug them all.
-
QDockWidgetGroupWindow *floatingTabs = layout->createTabbedDockWindow();
QDockAreaLayoutInfo *info = floatingTabs->layoutInfo();
*info = std::move(*parentItem.subinfo);
@@ -2424,6 +2762,30 @@ static bool unplugGroup(QMainWindowLayout *layout, QLayoutItem **item,
}
#endif
+#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
+static QTabBar::Shape tabwidgetPositionToTabBarShape(QWidget *w)
+{
+ QTabBar::Shape result = QTabBar::RoundedSouth;
+ if (qobject_cast<QDockWidget *>(w)) {
+ switch (static_cast<QDockWidgetPrivate *>(qt_widget_private(w))->tabPosition) {
+ case QTabWidget::North:
+ result = QTabBar::RoundedNorth;
+ break;
+ case QTabWidget::South:
+ result = QTabBar::RoundedSouth;
+ break;
+ case QTabWidget::West:
+ result = QTabBar::RoundedWest;
+ break;
+ case QTabWidget::East:
+ result = QTabBar::RoundedEast;
+ break;
+ }
+ }
+ return result;
+}
+#endif // QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
+
/*! \internal
Unplug \a widget (QDockWidget or QToolBar) from it's parent container.
@@ -2434,33 +2796,35 @@ static bool unplugGroup(QMainWindowLayout *layout, QLayoutItem **item,
Returns the QLayoutItem of the dragged element.
The layout item is kept in the layout but set as a gap item.
*/
-QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
+QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, QDockWidgetPrivate::DragScope scope)
{
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
auto *groupWindow = qobject_cast<const QDockWidgetGroupWindow *>(widget->parentWidget());
if (!widget->isWindow() && groupWindow) {
- if (group && groupWindow->tabLayoutInfo()) {
+ if (scope == QDockWidgetPrivate::DragScope::Group && groupWindow->tabLayoutInfo()) {
// We are just dragging a floating window as it, not need to do anything, we just have to
// look up the corresponding QWidgetItem* if it exists
if (QDockAreaLayoutInfo *info = dockInfo(widget->parentWidget())) {
QList<int> groupWindowPath = info->indexOf(widget->parentWidget());
return groupWindowPath.isEmpty() ? nullptr : info->item(groupWindowPath).widgetItem;
}
+ qCDebug(lcQpaDockWidgets) << "Drag only:" << widget << "Group:" << (scope == QDockWidgetPrivate::DragScope::Group);
return nullptr;
}
QList<int> path = groupWindow->layoutInfo()->indexOf(widget);
- QLayoutItem *item = groupWindow->layoutInfo()->item(path).widgetItem;
- if (group && path.size() > 1
- && unplugGroup(this, &item,
- groupWindow->layoutInfo()->item(path.mid(0, path.size() - 1)))) {
+ QDockAreaLayoutItem parentItem = groupWindow->layoutInfo()->item(path);
+ QLayoutItem *item = parentItem.widgetItem;
+ if (scope == QDockWidgetPrivate::DragScope::Group && path.size() > 1
+ && unplugGroup(this, &item, parentItem)) {
+ qCDebug(lcQpaDockWidgets) << "Unplugging:" << widget << "from" << item;
return item;
} else {
- // We are unplugging a dock widget from a floating window.
- QDockWidget *dw = qobject_cast<QDockWidget *>(widget);
- Q_ASSERT(dw); // cannot be a QDockWidgetGroupWindow because it's not floating.
- dw->d_func()->unplug(widget->geometry());
- groupWindow->layoutInfo()->fitItems();
- groupWindow->layoutInfo()->apply(dockOptions & QMainWindow::AnimatedDocks);
+ // We are unplugging a single dock widget from a floating window.
+ QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget);
+ Q_ASSERT(dockWidget); // cannot be a QDockWidgetGroupWindow because it's not floating.
+ dockWidget->d_func()->unplug(widget->geometry());
+
+ qCDebug(lcQpaDockWidgets) << "Unplugged from floating dock:" << widget << "from" << parentItem.widgetItem;
return item;
}
}
@@ -2480,7 +2844,7 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) {
Q_ASSERT(path.constFirst() == 1);
#if QT_CONFIG(tabwidget)
- if (group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3
+ if (scope == QDockWidgetPrivate::DragScope::Group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3
&& unplugGroup(this, &item,
layoutState.dockAreaLayout.item(path.mid(1, path.size() - 2)))) {
path.removeLast();
@@ -2488,6 +2852,36 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
} else
#endif // QT_CONFIG(tabwidget)
{
+ // Dock widget is unplugged from a main window dock
+ // => height or width need to be decreased by separator size
+ switch (dockWidgetArea(dw)) {
+ case Qt::LeftDockWidgetArea:
+ case Qt::RightDockWidgetArea:
+ r.setHeight(r.height() - sep);
+ break;
+ case Qt::TopDockWidgetArea:
+ case Qt::BottomDockWidgetArea:
+ r.setWidth(r.width() - sep);
+ break;
+ case Qt::NoDockWidgetArea:
+ case Qt::DockWidgetArea_Mask:
+ break;
+ }
+
+ // Depending on the title bar layout (vertical / horizontal),
+ // width and height have to provide minimum space for window handles
+ // and mouse dragging.
+ // Assuming horizontal title bar, if the dock widget does not have a layout.
+ const auto *layout = qobject_cast<QDockWidgetLayout *>(dw->layout());
+ const bool verticalTitleBar = layout ? layout->verticalTitleBar : false;
+ const int tbHeight = QApplication::style()
+ ? QApplication::style()->pixelMetric(QStyle::PixelMetric::PM_TitleBarHeight, nullptr, dw)
+ : 20;
+ const int minHeight = verticalTitleBar ? 2 * tbHeight : tbHeight;
+ const int minWidth = verticalTitleBar ? tbHeight : 2 * tbHeight;
+ r.setSize(r.size().expandedTo(QSize(minWidth, minHeight)));
+ qCDebug(lcQpaDockWidgets) << dw << "will be unplugged with size" << r.size();
+
dw->d_func()->unplug(r);
}
}
@@ -2499,7 +2893,7 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
#endif
#if !QT_CONFIG(dockwidget) || !QT_CONFIG(tabbar)
- Q_UNUSED(group);
+ Q_UNUSED(scope);
#endif
layoutState.unplug(path ,&savedState);
@@ -2529,58 +2923,45 @@ void QMainWindowLayout::updateGapIndicator()
if (!gapIndicator) {
gapIndicator = new QRubberBand(QRubberBand::Rectangle, expectedParent);
// For accessibility to identify this special widget.
- gapIndicator->setObjectName(QLatin1String("qt_rubberband"));
+ gapIndicator->setObjectName("qt_rubberband"_L1);
} else if (gapIndicator->parent() != expectedParent) {
gapIndicator->setParent(expectedParent);
}
+ // Prevent re-entry in case of size change
+ const bool sigBlockState = gapIndicator->signalsBlocked();
+ auto resetSignals = qScopeGuard([this, sigBlockState](){ gapIndicator->blockSignals(sigBlockState); });
+ gapIndicator->blockSignals(true);
+
#if QT_CONFIG(dockwidget)
if (currentHoveredFloat)
gapIndicator->setGeometry(currentHoveredFloat->currentGapRect);
else
#endif
gapIndicator->setGeometry(currentGapRect);
+
gapIndicator->show();
gapIndicator->raise();
+
+ // Reset signal state
+
} else if (gapIndicator) {
gapIndicator->hide();
}
-#endif // QT_CONFIG(rubberband)
-}
-#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
-static QTabBar::Shape tabwidgetPositionToTabBarShape(QWidget *w)
-{
- QTabBar::Shape result = QTabBar::RoundedSouth;
- if (qobject_cast<QDockWidget *>(w)) {
- switch (static_cast<QDockWidgetPrivate *>(qt_widget_private(w))->tabPosition) {
- case QTabWidget::North:
- result = QTabBar::RoundedNorth;
- break;
- case QTabWidget::South:
- result = QTabBar::RoundedSouth;
- break;
- case QTabWidget::West:
- result = QTabBar::RoundedWest;
- break;
- case QTabWidget::East:
- result = QTabBar::RoundedEast;
- break;
- }
- }
- return result;
+#endif // QT_CONFIG(rubberband)
}
-#endif // QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
-void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
-{
- if (!parentWidget()->isVisible() || parentWidget()->isMinimized()
- || pluggingWidget != nullptr || widgetItem == nullptr)
- return;
+void QMainWindowLayout::hover(QLayoutItem *hoverTarget,
+ const QPoint &mousePos) {
+ if (!parentWidget()->isVisible() || parentWidget()->isMinimized() ||
+ pluggingWidget != nullptr || hoverTarget == nullptr)
+ return;
- QWidget *widget = widgetItem->widget();
+ QWidget *widget = hoverTarget->widget();
#if QT_CONFIG(dockwidget)
+ widget->raise();
if ((dockOptions & QMainWindow::GroupedDragging) && (qobject_cast<QDockWidget*>(widget)
|| qobject_cast<QDockWidgetGroupWindow *>(widget))) {
@@ -2591,12 +2972,20 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
QWidget *w = qobject_cast<QWidget*>(c);
if (!w)
continue;
+
+ // Handle only dock widgets and group windows
if (!qobject_cast<QDockWidget*>(w) && !qobject_cast<QDockWidgetGroupWindow *>(w))
continue;
+
+ // Check permission to dock on another dock widget or floating dock
+ // FIXME in Qt 7
+
if (w != widget && w->isWindow() && w->isVisible() && !w->isMinimized())
candidates << w;
+
if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) {
- // Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent.
+ // floating QDockWidgets have a QDockWidgetGroupWindow as a parent,
+ // if they have been hovered over
const auto groupChildren = group->children();
for (QObject *c : groupChildren) {
if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) {
@@ -2606,6 +2995,7 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
}
}
}
+
for (QWidget *w : candidates) {
const QScreen *screen1 = qt_widget_private(widget)->associatedScreen();
const QScreen *screen2 = qt_widget_private(w)->associatedScreen();
@@ -2616,36 +3006,63 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
#if QT_CONFIG(tabwidget)
if (auto dropTo = qobject_cast<QDockWidget *>(w)) {
- // dropping to a normal widget, we mutate it in a QDockWidgetGroupWindow with two
- // tabs
- QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow(); // FIXME
- floatingTabs->setGeometry(dropTo->geometry());
- QDockAreaLayoutInfo *info = floatingTabs->layoutInfo();
- const QTabBar::Shape shape = tabwidgetPositionToTabBarShape(dropTo);
- *info = QDockAreaLayoutInfo(&layoutState.dockAreaLayout.sep, QInternal::LeftDock,
- Qt::Horizontal, shape,
- static_cast<QMainWindow *>(parentWidget()));
- info->tabbed = true;
- QLayout *parentLayout = dropTo->parentWidget()->layout();
- info->item_list.append(
- QDockAreaLayoutItem(parentLayout->takeAt(parentLayout->indexOf(dropTo))));
-
- dropTo->setParent(floatingTabs);
+
+ // w is the drop target's widget
+ w = dropTo->widget();
+
+ // Create a floating tab, unless already existing
+ if (!qobject_cast<QDockWidgetGroupWindow *>(w)) {
+ QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow();
+ floatingTabs->setGeometry(dropTo->geometry());
+ QDockAreaLayoutInfo *info = floatingTabs->layoutInfo();
+ const QTabBar::Shape shape = tabwidgetPositionToTabBarShape(dropTo);
+
+ // dropTo and widget may be in a state where they transition
+ // from being a group window child to a single floating dock widget.
+ // In that case, their path to a main window dock may not have been
+ // updated yet.
+ // => ask both and fall back to dock 1 (right dock)
+ QInternal::DockPosition dockPosition = toDockPos(dockWidgetArea(dropTo));
+ if (dockPosition == QInternal::DockPosition::DockCount)
+ dockPosition = toDockPos(dockWidgetArea(widget));
+ if (dockPosition == QInternal::DockPosition::DockCount)
+ dockPosition = QInternal::DockPosition::RightDock;
+
+ *info = QDockAreaLayoutInfo(&layoutState.dockAreaLayout.sep, dockPosition,
+ Qt::Horizontal, shape,
+ static_cast<QMainWindow *>(parentWidget()));
+ info->tabBar = getTabBar();
+ info->tabbed = true;
+ info->add(dropTo);
+ QDockAreaLayoutInfo &parentInfo = layoutState.dockAreaLayout.docks[dockPosition];
+ parentInfo.add(floatingTabs);
+ dropTo->setParent(floatingTabs);
+ qCDebug(lcQpaDockWidgets) << "Wrapping" << widget << "into floating tabs" << floatingTabs;
+ w = floatingTabs;
+ }
+
+ // Show the drop target and raise widget to foreground
dropTo->show();
- dropTo->d_func()->plug(QRect());
- w = floatingTabs;
- widget->raise(); // raise, as our newly created drop target is now on top
+ qCDebug(lcQpaDockWidgets) << "Showing" << dropTo;
+ widget->raise();
+ qCDebug(lcQpaDockWidgets) << "Raising" << widget;
}
#endif
- Q_ASSERT(qobject_cast<QDockWidgetGroupWindow *>(w));
- auto group = static_cast<QDockWidgetGroupWindow *>(w);
- if (group->hover(widgetItem, group->mapFromGlobal(mousePos))) {
- setCurrentHoveredFloat(group);
+ auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(w);
+ Q_ASSERT(groupWindow);
+ if (groupWindow->hover(hoverTarget, groupWindow->mapFromGlobal(mousePos))) {
+ setCurrentHoveredFloat(groupWindow);
applyState(layoutState); // update the tabbars
}
return;
}
}
+
+ // If a temporary group window has been created during a hover,
+ // remove it, if it has only one dockwidget child
+ if (currentHoveredFloat)
+ currentHoveredFloat->destroyIfSingleItemLeft();
+
setCurrentHoveredFloat(nullptr);
layoutState.dockAreaLayout.fallbackToSizeHints = false;
#endif // QT_CONFIG(dockwidget)
@@ -2661,11 +3078,7 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
bool allowed = false;
#if QT_CONFIG(dockwidget)
- if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
- allowed = dw->isAreaAllowed(toDockWidgetArea(path.at(1)));
-
- if (qobject_cast<QDockWidgetGroupWindow *>(widget))
- allowed = true;
+ allowed = isAreaAllowed(widget, path);
#endif
#if QT_CONFIG(toolbar)
if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
@@ -2681,16 +3094,16 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
currentGapPos = path;
if (path.isEmpty()) {
- fixToolBarOrientation(widgetItem, 2); // 2 = top dock, ie. horizontal
+ fixToolBarOrientation(hoverTarget, 2); // 2 = top dock, ie. horizontal
restore(true);
return;
}
- fixToolBarOrientation(widgetItem, currentGapPos.at(1));
+ fixToolBarOrientation(hoverTarget, currentGapPos.at(1));
QMainWindowLayoutState newState = savedState;
- if (!newState.insertGap(path, widgetItem)) {
+ if (!newState.insertGap(path, hoverTarget)) {
restore(true); // not enough space
return;
}
@@ -2727,10 +3140,16 @@ QDockWidgetGroupWindow *QMainWindowLayout::createTabbedDockWindow()
void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animate)
{
+ // applying the state can lead to showing separator widgets, which would lead to a re-layout
+ // (even though the separator widgets are not really part of the layout)
+ // break the loop
+ if (isInApplyState)
+ return;
+ isInApplyState = true;
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars();
const auto groups =
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ parent()->findChildren<QDockWidgetGroupWindow*>(Qt::FindDirectChildrenOnly);
for (QDockWidgetGroupWindow *dwgw : groups)
used += dwgw->layoutInfo()->usedTabBars();
@@ -2749,6 +3168,7 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
usedSeparatorWidgets = usedSeps;
for (QWidget *sepWidget : retiredSeps) {
unusedSeparatorWidgets.append(sepWidget);
+ sepWidget->hide();
}
}
@@ -2757,6 +3177,7 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
#endif // QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
newState.apply(dockOptions & QMainWindow::AnimatedDocks && animate);
+ isInApplyState = false;
}
void QMainWindowLayout::saveState(QDataStream &stream) const
@@ -2766,6 +3187,7 @@ void QMainWindowLayout::saveState(QDataStream &stream) const
bool QMainWindowLayout::restoreState(QDataStream &stream)
{
+ QScopedValueRollback<bool> guard(isInRestoreState, true);
savedState = layoutState;
layoutState.clear();
layoutState.rect = savedState.rect;
@@ -2781,6 +3203,18 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
if (parentWidget()->isVisible()) {
layoutState.fitLayout();
applyState(layoutState, false);
+ } else {
+ /*
+ The state might not fit into the size of the widget as it gets shown, but
+ if the window is expected to be maximized or full screened, then we might
+ get several resizes as part of that transition, at the end of which the
+ state might fit. So keep the restored state around for now and try again
+ later in setGeometry.
+ */
+ if ((parentWidget()->windowState() & (Qt::WindowFullScreen | Qt::WindowMaximized))
+ && !layoutState.fits()) {
+ restoredState.reset(new QMainWindowLayoutState(layoutState));
+ }
}
savedState.deleteAllLayoutItems();
@@ -2789,7 +3223,7 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
#if QT_CONFIG(dockwidget)
if (parentWidget()->isVisible()) {
#if QT_CONFIG(tabbar)
- for (QTabBar *tab_bar : qAsConst(usedTabBars))
+ for (QTabBar *tab_bar : std::as_const(usedTabBars))
tab_bar->show();
#endif
@@ -2799,6 +3233,42 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
return true;
}
+#if QT_CONFIG(draganddrop)
+bool QMainWindowLayout::needsPlatformDrag()
+{
+ static const bool wayland =
+ QGuiApplication::platformName().startsWith("wayland"_L1, Qt::CaseInsensitive);
+ return wayland;
+}
+
+Qt::DropAction QMainWindowLayout::performPlatformWidgetDrag(QLayoutItem *widgetItem,
+ const QPoint &pressPosition)
+{
+ draggingWidget = widgetItem;
+ QWidget *widget = widgetItem->widget();
+ auto drag = QDrag(widget);
+ auto mimeData = new QMimeData();
+ auto window = widgetItem->widget()->windowHandle();
+
+ auto serialize = [](const auto &object) {
+ QByteArray data;
+ QDataStream dataStream(&data, QIODevice::WriteOnly);
+ dataStream << object;
+ return data;
+ };
+ mimeData->setData("application/x-qt-mainwindowdrag-window"_L1,
+ serialize(reinterpret_cast<qintptr>(window)));
+ mimeData->setData("application/x-qt-mainwindowdrag-position"_L1, serialize(pressPosition));
+ drag.setMimeData(mimeData);
+
+ auto result = drag.exec();
+
+ draggingWidget = nullptr;
+ return result;
+}
+#endif
+
QT_END_NAMESPACE
+#include "qmainwindowlayout.moc"
#include "moc_qmainwindowlayout_p.cpp"
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 0c840d7ac7..55a27e4849 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICMAINWINDOWLAYOUT_P_H
-#define QDYNAMICMAINWINDOWLAYOUT_P_H
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QMAINWINDOWLAYOUT_P_H
+#define QMAINWINDOWLAYOUT_P_H
//
// W A R N I N G
@@ -65,18 +29,31 @@
#include "QtCore/qset.h"
#include "private/qlayoutengine_p.h"
#include "private/qwidgetanimator_p.h"
-
#if QT_CONFIG(dockwidget)
+#include "private/qdockwidget_p.h"
+
#include "qdockarealayout_p.h"
+#include "qdockwidget.h"
+#else
+struct QDockWidgetPrivate {
+ enum class DragScope {
+ Group
+ };
+};
#endif
#if QT_CONFIG(toolbar)
#include "qtoolbararealayout_p.h"
#endif
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(mainwindow);
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaDockWidgets);
+
class QToolBar;
class QRubberBand;
@@ -334,18 +311,21 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::endSeparatorMove(const QPoint &)
return true;
}
-class QDockWidgetGroupWindow : public QWidget
+class Q_AUTOTEST_EXPORT QDockWidgetGroupWindow : public QWidget
{
Q_OBJECT
public:
- explicit QDockWidgetGroupWindow(QWidget* parent = nullptr, Qt::WindowFlags f = { })
- : QWidget(parent, f) {}
+ explicit QDockWidgetGroupWindow(QWidget *parent = nullptr, Qt::WindowFlags f = {})
+ : QWidget(parent, f)
+ {
+ }
QDockAreaLayoutInfo *layoutInfo() const;
#if QT_CONFIG(tabbar)
const QDockAreaLayoutInfo *tabLayoutInfo() const;
QDockWidget *activeTabbedDockWidget() const;
#endif
void destroyOrHideIfEmpty();
+ bool hasVisibleDockWidgets() const;
void adjustFlags();
bool hasNativeDecos() const;
@@ -353,6 +333,10 @@ public:
void updateCurrentGapRect();
void restore();
void apply();
+ void childEvent(QChildEvent *event) override;
+ void reparent(QDockWidget *dockWidget);
+ void destroyIfSingleItemLeft();
+ QList<QDockWidget *> dockWidgets() const { return findChildren<QDockWidget *>(); }
QRect currentGapRect;
QList<int> currentGapPos;
@@ -362,6 +346,7 @@ signals:
protected:
bool event(QEvent *) override;
+ bool eventFilter(QObject *obj, QEvent *event) override;
void paintEvent(QPaintEvent*) override;
private:
@@ -369,14 +354,35 @@ private:
};
// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly
-// because QWidgetItem functions return an empty size for widgets that are are floating.
+// because QWidgetItem functions return an empty size for widgets that are floating.
class QDockWidgetGroupWindowItem : public QWidgetItem
{
public:
explicit QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {}
- QSize minimumSize() const override { return lay()->minimumSize(); }
- QSize maximumSize() const override { return lay()->maximumSize(); }
- QSize sizeHint() const override { return lay()->sizeHint(); }
+
+ // when the item contains a dock widget, obtain its size (to prevent infinite loop)
+ // ask the layout otherwise
+ QSize minimumSize() const override
+ {
+ if (auto dw = widget()->findChild<QDockWidget *>())
+ return dw->minimumSize();
+ return lay()->minimumSize();
+ }
+ QSize maximumSize() const override
+ {
+ auto dw = widget()->findChild<QDockWidget *>();
+ if (dw)
+ return dw->maximumSize();
+ return lay()->maximumSize();
+ }
+ QSize sizeHint() const override
+ {
+ auto dw = widget()->findChild<QDockWidget *>();
+ if (dw)
+ return dw->sizeHint();
+ return lay()->sizeHint();
+ }
+ QWidget* widget() const override { return wid; }
private:
QLayout *lay() const { return const_cast<QDockWidgetGroupWindowItem *>(this)->widget()->layout(); }
@@ -384,12 +390,12 @@ private:
#endif // QT_CONFIG(dockwidget)
/* This data structure represents the state of all the tool-bars and dock-widgets. It's value based
- so it can be easilly copied into a temporary variable. All operations are performed without moving
+ so it can be easily copied into a temporary variable. All operations are performed without moving
any widgets. Only when we are sure we have the desired state, we call apply(), which moves the
widgets.
*/
-class QMainWindowLayoutState
+class Q_AUTOTEST_EXPORT QMainWindowLayoutState
{
public:
QRect rect;
@@ -414,6 +420,7 @@ public:
QSize sizeHint() const;
QSize minimumSize() const;
+ bool fits() const;
void fitLayout();
QLayoutItem *itemAt(int index, int *x) const;
@@ -443,6 +450,7 @@ public:
bool restoreState(QDataStream &stream, const QMainWindowLayoutState &oldState);
};
+class QMainWindowTabBar;
class Q_AUTOTEST_EXPORT QMainWindowLayout
: public QLayout,
public QMainWindowLayoutSeparatorHelper<QMainWindowLayout>
@@ -451,6 +459,7 @@ class Q_AUTOTEST_EXPORT QMainWindowLayout
public:
QMainWindowLayoutState layoutState, savedState;
+ std::unique_ptr<QMainWindowLayoutState> restoredState;
QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLayout);
~QMainWindowLayout();
@@ -458,22 +467,19 @@ public:
QMainWindow::DockOptions dockOptions;
void setDockOptions(QMainWindow::DockOptions opts);
- // status bar
-
QLayoutItem *statusbar;
+ // status bar
#if QT_CONFIG(statusbar)
QStatusBar *statusBar() const;
void setStatusBar(QStatusBar *sb);
#endif
// central widget
-
QWidget *centralWidget() const;
void setCentralWidget(QWidget *cw);
// toolbars
-
#if QT_CONFIG(toolbar)
void addToolBarBreak(Qt::ToolBarArea area);
void insertToolBarBreak(QToolBar *before);
@@ -490,10 +496,11 @@ public:
#endif
// dock widgets
-
#if QT_CONFIG(dockwidget)
void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
Qt::DockWidgetArea corner(Qt::Corner corner) const;
+ enum DockWidgetAreaSize {Visible, Maximum};
+ QRect dockWidgetAreaRect(Qt::DockWidgetArea area, DockWidgetAreaSize size = Maximum) const;
void addDockWidget(Qt::DockWidgetArea area,
QDockWidget *dockwidget,
Qt::Orientation orientation);
@@ -540,15 +547,14 @@ public:
#endif // QT_CONFIG(dockwidget)
// save/restore
-
enum VersionMarkers { // sentinel values used to validate state data
VersionMarker = 0xff
};
void saveState(QDataStream &stream) const;
bool restoreState(QDataStream &stream);
+ QBasicTimer discardRestoredStateTimer;
// QLayout interface
-
void addItem(QLayoutItem *item) override;
void setGeometry(const QRect &r) override;
QLayoutItem *itemAt(int index) const override;
@@ -562,7 +568,6 @@ public:
void invalidate() override;
// animations
-
QWidgetAnimator widgetAnimator;
QList<int> currentGapPos;
QRect currentGapRect;
@@ -573,17 +578,32 @@ public:
#if QT_CONFIG(dockwidget)
QPointer<QDockWidgetGroupWindow> currentHoveredFloat; // set when dragging over a floating dock widget
void setCurrentHoveredFloat(QDockWidgetGroupWindow *w);
+#if QT_CONFIG(tabbar)
+ bool isDockWidgetTabbed(const QDockWidget *dockWidget) const;
+ QList<QDockWidget *> tabifiedDockWidgets(const QDockWidget *dockWidget) const;
+ QMainWindowTabBar *findTabBar(const QDockWidget *dockWidget) const;
#endif
+#endif
+ bool isInApplyState = false;
- void hover(QLayoutItem *widgetItem, const QPoint &mousePos);
+ void hover(QLayoutItem *hoverTarget, const QPoint &mousePos);
bool plug(QLayoutItem *widgetItem);
- QLayoutItem *unplug(QWidget *widget, bool group = false);
+ QLayoutItem *unplug(QWidget *widget, QDockWidgetPrivate::DragScope scope);
void revert(QLayoutItem *widgetItem);
- void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip);
void applyState(QMainWindowLayoutState &newState, bool animate = true);
+ void applyRestoredState();
void restore(bool keepSavedState = false);
void animationFinished(QWidget *widget);
+#if QT_CONFIG(draganddrop)
+ static bool needsPlatformDrag();
+ Qt::DropAction performPlatformWidgetDrag(QLayoutItem *widgetItem, const QPoint &pressPosition);
+ QLayoutItem *draggingWidget = nullptr;
+#endif
+
+protected:
+ void timerEvent(QTimerEvent *e) override;
+
private Q_SLOTS:
void updateGapIndicator();
#if QT_CONFIG(dockwidget)
@@ -596,6 +616,7 @@ private:
#if QT_CONFIG(tabbar)
void updateTabBarShapes();
#endif
+ bool isInRestoreState = false;
};
#if QT_CONFIG(dockwidget) && !defined(QT_NO_DEBUG_STREAM)
@@ -606,4 +627,4 @@ QDebug operator<<(QDebug debug, const QMainWindowLayout *layout);
QT_END_NAMESPACE
-#endif // QDYNAMICMAINWINDOWLAYOUT_P_H
+#endif // QMAINWINDOWLAYOUT_P_H
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 99b2009890..79b83453ac 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*!
\class QMdiArea
@@ -176,6 +140,7 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
using namespace QMdi;
// Asserts in debug mode, gives warning otherwise.
@@ -255,19 +220,7 @@ static inline QMdiArea *mdiAreaParent(QWidget *widget)
}
#if QT_CONFIG(tabwidget)
-static inline QTabBar::Shape tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position)
-{
- const bool rounded = (shape == QTabWidget::Rounded);
- if (position == QTabWidget::North)
- return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth;
- if (position == QTabWidget::South)
- return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth;
- if (position == QTabWidget::East)
- return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast;
- if (position == QTabWidget::West)
- return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest;
- return QTabBar::RoundedNorth;
-}
+QTabBar::Shape _q_tb_tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position);
#endif // QT_CONFIG(tabwidget)
static inline QString tabTextFor(QMdiSubWindow *subWindow)
@@ -277,7 +230,7 @@ static inline QString tabTextFor(QMdiSubWindow *subWindow)
QString title = subWindow->windowTitle();
if (subWindow->isWindowModified()) {
- title.replace(QLatin1String("[*]"), QLatin1String("*"));
+ title.replace("[*]"_L1, "*"_L1);
} else {
extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*);
title = qt_setWindowTitle_helperHelper(title, subWindow);
@@ -469,8 +422,8 @@ QList<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const Q
ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end());
result.reserve(ylist.size() * xlist.size());
- for (int y : qAsConst(ylist))
- for (int x : qAsConst(xlist))
+ for (int y : std::as_const(ylist))
+ for (int x : std::as_const(xlist))
result << QRect(QPoint(x, y), size);
return result;
}
@@ -718,7 +671,11 @@ void QMdiAreaPrivate::_q_deactivateAllWindows(QMdiSubWindow *aboutToActivate)
aboutToBecomeActive = aboutToActivate;
Q_ASSERT(aboutToBecomeActive);
- foreach (QMdiSubWindow *child, childWindows) {
+ // Take a copy because child->showNormal() could indirectly call
+ // QCoreApplication::sendEvent(), which could call unknown code that e.g.
+ // recurses into the class modifying childWindows.
+ const auto subWindows = childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::deactivateAllWindows") || aboutToBecomeActive == child)
continue;
// We don't want to handle signals caused by child->showNormal().
@@ -785,7 +742,7 @@ void QMdiAreaPrivate::_q_currentTabChanged(int index)
// If the previous active sub-window was hidden, disable the tab.
if (indexToLastActiveTab >= 0 && indexToLastActiveTab < tabBar->count()
- && indexToLastActiveTab < childWindows.count()) {
+ && indexToLastActiveTab < childWindows.size()) {
QMdiSubWindow *lastActive = childWindows.at(indexToLastActiveTab);
if (lastActive && lastActive->isHidden())
tabBar->setTabEnabled(indexToLastActiveTab, false);
@@ -859,7 +816,7 @@ void QMdiAreaPrivate::appendChild(QMdiSubWindow *child)
if (tabBar) {
tabBar->addTab(child->windowIcon(), tabTextFor(child));
updateTabBarGeometry();
- if (childWindows.count() == 1 && !(options & QMdiArea::DontMaximizeSubWindowOnActivation))
+ if (childWindows.size() == 1 && !(options & QMdiArea::DontMaximizeSubWindowOnActivation))
showActiveWindowMaximized = true;
}
#endif
@@ -893,7 +850,7 @@ void QMdiAreaPrivate::place(Placer *placer, QMdiSubWindow *child)
QList<QRect> rects;
rects.reserve(childWindows.size());
QRect parentRect = q->rect();
- foreach (QMdiSubWindow *window, childWindows) {
+ for (QMdiSubWindow *window : std::as_const(childWindows)) {
if (!sanityCheck(window, "QMdiArea::place") || window == child || !window->isVisibleTo(q)
|| !window->testAttribute(Qt::WA_Moved)) {
continue;
@@ -935,7 +892,7 @@ void QMdiAreaPrivate::rearrange(Rearranger *rearranger)
const bool reverseList = rearranger->type() == Rearranger::RegularTiler;
const QList<QMdiSubWindow *> subWindows = subWindowList(activationOrder, reverseList);
QSize minSubWindowSize;
- foreach (QMdiSubWindow *child, subWindows) {
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::rearrange") || !child->isVisible())
continue;
if (rearranger->type() == Rearranger::IconTiler) {
@@ -954,7 +911,7 @@ void QMdiAreaPrivate::rearrange(Rearranger *rearranger)
QRect domain = viewport->rect();
if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty())
- domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count());
+ domain = resizeToMinimumTileSize(minSubWindowSize, widgets.size());
rearranger->rearrange(widgets, domain);
@@ -1000,6 +957,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);
}
@@ -1327,7 +1288,7 @@ bool QMdiAreaPrivate::scrollBarsEnabled() const
*/
bool QMdiAreaPrivate::lastWindowAboutToBeDestroyed() const
{
- if (childWindows.count() != 1)
+ if (childWindows.size() != 1)
return false;
QMdiSubWindow *last = childWindows.at(0);
@@ -1345,7 +1306,7 @@ bool QMdiAreaPrivate::lastWindowAboutToBeDestroyed() const
*/
void QMdiAreaPrivate::setChildActivationEnabled(bool enable, bool onlyNextActivationEvent) const
{
- foreach (QMdiSubWindow *subWindow, childWindows) {
+ for (QMdiSubWindow *subWindow : childWindows) {
if (!subWindow || !subWindow->isVisible())
continue;
if (onlyNextActivationEvent)
@@ -1367,7 +1328,11 @@ void QMdiAreaPrivate::scrollBarPolicyChanged(Qt::Orientation orientation, Qt::Sc
const QMdiSubWindow::SubWindowOption option = orientation == Qt::Horizontal ?
QMdiSubWindow::AllowOutsideAreaHorizontally : QMdiSubWindow::AllowOutsideAreaVertically;
const bool enable = policy != Qt::ScrollBarAlwaysOff;
- foreach (QMdiSubWindow *child, childWindows) {
+ // Take a copy because child->setOption() may indirectly call QCoreApplication::sendEvent(),
+ // the latter could call unknown code that could e.g. recurse into the class
+ // modifying childWindows.
+ const auto subWindows = childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::scrollBarPolicyChanged"))
continue;
child->setOption(option, enable);
@@ -1383,7 +1348,7 @@ QMdiAreaPrivate::subWindowList(QMdiArea::WindowOrder order, bool reversed) const
return list;
if (order == QMdiArea::CreationOrder) {
- foreach (QMdiSubWindow *child, childWindows) {
+ for (QMdiSubWindow *child : childWindows) {
if (!child)
continue;
if (!reversed)
@@ -1403,7 +1368,7 @@ QMdiAreaPrivate::subWindowList(QMdiArea::WindowOrder order, bool reversed) const
}
} else { // ActivationHistoryOrder
Q_ASSERT(indicesToActivatedChildren.size() == childWindows.size());
- for (int i = indicesToActivatedChildren.count() - 1; i >= 0; --i) {
+ for (int i = indicesToActivatedChildren.size() - 1; i >= 0; --i) {
QMdiSubWindow *child = childWindows.at(indicesToActivatedChildren.at(i));
if (!child)
continue;
@@ -1511,7 +1476,7 @@ void QMdiAreaPrivate::highlightNextSubWindow(int increaseFactor)
if (!rubberBand) {
rubberBand = new QRubberBand(QRubberBand::Rectangle, q);
// For accessibility to identify this special widget.
- rubberBand->setObjectName(QLatin1String("qt_rubberband"));
+ rubberBand->setObjectName("qt_rubberband"_L1);
rubberBand->setWindowFlags(rubberBand->windowFlags() | Qt::WindowStaysOnTopHint);
}
#endif
@@ -1564,12 +1529,17 @@ void QMdiAreaPrivate::setViewMode(QMdiArea::ViewMode mode)
tabBar->setTabsClosable(tabsClosable);
tabBar->setMovable(tabsMovable);
#if QT_CONFIG(tabwidget)
- tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition));
+ tabBar->setShape(_q_tb_tabBarShapeFrom(tabShape, tabPosition));
#endif
isSubWindowsTiled = false;
- foreach (QMdiSubWindow *subWindow, childWindows)
+ // Take a copy as tabBar->addTab() will (indirectly) create a connection between
+ // the tab close button clicked() signal and the _q_closeTab() slot, which may
+ // indirectly call QCoreApplication::sendEvent(), the latter could result in
+ // invoking unknown code that could e.g. recurse into the class modifying childWindows.
+ const auto subWindows = childWindows;
+ for (QMdiSubWindow *subWindow : subWindows)
tabBar->addTab(subWindow->windowIcon(), tabTextFor(subWindow));
QMdiSubWindow *current = q->currentSubWindow();
@@ -1628,7 +1598,7 @@ void QMdiAreaPrivate::updateTabBarGeometry()
Q_Q(QMdiArea);
#if QT_CONFIG(tabwidget)
- Q_ASSERT(tabBarShapeFrom(tabShape, tabPosition) == tabBar->shape());
+ Q_ASSERT(_q_tb_tabBarShapeFrom(tabShape, tabPosition) == tabBar->shape());
#endif
const QSize tabBarSizeHint = tabBar->sizeHint();
@@ -1685,7 +1655,7 @@ void QMdiAreaPrivate::refreshTabBar()
tabBar->setTabsClosable(tabsClosable);
tabBar->setMovable(tabsMovable);
#if QT_CONFIG(tabwidget)
- tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition));
+ tabBar->setShape(_q_tb_tabBarShapeFrom(tabShape, tabPosition));
#endif
updateTabBarGeometry();
}
@@ -1792,7 +1762,7 @@ QMdiSubWindow *QMdiArea::currentSubWindow() const
if (d->isActivated && !window()->isMinimized())
return nullptr;
- Q_ASSERT(d->indicesToActivatedChildren.count() > 0);
+ Q_ASSERT(d->indicesToActivatedChildren.size() > 0);
int index = d->indicesToActivatedChildren.at(0);
Q_ASSERT(index >= 0 && index < d->childWindows.size());
QMdiSubWindow *current = d->childWindows.at(index);
@@ -1891,7 +1861,11 @@ void QMdiArea::closeAllSubWindows()
return;
d->isSubWindowsTiled = false;
- foreach (QMdiSubWindow *child, d->childWindows) {
+ // Take a copy because the child->close() call below may end up indirectly calling
+ // QCoreApplication::send{Spontaneous}Event(), which may call unknown code that
+ // could e.g. recurse into the class modifying d->childWindows.
+ const auto subWindows = d->childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::closeAllSubWindows"))
continue;
child->close();
@@ -2030,7 +2004,11 @@ void QMdiArea::removeSubWindow(QWidget *widget)
}
bool found = false;
- foreach (QMdiSubWindow *child, d->childWindows) {
+ // Take a copy because child->setWidget(nullptr) will indirectly
+ // QCoreApplication::sendEvent(); the latter could call unknown code that could
+ // e.g. recurse into the class modifying d->childWindows.
+ const auto subWindows = d->childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::removeSubWindow"))
continue;
if (child->widget() == widget) {
@@ -2311,10 +2289,21 @@ void QMdiArea::resizeEvent(QResizeEvent *resizeEvent)
// Resize maximized views.
bool hasMaximizedSubWindow = false;
- foreach (QMdiSubWindow *child, d->childWindows) {
+ // Take a copy because child->resize() may call QCoreApplication::sendEvent()
+ // which may invoke unknown code, that could e.g. recurse into the class
+ // modifying d->childWindows.
+ const auto subWindows = d->childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (sanityCheck(child, "QMdiArea::resizeEvent") && child->isMaximized()
&& child->size() != resizeEvent->size()) {
- child->resize(resizeEvent->size());
+ auto realSize = resizeEvent->size();
+ const auto minSizeHint = child->minimumSizeHint();
+ // QMdiSubWindow is no tlw so minimumSize() is not set by the layout manager
+ // and therefore we have to take care by ourself that we're not getting smaller
+ // than allowed
+ if (minSizeHint.isValid())
+ realSize = realSize.expandedTo(minSizeHint);
+ child->resize(realSize);
if (!hasMaximizedSubWindow)
hasMaximizedSubWindow = true;
}
@@ -2363,7 +2352,9 @@ void QMdiArea::showEvent(QShowEvent *showEvent)
Q_D(QMdiArea);
if (!d->pendingRearrangements.isEmpty()) {
bool skipPlacement = false;
- foreach (Rearranger *rearranger, d->pendingRearrangements) {
+ // Take a copy because d->rearrange() may modify d->pendingRearrangements
+ const auto pendingRearrange = d->pendingRearrangements;
+ for (Rearranger *rearranger : pendingRearrange) {
// If this is the case, we don't have to lay out pending child windows
// since the rearranger will find a placement for them.
if (rearranger->type() != Rearranger::IconTiler && !skipPlacement)
@@ -2377,9 +2368,19 @@ void QMdiArea::showEvent(QShowEvent *showEvent)
}
if (!d->pendingPlacements.isEmpty()) {
- foreach (QMdiSubWindow *window, d->pendingPlacements) {
+ // Nothing obvious in the loop body changes the container (in this code path)
+ // during iteration, this is calling into a non-const method that does change
+ // the container when called from other places. So take a copy anyway for good
+ // measure.
+ const auto copy = d->pendingPlacements;
+ for (QMdiSubWindow *window : copy) {
if (!window)
continue;
+ if (d->viewMode == TabbedView && window->d_func()->isActive && !d->active) {
+ d->showActiveWindowMaximized = true;
+ d->emitWindowActivated(window); // Also maximizes the window
+ continue;
+ }
if (!window->testAttribute(Qt::WA_Resized)) {
QSize newSize(window->sizeHint().boundedTo(viewport()->size()));
window->resize(newSize.expandedTo(qSmartMinSize(window)));
@@ -2513,12 +2514,16 @@ bool QMdiArea::event(QEvent *event)
d->isSubWindowsTiled = true;
}
break;
- case QEvent::WindowIconChange:
- foreach (QMdiSubWindow *window, d->childWindows) {
+ case QEvent::WindowIconChange: {
+ // Take a copy because QCoreApplication::sendEvent() may call unknown code,
+ // that may cause recursing into the class
+ const auto subWindows = d->childWindows;
+ for (QMdiSubWindow *window : subWindows) {
if (sanityCheck(window, "QMdiArea::WindowIconChange"))
QCoreApplication::sendEvent(window, event);
}
break;
+ }
case QEvent::Hide:
d->setActive(d->active, false, false);
d->setChildActivationEnabled(false);
@@ -2547,7 +2552,7 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event)
if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- // Ingore key events without a Ctrl modifier (except for press/release on the modifier itself).
+ // Ignore key events without a Ctrl modifier (except for press/release on the modifier itself).
if (!(keyEvent->modifiers() & Qt::ControlModifier) && keyEvent->key() != Qt::Key_Control)
return QAbstractScrollArea::eventFilter(object, event);
@@ -2673,7 +2678,10 @@ void QMdiArea::setupViewport(QWidget *viewport)
Q_D(QMdiArea);
if (viewport)
viewport->setAttribute(Qt::WA_OpaquePaintEvent, d->background.isOpaque());
- foreach (QMdiSubWindow *child, d->childWindows) {
+ // Take a copy because the child->setParent() call below may call QCoreApplication::sendEvent()
+ // which may call unknown code that could e.g. recurse into the class modifying d->childWindows.
+ const auto subWindows = d->childWindows;
+ for (QMdiSubWindow *child : subWindows) {
if (!sanityCheck(child, "QMdiArea::setupViewport"))
continue;
child->setParent(viewport, child->windowFlags());
diff --git a/src/widgets/widgets/qmdiarea.h b/src/widgets/widgets/qmdiarea.h
index 35edde9eb8..c1442bc645 100644
--- a/src/widgets/widgets/qmdiarea.h
+++ b/src/widgets/widgets/qmdiarea.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMDIAREA_H
#define QMDIAREA_H
diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h
index 1c39d1a378..e57b9772ca 100644
--- a/src/widgets/widgets/qmdiarea_p.h
+++ b/src/widgets/widgets/qmdiarea_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMDIAREA_P_H
#define QMDIAREA_P_H
@@ -65,6 +29,8 @@ QT_REQUIRE_CONFIG(mdiarea);
#include <private/qmdisubwindow_p.h>
#include <private/qabstractscrollarea_p.h>
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
namespace QMdi {
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 89d77574f0..d8700e3df2 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*!
\class QMdiSubWindow
@@ -174,6 +138,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
using namespace QMdi;
static const QStyle::SubControl SubControls[] =
@@ -263,13 +229,30 @@ static inline ControlElement<T> *ptr(QWidget *widget)
return nullptr;
}
+QString QMdiSubWindowPrivate::originalWindowTitleHelper() const
+{
+ Q_Q(const QMdiSubWindow);
+ // QTBUG-92240: When DontMaximizeSubWindowOnActivation is set and
+ // there is another subwindow maximized, use its original title.
+ if (auto *mdiArea = q->mdiArea()) {
+ const auto &subWindows = mdiArea->subWindowList();
+ for (auto *subWindow : subWindows) {
+ if (subWindow != q && subWindow->isMaximized()) {
+ auto *subWindowD = static_cast<QMdiSubWindowPrivate *>(qt_widget_private(subWindow));
+ if (!subWindowD->originalTitle.isNull())
+ return subWindowD->originalTitle;
+ }
+ }
+ }
+ return q->window()->windowTitle();
+}
+
QString QMdiSubWindowPrivate::originalWindowTitle()
{
- Q_Q(QMdiSubWindow);
if (originalTitle.isNull()) {
- originalTitle = q->window()->windowTitle();
+ originalTitle = originalWindowTitleHelper();
if (originalTitle.isNull())
- originalTitle = QLatin1String("");
+ originalTitle = ""_L1;
}
return originalTitle;
}
@@ -282,11 +265,17 @@ void QMdiSubWindowPrivate::setNewWindowTitle()
return;
QString original = originalWindowTitle();
if (!original.isEmpty()) {
- if (!original.contains(QMdiSubWindow::tr("- [%1]").arg(childTitle)))
- q->window()->setWindowTitle(QMdiSubWindow::tr("%1 - [%2]").arg(original, childTitle));
+ if (!original.contains(QMdiSubWindow::tr("- [%1]").arg(childTitle))) {
+ auto title = QMdiSubWindow::tr("%1 - [%2]").arg(original, childTitle);
+ ignoreWindowTitleChange = true;
+ q->window()->setWindowTitle(title);
+ ignoreWindowTitleChange = false;
+ }
} else {
+ ignoreWindowTitleChange = true;
q->window()->setWindowTitle(childTitle);
+ ignoreWindowTitleChange = false;
}
}
@@ -399,7 +388,7 @@ ControlLabel::ControlLabel(QMdiSubWindow *subWindow, QWidget *parent)
Q_UNUSED(subWindow);
setFocusPolicy(Qt::NoFocus);
updateWindowIcon();
- setFixedSize(label.size() / label.devicePixelRatio());
+ setFixedSize(label.deviceIndependentSize().toSize());
}
/*
@@ -407,7 +396,7 @@ ControlLabel::ControlLabel(QMdiSubWindow *subWindow, QWidget *parent)
*/
QSize ControlLabel::sizeHint() const
{
- return label.size() / label.devicePixelRatio();
+ return label.deviceIndependentSize().toSize();
}
/*
@@ -744,7 +733,7 @@ ControlContainer::~ControlContainer()
QMenuBar *QMdiSubWindowPrivate::menuBar() const
{
#if !QT_CONFIG(mainwindow)
- return 0;
+ return nullptr;
#else
Q_Q(const QMdiSubWindow);
if (!q->isMaximized() || drawTitleBarWhenMaximized() || isChildOfTabbedQMdiArea(q))
@@ -1896,7 +1885,7 @@ void QMdiSubWindowPrivate::enterRubberBandMode()
if (!rubberBand) {
rubberBand = new QRubberBand(QRubberBand::Rectangle, q->parentWidget());
// For accessibility to identify this special widget.
- rubberBand->setObjectName(QLatin1String("qt_rubberband"));
+ rubberBand->setObjectName("qt_rubberband"_L1);
}
QPoint rubberBandPos = q->mapToParent(QPoint(0, 0));
rubberBand->setGeometry(rubberBandPos.x(), rubberBandPos.y(),
@@ -1925,20 +1914,16 @@ QPalette QMdiSubWindowPrivate::desktopPalette() const
Q_Q(const QMdiSubWindow);
QPalette newPalette = q->palette();
- bool colorsInitialized = false;
-
- if (!colorsInitialized) {
- newPalette.setColor(QPalette::Active, QPalette::Highlight,
- newPalette.color(QPalette::Active, QPalette::Highlight));
- newPalette.setColor(QPalette::Active, QPalette::Base,
- newPalette.color(QPalette::Active, QPalette::Highlight));
- newPalette.setColor(QPalette::Inactive, QPalette::Highlight,
- newPalette.color(QPalette::Inactive, QPalette::Dark));
- newPalette.setColor(QPalette::Inactive, QPalette::Base,
- newPalette.color(QPalette::Inactive, QPalette::Dark));
- newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText,
- newPalette.color(QPalette::Inactive, QPalette::Window));
- }
+ newPalette.setColor(QPalette::Active, QPalette::Highlight,
+ newPalette.color(QPalette::Active, QPalette::Highlight));
+ newPalette.setColor(QPalette::Active, QPalette::Base,
+ newPalette.color(QPalette::Active, QPalette::Highlight));
+ newPalette.setColor(QPalette::Inactive, QPalette::Highlight,
+ newPalette.color(QPalette::Inactive, QPalette::Dark));
+ newPalette.setColor(QPalette::Inactive, QPalette::Base,
+ newPalette.color(QPalette::Inactive, QPalette::Dark));
+ newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ newPalette.color(QPalette::Inactive, QPalette::Window));
return newPalette;
}
@@ -2193,7 +2178,7 @@ void QMdiSubWindowPrivate::updateInternalWindowTitle()
Q_Q(QMdiSubWindow);
if (q->isWindowModified()) {
windowTitle = q->windowTitle();
- windowTitle.replace(QLatin1String("[*]"), QLatin1String("*"));
+ windowTitle.replace("[*]"_L1, "*"_L1);
} else {
windowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
}
@@ -2311,10 +2296,8 @@ void QMdiSubWindow::setWidget(QWidget *widget)
d->updateWindowTitle(true);
isWindowModified = d->baseWidget->isWindowModified();
}
- if (!this->isWindowModified() && isWindowModified
- && windowTitle().contains(QLatin1String("[*]"))) {
+ if (!this->isWindowModified() && isWindowModified && windowTitle().contains("[*]"_L1))
setWindowModified(isWindowModified);
- }
d->lastChildWindowTitle = d->baseWidget->windowTitle();
d->ignoreWindowTitleChange = false;
@@ -2747,7 +2730,7 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event)
bool windowModified = d->baseWidget->isWindowModified();
if (!windowModified && d->baseWidget->windowTitle() != windowTitle())
break;
- if (windowTitle().contains(QLatin1String("[*]")))
+ if (windowTitle().contains("[*]"_L1))
setWindowModified(windowModified);
break;
}
@@ -2848,7 +2831,7 @@ bool QMdiSubWindow::event(QEvent *event)
d->updateInternalWindowTitle();
break;
case QEvent::ModifiedChange:
- if (!windowTitle().contains(QLatin1String("[*]")))
+ if (!windowTitle().contains("[*]"_L1))
break;
#if QT_CONFIG(menubar)
if (maximizedButtonsWidget() && d->controlContainer->menuBar() && d->controlContainer->menuBar()
diff --git a/src/widgets/widgets/qmdisubwindow.h b/src/widgets/widgets/qmdisubwindow.h
index 302522e1c3..4227f02dac 100644
--- a/src/widgets/widgets/qmdisubwindow.h
+++ b/src/widgets/widgets/qmdisubwindow.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMDISUBWINDOW_H
#define QMDISUBWINDOW_H
@@ -137,6 +101,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_enterInteractiveMode())
Q_PRIVATE_SLOT(d_func(), void _q_processFocusChanged(QWidget *, QWidget *))
friend class QMdiAreaPrivate;
+ friend class QMdiArea;
#if QT_CONFIG(tabbar)
friend class QMdiAreaTabBar;
#endif
diff --git a/src/widgets/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h
index d3513b6708..2a1f83269a 100644
--- a/src/widgets/widgets/qmdisubwindow_p.h
+++ b/src/widgets/widgets/qmdisubwindow_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMDISUBWINDOW_P_H
#define QMDISUBWINDOW_P_H
@@ -75,7 +39,7 @@ class QMouseEvent;
namespace QMdi {
template<typename T>
-class ControlElement : public T
+class ControlElement : public T // ELFVERSION:ignore
{
public:
ControlElement(QMdiSubWindow *child) : T(child, nullptr)
@@ -94,7 +58,7 @@ public:
QPointer<QMdiSubWindow> mdiChild;
};
-class ControlContainer : public QObject
+class ControlContainer : public QObject // ELFVERSION:ignore
{
public:
ControlContainer(QMdiSubWindow *mdiChild);
@@ -121,7 +85,7 @@ private:
};
} // namespace QMdi
-class QMdiSubWindowPrivate : public QWidgetPrivate
+class Q_AUTOTEST_EXPORT QMdiSubWindowPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMdiSubWindow)
public:
@@ -286,6 +250,7 @@ public:
#endif
void updateInternalWindowTitle();
QString originalWindowTitle();
+ QString originalWindowTitleHelper() const;
void setNewWindowTitle();
inline int titleBarHeight() const
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 282cbe420f..db00f8a650 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qmenu.h"
@@ -48,10 +12,10 @@
#include "qevent.h"
#include "qtimer.h"
#include "qlayout.h"
-#include "qpainter.h"
+#include "qstylepainter.h"
#include <qpa/qplatformtheme.h>
#include "qapplication.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
# include "qaccessible.h"
#endif
#if QT_CONFIG(effects)
@@ -129,7 +93,9 @@ public:
Q_D(QTornOffMenu);
// make the torn-off menu a sibling of p (instead of a child)
QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.constLast();
- if (parentWidget->parentWidget())
+ if (!parentWidget && p)
+ parentWidget = p;
+ if (parentWidget && parentWidget->parentWidget())
parentWidget = parentWidget->parentWidget();
setParent(parentWidget, Qt::Window | Qt::Tool);
setAttribute(Qt::WA_DeleteOnClose, true);
@@ -146,7 +112,7 @@ public:
//QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*)));
//QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*)));
QList<QAction*> items = p->actions();
- for(int i = 0; i < items.count(); i++)
+ for(int i = 0; i < items.size(); i++)
addAction(items.at(i));
d->setMenuSize(sizeHint());
d->initialized = true;
@@ -199,7 +165,7 @@ void QMenuPrivate::init()
defaultMenuAction = menuAction = new QAction(q);
menuAction->setMenu(q); // this calls setOverrideMenuAction
setOverrideMenuAction(nullptr);
- QObject::connect(menuAction, &QAction::changed, [this] {
+ QObject::connect(menuAction, &QAction::changed, q, [this] {
if (!tornPopup.isNull())
tornPopup->updateWindowTitle();
});
@@ -251,13 +217,21 @@ void QMenuPrivate::syncPlatformMenu()
platformMenu->setEnabled(q->isEnabled());
}
+static QWidget *getParentWidget(const QAction *action)
+{
+ auto result = action->parent();
+ while (result && !qobject_cast<QWidget *>(result))
+ result = result->parent();
+ return static_cast<QWidget *>(result);
+}
+
void QMenuPrivate::copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item)
{
item->setText(action->text());
item->setIsSeparator(action->isSeparator());
if (action->isIconVisibleInMenu()) {
item->setIcon(action->icon());
- if (QWidget *w = action->parentWidget()) {
+ if (QWidget *w = getParentWidget(action)) {
QStyleOption opt;
opt.initFrom(w);
item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w));
@@ -318,6 +292,13 @@ inline bool QMenuPrivate::useFullScreenForPopup() const
QRect QMenuPrivate::popupGeometry(QScreen *screen) const
{
Q_Q(const QMenu);
+ if (screen == nullptr
+#if QT_CONFIG(graphicsview)
+ && q->graphicsProxyWidget() == nullptr
+#endif
+ ) {
+ screen = q->isVisible() ? q->screen() : popupScreen.data();
+ }
if (useFullScreenForPopup())
return screen ? screen->geometry()
: QWidgetPrivate::screenGeometry(q);
@@ -363,7 +344,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
q->ensurePolished();
//let's reinitialize the buffer
- actionRects.resize(actions.count());
+ actionRects.resize(actions.size());
actionRects.fill(QRect());
int lastVisibleAction = getLastVisibleAction();
@@ -388,7 +369,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
hasCheckableItems = false;
ncols = 1;
- for (int i = 0; i < actions.count(); ++i) {
+ for (int i = 0; i < actions.size(); ++i) {
QAction *action = actions.at(i);
if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
continue;
@@ -432,7 +413,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
sz = QSize(2, 2);
} else {
QString s = action->text();
- int t = s.indexOf(QLatin1Char('\t'));
+ qsizetype t = s.indexOf(u'\t');
if (t != -1) {
tabWidth = qMax(int(tabWidth), qfm.horizontalAdvance(s.mid(t+1)));
s = s.left(t);
@@ -482,7 +463,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
int x = hmargin + fw + leftmargin;
y = base_y;
- for(int i = 0; i < actions.count(); i++) {
+ for(int i = 0; i < actions.size(); i++) {
QRect &rect = actionRects[i];
if (rect.isNull())
continue;
@@ -507,7 +488,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
int QMenuPrivate::getLastVisibleAction() const
{
//let's try to get the last visible action
- int lastVisibleAction = actions.count() - 1;
+ int lastVisibleAction = actions.size() - 1;
for (;lastVisibleAction >= 0; --lastVisibleAction) {
const QAction *action = actions.at(lastVisibleAction);
if (action->isVisible()) {
@@ -595,10 +576,16 @@ void QMenuPrivate::hideMenu(QMenu *menu)
};
#if QT_CONFIG(effects)
- QSignalBlocker blocker(menu);
+ // If deleteLater has been called and the event loop spins, while waiting
+ // for visual effects to happen, menu might become stale.
+ // To prevent a QSignalBlocker from restoring a stale object, block and restore signals manually.
+ QPointer<QMenu> stillAlive(menu);
+ const bool signalsBlocked = menu->signalsBlocked();
+ menu->blockSignals(true);
+
aboutToHide = true;
// Flash item which is about to trigger (if any).
- if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
+ if (menu && menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
&& currentAction && currentAction == actionAboutToTrigger
&& menu->actions().contains(currentAction)) {
QEventLoop eventLoop;
@@ -609,6 +596,9 @@ void QMenuPrivate::hideMenu(QMenu *menu)
QTimer::singleShot(60, &eventLoop, SLOT(quit()));
eventLoop.exec();
+ if (!stillAlive)
+ return;
+
// Select and wait 20 ms.
menu->setActiveAction(activeAction);
QTimer::singleShot(20, &eventLoop, SLOT(quit()));
@@ -616,15 +606,44 @@ void QMenuPrivate::hideMenu(QMenu *menu)
}
aboutToHide = false;
- blocker.unblock();
+
+ if (stillAlive)
+ menu->blockSignals(signalsBlocked);
+ else
+ return;
+
#endif // QT_CONFIG(effects)
if (activeMenu == menu)
activeMenu = nullptr;
+
menu->d_func()->causedPopup.action = nullptr;
menu->close();
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);
@@ -666,7 +685,7 @@ void QMenuPrivate::setFirstActionActive()
{
Q_Q(QMenu);
updateActionRects();
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ for(int i = 0, saccum = 0; i < actions.size(); i++) {
const QRect &rect = actionRects.at(i);
if (rect.isNull())
continue;
@@ -903,7 +922,7 @@ QAction *QMenuPrivate::actionAt(QPoint p) const
if (!rect().contains(p)) //sanity check
return nullptr;
- for(int i = 0; i < actionRects.count(); i++) {
+ for(int i = 0; i < actionRects.size(); i++) {
if (actionRects.at(i).contains(p))
return actions.at(i);
}
@@ -1053,6 +1072,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
@@ -1104,7 +1133,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, q);
if (location == QMenuScroller::ScrollTop) {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ for(int i = 0, saccum = 0; i < actions.size(); i++) {
if (actions.at(i) == action) {
newOffset = topScroll - saccum;
break;
@@ -1112,7 +1141,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
saccum += actionRects.at(i).height();
}
} else {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ for(int i = 0, saccum = 0; i < actions.size(); i++) {
saccum += actionRects.at(i).height();
if (actions.at(i) == action) {
if (location == QMenuScroller::ScrollCenter)
@@ -1131,7 +1160,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
if (newOffset < 0) //easy and cheap one
newScrollFlags |= QMenuScroller::ScrollUp;
int saccum = newOffset;
- for(int i = 0; i < actionRects.count(); i++) {
+ for(int i = 0; i < actionRects.size(); i++) {
saccum += actionRects.at(i).height();
if (saccum > q->height()) {
newScrollFlags |= QMenuScroller::ScrollDown;
@@ -1188,7 +1217,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
if (!itemsDirty && delta) {
//we've scrolled so we need to update the action rects
- for (int i = 0; i < actionRects.count(); ++i) {
+ for (int i = 0; i < actionRects.size(); ++i) {
QRect &current = actionRects[i];
current.moveTop(current.top() + delta);
@@ -1255,7 +1284,7 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, q);
const int offset = topScroll ? topScroll-vmargin : 0;
if (direction == QMenuScroller::ScrollUp) {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ for(int i = 0, saccum = 0; i < actions.size(); i++) {
saccum -= actionRects.at(i).height();
if (saccum <= scroll->scrollOffset-offset) {
scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);
@@ -1264,13 +1293,13 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag
}
} else if (direction == QMenuScroller::ScrollDown) {
bool scrolled = false;
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ for(int i = 0, saccum = 0; i < actions.size(); i++) {
const int iHeight = actionRects.at(i).height();
saccum -= iHeight;
if (saccum <= scroll->scrollOffset-offset) {
const int scrollerArea = q->height() - botScroll - fw*2;
int visible = (scroll->scrollOffset-offset) - saccum;
- for(i++ ; i < actions.count(); i++) {
+ for(i++ ; i < actions.size(); i++) {
visible += actionRects.at(i).height();
if (visible > scrollerArea - topScroll) {
scrolled = true;
@@ -1382,9 +1411,18 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget>> &causedStack, QAction *action,
QAction::ActionEvent action_e, bool self)
{
- QBoolBlocker guard(activationRecursionGuard);
+ Q_Q(QMenu);
+ // can't use QBoolBlocker here
+ const bool activationRecursionGuardReset = activationRecursionGuard;
+ activationRecursionGuard = true;
+ QPointer<QMenu> guard(q);
if (self)
action->activate(action_e);
+ if (!guard)
+ return;
+ auto boolBlocker = qScopeGuard([this, activationRecursionGuardReset]{
+ activationRecursionGuard = activationRecursionGuardReset;
+ });
for(int i = 0; i < causedStack.size(); ++i) {
QPointer<QWidget> widget = causedStack.at(i);
@@ -1460,12 +1498,13 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
#endif
}
-
+ QPointer<QMenu> thisGuard(q);
activateCausedStack(causedStack, action, action_e, self);
-
+ if (!thisGuard)
+ return;
if (action_e == QAction::Hover) {
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
int actionIndex = indexOf(action);
QAccessibleEvent focusEvent(q, QAccessible::Focus);
@@ -1604,10 +1643,10 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
QString textAndAccel = action->text();
#ifndef QT_NO_SHORTCUT
if ((action->isShortcutVisibleInContextMenu() || !d->isContextMenu())
- && textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
+ && textAndAccel.indexOf(u'\t') == -1) {
QKeySequence seq = action->shortcut();
if (!seq.isEmpty())
- textAndAccel += QLatin1Char('\t') + seq.toString(QKeySequence::NativeText);
+ textAndAccel += u'\t' + seq.toString(QKeySequence::NativeText);
}
#endif
option->text = textAndAccel;
@@ -1654,7 +1693,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
and all other items are considered action items.
When inserting action items you usually specify a receiver and a
- slot. The receiver will be notifed whenever the item is
+ slot. The receiver will be notified whenever the item is
\l{QAction::triggered()}{triggered()}. In addition, QMenu provides
two signals, triggered() and hovered(), which signal the
QAction that was triggered from the menu.
@@ -1678,7 +1717,9 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
QWidgetAction fires the triggered() signal, the menu will close.
\warning To make QMenu visible on the screen, exec() or popup() should be
- used instead of show().
+ used instead of show() or setVisible(). To hide or disable the menu in the
+ menubar, or in another menu to which it was added as a submenu, use the
+ respective properties of menuAction() instead.
\section1 QMenu on \macos with Qt Build Against Cocoa
@@ -1691,8 +1732,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, {Menus Example}
*/
@@ -1757,162 +1797,75 @@ QMenu::~QMenu()
hideTearOffMenu();
}
+#if QT_DEPRECATED_SINCE(6, 4)
/*!
- This convenience function creates a new action with \a text.
- The function adds the newly created action to the menu's
- list of actions, and returns it.
-
- QMenu takes ownership of the returned QAction.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QString &text)
-{
- QAction *ret = new QAction(text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with an \a icon
- and some \a text. The function adds the newly created action to
- the menu's list of actions, and returns it.
-
- QMenu takes ownership of the returned QAction.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QIcon &icon, const QString &text)
-{
- QAction *ret = new QAction(icon, text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with the text \a
- text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a receiver's \a member slot. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenu takes ownership of the returned QAction.
+ \fn QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
+ \obsolete
- \sa QWidget::addAction()
+ Use \c{QWidget::addAction(text, shortcut, receiver, member)} instead.
*/
-QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member
#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut
-#endif
- )
+QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
{
- QAction *action = new QAction(text, this);
-#if QT_CONFIG(shortcut)
- action->setShortcut(shortcut);
-#endif
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
+ return QWidget::addAction(text, shortcut, receiver, member);
}
+#endif
-/*!\fn template<typename Functor> QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0)
+/*!
+ \fn template<typename Functor> QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut)
\since 5.6
+ \obsolete
- \overload
-
- This convenience function creates a new action with the text \a
- text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenu takes ownership of the returned QAction.
+ Use QWidget::addAction(text, shortcut, functor) instead.
*/
-/*!\fn template<typename Functor> QAction *QMenu::addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut)
+/*!
+ \fn template<typename Functor> QAction *QMenu::addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut)
\since 5.6
+ \obsolete
- \overload
-
- This convenience function creates a new action with the text \a
- text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The functor can be a pointer to a member function of
- the \a context object. The newly created action is added to the
- menu's list of actions and a pointer to it is returned.
-
- If the \a context object is destroyed, the functor will not be called.
-
- QMenu takes ownership of the returned QAction.
+ Use QWidget::addAction(text, shortcut, context, functor) instead.
*/
-/*!\fn template<typename Functor> QAction *QMenu::addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0)
+/*!
+ \fn template<typename Functor> QAction *QMenu::addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
\since 5.6
+ \obsolete
- \overload
-
- This convenience function creates a new action with an \a icon
- and some \a text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenu takes ownership of the returned QAction.
+ Use QWidget::addAction(icon, text, shortcut, functor) instead.
*/
-/*!\fn template<typename Functor> QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut)
+/*!
+ \fn template<typename Functor> QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut)
\since 5.6
+ \obsolete
- \overload
-
- This convenience function creates a new action with an \a icon
- and some \a text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The \a functor can be a pointer to a member function
- of the \a context object. The newly created action is added to the
- menu's list of actions and a pointer to it is returned.
-
- If \a context is destroyed, the functor will not be called.
-
- QMenu takes ownership of the returned QAction.
+ Use QWidget::addAction(icon, text, shortcut, context, functor) instead.
*/
/*!
- \overload
+ \fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
- This convenience function creates a new action with an \a icon and
- some \a text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a member slot of the \a receiver object. The function adds the
- newly created action to the menu's list of actions, and returns it.
+ \obsolete
- QMenu takes ownership of the returned QAction.
-
- \sa QWidget::addAction()
+ Use QWidget::addAction(icon, text, shortcut, receiver, member) instead.
*/
-QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,
- const char* member
#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut
-#endif
- )
+QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,
+ const char* member, const QKeySequence &shortcut)
{
QAction *action = new QAction(icon, text, this);
-#if QT_CONFIG(shortcut)
action->setShortcut(shortcut);
-#endif
QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
addAction(action);
return action;
}
+#endif
+#endif // QT_DEPRECATED_SINCE(6, 4)
/*!
This convenience function adds \a menu as a submenu to this menu.
@@ -2254,7 +2207,7 @@ QAction *QMenu::activeAction() const
bool QMenu::isEmpty() const
{
bool ret = true;
- for(int i = 0; ret && i < actions().count(); ++i) {
+ for(int i = 0; ret && i < actions().size(); ++i) {
const QAction *action = actions().at(i);
if (!action->isSeparator() && action->isVisible()) {
ret = false;
@@ -2319,7 +2272,7 @@ QSize QMenu::sizeHint() const
d->updateActionRects();
QSize s;
- for (int i = 0; i < d->actionRects.count(); ++i) {
+ for (int i = 0; i < d->actionRects.size(); ++i) {
const QRect &rect = d->actionRects.at(i);
if (rect.isNull())
continue;
@@ -2363,6 +2316,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction positionFunction)
{
Q_Q(QMenu);
+ popupScreen = QGuiApplication::screenAt(p);
+ QScopeGuard popupScreenGuard([this](){ popupScreen.clear(); });
+
if (scroll) { // reset scroll state from last popup
if (scroll->scrollOffset)
itemsDirty = 1; // sizeHint will be incorrect if there is previous scroll
@@ -2404,6 +2360,15 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
lastContextMenu = contextMenu;
}
+ // Until QWidget::metric accepts the screen set on a widget (without having a window handle)
+ // we need to make sure we get a window handle. This must be done near here because
+ // we want the screen to be correctly set and items to be marked dirty.
+ // (and screen set could 'fail' on oldscreen == newScreen if created before causing the
+ // itemsDirty not to be set though needed to get the correct size on first show).
+ if (!windowHandle()) {
+ createWinId();
+ }
+
#if QT_CONFIG(menubar)
// if this menu is part of a chain attached to a QMenuBar, set the
// _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
@@ -2429,6 +2394,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
else
pos = p;
+ popupScreen = QGuiApplication::screenAt(pos);
const QSize menuSizeHint(q->sizeHint());
QSize size = menuSizeHint;
@@ -2455,7 +2421,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
atAction = defaultAction;
// TODO: This works for first level menus, not yet sub menus
} else {
- for (QAction *action : qAsConst(actions))
+ for (QAction *action : std::as_const(actions))
if (action->isEnabled()) {
atAction = action;
break;
@@ -2467,7 +2433,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
if (ncols > 1) {
pos.setY(screen.top() + desktopFrame);
} else if (atAction) {
- for (int i = 0, above_height = 0; i < actions.count(); i++) {
+ for (int i = 0, above_height = 0; i < actions.size(); i++) {
QAction *action = actions.at(i);
if (action == atAction) {
int newY = pos.y() - above_height;
@@ -2482,7 +2448,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
if (scroll && scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone
&& !q->style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, nullptr, q)) {
int below_height = above_height + scroll->scrollOffset;
- for (int i2 = i; i2 < actionRects.count(); i2++)
+ for (int i2 = i; i2 < actionRects.size(); i2++)
below_height += actionRects.at(i2).height();
size.setHeight(below_height);
}
@@ -2567,6 +2533,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
}
}
}
+ popupScreen = QGuiApplication::screenAt(pos);
q->setGeometry(QRect(pos, size));
#if QT_CONFIG(effects)
int hGuess = q->isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
@@ -2620,7 +2587,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
q->show();
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleEvent event(q, QAccessible::PopupMenuStart);
QAccessible::updateAccessibility(&event);
#endif
@@ -2707,6 +2674,7 @@ QAction *QMenuPrivate::exec(const QPoint &p, QAction *action, PositionFunction p
action = syncAction;
syncAction = nullptr;
eventLoop = nullptr;
+ popupScreen.clear();
return action;
}
@@ -2749,7 +2717,7 @@ void QMenu::hideEvent(QHideEvent *)
if (d->eventLoop)
d->eventLoop->exit();
d->setCurrentAction(nullptr);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleEvent event(this, QAccessible::PopupMenuEnd);
QAccessible::updateAccessibility(&event);
#endif
@@ -2775,7 +2743,7 @@ void QMenu::paintEvent(QPaintEvent *e)
{
Q_D(QMenu);
d->updateActionRects();
- QPainter p(this);
+ QStylePainter p(this);
QRegion emptyArea = QRegion(rect());
QStyleOptionMenuItem menuOpt;
@@ -2784,7 +2752,7 @@ void QMenu::paintEvent(QPaintEvent *e)
menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
menuOpt.maxIconWidth = 0;
menuOpt.reservedShortcutWidth = 0;
- style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this);
+ p.drawPrimitive(QStyle::PE_PanelMenu, menuOpt);
//calculate the scroll up / down rect
const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, this);
@@ -2816,7 +2784,7 @@ void QMenu::paintEvent(QPaintEvent *e)
//draw the items that need updating..
QRect scrollUpTearOffRect = scrollUpRect.united(tearOffRect);
- for (int i = 0; i < d->actions.count(); ++i) {
+ for (int i = 0; i < d->actions.size(); ++i) {
QAction *action = d->actions.at(i);
QRect actionRect = d->actionRects.at(i);
if (!e->rect().intersects(actionRect)
@@ -2852,7 +2820,7 @@ void QMenu::paintEvent(QPaintEvent *e)
QStyleOptionMenuItem opt;
initStyleOption(&opt, action);
opt.rect = actionRect;
- style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
+ p.drawControl(QStyle::CE_MenuItem, opt);
}
emptyArea -= QRegion(scrollUpTearOffRect);
@@ -2884,9 +2852,9 @@ void QMenu::paintEvent(QPaintEvent *e)
frame.rect = rect();
frame.palette = palette();
frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &frame);
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &frame, this);
frame.midLineWidth = 0;
- style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
+ p.drawPrimitive(QStyle::PE_FrameMenu, frame);
}
//finally the rest of the spaces
@@ -2896,7 +2864,7 @@ void QMenu::paintEvent(QPaintEvent *e)
menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
menuOpt.rect = rect();
menuOpt.menuRect = rect();
- style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
+ p.drawControl(QStyle::CE_MenuEmptyArea, menuOpt);
}
#if QT_CONFIG(wheelevent)
@@ -3011,7 +2979,7 @@ bool QMenu::event(QEvent *e)
d->updateLayoutDirection();
break;
case QEvent::ShortcutOverride: {
- QKeyEvent *kev = static_cast<QKeyEvent*>(e);
+ QKeyEvent *kev = static_cast<QKeyEvent *>(e);
if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down
|| kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right
|| kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
@@ -3025,7 +2993,7 @@ bool QMenu::event(QEvent *e)
}
break;
case QEvent::KeyPress: {
- QKeyEvent *ke = (QKeyEvent*)e;
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
keyPressEvent(ke);
return true;
@@ -3058,6 +3026,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:
@@ -3158,7 +3128,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay;
if (!d->currentAction) {
if (key == Qt::Key_Down) {
- for(int i = 0; i < d->actions.count(); ++i) {
+ for(int i = 0; i < d->actions.size(); ++i) {
QAction *act = d->actions.at(i);
if (d->actionRects.at(i).isNull())
continue;
@@ -3170,7 +3140,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
}
} else {
- for(int i = d->actions.count()-1; i >= 0; --i) {
+ for(int i = d->actions.size()-1; i >= 0; --i) {
QAction *act = d->actions.at(i);
if (d->actionRects.at(i).isNull())
continue;
@@ -3183,7 +3153,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
}
} else {
- for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {
+ for(int i = 0, y = 0; !nextAction && i < d->actions.size(); i++) {
QAction *act = d->actions.at(i);
if (act == d->currentAction) {
if (key == Qt::Key_Up) {
@@ -3193,7 +3163,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
break;
if (d->scroll)
scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
- next_i = d->actionRects.count()-1;
+ next_i = d->actionRects.size()-1;
}
QAction *next = d->actions.at(next_i);
if (next == d->currentAction)
@@ -3219,7 +3189,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
} else {
y += d->actionRects.at(i).height();
for(int next_i = i+1; true; next_i++) {
- if (next_i == d->actionRects.count()) {
+ if (next_i == d->actionRects.size()) {
if (!style()->styleHint(QStyle::SH_Menu_SelectionWrap, nullptr, this))
break;
if (d->scroll)
@@ -3376,7 +3346,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
if (!key_consumed) { // send to menu bar
if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
- e->text().length()==1) {
+ e->text().size()==1) {
bool activateAction = false;
QAction *nextAction = nullptr;
if (style()->styleHint(QStyle::SH_Menu_KeyboardSearch, nullptr, this) && !e->modifiers()) {
@@ -3657,7 +3627,7 @@ void QMenu::internalDelayedPopup()
const QRect actionRect(d->actionRect(d->currentAction));
QPoint subMenuPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top())));
if (subMenuPos.x() > screen.right())
- subMenuPos.setX(QCursor::pos().x());
+ subMenuPos.setX(geometry().left());
const auto &subMenuActions = d->activeMenu->actions();
if (!subMenuActions.isEmpty()) {
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index f7348529e2..33ebd79d1f 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMENU_H
#define QMENU_H
@@ -46,7 +10,7 @@
#include <QtGui/qicon.h>
#include <QtGui/qaction.h>
-#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
+#if defined(Q_OS_MACOS) || defined(Q_QDOC)
Q_FORWARD_DECLARE_OBJC_CLASS(NSMenu);
#endif
@@ -76,96 +40,75 @@ public:
~QMenu();
using QWidget::addAction;
+#if QT_WIDGETS_REMOVED_SINCE(6, 3)
QAction *addAction(const QString &text);
QAction *addAction(const QIcon &icon, const QString &text);
-
- QAction *addAction(const QString &text, const QObject *receiver, const char* member
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
+#if !QT_CONFIG(shortcut)
+ QAction *addAction(const QString &text, const QObject *receiver, const char* member);
+ QAction *addAction(const QIcon &icon, const QString &text,
+ const QObject *receiver, const char* member);
#endif
- );
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
#endif
- );
-#ifdef Q_CLANG_QDOC
+#if QT_CONFIG(shortcut)
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(text, shortcut, receiver, member) instead.")
+ QAction *addAction(const QString &text, const QObject *receiver, const char* member,
+ const QKeySequence &shortcut);
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(icon, text, shortcut, receiver, member) instead.")
+ QAction *addAction(const QIcon &icon, const QString &text,
+ const QObject *receiver, const char* member,
+ const QKeySequence &shortcut);
+
+#ifdef Q_QDOC
template<typename Functor>
- QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0);
+ QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut);
template<typename Functor>
- QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0);
+ QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut);
template<typename Functor>
- QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0);
+ QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut);
template<typename Functor>
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0);
+ QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut);
#else
// addAction(QString): Connect to a QObject slot / functor or function pointer (with context)
template<class Obj, typename Func1>
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(text, shortcut, object, slot) instead.")
inline typename std::enable_if<!std::is_same<const char*, Func1>::value
&& QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type
- addAction(const QString &text, const Obj *object, Func1 slot
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
-#endif
- )
+ addAction(const QString &text, const Obj *object, Func1 slot,
+ const QKeySequence &shortcut)
{
- QAction *result = addAction(text);
-#if QT_CONFIG(shortcut)
- result->setShortcut(shortcut);
-#endif
- connect(result, &QAction::triggered, object, std::move(slot));
- return result;
+ return addAction(text, shortcut, object, slot);
}
// addAction(QString): Connect to a functor or function pointer (without context)
template <typename Func1>
- inline QAction *addAction(const QString &text, Func1 slot
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
-#endif
- )
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(text, shortcut, slot) instead.")
+ inline QAction *addAction(const QString &text, Func1 slot, const QKeySequence &shortcut)
{
- QAction *result = addAction(text);
-#if QT_CONFIG(shortcut)
- result->setShortcut(shortcut);
-#endif
- connect(result, &QAction::triggered, std::move(slot));
- return result;
+ return addAction(text, shortcut, slot);
}
// addAction(QIcon, QString): Connect to a QObject slot / functor or function pointer (with context)
template<class Obj, typename Func1>
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(icon, text, shortcut, object, slot) instead.")
inline typename std::enable_if<!std::is_same<const char*, Func1>::value
&& QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type
- addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
-#endif
- )
+ addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot,
+ const QKeySequence &shortcut)
{
- QAction *result = addAction(actionIcon, text);
-#if QT_CONFIG(shortcut)
- result->setShortcut(shortcut);
-#endif
- connect(result, &QAction::triggered, object, std::move(slot));
- return result;
+ return addAction(actionIcon, text, shortcut, object, slot);
}
// addAction(QIcon, QString): Connect to a functor or function pointer (without context)
template <typename Func1>
- inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot
-#if QT_CONFIG(shortcut)
- , const QKeySequence &shortcut = {}
-#endif
- )
+ QT_DEPRECATED_VERSION_X_6_4("Use addAction(icon, text, shortcut, slot) instead.")
+ inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot,
+ const QKeySequence &shortcut)
{
- QAction *result = addAction(actionIcon, text);
-#if QT_CONFIG(shortcut)
- result->setShortcut(shortcut);
-#endif
- connect(result, &QAction::triggered, std::move(slot));
- return result;
+ return addAction(actionIcon, text, shortcut, slot);
}
-#endif // !Q_CLANG_QDOC
+#endif // !Q_QDOC
+#endif // QT_DEPRECATED_SINCE(6, 4)
+#endif // QT_CONFIG(shortcut)
QAction *addMenu(QMenu *menu);
QMenu *addMenu(const QString &title);
@@ -210,6 +153,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);
@@ -221,7 +166,7 @@ public:
QPlatformMenu *platformMenu();
void setPlatformMenu(QPlatformMenu *platformMenu);
-#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
+#if defined(Q_OS_MACOS) || defined(Q_QDOC)
NSMenu* toNSMenu();
void setAsDockMenu();
#endif
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index e10c75cc58..184386a731 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index ffe956d007..1e32fbcdfa 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMENU_P_H
#define QMENU_P_H
@@ -65,6 +29,8 @@
#include <qpa/qplatformmenu.h>
+#include <QtCore/qpointer.h>
+
#include <functional>
QT_REQUIRE_CONFIG(menu);
@@ -440,6 +406,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); }
@@ -506,6 +473,11 @@ public:
mutable quint8 ncols = 0; // "255cols ought to be enough for anybody."
+ // Contains the screen of the popup point during popup(QPoint).
+ // This is to make sure the screen is remembered,
+ // when the menu contains many items on multiple screens
+ QPointer<QScreen> popupScreen;
+
mutable bool itemsDirty : 1;
mutable bool hasCheckableItems : 1;
bool lastContextMenu : 1;
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index f92a975455..c9c9191c17 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qmenubar.h>
#include <qstyle.h>
#include <qlayout.h>
#include <qapplication.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
# include <qaccessible.h>
#endif
#include <qpainter.h>
@@ -71,6 +35,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QMenuBarExtension : public QToolButton
{
public:
@@ -83,7 +49,7 @@ public:
QMenuBarExtension::QMenuBarExtension(QWidget *parent)
: QToolButton(parent)
{
- setObjectName(QLatin1String("qt_menubar_ext_button"));
+ setObjectName("qt_menubar_ext_button"_L1);
setAutoRaise(true);
#if QT_CONFIG(menu)
setPopupMode(QToolButton::InstantPopup);
@@ -202,7 +168,7 @@ void QMenuBarPrivate::updateGeometries()
for(int j = 0; j < shortcutIndexMap.size(); ++j)
q->releaseShortcut(shortcutIndexMap.value(j));
shortcutIndexMap.clear();
- const int actionsCount = actions.count();
+ const int actionsCount = actions.size();
shortcutIndexMap.reserve(actionsCount);
for (int i = 0; i < actionsCount; i++)
shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
@@ -216,7 +182,7 @@ void QMenuBarPrivate::updateGeometries()
//we try to see if the actions will fit there
bool hasHiddenActions = false;
- for (int i = 0; i < actions.count(); ++i) {
+ for (int i = 0; i < actions.size(); ++i) {
const QRect &rect = actionRects.at(i);
if (rect.isValid() && !menuRect.contains(rect)) {
hasHiddenActions = true;
@@ -227,7 +193,7 @@ void QMenuBarPrivate::updateGeometries()
//...and if not, determine the ones that fit on the menu with the extension visible
if (hasHiddenActions) {
menuRect = this->menuRect(true);
- for (int i = 0; i < actions.count(); ++i) {
+ for (int i = 0; i < actions.size(); ++i) {
const QRect &rect = actionRects.at(i);
if (rect.isValid() && !menuRect.contains(rect)) {
hiddenActions.append(actions.at(i));
@@ -235,7 +201,7 @@ void QMenuBarPrivate::updateGeometries()
}
}
- if (hiddenActions.count() > 0) {
+ if (hiddenActions.size() > 0) {
QMenu *pop = extension->menu();
if (!pop) {
pop = new QMenu(q);
@@ -263,7 +229,7 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const
//makes sure the geometries are up-to-date
const_cast<QMenuBarPrivate*>(this)->updateGeometries();
- if (index < 0 || index >= actionRects.count())
+ if (index < 0 || index >= actionRects.size())
return QRect(); // that can happen in case of native menubar
return actionRects.at(index);
@@ -274,8 +240,8 @@ void QMenuBarPrivate::focusFirstAction()
if (!currentAction) {
updateGeometries();
int index = 0;
- while (index < actions.count() && actionRects.at(index).isNull()) ++index;
- if (index < actions.count())
+ while (index < actions.size() && actionRects.at(index).isNull()) ++index;
+ if (index < actions.size())
setCurrentAction(actions.at(index));
}
}
@@ -315,17 +281,28 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
if (action->isEnabled() && action->menu()->isEnabled()) {
closePopupMode = 0;
activeMenu = action->menu();
- activeMenu->d_func()->causedPopup.widget = q;
- activeMenu->d_func()->causedPopup.action = action;
+ auto *activeMenuPriv = activeMenu->d_func();
+ activeMenuPriv->causedPopup.widget = q;
+ activeMenuPriv->causedPopup.action = action;
QRect adjustedActionRect = actionRect(action);
- QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
- QSize popup_size = activeMenu->sizeHint();
+ QPoint popupPos = adjustedActionRect.bottomLeft() + QPoint(0, 1);
+
//we put the popup menu on the screen containing the bottom-center of the action rect
QScreen *menubarScreen = q->window()->windowHandle()->screen();
- QScreen *popupScreen = menubarScreen->virtualSiblingAt(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ QPoint screenTestPos = q->mapToGlobal(popupPos + QPoint(adjustedActionRect.width() / 2, 0));
+ QPointer<QScreen> popupScreen = menubarScreen->virtualSiblingAt(screenTestPos);
if (!popupScreen)
popupScreen = menubarScreen;
+ std::swap(popupScreen, activeMenuPriv->popupScreen);
+ const QSize popup_size = activeMenu->sizeHint();
+ std::swap(popupScreen, activeMenuPriv->popupScreen);
+
+ // Use screenTestPos.y() for the popup y position. This is the correct global y
+ // consistent with the selected screen in cases where the action rect spans
+ // multiple screens with different scale factors.
+ QPoint pos(q->mapToGlobal(popupPos).x(), screenTestPos.y());
+
QRect screenRect = popupScreen->geometry();
pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
@@ -412,7 +389,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const
return;
//let's reinitialize the buffer
- actionRects.resize(actions.count());
+ actionRects.resize(actions.size());
actionRects.fill(QRect());
const QStyle *style = q->style();
@@ -425,7 +402,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const
const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, nullptr, q),
vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, nullptr, q),
icone = style->pixelMetric(QStyle::PM_SmallIconSize, nullptr, q);
- for(int i = 0; i < actions.count(); i++) {
+ for(int i = 0; i < actions.size(); i++) {
QAction *action = actions.at(i);
if (!action->isVisible())
continue;
@@ -471,7 +448,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const
const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, nullptr, q);
int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
int y = fw + vmargin;
- for(int i = 0; i < actions.count(); i++) {
+ for(int i = 0; i < actions.size(); i++) {
QRect &rect = actionRects[i];
if (rect.isNull())
continue;
@@ -529,14 +506,14 @@ void QMenuBarPrivate::_q_actionHovered()
Q_Q(QMenuBar);
if (QAction *action = qobject_cast<QAction *>(q->sender())) {
emit q->hovered(action);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
int actionIndex = actions.indexOf(action);
QAccessibleEvent focusEvent(q, QAccessible::Focus);
focusEvent.setChild(actionIndex);
QAccessible::updateAccessibility(&focusEvent);
}
-#endif //QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
}
}
@@ -581,7 +558,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
\inmodule QtWidgets
A menu bar consists of a list of pull-down menu items. You add
- menu items with addMenu(). For example, asuming that \c menubar
+ menu items with addMenu(). For example, assuming that \c menubar
is a pointer to a QMenuBar and \c fileMenu is a pointer to a
QMenu, the following statement inserts the menu into the menu bar:
\snippet code/src_gui_widgets_qmenubar.cpp 0
@@ -630,11 +607,13 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
Qt for \macos also provides a menu bar merging feature to make
QMenuBar conform more closely to accepted \macos menu bar layout.
- The merging functionality is based on string matching the title of
- a QMenu entry. These strings are translated (using QObject::tr())
- in the "QMenuBar" context. If an entry is moved its slots will still
- fire as if it was in the original place. The table below outlines
- the strings looked for and where the entry is placed if matched:
+ If an entry is moved its slots will still fire as if it was in the
+ original place.
+
+ The merging functionality is based on the QAction::menuRole() of
+ the menu entries. If an item has QAction::TextHeuristicRole,
+ the role is determined by string matching the title using the
+ following heuristics:
\table
\header \li String matches \li Placement \li Notes
@@ -652,8 +631,8 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
created to call QCoreApplication::quit()
\endtable
- You can override this behavior by using the QAction::menuRole()
- property.
+ You can override this behavior by setting the QAction::menuRole()
+ property to QAction::NoRole.
If you want all windows in a Mac application to share one menu
bar, you must create a menu bar that does not have a parent.
@@ -684,7 +663,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}
*/
@@ -714,8 +693,8 @@ QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) c
Q_Q(const QMenuBar);
const_cast<QMenuBarPrivate*>(this)->updateGeometries();
bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, nullptr, q);
- const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
- const int end = increment == -1 ? 0 : actions.count() - 1;
+ const int start = (_start == -1 && increment == -1) ? actions.size() : _start;
+ const int end = increment == -1 ? 0 : actions.size() - 1;
for (int i = start; i != end;) {
i += increment;
@@ -751,72 +730,6 @@ QMenuBar::~QMenuBar()
}
/*!
- This convenience function creates a new action with \a text.
- The function adds the newly created action to the menu's
- list of actions, and returns it.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-QAction *QMenuBar::addAction(const QString &text)
-{
- QAction *ret = new QAction(text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with the given \a
- text. The action's triggered() signal is connected to the \a
- receiver's \a member slot. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const char* member)
-{
- QAction *ret = new QAction(text, this);
- QObject::connect(ret, SIGNAL(triggered(bool)), receiver, member);
- addAction(ret);
- return ret;
-}
-
-/*!
- \fn template<typename Obj, typename PointerToMemberFunctionOrFunctor> QAction *QMenuBar::addAction(const QString &text, const Obj *receiver, PointerToMemberFunctionOrFunctor method)
-
- \since 5.11
-
- \overload
-
- This convenience function creates a new action with the given \a
- text. The action's triggered() signal is connected to the
- \a method of the \a receiver. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenuBar takes ownership of the returned QAction.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-
-/*!
- \fn template<typename Functor> QAction *QMenuBar::addAction(const QString &text, Functor functor)
-
- \since 5.11
-
- \overload
-
- This convenience function creates a new action with the given \a
- text. The action's triggered() signal is connected to the
- \a functor. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenuBar takes ownership of the returned QAction.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-
-/*!
Appends a new QMenu with \a title to the menu bar. The menu bar
takes ownership of the menu. Returns the new menu.
@@ -984,7 +897,7 @@ void QMenuBar::paintEvent(QPaintEvent *e)
QRegion emptyArea(rect());
//draw the items
- for (int i = 0; i < d->actions.count(); ++i) {
+ for (int i = 0; i < d->actions.size(); ++i) {
QAction *action = d->actions.at(i);
QRect adjustedActionRect = d->actionRect(action);
if (adjustedActionRect.isEmpty() || !d->isVisible(action))
@@ -1012,7 +925,7 @@ void QMenuBar::paintEvent(QPaintEvent *e)
frame.rect = rect();
frame.palette = palette();
frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame);
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame, this);
frame.midLineWidth = 0;
style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this);
}
@@ -1160,7 +1073,7 @@ void QMenuBar::keyPressEvent(QKeyEvent *e)
if (!key_consumed &&
(!e->modifiers() ||
- (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().length()==1 && !d->popupState) {
+ (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().size()==1 && !d->popupState) {
int clashCount = 0;
QAction *first = nullptr, *currentSelected = nullptr, *firstAfterCurrent = nullptr;
{
@@ -1171,7 +1084,7 @@ void QMenuBar::keyPressEvent(QKeyEvent *e)
QAction *act = d->actions.at(i);
QString s = act->text();
if (!s.isEmpty()) {
- int ampersand = s.indexOf(QLatin1Char('&'));
+ qsizetype ampersand = s.indexOf(u'&');
if (ampersand >= 0) {
if (s[ampersand+1].toUpper() == c) {
clashCount++;
@@ -1385,7 +1298,12 @@ void QMenuBarPrivate::handleReparent()
QList<QPointer<QWidget>> newParents;
// Remove event filters on ex-parents, keep them on still-parents
// The parents are always ordered in the vector
- foreach (const QPointer<QWidget> &w, oldParents) {
+ //
+ // Take a copy because this method is called from changeEvent() and eventFilter(),
+ // which might cause recursion into the class due to event processing, which might
+ // modify oldParents.
+ const auto copy = oldParents;
+ for (const QPointer<QWidget> &w : copy) {
if (w) {
if (newParent == w) {
newParents.append(w);
@@ -1456,7 +1374,7 @@ bool QMenuBar::event(QEvent *e)
Q_D(QMenuBar);
switch (e->type()) {
case QEvent::KeyPress: {
- QKeyEvent *ke = (QKeyEvent*)e;
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
#if 0
if (!d->keyboardState) { //all keypresses..
d->setCurrentAction(0);
@@ -1484,7 +1402,7 @@ bool QMenuBar::event(QEvent *e)
break;
#ifndef QT_NO_SHORTCUT
case QEvent::ShortcutOverride: {
- QKeyEvent *kev = static_cast<QKeyEvent*>(e);
+ QKeyEvent *kev = static_cast<QKeyEvent *>(e);
//we only filter out escape if there is a current action
if (kev->matches(QKeySequence::Cancel) && d->currentAction) {
e->accept();
@@ -1588,7 +1506,7 @@ bool QMenuBar::eventFilter(QObject *object, QEvent *event)
Returns the QAction at \a pt. Returns \nullptr if there is no action at \a pt or if
the location has a separator.
- \sa addAction(), addSeparator()
+ \sa QWidget::addAction(), addSeparator()
*/
QAction *QMenuBar::actionAt(const QPoint &pt) const
{
@@ -1625,7 +1543,7 @@ QSize QMenuBar::minimumSizeHint() const
if (as_gui_menubar) {
int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
d->calcActionRects(w - (2 * fw), 0);
- for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
+ for (int i = 0; ret.isNull() && i < d->actions.size(); ++i)
ret = d->actionRects.at(i).size();
if (!d->extension->isHidden())
ret += QSize(d->extension->sizeHint().width(), 0);
@@ -1675,7 +1593,7 @@ QSize QMenuBar::sizeHint() const
if (as_gui_menubar) {
const int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
d->calcActionRects(w - (2 * fw), 0);
- for (int i = 0; i < d->actionRects.count(); ++i) {
+ for (int i = 0; i < d->actionRects.size(); ++i) {
const QRect &actionRect = d->actionRects.at(i);
ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
}
@@ -1722,7 +1640,7 @@ int QMenuBar::heightForWidth(int) const
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, nullptr, this);
int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, nullptr, this);
if (as_gui_menubar) {
- for (int i = 0; i < d->actionRects.count(); ++i)
+ for (int i = 0; i < d->actionRects.size(); ++i)
height = qMax(height, d->actionRects.at(i).height());
if (height) //there is at least one non-null item
height += spaceBelowMenuBar;
@@ -1872,6 +1790,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
if (!nativeMenuBar) {
delete d->platformMenuBar;
d->platformMenuBar = nullptr;
+ d->itemsDirty = true;
} else {
if (!d->platformMenuBar)
d->platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h
index f2170ebf5a..dc0d1559bf 100644
--- a/src/widgets/widgets/qmenubar.h
+++ b/src/widgets/widgets/qmenubar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMENUBAR_H
#define QMENUBAR_H
@@ -64,34 +28,10 @@ public:
~QMenuBar();
using QWidget::addAction;
+#if QT_WIDGETS_REMOVED_SINCE(6, 3)
QAction *addAction(const QString &text);
QAction *addAction(const QString &text, const QObject *receiver, const char* member);
-
-#ifdef Q_CLANG_QDOC
- template<typename Obj, typename PointerToMemberFunctionOrFunctor>
- QAction *addAction(const QString &text, const Obj *receiver, PointerToMemberFunctionOrFunctor method);
- template<typename Functor>
- QAction *addAction(const QString &text, Functor functor);
-#else
- // addAction(QString): Connect to a QObject slot / functor or function pointer (with context)
- template<typename Obj, typename Func1>
- inline typename std::enable_if<!std::is_same<const char*, Func1>::value
- && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type
- addAction(const QString &text, const Obj *object, Func1 slot)
- {
- QAction *result = addAction(text);
- connect(result, &QAction::triggered, object, std::move(slot));
- return result;
- }
- // addAction(QString): Connect to a functor or function pointer (without context)
- template <typename Func1>
- inline QAction *addAction(const QString &text, Func1 slot)
- {
- QAction *result = addAction(text);
- connect(result, &QAction::triggered, std::move(slot));
- return result;
- }
-#endif // !Q_CLANG_QDOC
+#endif
QAction *addMenu(QMenu *menu);
QMenu *addMenu(const QString &title);
@@ -121,7 +61,7 @@ public:
void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner);
QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
-#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
+#if defined(Q_OS_MACOS) || defined(Q_QDOC)
NSMenu* toNSMenu();
#endif
diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h
index 20a69e0818..549a4c7a1f 100644
--- a/src/widgets/widgets/qmenubar_p.h
+++ b/src/widgets/widgets/qmenubar_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QMENUBAR_P_H
#define QMENUBAR_P_H
@@ -56,6 +20,8 @@
#include <private/qmenu_p.h> // Mac needs what in this file!
#include <qpa/qplatformmenu.h>
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(menubar);
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 20fdbcd6a8..8362c6c629 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplaintextedit_p.h"
@@ -454,22 +418,29 @@ QPlainTextEditControl::QPlainTextEditControl(QPlainTextEdit *parent)
setAcceptRichText(false);
}
-void QPlainTextEditPrivate::_q_cursorPositionChanged()
+void QPlainTextEditPrivate::cursorPositionChanged()
{
pageUpDownLastCursorYIsValid = false;
Q_Q(QPlainTextEdit);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextCursorEvent ev(q, q->textCursor().position());
QAccessible::updateAccessibility(&ev);
#endif
emit q->cursorPositionChanged();
}
-void QPlainTextEditPrivate::_q_verticalScrollbarActionTriggered(int action) {
- if (action == QAbstractSlider::SliderPageStepAdd) {
+void QPlainTextEditPrivate::verticalScrollbarActionTriggered(int action) {
+
+ const auto a = static_cast<QAbstractSlider::SliderAction>(action);
+ switch (a) {
+ case QAbstractSlider::SliderPageStepAdd:
pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor, false);
- } else if (action == QAbstractSlider::SliderPageStepSub) {
+ break;
+ case QAbstractSlider::SliderPageStepSub:
pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor, false);
+ break;
+ default:
+ break;
}
}
@@ -658,10 +629,7 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
lineNumber = maxTopLine - block.firstLineNumber();
}
- {
- const QSignalBlocker blocker(vbar);
- vbar->setValue(newTopLine);
- }
+ vbar->setValue(newTopLine);
if (!dx && blockNumber == control->topBlock && lineNumber == topLine)
return;
@@ -677,10 +645,7 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
control->topBlock = blockNumber;
topLine = lineNumber;
- {
- const QSignalBlocker blocker(vbar);
- vbar->setValue(block.firstLineNumber() + lineNumber);
- }
+ vbar->setValue(block.firstLineNumber() + lineNumber);
if (dx || dy) {
viewport->scroll(q->isRightToLeft() ? -dx : dx, dy);
@@ -760,9 +725,14 @@ void QPlainTextEditPrivate::updateViewport()
}
QPlainTextEditPrivate::QPlainTextEditPrivate()
- : tabChangesFocus(false), showCursorOnInitialShow(false), backgroundVisible(false),
- centerOnScroll(false), inDrag(false), clickCausedFocus(false), placeholderVisible(true),
- pageUpDownLastCursorYIsValid(false)
+ : tabChangesFocus(false)
+ , showCursorOnInitialShow(false)
+ , backgroundVisible(false)
+ , centerOnScroll(false)
+ , inDrag(false)
+ , clickCausedFocus(false)
+ , pageUpDownLastCursorYIsValid(false)
+ , placeholderTextShown(false)
{
}
@@ -778,23 +748,28 @@ void QPlainTextEditPrivate::init(const QString &txt)
control->setPalette(q->palette());
- QObject::connect(vbar, SIGNAL(actionTriggered(int)), q, SLOT(_q_verticalScrollbarActionTriggered(int)));
-
- QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
- QObject::connect(control, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int)));
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
- QObject::connect(control, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool)));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
- QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(_q_textChanged()));
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+ QObjectPrivate::connect(vbar, &QAbstractSlider::actionTriggered,
+ this, &QPlainTextEditPrivate::verticalScrollbarActionTriggered);
+ QObject::connect(control, &QWidgetTextControl::microFocusChanged, q,
+ [q](){q->updateMicroFocus(); });
+ QObjectPrivate::connect(control, &QWidgetTextControl::documentSizeChanged,
+ this, &QPlainTextEditPrivate::adjustScrollbars);
+ QObject::connect(control, &QWidgetTextControl::blockCountChanged,
+ q, &QPlainTextEdit::blockCountChanged);
+ QObjectPrivate::connect(control, &QWidgetTextControl::updateRequest,
+ this, &QPlainTextEditPrivate::repaintContents);
+ QObject::connect(control, &QWidgetTextControl::modificationChanged,
+ q, &QPlainTextEdit::modificationChanged);
+ QObject::connect(control, &QWidgetTextControl::textChanged, q, &QPlainTextEdit::textChanged);
+ QObject::connect(control, &QWidgetTextControl::undoAvailable, q, &QPlainTextEdit::undoAvailable);
+ QObject::connect(control, &QWidgetTextControl::redoAvailable, q, &QPlainTextEdit::redoAvailable);
+ QObject::connect(control, &QWidgetTextControl::copyAvailable, q, &QPlainTextEdit::copyAvailable);
+ QObject::connect(control, &QWidgetTextControl::selectionChanged, q, &QPlainTextEdit::selectionChanged);
+ QObjectPrivate::connect(control, &QWidgetTextControl::cursorPositionChanged,
+ this, &QPlainTextEditPrivate::cursorPositionChanged);
+ QObjectPrivate::connect(control, &QWidgetTextControl::textChanged,
+ this, &QPlainTextEditPrivate::updatePlaceholderVisibility);
+ QObject::connect(control, &QWidgetTextControl::textChanged, q, [q](){q->updateMicroFocus(); });
// set a null page size initially to avoid any relayouting until the textedit
// is shown. relayoutDocument() will take care of setting the page size to the
@@ -822,26 +797,19 @@ void QPlainTextEditPrivate::init(const QString &txt)
#endif
}
-void QPlainTextEditPrivate::_q_textChanged()
+void QPlainTextEditPrivate::updatePlaceholderVisibility()
{
- Q_Q(QPlainTextEdit);
-
// We normally only repaint the part of view that contains text in the
- // document that has changed (in _q_repaintContents). But the placeholder
+ // document that has changed (in repaintContents). But the placeholder
// text is not a part of the document, but is drawn on separately. So whenever
// we either show or hide the placeholder text, we issue a full update.
- bool placeholderCurrentyVisible = placeholderVisible;
-
- placeholderVisible = !placeholderText.isEmpty()
- && q->document()->isEmpty()
- && (!q->firstVisibleBlock().isValid() ||
- q->firstVisibleBlock().layout()->preeditAreaText().isEmpty());
-
- if (placeholderCurrentyVisible != placeholderVisible)
+ if (placeholderTextShown != placeHolderTextToBeShown()) {
viewport->update();
+ placeholderTextShown = placeHolderTextToBeShown();
+ }
}
-void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
+void QPlainTextEditPrivate::repaintContents(const QRectF &contentsRect)
{
Q_Q(QPlainTextEdit);
if (!contentsRect.isValid()) {
@@ -974,7 +942,7 @@ void QPlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCurso
#if QT_CONFIG(scrollbar)
-void QPlainTextEditPrivate::_q_adjustScrollbars()
+void QPlainTextEditPrivate::adjustScrollbars()
{
Q_Q(QPlainTextEdit);
QTextDocument *doc = control->document();
@@ -1028,8 +996,6 @@ void QPlainTextEditPrivate::_q_adjustScrollbars()
vSliderLength = lineSpacing != 0 ? viewport->height() / lineSpacing : 0;
}
-
-
QSizeF documentSize = documentLayout->documentSize();
vbar->setRange(0, qMax(0, vmax));
vbar->setPageStep(vSliderLength);
@@ -1038,10 +1004,7 @@ void QPlainTextEditPrivate::_q_adjustScrollbars()
if (firstVisibleBlock.isValid())
visualTopLine = firstVisibleBlock.firstLineNumber() + topLine;
- {
- const QSignalBlocker blocker(vbar);
- vbar->setValue(visualTopLine);
- }
+ vbar->setValue(visualTopLine);
hbar->setRange(0, (int)documentSize.width() - viewport->width());
hbar->setPageStep(viewport->width());
@@ -1221,10 +1184,8 @@ void QPlainTextEditPrivate::ensureViewportLayouted()
editor with line wrap enabled in real time. It also makes for a
fast log viewer (see setMaximumBlockCount()).
-
- \sa QTextDocument, QTextCursor, {Qt Widgets - Application Example},
- {Code Editor Example}, {Syntax Highlighter Example},
- {Rich Text Processing}
+ \sa QTextDocument, QTextCursor
+ {Syntax Highlighter Example}, {Rich Text Processing}
*/
@@ -1336,7 +1297,7 @@ void QPlainTextEdit::setDocument(QTextDocument *document)
d->documentLayoutPtr = documentLayout;
d->updateDefaultTextOption();
d->relayoutDocument();
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
/*!
@@ -1368,8 +1329,7 @@ void QPlainTextEdit::setPlaceholderText(const QString &placeholderText)
Q_D(QPlainTextEdit);
if (d->placeholderText != placeholderText) {
d->placeholderText = placeholderText;
- if (d->control->document()->isEmpty())
- d->viewport->update();
+ d->updatePlaceholderVisibility();
}
}
@@ -1549,53 +1509,61 @@ bool QPlainTextEdit::event(QEvent *e)
{
Q_D(QPlainTextEdit);
+ switch (e->type()) {
#ifndef QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ContextMenu
- && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
- ensureCursorVisible();
- const QPoint cursorPos = cursorRect().center();
- QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
- ce.setAccepted(e->isAccepted());
- const bool result = QAbstractScrollArea::event(&ce);
- e->setAccepted(ce.isAccepted());
- return result;
- }
+ case QEvent::ContextMenu:
+ if (static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
+ ensureCursorVisible();
+ const QPoint cursorPos = cursorRect().center();
+ QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
+ ce.setAccepted(e->isAccepted());
+ const bool result = QAbstractScrollArea::event(&ce);
+ e->setAccepted(ce.isAccepted());
+ return result;
+ }
+ break;
#endif // QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ShortcutOverride
- || e->type() == QEvent::ToolTip) {
+ case QEvent::ShortcutOverride:
+ case QEvent::ToolTip:
d->sendControlEvent(e);
- }
+ break;
#ifdef QT_KEYPAD_NAVIGATION
- else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
+ case QEvent::EnterEditFocus:
+ case QEvent::LeaveEditFocus:
if (QApplicationPrivate::keypadNavigationEnabled())
d->sendControlEvent(e);
- }
+ break;
#endif
#ifndef QT_NO_GESTURES
- else if (e->type() == QEvent::Gesture) {
- QGestureEvent *ge = static_cast<QGestureEvent *>(e);
- QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
- if (g) {
+ case QEvent::Gesture:
+ if (auto *g = static_cast<QGestureEvent *>(e)->gesture(Qt::PanGesture)) {
+ QPanGesture *panGesture = static_cast<QPanGesture *>(g);
QScrollBar *hBar = horizontalScrollBar();
QScrollBar *vBar = verticalScrollBar();
- if (g->state() == Qt::GestureStarted)
+ if (panGesture->state() == Qt::GestureStarted)
d->originalOffsetY = vBar->value();
- QPointF offset = g->offset();
+ QPointF offset = panGesture->offset();
if (!offset.isNull()) {
if (QGuiApplication::isRightToLeft())
offset.rx() *= -1;
// QPlainTextEdit scrolls by lines only in vertical direction
QFontMetrics fm(document()->defaultFont());
int lineHeight = fm.height();
- int newX = hBar->value() - g->delta().x();
+ int newX = hBar->value() - panGesture->delta().x();
int newY = d->originalOffsetY - offset.y()/lineHeight;
hBar->setValue(newX);
vBar->setValue(newY);
}
}
return true;
- }
#endif // QT_NO_GESTURES
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ d->control->setPalette(palette());
+ break;
+ default:
+ break;
+ }
return QAbstractScrollArea::event(e);
}
@@ -1616,7 +1584,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 +1649,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()) {
@@ -1830,10 +1797,10 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QPlainTextEdit);
- d->keyboardModifiers = e->modifiers();
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel();
#ifdef QT_KEYPAD_NAVIGATION
- Q_D(QPlainTextEdit);
if (QApplicationPrivate::keypadNavigationEnabled()) {
if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
&& d->deleteAllTimer.isActive()) {
@@ -1879,7 +1846,7 @@ void QPlainTextEdit::resizeEvent(QResizeEvent *e)
Q_D(QPlainTextEdit);
if (e->oldSize().width() != e->size().width())
d->relayoutDocument();
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
void QPlainTextEditPrivate::relayoutDocument()
@@ -1941,11 +1908,11 @@ 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);
- if (d->placeholderVisible) {
+ if (d->placeHolderTextToBeShown()) {
const QColor col = d->control->palette().placeholderText().color();
painter.setPen(col);
painter.setClipRect(e->rect());
@@ -2216,6 +2183,10 @@ void QPlainTextEdit::inputMethodEvent(QInputMethodEvent *e)
}
#endif
d->sendControlEvent(e);
+ const bool emptyEvent = e->preeditString().isEmpty() && e->commitString().isEmpty()
+ && e->attributes().isEmpty();
+ if (emptyEvent)
+ return;
ensureCursorVisible();
}
@@ -2240,8 +2211,10 @@ QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant a
{
Q_D(const QPlainTextEdit);
switch (query) {
- case Qt::ImHints:
- case Qt::ImInputItemClipRectangle:
+ case Qt::ImEnabled:
+ return isEnabled() && !isReadOnly();
+ case Qt::ImHints:
+ case Qt::ImInputItemClipRectangle:
return QWidget::inputMethodQuery(query);
case Qt::ImReadOnly:
return isReadOnly();
@@ -2313,7 +2286,7 @@ void QPlainTextEdit::showEvent(QShowEvent *)
d->showCursorOnInitialShow = false;
ensureCursorVisible();
}
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
/*! \reimp
@@ -2322,20 +2295,29 @@ void QPlainTextEdit::changeEvent(QEvent *e)
{
Q_D(QPlainTextEdit);
QAbstractScrollArea::changeEvent(e);
- if (e->type() == QEvent::ApplicationFontChange
- || e->type() == QEvent::FontChange) {
+
+ switch (e->type()) {
+ case QEvent::ApplicationFontChange:
+ case QEvent::FontChange:
d->control->document()->setDefaultFont(font());
- } else if (e->type() == QEvent::ActivationChange) {
+ break;
+ case QEvent::ActivationChange:
if (!isActiveWindow())
d->autoScrollTimer.stop();
- } else if (e->type() == QEvent::EnabledChange) {
+ break;
+ case QEvent::EnabledChange:
e->setAccepted(isEnabled());
d->control->setPalette(palette());
d->sendControlEvent(e);
- } else if (e->type() == QEvent::PaletteChange) {
+ break;
+ case QEvent::PaletteChange:
d->control->setPalette(palette());
- } else if (e->type() == QEvent::LayoutDirectionChange) {
+ break;
+ case QEvent::LayoutDirectionChange:
d->sendControlEvent(e);
+ break;
+ default:
+ break;
}
}
@@ -2497,7 +2479,13 @@ void QPlainTextEdit::setOverwriteMode(bool overwrite)
\brief the tab stop distance in pixels
\since 5.10
- By default, this property contains a value of 80.
+ By default, this property contains a value of 80 pixels.
+
+ Do not set a value less than the \l {QFontMetrics::}{horizontalAdvance()}
+ of the QChar::VisualTabCharacter character, otherwise the tab-character
+ will be drawn incompletely.
+
+ \sa QTextOption::ShowTabsAndSpaces, QTextDocument::defaultTextOption
*/
qreal QPlainTextEdit::tabStopDistance() const
@@ -2615,7 +2603,7 @@ void QPlainTextEdit::insertFromMimeData(const QMimeData *source)
bool QPlainTextEdit::isReadOnly() const
{
Q_D(const QPlainTextEdit);
- return !(d->control->textInteractionFlags() & Qt::TextEditable);
+ return !d->control || !(d->control->textInteractionFlags() & Qt::TextEditable);
}
void QPlainTextEdit::setReadOnly(bool ro)
@@ -2800,7 +2788,7 @@ void QPlainTextEdit::setLineWrapMode(LineWrapMode wrap)
d->lineWrap = wrap;
d->updateDefaultTextOption();
d->relayoutDocument();
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
ensureCursorVisible();
}
@@ -2886,7 +2874,7 @@ void QPlainTextEdit::setCenterOnScroll(bool enabled)
if (enabled == d->centerOnScroll)
return;
d->centerOnScroll = enabled;
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
@@ -2909,11 +2897,14 @@ bool QPlainTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
\overload
Finds the next occurrence, matching the regular expression, \a exp, using the given
- \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
- use QRegularExpression::CaseInsensitiveOption instead.
+ \a options.
Returns \c true if a match was found and changes the cursor to select the match;
otherwise returns \c false.
+
+ \warning For historical reasons, the case sensitivity option set on
+ \a exp is ignored. Instead, the \a options are used to determine
+ if the search is case sensitive or not.
*/
#if QT_CONFIG(regularexpression)
bool QPlainTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
@@ -3014,12 +3005,17 @@ void QPlainTextEditPrivate::append(const QString &text, Qt::TextFormat format)
bool documentSizeChangedBlocked = documentLayout->priv()->blockDocumentSizeChanged;
documentLayout->priv()->blockDocumentSizeChanged = true;
- if (format == Qt::RichText)
+ switch (format) {
+ case Qt::RichText:
control->appendHtml(text);
- else if (format == Qt::PlainText)
+ break;
+ case Qt::PlainText:
control->appendPlainText(text);
- else
+ break;
+ default:
control->append(text);
+ break;
+ }
if (maximumBlockCount > 0) {
if (document->blockCount() > maximumBlockCount) {
@@ -3041,7 +3037,7 @@ void QPlainTextEditPrivate::append(const QString &text, Qt::TextFormat format)
}
documentLayout->priv()->blockDocumentSizeChanged = documentSizeChangedBlocked;
- _q_adjustScrollbars();
+ adjustScrollbars();
if (atBottom) {
diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h
index f2213c9ca7..89a4d3ab04 100644
--- a/src/widgets/widgets/qplaintextedit.h
+++ b/src/widgets/widgets/qplaintextedit.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLAINTEXTEDIT_H
#define QPLAINTEXTEDIT_H
@@ -76,7 +40,8 @@ class Q_WIDGETS_EXPORT QPlainTextEdit : public QAbstractScrollArea
Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance)
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags
+ WRITE setTextInteractionFlags)
Q_PROPERTY(int blockCount READ blockCount)
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
Q_PROPERTY(bool backgroundVisible READ backgroundVisible WRITE setBackgroundVisible)
@@ -275,11 +240,6 @@ protected:
private:
Q_DISABLE_COPY(QPlainTextEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
- Q_PRIVATE_SLOT(d_func(), void _q_textChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
- Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
- Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
friend class QPlainTextEditControl;
};
diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h
index 112eb2e4f6..9ca1cdcc67 100644
--- a/src/widgets/widgets/qplaintextedit_p.h
+++ b/src/widgets/widgets/qplaintextedit_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLAINTEXTEDIT_P_H
#define QPLAINTEXTEDIT_P_H
@@ -68,6 +32,8 @@
#include "private/qwidgettextcontrol_p.h"
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(textedit);
QT_BEGIN_NAMESPACE
@@ -120,14 +86,14 @@ public:
QPlainTextEditPrivate();
void init(const QString &txt = QString());
- void _q_repaintContents(const QRectF &contentsRect);
- void _q_textChanged();
+ void repaintContents(const QRectF &contentsRect);
+ void updatePlaceholderVisibility();
inline QPoint mapToContents(const QPoint &point) const
{ return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
- void _q_adjustScrollbars();
- void _q_verticalScrollbarActionTriggered(int action);
+ void adjustScrollbars();
+ void verticalScrollbarActionTriggered(int action);
void ensureViewportLayouted();
void relayoutDocument();
@@ -155,7 +121,6 @@ public:
qreal pageUpDownLastCursorY = 0;
QPlainTextEdit::LineWrapMode lineWrap = QPlainTextEdit::WidgetWidth;
QTextOption::WrapMode wordWrap = QTextOption::WrapAtWordBoundaryOrAnywhere;
- Qt::KeyboardModifiers keyboardModifiers = {};
int originalOffsetY = 0;
int topLine = 0;
@@ -165,8 +130,8 @@ public:
uint centerOnScroll : 1;
uint inDrag : 1;
uint clickCausedFocus : 1;
- uint placeholderVisible : 1;
uint pageUpDownLastCursorYIsValid : 1;
+ uint placeholderTextShown : 1;
void setTopLine(int visualTopLine, int dx = 0);
void setTopBlock(int newTopBlock, int newTopLine, int dx = 0);
@@ -179,8 +144,13 @@ public:
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
- void _q_cursorPositionChanged();
- void _q_modificationChanged(bool);
+ void cursorPositionChanged();
+ void modificationChanged(bool);
+ inline bool placeHolderTextToBeShown() const
+ {
+ Q_Q(const QPlainTextEdit);
+ return q->document()->isEmpty() && !q->placeholderText().isEmpty();
+ }
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp
index e2d4875f54..79cdecd22a 100644
--- a/src/widgets/widgets/qprogressbar.cpp
+++ b/src/widgets/widgets/qprogressbar.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qprogressbar.h"
@@ -45,13 +9,15 @@
#include <qstylepainter.h>
#include <qstyleoption.h>
#include <private/qwidget_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
#include <limits.h>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QProgressBarPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QProgressBar)
@@ -89,7 +55,7 @@ QProgressBarPrivate::QProgressBarPrivate()
void QProgressBarPrivate::initDefaultFormat()
{
if (defaultFormat)
- format = QLatin1String("%p") + locale.percent();
+ format = "%p"_L1 + locale.percent();
}
void QProgressBarPrivate::init()
@@ -152,10 +118,9 @@ bool QProgressBarPrivate::repaintRequired() const
const auto totalSteps = qint64(maximum) - minimum;
if (textVisible) {
- if ((format.contains(QLatin1String("%v"))))
+ if (format.contains("%v"_L1))
return true;
- if ((format.contains(QLatin1String("%p"))
- && valueDifference >= qAbs(totalSteps / 100)))
+ if (format.contains("%p"_L1) && valueDifference >= qAbs(totalSteps / 100))
return true;
}
@@ -201,7 +166,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
*/
/*!
@@ -318,7 +283,7 @@ void QProgressBar::setValue(int value)
return;
d->value = value;
emit valueChanged(value);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (isVisible()) {
QAccessibleValueChangeEvent event(this, value);
QAccessible::updateAccessibility(&event);
@@ -422,7 +387,7 @@ QSize QProgressBar::sizeHint() const
QStyleOptionProgressBar opt;
initStyleOption(&opt);
int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, this);
- QSize size = QSize(qMax(9, cw) * 7 + fm.horizontalAdvance(QLatin1Char('0')) * 4, fm.height() + 8);
+ QSize size = QSize(qMax(9, cw) * 7 + fm.horizontalAdvance(u'0') * 4, fm.height() + 8);
if (!(opt.state & QStyle::State_Horizontal))
size = size.transposed();
return style()->sizeFromContents(QStyle::CT_ProgressBar, &opt, size, this);
@@ -468,19 +433,19 @@ QString QProgressBar::text() const
QString result = d->format;
QLocale locale = d->locale; // Omit group separators for compatibility with previous versions that were non-localized.
locale.setNumberOptions(locale.numberOptions() | QLocale::OmitGroupSeparator);
- result.replace(QLatin1String("%m"), locale.toString(totalSteps));
- result.replace(QLatin1String("%v"), locale.toString(d->value));
+ result.replace("%m"_L1, locale.toString(totalSteps));
+ result.replace("%v"_L1, locale.toString(d->value));
// If max and min are equal and we get this far, it means that the
// progress bar has one step and that we are on that step. Return
// 100% here in order to avoid division by zero further down.
if (totalSteps == 0) {
- result.replace(QLatin1String("%p"), locale.toString(100));
+ result.replace("%p"_L1, locale.toString(100));
return result;
}
const auto progress = static_cast<int>((qint64(d->value) - d->minimum) * 100.0 / totalSteps);
- result.replace(QLatin1String("%p"), locale.toString(progress));
+ result.replace("%p"_L1, locale.toString(progress));
return result;
}
diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h
index e112af416b..96b2993ec2 100644
--- a/src/widgets/widgets/qprogressbar.h
+++ b/src/widgets/widgets/qprogressbar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPROGRESSBAR_H
#define QPROGRESSBAR_H
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index 8d3d472882..c180a08d62 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qapplication.h"
#include "qbitmap.h"
@@ -60,7 +24,7 @@
#include "qdialogbuttonbox.h"
#endif
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
@@ -171,7 +135,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
*/
/*!
@@ -370,7 +334,7 @@ void QPushButton::setDefault(bool enable)
}
#endif
update();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::State s;
s.defaultButton = true;
QAccessibleStateChangeEvent event(this, s);
@@ -525,6 +489,8 @@ void QPushButton::mouseMoveEvent(QMouseEvent *e)
d->hovering = hit;
}
}
+
+ QAbstractButton::mouseMoveEvent(e);
}
/*!
@@ -559,7 +525,8 @@ void QPushButton::setMenu(QMenu* menu)
return;
if (menu && !d->menu) {
- connect(this, SIGNAL(pressed()), this, SLOT(_q_popupPressed()), Qt::UniqueConnection);
+ QObjectPrivate::connect(this, &QPushButton::pressed,
+ d, &QPushButtonPrivate::popupPressed, Qt::UniqueConnection);
}
if (d->menu)
removeAction(d->menu->menuAction());
@@ -596,10 +563,10 @@ void QPushButton::showMenu()
if (!d || !d->menu)
return;
setDown(true);
- d->_q_popupPressed();
+ d->popupPressed();
}
-void QPushButtonPrivate::_q_popupPressed()
+void QPushButtonPrivate::popupPressed()
{
Q_Q(QPushButton);
if (!down || !menu)
@@ -609,17 +576,14 @@ void QPushButtonPrivate::_q_popupPressed()
QPoint menuPos = adjustedMenuPosition();
- QPointer<QPushButton> guard(q);
- QMenuPrivate::get(menu)->causedPopup.widget = guard;
+ QMenuPrivate::get(menu)->causedPopup.widget = q;
//Because of a delay in menu effects, we must keep track of the
//menu visibility to avoid flicker on button release
menuOpen = true;
- menu->exec(menuPos);
- if (guard) {
- menuOpen = false;
- q->setDown(false);
- }
+ QObject::connect(menu, &QMenu::aboutToHide,
+ q, [q, this]{ menuOpen = false; q->setDown(false); }, Qt::SingleShotConnection);
+ menu->popup(menuPos);
}
QPoint QPushButtonPrivate::adjustedMenuPosition()
@@ -641,7 +605,7 @@ QPoint QPushButtonPrivate::adjustedMenuPosition()
QPoint globalPos = q->mapToGlobal(rect.topLeft());
int x = globalPos.x();
int y = globalPos.y();
- const QRect availableGeometry = QWidgetPrivate::availableScreenGeometry(q);
+ const QRect availableGeometry = QWidgetPrivate::availableScreenGeometry(q, q->mapToGlobal(rect.center()));
if (horizontal) {
if (globalPos.y() + rect.height() + menuSize.height() <= availableGeometry.bottom()) {
y += rect.height();
diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h
index eeaa50bb4c..3c420b5313 100644
--- a/src/widgets/widgets/qpushbutton.h
+++ b/src/widgets/widgets/qpushbutton.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPUSHBUTTON_H
#define QPUSHBUTTON_H
@@ -98,14 +62,9 @@ protected:
bool hitButton(const QPoint &pos) const override;
QPushButton(QPushButtonPrivate &dd, QWidget* parent = nullptr);
-public:
-
private:
Q_DISABLE_COPY(QPushButton)
Q_DECLARE_PRIVATE(QPushButton)
-#if QT_CONFIG(menu)
- Q_PRIVATE_SLOT(d_func(), void _q_popupPressed())
-#endif
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qpushbutton_p.h b/src/widgets/widgets/qpushbutton_p.h
index 2a3dfeff23..0817589baf 100644
--- a/src/widgets/widgets/qpushbutton_p.h
+++ b/src/widgets/widgets/qpushbutton_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPUSHBUTTON_P_H
#define QPUSHBUTTON_P_H
@@ -43,6 +7,8 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include "private/qabstractbutton_p.h"
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(pushbutton);
//
@@ -79,11 +45,11 @@ public:
QPoint adjustedMenuPosition();
#endif
void resetLayoutItemMargins();
- void _q_popupPressed();
+ void popupPressed();
#if QT_CONFIG(dialog)
QDialog *dialogParent() const;
#else
- QDialog *dialogParent() const { return 0; }
+ QDialog *dialogParent() const { return nullptr; }
#endif
QPointer<QMenu> menu;
diff --git a/src/widgets/widgets/qradiobutton.cpp b/src/widgets/widgets/qradiobutton.cpp
index 8e880a3f35..af1bd3f649 100644
--- a/src/widgets/widgets/qradiobutton.cpp
+++ b/src/widgets/widgets/qradiobutton.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qradiobutton.h"
#include "qapplication.h"
@@ -118,8 +82,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
*/
diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h
index 009e7107c6..7a59b186d1 100644
--- a/src/widgets/widgets/qradiobutton.h
+++ b/src/widgets/widgets/qradiobutton.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRADIOBUTTON_H
#define QRADIOBUTTON_H
diff --git a/src/widgets/widgets/qrubberband.cpp b/src/widgets/widgets/qrubberband.cpp
index af730f8023..e00f739ca7 100644
--- a/src/widgets/widgets/qrubberband.cpp
+++ b/src/widgets/widgets/qrubberband.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qbitmap.h"
#include "qevent.h"
diff --git a/src/widgets/widgets/qrubberband.h b/src/widgets/widgets/qrubberband.h
index 9822f036f1..76d60b642b 100644
--- a/src/widgets/widgets/qrubberband.h
+++ b/src/widgets/widgets/qrubberband.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRUBBERBAND_H
#define QRUBBERBAND_H
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index f7a4f8e446..efbf4da07f 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qscrollarea.h"
#include "private/qscrollarea_p.h"
@@ -127,11 +91,7 @@ QT_BEGIN_NAMESPACE
cause the size of the scroll area to be updated whenever the
contents of the layout changes.
- For a complete example using the QScrollArea class, see the \l
- {widgets/imageviewer}{Image Viewer} example. The example shows how
- to combine QLabel and QScrollArea to display an image.
-
- \sa QAbstractScrollArea, QScrollBar, {Image Viewer Example}
+ \sa QAbstractScrollArea, QScrollBar
*/
@@ -196,7 +156,23 @@ void QScrollAreaPrivate::updateScrollBars()
if (resizable) {
if ((widget->layout() ? widget->layout()->hasHeightForWidth() : widget->sizePolicy().hasHeightForWidth())) {
QSize p_hfw = p.expandedTo(min).boundedTo(max);
- int h = widget->heightForWidth( p_hfw.width() );
+ int h = widget->heightForWidth(p_hfw.width());
+ // If the height we calculated requires a vertical scrollbar,
+ // then we need to constrain the width and calculate the height again,
+ // otherwise we end up flipping the scrollbar on and off all the time.
+ if (vbarpolicy == Qt::ScrollBarAsNeeded) {
+ int vbarWidth = vbar->sizeHint().width();
+ QSize m_hfw = m.expandedTo(min).boundedTo(max);
+ // 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));
+ }
min = QSize(p_hfw.width(), qMax(p_hfw.height(), h));
}
}
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
index 6d252821c5..7486a121ea 100644
--- a/src/widgets/widgets/qscrollarea.h
+++ b/src/widgets/widgets/qscrollarea.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSCROLLAREA_H
#define QSCROLLAREA_H
diff --git a/src/widgets/widgets/qscrollarea_p.h b/src/widgets/widgets/qscrollarea_p.h
index 26335285a4..a599fa8c36 100644
--- a/src/widgets/widgets/qscrollarea_p.h
+++ b/src/widgets/widgets/qscrollarea_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSCROLLAREA_P_H
#define QSCROLLAREA_P_H
@@ -56,6 +20,8 @@
#include "private/qabstractscrollarea_p.h"
#include <QtWidgets/qscrollbar.h>
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(scrollarea);
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index de58e8ffe7..789cffba99 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qapplication.h"
#include "qcursor.h"
@@ -44,12 +8,16 @@
#include "qscrollbar.h"
#include "qstyle.h"
#include "qstyleoption.h"
+#include "qstylepainter.h"
#if QT_CONFIG(menu)
#include "qmenu.h"
#endif
+
#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qpointer.h>
+
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#include <limits.h>
@@ -175,7 +143,7 @@ QT_BEGIN_NAMESPACE
\li Up/Down move a vertical scroll bar by one single step.
\li PageUp moves up one page.
\li PageDown moves down one page.
- \li Home moves to the start (mininum).
+ \li Home moves to the start (minimum).
\li End moves to the end (maximum).
\endlist
@@ -187,7 +155,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)
@@ -224,7 +192,9 @@ void QScrollBarPrivate::setTransient(bool value)
if (transient != value) {
transient = value;
if (q->isVisible()) {
- if (q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q))
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ if (q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q))
q->update();
} else if (!transient) {
q->show();
@@ -235,7 +205,9 @@ void QScrollBarPrivate::setTransient(bool value)
void QScrollBarPrivate::flash()
{
Q_Q(QScrollBar);
- if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q)) {
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q)) {
flashed = true;
if (!q->isVisible())
q->show();
@@ -319,7 +291,7 @@ void QScrollBar::initStyleOption(QStyleOptionSlider *option) const
option->upsideDown = d->invertedAppearance;
if (d->orientation == Qt::Horizontal)
option->state |= QStyle::State_Horizontal;
- if ((d->flashed || !d->transient) && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this))
+ if ((d->flashed || !d->transient) && style()->styleHint(QStyle::SH_ScrollBar_Transient, option, this))
option->state |= QStyle::State_On;
}
@@ -376,7 +348,9 @@ void QScrollBarPrivate::init()
invertedControls = true;
pressedControl = hoverControl = QStyle::SC_None;
pointerOutsidePressedControl = false;
- transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q);
+ QStyleOption opt;
+ opt.initFrom(q);
+ transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q);
flashed = false;
flashTimer = 0;
q->setFocusPolicy(Qt::NoFocus);
@@ -470,12 +444,17 @@ bool QScrollBar::event(QEvent *event)
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d_func()->updateHoverControl(he->position().toPoint());
break;
- case QEvent::StyleChange:
- d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this));
+ case QEvent::StyleChange: {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, this));
break;
+ }
case QEvent::Timer:
if (static_cast<QTimerEvent *>(event)->timerId() == d->flashTimer) {
- if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, this)) {
d->flashed = false;
update();
}
@@ -525,7 +504,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 +515,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/qscrollbar.h b/src/widgets/widgets/qscrollbar.h
index de4e0c14c7..9fd8f617ab 100644
--- a/src/widgets/widgets/qscrollbar.h
+++ b/src/widgets/widgets/qscrollbar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSCROLLBAR_H
#define QSCROLLBAR_H
diff --git a/src/widgets/widgets/qscrollbar_p.h b/src/widgets/widgets/qscrollbar_p.h
index 8693495c6f..1c8d07608d 100644
--- a/src/widgets/widgets/qscrollbar_p.h
+++ b/src/widgets/widgets/qscrollbar_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSCROLLBAR_P_H
#define QSCROLLBAR_P_H
diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp
index 92042f31df..2500983450 100644
--- a/src/widgets/widgets/qsizegrip.cpp
+++ b/src/widgets/widgets/qsizegrip.cpp
@@ -1,47 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsizegrip.h"
#include "qapplication.h"
#include "qevent.h"
-#include "qpainter.h"
+#include "qstylepainter.h"
#include "qwindow.h"
#include <qpa/qplatformwindow.h>
#include "qstyle.h"
@@ -54,6 +18,8 @@
#include <qpa/qplatformtheme.h>
#include <QtWidgets/qabstractscrollarea.h>
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
@@ -109,7 +75,7 @@ public:
void _q_showIfNotHidden()
{
Q_Q(QSizeGrip);
- bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
+ bool showSizeGrip = !isExplicitlyHidden();
updateTopLevelWidget();
if (tlw && showSizeGrip) {
Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
@@ -173,6 +139,10 @@ Qt::Corner QSizeGripPrivate::corner() const
On some platforms the size grip automatically hides itself when the
window is shown full screen or maximised.
+ \note On macOS, size grips are no longer part of the human interface
+ guideline, and won't show unless used in a QMdiSubWindow. Set another
+ style on size grips that you want to be visible in main windows.
+
\table 50%
\row \li \inlineimage fusion-statusbar-sizegrip.png Screenshot of a Fusion style size grip
\li A size grip widget at the bottom-right corner of a main window, shown in the
@@ -244,11 +214,11 @@ void QSizeGrip::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
Q_D(QSizeGrip);
- QPainter painter(this);
+ QStylePainter painter(this);
QStyleOptionSizeGrip opt;
opt.initFrom(this);
opt.corner = d->m_corner;
- style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, this);
+ painter.drawControl(QStyle::CE_SizeGrip, opt);
}
/*!
@@ -481,7 +451,7 @@ void QSizeGrip::setVisible(bool visible)
bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
{
Q_D(QSizeGrip);
- if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
+ if (d->isExplicitlyHidden()
|| e->type() != QEvent::WindowStateChange
|| o != d->tlw) {
return QWidget::eventFilter(o, e);
diff --git a/src/widgets/widgets/qsizegrip.h b/src/widgets/widgets/qsizegrip.h
index 5285ffdfb8..c69b83e5d5 100644
--- a/src/widgets/widgets/qsizegrip.h
+++ b/src/widgets/widgets/qsizegrip.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSIZEGRIP_H
#define QSIZEGRIP_H
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
index 5accb9c92f..e39521a2e9 100644
--- a/src/widgets/widgets/qslider.cpp
+++ b/src/widgets/widgets/qslider.cpp
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qslider.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#include "qapplication.h"
@@ -46,6 +10,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 +120,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)
@@ -252,11 +224,11 @@ QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
\li Up/Down move a vertical slider by one single step.
\li PageUp moves up one page.
\li PageDown moves down one page.
- \li Home moves to the start (mininum).
+ \li Home moves to the start (minimum).
\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 +282,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);
}
/*!
@@ -426,8 +392,6 @@ void QSlider::mouseMoveEvent(QMouseEvent *ev)
}
ev->accept();
int newPosition = d->pixelPosToRangeValue(d->pick(ev->position().toPoint()) - d->clickOffset);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
setSliderPosition(newPosition);
}
diff --git a/src/widgets/widgets/qslider.h b/src/widgets/widgets/qslider.h
index a4f05c3c12..9e28928c14 100644
--- a/src/widgets/widgets/qslider.h
+++ b/src/widgets/widgets/qslider.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSLIDER_H
#define QSLIDER_H
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 6ac2e1cec2..73946d54a9 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <private/qabstractspinbox_p.h>
#include <qspinbox.h>
@@ -51,6 +15,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
//#define QSPINBOX_QSBDEBUG
#ifdef QSPINBOX_QSBDEBUG
# define QSBDEBUG qDebug
@@ -166,12 +132,9 @@ public:
for a custom spin box that allows the user to enter icon sizes
(e.g., "32 x 32"):
- \snippet widgets/icons/iconsizespinbox.cpp 1
+ \snippet code/src_gui_widgets_qspinbox.cpp 8
\codeline
- \snippet widgets/icons/iconsizespinbox.cpp 2
-
- See the \l{widgets/icons}{Icons} example for the full source
- code.
+ \snippet code/src_gui_widgets_qspinbox.cpp 9
\sa QDoubleSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}
*/
@@ -518,7 +481,7 @@ QString QSpinBox::textFromValue(int value) const
QString str;
if (d->displayIntegerBase != 10) {
- const QLatin1String prefix = value < 0 ? QLatin1String("-") : QLatin1String();
+ const auto prefix = value < 0 ? "-"_L1 : ""_L1;
str = prefix + QString::number(qAbs(value), d->displayIntegerBase);
} else {
str = locale().toString(value);
@@ -977,9 +940,8 @@ void QDoubleSpinBox::setDecimals(int decimals)
This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a string
containing \a value printed using QWidget::locale().toString(\a value,
- QLatin1Char('f'), decimals()) and will remove the thousand
- separator unless setGroupSeparatorShown() is set. Reimplementations may
- return anything.
+ \c u'f', decimals()) and will remove the thousand separator unless
+ setGroupSeparatorShown() is set. Reimplementations may return anything.
Note: QDoubleSpinBox does not call this function for
specialValueText() and that neither prefix() nor suffix() should
@@ -1127,11 +1089,11 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
int num = min;
if (max != min && (copy.isEmpty()
- || (min < 0 && copy == QLatin1String("-"))
- || (max >= 0 && copy == QLatin1String("+")))) {
+ || (min < 0 && copy == "-"_L1)
+ || (max >= 0 && copy == "+"_L1))) {
state = QValidator::Intermediate;
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
- } else if (copy.startsWith(QLatin1Char('-')) && min >= 0) {
+ } else if (copy.startsWith(u'-') && min >= 0) {
state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
} else {
bool ok = false;
@@ -1281,24 +1243,25 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
const bool minus = min <= 0;
const QString group(locale.groupSeparator());
- const uint groupUcs = (group.size() > 1 && group.at(0).isHighSurrogate()
- ? QChar::surrogateToUcs4(group.at(0), group.at(1))
- : group.at(0).unicode());
+ const uint groupUcs = (group.isEmpty() ? 0 :
+ (group.size() > 1 && group.at(0).isHighSurrogate()
+ ? QChar::surrogateToUcs4(group.at(0), group.at(1))
+ : group.at(0).unicode()));
switch (len) {
case 0:
state = max != min ? QValidator::Intermediate : QValidator::Invalid;
goto end;
case 1:
if (copy.at(0) == locale.decimalPoint()
- || (plus && copy.at(0) == QLatin1Char('+'))
- || (minus && copy.at(0) == QLatin1Char('-'))) {
+ || (plus && copy.at(0) == u'+')
+ || (minus && copy.at(0) == u'-')) {
state = QValidator::Intermediate;
goto end;
}
break;
case 2:
if (copy.at(1) == locale.decimalPoint()
- && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) {
+ && ((plus && copy.at(0) == u'+') || (minus && copy.at(0) == u'-'))) {
state = QValidator::Intermediate;
goto end;
}
@@ -1306,7 +1269,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
default: break;
}
- if (copy.at(0) == locale.groupSeparator()) {
+ if (groupUcs && copy.startsWith(group)) {
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
state = QValidator::Invalid;
goto end;
@@ -1322,8 +1285,9 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid;
goto end;
}
- for (int i=dec + 1; i<copy.size(); ++i) {
- if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) {
+ for (int i = dec + 1; i < copy.size(); ++i) {
+ if (copy.at(i).isSpace()
+ || (groupUcs && QStringView{copy}.sliced(i).startsWith(group))) {
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
state = QValidator::Invalid;
goto end;
@@ -1331,10 +1295,11 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
}
} else {
const QChar last = copy.back();
- const bool groupEnd = copy.endsWith(group);
+ const bool groupEnd = groupUcs && copy.endsWith(group);
const QStringView head(copy.constData(), groupEnd ? len - group.size() : len - 1);
const QChar secondLast = head.back();
- if ((groupEnd || last.isSpace()) && (head.endsWith(group) || secondLast.isSpace())) {
+ if ((groupEnd || last.isSpace())
+ && ((groupUcs && head.endsWith(group)) || secondLast.isSpace())) {
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
goto end;
@@ -1353,7 +1318,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
if (!ok) {
if (QChar::isPrint(groupUcs)) {
- if (max < 1000 && min > -1000 && copy.contains(group)) {
+ if (max < 1000 && min > -1000 && groupUcs && copy.contains(group)) {
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
goto end;
@@ -1361,7 +1326,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
const int len = copy.size();
for (int i = 0; i < len - 1;) {
- if (QStringView(copy).mid(i).startsWith(group)) {
+ if (groupUcs && QStringView{copy}.sliced(i).startsWith(group)) {
if (QStringView(copy).mid(i + group.size()).startsWith(group)) {
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
state = QValidator::Invalid;
@@ -1374,7 +1339,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
}
QString copy2 = copy;
- copy2.remove(group);
+ if (groupUcs)
+ copy2.remove(group);
num = locale.toDouble(copy2, &ok);
QSBDEBUG() << group << num << copy2 << ok;
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index be5357b028..38affecdbb 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSPINBOX_H
#define QSPINBOX_H
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index f417a997a7..fcd09908cd 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsplashscreen.h"
@@ -68,6 +32,8 @@ public:
int currAlign;
inline QSplashScreenPrivate();
+
+ void handlePaintEvent();
};
/*!
@@ -103,9 +69,9 @@ public:
\snippet qsplashscreen/main.cpp 1
The user can hide the splash screen by clicking on it with the
- mouse. Since the splash screen is typically displayed before the
- event loop has started running, it is necessary to periodically
- call QCoreApplication::processEvents() to receive the mouse clicks.
+ mouse. For mouse handling to work, call QApplication::processEvents()
+ periodically during startup.
+
It is sometimes useful to update the splash screen with messages,
for example, announcing connections established or modules loaded
@@ -237,18 +203,21 @@ void QSplashScreen::clearMessage()
repaint();
}
-// A copy of Qt Test's qWaitForWindowExposed() and qSleep().
-inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000)
+static bool waitForWidgetMapped(QWidget *widget, int timeout = 1000)
{
enum { TimeOutMs = 10 };
+ auto isMapped = [widget](){
+ return widget->windowHandle() && widget->windowHandle()->isVisible();
+ };
+
QElapsedTimer timer;
timer.start();
- while (!window->isExposed()) {
+ while (!isMapped()) {
const int remaining = timeout - int(timer.elapsed());
if (remaining <= 0)
break;
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
- QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents();
#if defined(Q_OS_WIN)
Sleep(uint(TimeOutMs));
#else
@@ -256,7 +225,7 @@ inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000)
nanosleep(&ts, nullptr);
#endif
}
- return window->isExposed();
+ return isMapped();
}
/*!
@@ -269,7 +238,7 @@ void QSplashScreen::finish(QWidget *mainWin)
if (mainWin) {
if (!mainWin->windowHandle())
mainWin->createWinId();
- waitForWindowExposed(mainWin->windowHandle());
+ waitForWidgetMapped(mainWin);
}
close();
}
@@ -284,7 +253,7 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap)
d->pixmap = pixmap;
setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha());
- const QRect r(QPoint(), pixmap.size() / pixmap.devicePixelRatio());
+ const QRect r(QPoint(), pixmap.deviceIndependentSize().toSize());
resize(r.size());
move(screen()->geometry().center() - r.center());
@@ -347,18 +316,33 @@ void QSplashScreen::drawContents(QPainter *painter)
}
}
+void QSplashScreenPrivate::handlePaintEvent()
+{
+ Q_Q(QSplashScreen);
+ QPainter painter(q);
+ painter.setRenderHints(QPainter::SmoothPixmapTransform);
+ painter.setLayoutDirection(q->layoutDirection());
+ if (!pixmap.isNull())
+ painter.drawPixmap(QPoint(), pixmap);
+ q->drawContents(&painter);
+}
+
/*! \reimp */
bool QSplashScreen::event(QEvent *e)
{
- if (e->type() == QEvent::Paint) {
- Q_D(QSplashScreen);
- QPainter painter(this);
- painter.setRenderHints(QPainter::SmoothPixmapTransform);
- painter.setLayoutDirection(layoutDirection());
- if (!d->pixmap.isNull())
- painter.drawPixmap(QPoint(), d->pixmap);
- drawContents(&painter);
+ Q_D(QSplashScreen);
+
+ switch (e->type()) {
+ case QEvent::Paint:
+ d->handlePaintEvent();
+ break;
+ case QEvent::Show:
+ waitForWidgetMapped(this);
+ break;
+ default:
+ break;
}
+
return QWidget::event(e);
}
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
index de51494f85..2670e5c68b 100644
--- a/src/widgets/widgets/qsplashscreen.h
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSPLASHSCREEN_H
#define QSPLASHSCREEN_H
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 1c04f02422..d0519a56a2 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsplitter.h"
@@ -62,6 +26,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
//#define QSPLITTER_DEBUG
QSplitterPrivate::~QSplitterPrivate()
@@ -289,10 +255,11 @@ bool QSplitterHandle::event(QEvent *event)
void QSplitterHandle::mouseMoveEvent(QMouseEvent *e)
{
Q_D(QSplitterHandle);
- if (!(e->buttons() & Qt::LeftButton))
+ if (!d->pressed)
return;
- int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPosition().toPoint()))
- - d->mouseOffset;
+
+ const int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPosition().toPoint()))
+ - d->mouseOffset;
if (opaqueResize()) {
moveSplitter(pos);
} else {
@@ -319,16 +286,18 @@ void QSplitterHandle::mousePressEvent(QMouseEvent *e)
void QSplitterHandle::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QSplitterHandle);
- if (!opaqueResize() && e->button() == Qt::LeftButton) {
- int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPosition().toPoint()))
- - d->mouseOffset;
+ if (!d->pressed)
+ return;
+
+ if (!opaqueResize()) {
+ const int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPosition().toPoint()))
+ - d->mouseOffset;
d->s->setRubberBand(-1);
moveSplitter(pos);
}
- if (e->button() == Qt::LeftButton) {
- d->pressed = false;
- update();
- }
+
+ d->pressed = false;
+ update();
}
/*!
@@ -392,7 +361,7 @@ void QSplitterPrivate::init()
void QSplitterPrivate::recalc(bool update)
{
Q_Q(QSplitter);
- int n = list.count();
+ int n = list.size();
/*
Splitter handles before the first visible widget or right
before a hidden widget must be hidden.
@@ -482,7 +451,7 @@ void QSplitterPrivate::doResize()
{
Q_Q(QSplitter);
QRect r = q->contentsRect();
- int n = list.count();
+ int n = list.size();
QList<QLayoutStruct> a(n * 2);
int i;
@@ -596,7 +565,7 @@ int QSplitterPrivate::findWidgetJustBeforeOrJustAfter(int index, int delta, int
return index;
}
index += delta;
- } while (index >= 0 && index < list.count());
+ } while (index >= 0 && index < list.size());
return -1;
}
@@ -608,7 +577,7 @@ int QSplitterPrivate::findWidgetJustBeforeOrJustAfter(int index, int delta, int
void QSplitterPrivate::getRange(int index, int *farMin, int *min, int *max, int *farMax) const
{
Q_Q(const QSplitter);
- int n = list.count();
+ int n = list.size();
if (index <= 0 || index >= n)
return;
@@ -732,10 +701,15 @@ void QSplitterPrivate::setSizes_helper(const QList<int> &sizes, bool clampNegati
doResize();
}
+/*
+ Used by various methods inserting a widget to find out if we need to show the widget
+ explicitly, which we have to if the splitter is already visible, and if the widget hasn't
+ been explicitly hidden before inserting it.
+*/
bool QSplitterPrivate::shouldShowWidget(const QWidget *w) const
{
Q_Q(const QSplitter);
- return q->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
+ return q->isVisible() && !QWidgetPrivate::get(w)->isExplicitlyHidden();
}
void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool allowCollapse)
@@ -783,7 +757,7 @@ void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool all
void QSplitterPrivate::doMove(bool backwards, int hPos, int index, int delta, bool mayCollapse,
int *positions, int *widths)
{
- if (index < 0 || index >= list.count())
+ if (index < 0 || index >= list.size())
return;
#ifdef QSPLITTER_DEBUG
@@ -853,7 +827,7 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
Q_Q(QSplitter);
QSplitterLayoutStruct *sls = nullptr;
int i;
- int last = list.count();
+ int last = list.size();
for (i = 0; i < list.size(); ++i) {
QSplitterLayoutStruct *s = list.at(i);
if (s->widget == w) {
@@ -870,7 +844,7 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
} else {
sls = new QSplitterLayoutStruct;
QSplitterHandle *newHandle = q->createHandle();
- newHandle->setObjectName(QLatin1String("qt_splithandle_") + w->objectName());
+ newHandle->setObjectName("qt_splithandle_"_L1 + w->objectName());
sls->handle = newHandle;
sls->widget = w;
w->lower();
@@ -1105,7 +1079,7 @@ void QSplitter::resizeEvent(QResizeEvent *)
void QSplitter::addWidget(QWidget *widget)
{
Q_D(QSplitter);
- insertWidget(d->list.count(), widget);
+ insertWidget(d->list.size(), widget);
}
/*!
@@ -1155,7 +1129,7 @@ QWidget *QSplitter::replaceWidget(int index, QWidget *widget)
return nullptr;
}
- if (index < 0 || index >= d->list.count()) {
+ if (index < 0 || index >= d->list.size()) {
qWarning("QSplitter::replaceWidget: Index %d out of range", index);
return nullptr;
}
@@ -1175,7 +1149,7 @@ QWidget *QSplitter::replaceWidget(int index, QWidget *widget)
QBoolBlocker b(d->blockChildAdd);
const QRect geom = current->geometry();
- const bool shouldShow = d->shouldShowWidget(current);
+ const bool wasHidden = current->isHidden();
s->widget = widget;
current->setParent(nullptr);
@@ -1185,7 +1159,10 @@ QWidget *QSplitter::replaceWidget(int index, QWidget *widget)
// should not change. Only set the geometry on the new widget
widget->setGeometry(geom);
widget->lower();
- widget->setVisible(shouldShow);
+ if (wasHidden)
+ widget->hide();
+ else if (d->shouldShowWidget(widget))
+ widget->show();
return current;
}
@@ -1265,7 +1242,7 @@ QWidget *QSplitter::widget(int index) const
int QSplitter::count() const
{
Q_D(const QSplitter);
- return d->list.count();
+ return d->list.size();
}
/*!
@@ -1286,16 +1263,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);
+ d->insertWidget_helper(d->list.size(), 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();
@@ -1335,7 +1314,7 @@ void QSplitter::setRubberBand(int pos)
QBoolBlocker b(d->blockChildAdd);
d->rubberBand = new QRubberBand(QRubberBand::Line, this);
// For accessibility to identify this special widget.
- d->rubberBand->setObjectName(QLatin1String("qt_rubberband"));
+ d->rubberBand->setObjectName("qt_rubberband"_L1);
}
const QRect newGeom = d->orient == Qt::Horizontal ? QRect(QPoint(pos + hw / 2 - rBord, r.y()), QSize(2 * rBord, r.height()))
@@ -1419,15 +1398,15 @@ void QSplitter::moveSplitter(int pos, int index)
qDebug() << "QSplitter::moveSplitter" << debugp << index << "adjusted" << pos << "oldP" << oldP;
#endif
- QVarLengthArray<int, 32> poss(d->list.count());
- QVarLengthArray<int, 32> ws(d->list.count());
+ QVarLengthArray<int, 32> poss(d->list.size());
+ QVarLengthArray<int, 32> ws(d->list.size());
bool upLeft;
d->doMove(false, pos, index, +1, (d->collapsible(s) && (pos > max)), poss.data(), ws.data());
d->doMove(true, pos, index - 1, +1, (d->collapsible(index - 1) && (pos < min)), poss.data(), ws.data());
upLeft = (pos < oldP);
- int wid, delta, count = d->list.count();
+ int wid, delta, count = d->list.size();
if (upLeft) {
wid = 0;
delta = 1;
@@ -1679,6 +1658,7 @@ QByteArray QSplitter::saveState() const
int version = 1;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << qint32(SplitterMagic);
stream << qint32(version);
@@ -1720,6 +1700,7 @@ bool QSplitter::restoreState(const QByteArray &state)
int version = 1;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
QList<int> list;
bool b;
qint32 i;
@@ -1770,7 +1751,7 @@ bool QSplitter::restoreState(const QByteArray &state)
void QSplitter::setStretchFactor(int index, int stretch)
{
Q_D(QSplitter);
- if (index <= -1 || index >= d->list.count())
+ if (index <= -1 || index >= d->list.size())
return;
QWidget *widget = d->list.at(index)->widget;
diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h
index b7a097ca92..96c19be24d 100644
--- a/src/widgets/widgets/qsplitter.h
+++ b/src/widgets/widgets/qsplitter.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSPLITTER_H
#define QSPLITTER_H
diff --git a/src/widgets/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h
index 871406a51d..5d5723a957 100644
--- a/src/widgets/widgets/qsplitter_p.h
+++ b/src/widgets/widgets/qsplitter_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSPLITTER_P_H
#define QSPLITTER_P_H
@@ -54,6 +18,8 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include "private/qframe_p.h"
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(splitter);
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 9a9d2ddcbd..9cecee2ef8 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qstackedwidget.h"
@@ -51,7 +15,6 @@ class QStackedWidgetPrivate : public QFramePrivate
public:
QStackedWidgetPrivate():layout(nullptr){}
QStackedLayout *layout;
- bool blockChildAdd;
};
/*!
@@ -135,8 +98,10 @@ QStackedWidget::QStackedWidget(QWidget *parent)
{
Q_D(QStackedWidget);
d->layout = new QStackedLayout(this);
- connect(d->layout, SIGNAL(widgetRemoved(int)), this, SIGNAL(widgetRemoved(int)));
- connect(d->layout, SIGNAL(currentChanged(int)), this, SIGNAL(currentChanged(int)));
+ connect(d->layout, &QStackedLayout::widgetRemoved,
+ this, &QStackedWidget::widgetRemoved);
+ connect(d->layout, &QStackedLayout::currentChanged,
+ this, &QStackedWidget::currentChanged);
}
/*!
diff --git a/src/widgets/widgets/qstackedwidget.h b/src/widgets/widgets/qstackedwidget.h
index 5ca6429d75..49f2794ff4 100644
--- a/src/widgets/widgets/qstackedwidget.h
+++ b/src/widgets/widgets/qstackedwidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTACKEDWIDGET_H
#define QSTACKEDWIDGET_H
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 33b0d24d60..e398f52ac4 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qstatusbar.h"
@@ -54,7 +18,7 @@
#include "qmainwindow.h"
#endif
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
@@ -69,22 +33,27 @@ class QStatusBarPrivate : public QWidgetPrivate
public:
QStatusBarPrivate() {}
+ enum ItemCategory
+ {
+ Normal,
+ Permanent
+ };
+
struct SBItem {
- SBItem(QWidget* widget, int stretch, bool permanent)
- : s(stretch), w(widget), p(permanent) {}
- int s;
- QWidget * w;
- bool p;
+ QWidget *widget = nullptr;
+ int stretch = 0;
+ ItemCategory category = Normal;
+ bool isPermanent() const { return category == Permanent; }
};
- QList<SBItem *> items;
+ QList<SBItem> items;
QString tempItem;
- QBoxLayout * box;
- QTimer * timer;
+ QBoxLayout *box;
+ QTimer *timer;
#if QT_CONFIG(sizegrip)
- QSizeGrip * resizer;
+ QSizeGrip *resizer;
bool showSizeGrip;
#endif
@@ -94,8 +63,8 @@ public:
{
int i = items.size() - 1;
for (; i >= 0; --i) {
- SBItem *item = items.at(i);
- if (!(item && item->p))
+ const SBItem &item = items.at(i);
+ if (!item.isPermanent())
break;
}
return i;
@@ -122,7 +91,7 @@ public:
QRect QStatusBarPrivate::messageRect() const
{
Q_Q(const QStatusBar);
- bool rtl = q->layoutDirection() == Qt::RightToLeft;
+ const bool rtl = q->layoutDirection() == Qt::RightToLeft;
int left = 6;
int right = q->width() - 12;
@@ -136,18 +105,13 @@ QRect QStatusBarPrivate::messageRect() const
}
#endif
- for (int i=0; i<items.size(); ++i) {
- QStatusBarPrivate::SBItem* item = items.at(i);
- if (!item)
+ for (const auto &item : items) {
+ if (item.isPermanent() && item.widget->isVisible()) {
+ if (rtl)
+ left = qMax(left, item.widget->x() + item.widget->width() + 2);
+ else
+ right = qMin(right, item.widget->x() - 2);
break;
- if (item->p && item->w->isVisible()) {
- if (item->p) {
- if (rtl)
- left = qMax(left, item->w->x() + item->w->width() + 2);
- else
- right = qMin(right, item->w->x() - 2);
- }
- break;
}
}
return QRect(left, 0, right-left, q->height());
@@ -187,12 +151,12 @@ QRect QStatusBarPrivate::messageRect() const
Use the showMessage() slot to display a \e temporary message:
- \snippet mainwindows/dockwidgets/mainwindow.cpp 8
+ \snippet code/src_gui_widgets_qstatusbar.cpp 1
To remove a temporary message, use the clearMessage() slot, or set
a time limit when calling showMessage(). For example:
- \snippet mainwindows/dockwidgets/mainwindow.cpp 3
+ \snippet code/src_gui_widgets_qstatusbar.cpp 2
Use the currentMessage() function to retrieve the temporary
message currently shown. The QStatusBar class also provide the
@@ -215,8 +179,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
*/
@@ -246,9 +209,6 @@ QStatusBar::QStatusBar(QWidget * parent)
*/
QStatusBar::~QStatusBar()
{
- Q_D(QStatusBar);
- while (!d->items.isEmpty())
- delete d->items.takeFirst();
}
@@ -298,7 +258,7 @@ int QStatusBar::insertWidget(int index, QWidget *widget, int stretch)
return -1;
Q_D(QStatusBar);
- QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, false);
+ QStatusBarPrivate::SBItem item{widget, stretch, QStatusBarPrivate::Normal};
int idx = d->indexToLastNonPermanentWidget();
if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1))) {
@@ -311,7 +271,7 @@ int QStatusBar::insertWidget(int index, QWidget *widget, int stretch)
widget->hide();
reformat();
- if (!widget->isHidden() || !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
+ if (!QWidgetPrivate::get(widget)->isExplicitlyHidden())
widget->show();
return index;
@@ -326,7 +286,7 @@ int QStatusBar::insertWidget(int index, QWidget *widget, int stretch)
minimum of space.
Permanently means that the widget may not be obscured by temporary
- messages. It is is located at the far right of the status bar.
+ messages. It is located at the far right of the status bar.
\sa insertPermanentWidget(), removeWidget(), addWidget()
*/
@@ -338,7 +298,6 @@ void QStatusBar::addPermanentWidget(QWidget * widget, int stretch)
insertPermanentWidget(d_func()->items.size(), widget, stretch);
}
-
/*!
\since 4.2
@@ -353,7 +312,7 @@ void QStatusBar::addPermanentWidget(QWidget * widget, int stretch)
minimum of space.
Permanently means that the widget may not be obscured by temporary
- messages. It is is located at the far right of the status bar.
+ messages. It is located at the far right of the status bar.
\sa addPermanentWidget(), removeWidget(), addWidget()
*/
@@ -363,7 +322,7 @@ int QStatusBar::insertPermanentWidget(int index, QWidget *widget, int stretch)
return -1;
Q_D(QStatusBar);
- QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, true);
+ QStatusBarPrivate::SBItem item{widget, stretch, QStatusBarPrivate::Permanent};
int idx = d->indexToLastNonPermanentWidget();
if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index <= idx))) {
@@ -373,7 +332,7 @@ int QStatusBar::insertPermanentWidget(int index, QWidget *widget, int stretch)
d->items.insert(index, item);
reformat();
- if (!widget->isHidden() || !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
+ if (!QWidgetPrivate::get(widget)->isExplicitlyHidden())
widget->show();
return index;
@@ -395,23 +354,10 @@ void QStatusBar::removeWidget(QWidget *widget)
return;
Q_D(QStatusBar);
- bool found = false;
- QStatusBarPrivate::SBItem* item;
- for (int i=0; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item)
- break;
- if (item->w == widget) {
- d->items.removeAt(i);
- item->w->hide();
- delete item;
- found = true;
- break;
- }
- }
-
- if (found)
+ if (d->items.removeIf([widget](const auto &item) { return item.widget == widget; })) {
+ widget->hide();
reformat();
+ }
#if defined(QT_DEBUG)
else
qDebug("QStatusBar::removeWidget(): Widget not found.");
@@ -495,25 +441,22 @@ void QStatusBar::reformat()
int maxH = fontMetrics().height();
- int i;
- QStatusBarPrivate::SBItem* item;
- for (i=0,item=nullptr; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item || item->p)
+ qsizetype i;
+ for (i = 0; i < d->items.size(); ++i) {
+ const auto &item = d->items.at(i);
+ if (item.isPermanent())
break;
- l->addWidget(item->w, item->s);
- int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
+ l->addWidget(item.widget, item.stretch);
+ int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
maxH = qMax(maxH, itemH);
}
l->addStretch(0);
- for (item=nullptr; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item)
- break;
- l->addWidget(item->w, item->s);
- int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
+ for (; i < d->items.size(); ++i) {
+ const auto &item = d->items.at(i);
+ l->addWidget(item.widget, item.stretch);
+ int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
maxH = qMax(maxH, itemH);
}
#if QT_CONFIG(sizegrip)
@@ -551,7 +494,7 @@ void QStatusBar::showMessage(const QString &message, int timeout)
if (timeout > 0) {
if (!d->timer) {
d->timer = new QTimer(this);
- connect(d->timer, SIGNAL(timeout()), this, SLOT(clearMessage()));
+ connect(d->timer, &QTimer::timeout, this, &QStatusBar::clearMessage);
}
d->timer->start(timeout);
} else if (d->timer) {
@@ -577,7 +520,7 @@ void QStatusBar::clearMessage()
if (d->tempItem.isEmpty())
return;
if (d->timer) {
- qDeleteInEventHandler(d->timer);
+ delete d->timer;
d->timer = nullptr;
}
d->tempItem.clear();
@@ -617,22 +560,20 @@ void QStatusBar::hideOrShow()
Q_D(QStatusBar);
bool haveMessage = !d->tempItem.isEmpty();
- QStatusBarPrivate::SBItem* item = nullptr;
- for (int i=0; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item || item->p)
+ for (const auto &item : std::as_const(d->items)) {
+ if (item.isPermanent())
break;
- if (haveMessage && item->w->isVisible()) {
- item->w->hide();
- item->w->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- } else if (!haveMessage && !item->w->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
- item->w->show();
+ if (haveMessage && item.widget->isVisible()) {
+ item.widget->hide();
+ item.widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+ } else if (!haveMessage && !item.widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
+ item.widget->show();
}
}
emit messageChanged(d->tempItem);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
@@ -671,16 +612,15 @@ void QStatusBar::paintEvent(QPaintEvent *event)
opt.initFrom(this);
style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p, this);
- for (int i=0; i<d->items.size(); ++i) {
- QStatusBarPrivate::SBItem* item = d->items.at(i);
- if (item && item->w->isVisible() && (!haveMessage || item->p)) {
- QRect ir = item->w->geometry().adjusted(-2, -1, 2, 1);
+ for (const auto &item : std::as_const(d->items)) {
+ if (item.widget->isVisible() && (!haveMessage || item.isPermanent())) {
+ QRect ir = item.widget->geometry().adjusted(-2, -1, 2, 1);
if (event->rect().intersects(ir)) {
QStyleOption opt(0);
opt.rect = ir;
opt.palette = palette();
opt.state = QStyle::State_None;
- style()->drawPrimitive(QStyle::PE_FrameStatusBarItem, &opt, &p, item->w);
+ style()->drawPrimitive(QStyle::PE_FrameStatusBarItem, &opt, &p, item.widget);
}
}
}
@@ -706,17 +646,13 @@ bool QStatusBar::event(QEvent *e)
{
Q_D(QStatusBar);
- if (e->type() == QEvent::LayoutRequest
- ) {
+ switch (e->type()) {
+ case QEvent::LayoutRequest: {
// Calculate new strut height and call reformat() if it has changed
int maxH = fontMetrics().height();
- QStatusBarPrivate::SBItem* item = nullptr;
- for (int i=0; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item)
- break;
- int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
+ for (const auto &item : std::as_const(d->items)) {
+ const int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
maxH = qMax(maxH, itemH);
}
@@ -729,18 +665,17 @@ bool QStatusBar::event(QEvent *e)
reformat();
else
update();
+ break;
}
- if (e->type() == QEvent::ChildRemoved) {
- QStatusBarPrivate::SBItem* item = nullptr;
- for (int i=0; i<d->items.size(); ++i) {
- item = d->items.at(i);
- if (!item)
- break;
- if (item->w == ((QChildEvent*)e)->child()) {
+ case QEvent::ChildRemoved:
+ for (int i = 0; i < d->items.size(); ++i) {
+ const auto &item = d->items.at(i);
+ if (item.widget == static_cast<QChildEvent *>(e)->child())
d->items.removeAt(i);
- delete item;
- }
}
+ break;
+ default:
+ break;
}
return QWidget::event(e);
diff --git a/src/widgets/widgets/qstatusbar.h b/src/widgets/widgets/qstatusbar.h
index 976e45f9ed..2bf8e0c632 100644
--- a/src/widgets/widgets/qstatusbar.h
+++ b/src/widgets/widgets/qstatusbar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTATUSBAR_H
#define QSTATUSBAR_H
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index a390f9ec0d..0b463840ae 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "private/qlayoutengine_p.h"
#if QT_CONFIG(itemviews)
#include "qabstractitemdelegate.h"
#endif
#include "qapplication.h"
-#include "qbitmap.h"
-#include "qcursor.h"
#include "qevent.h"
#include "qpainter.h"
#include "qstyle.h"
@@ -59,7 +21,7 @@
#include "qwhatsthis.h"
#endif
#include "private/qtextengine_p.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
#ifdef Q_OS_MACOS
@@ -72,6 +34,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
namespace {
class CloseButton : public QAbstractButton
{
@@ -107,14 +71,6 @@ void QMovableTabWidget::paintEvent(QPaintEvent *e)
p.drawPixmap(0, 0, m_pixmap);
}
-inline static bool verticalTabs(QTabBar::Shape shape)
-{
- return shape == QTabBar::RoundedWest
- || shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularWest
- || shape == QTabBar::TriangularEast;
-}
-
void QTabBarPrivate::updateMacBorderMetrics()
{
#if defined(Q_OS_MACOS)
@@ -319,9 +275,9 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
returns the visual geometry of a single tab.
\table 100%
- \row \li \inlineimage fusion-tabbar.png Screenshot of a Fusion style tab bar
+ \row \li \inlineimage {fusion-tabbar.png} {Screenshot of a Fusion style tab bar}
\li A tab bar shown in the \l{Qt Widget Gallery}{Fusion widget style}.
- \row \li \inlineimage fusion-tabbar-truncated.png Screenshot of a truncated Fusion tab bar
+ \row \li \inlineimage {fusion-tabbar-truncated.png} {Screenshot of a truncated Fusion tab bar}
\li A truncated tab bar shown in the Fusion widget style.
\endtable
@@ -408,12 +364,16 @@ void QTabBarPrivate::init()
{
Q_Q(QTabBar);
leftB = new QToolButton(q);
+ leftB->setObjectName(u"ScrollLeftButton"_s);
leftB->setAutoRepeat(true);
- QObject::connect(leftB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));
+ QObjectPrivate::connect(leftB, &QToolButton::clicked,
+ this, &QTabBarPrivate::scrollTabs);
leftB->hide();
rightB = new QToolButton(q);
+ rightB->setObjectName(u"ScrollRightButton"_s);
rightB->setAutoRepeat(true);
- QObject::connect(rightB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));
+ QObjectPrivate::connect(rightB, &QToolButton::clicked,
+ this, &QTabBarPrivate::scrollTabs);
rightB->hide();
#ifdef QT_KEYPAD_NAVIGATION
if (QApplicationPrivate::keypadNavigationEnabled()) {
@@ -424,7 +384,7 @@ void QTabBarPrivate::init()
#endif
q->setFocusPolicy(Qt::TabFocus);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
leftB->setAccessibleName(QTabBar::tr("Scroll Left"));
rightB->setAccessibleName(QTabBar::tr("Scroll Right"));
#endif
@@ -438,7 +398,7 @@ int QTabBarPrivate::indexAtPos(const QPoint &p) const
Q_Q(const QTabBar);
if (q->tabRect(currentIndex).contains(p))
return currentIndex;
- for (int i = 0; i < tabList.count(); ++i)
+ for (int i = 0; i < tabList.size(); ++i)
if (tabList.at(i)->enabled && q->tabRect(i).contains(p))
return i;
return -1;
@@ -456,7 +416,7 @@ void QTabBarPrivate::layoutTabs()
int hiddenTabs = 0;
Qt::Alignment tabAlignment = Qt::Alignment(q->style()->styleHint(QStyle::SH_TabBar_Alignment, nullptr, q));
- QList<QLayoutStruct> tabChain(tabList.count() + 2);
+ QList<QLayoutStruct> tabChain(tabList.size() + 2);
// We put an empty item at the front and back and set its expansive attribute
// depending on tabAlignment and expanding.
@@ -479,7 +439,7 @@ void QTabBarPrivate::layoutTabs()
int minx = 0;
int x = 0;
int maxHeight = 0;
- for (int i = 0; i < tabList.count(); ++i) {
+ for (int i = 0; i < tabList.size(); ++i) {
const auto tab = tabList.at(i);
if (!tab->visible) {
++hiddenTabs;
@@ -510,7 +470,7 @@ void QTabBarPrivate::layoutTabs()
int miny = 0;
int y = 0;
int maxWidth = 0;
- for (int i = 0; i < tabList.count(); ++i) {
+ for (int i = 0; i < tabList.size(); ++i) {
auto tab = tabList.at(i);
if (!tab->visible) {
++hiddenTabs;
@@ -521,7 +481,7 @@ void QTabBarPrivate::layoutTabs()
y += sz.height();
maxWidth = qMax(maxWidth, sz.width());
sz = q->minimumTabSizeHint(i);
- tab->data = QRect(0, miny, sz.width(), sz.height());
+ tab->minRect = QRect(0, miny, sz.width(), sz.height());
miny += sz.height();
tabChain[tabChainIndex].init();
tabChain[tabChainIndex].sizeHint = tab->maxRect.height();
@@ -545,14 +505,14 @@ void QTabBarPrivate::layoutTabs()
&& (tabAlignment != Qt::AlignRight)
&& (tabAlignment != Qt::AlignJustify);
tabChain[tabChainIndex].empty = true;
- Q_ASSERT(tabChainIndex == tabChain.count() - 1 - hiddenTabs); // add an assert just to make sure.
+ Q_ASSERT(tabChainIndex == tabChain.size() - 1 - hiddenTabs); // add an assert just to make sure.
// Do the calculation
- qGeomCalc(tabChain, 0, tabChain.count(), 0, qMax(available, last), 0);
+ qGeomCalc(tabChain, 0, tabChain.size(), 0, qMax(available, last), 0);
// Use the results
hiddenTabs = 0;
- for (int i = 0; i < tabList.count(); ++i) {
+ for (int i = 0; i < tabList.size(); ++i) {
auto tab = tabList.at(i);
if (!tab->visible) {
tab->rect = QRect();
@@ -566,9 +526,8 @@ void QTabBarPrivate::layoutTabs()
tab->rect.setRect(0, lstruct.pos, maxExtent, lstruct.size);
}
- if (useScrollButtons && tabList.count() && last > available) {
+ if (useScrollButtons && tabList.size() && last > available) {
const QRect scrollRect = normalizedScrollRect(0);
- scrollOffset = -scrollRect.left();
Q_Q(QTabBar);
QStyleOption opt;
@@ -605,10 +564,9 @@ void QTabBarPrivate::layoutTabs()
leftB->show();
rightB->setGeometry(scrollButtonRightRect);
- rightB->setEnabled(last - scrollOffset > scrollRect.x() + scrollRect.width());
+ rightB->setEnabled(last + scrollRect.left() > scrollRect.x() + scrollRect.width());
rightB->show();
} else {
- scrollOffset = 0;
rightB->hide();
leftB->hide();
}
@@ -625,6 +583,11 @@ QRect QTabBarPrivate::normalizedScrollRect(int index)
// tab bar itself is in a different orientation.
Q_Q(QTabBar);
+ // If scrollbuttons are not visible, then there's no tear either, and
+ // the entire widget is the scroll rect.
+ if (leftB->isHidden())
+ return verticalTabs(shape) ? q->rect().transposed() : q->rect();
+
QStyleOptionTab opt;
q->initStyleOption(&opt, currentIndex);
opt.rect = q->rect();
@@ -704,25 +667,33 @@ int QTabBarPrivate::hoveredTabIndex() const
void QTabBarPrivate::makeVisible(int index)
{
Q_Q(QTabBar);
- if (!validIndex(index) || leftB->isHidden())
+ if (!validIndex(index))
return;
const QRect tabRect = tabList.at(index)->rect;
const int oldScrollOffset = scrollOffset;
const bool horiz = !verticalTabs(shape);
+ const int available = horiz ? q->width() : q->height();
const int tabStart = horiz ? tabRect.left() : tabRect.top();
const int tabEnd = horiz ? tabRect.right() : tabRect.bottom();
const int lastTabEnd = horiz ? tabList.constLast()->rect.right() : tabList.constLast()->rect.bottom();
const QRect scrollRect = normalizedScrollRect(index);
+ const QRect entireScrollRect = normalizedScrollRect(0); // ignore tears
const int scrolledTabBarStart = qMax(1, scrollRect.left() + scrollOffset);
const int scrolledTabBarEnd = qMin(lastTabEnd - 1, scrollRect.right() + scrollOffset);
- if (tabStart < scrolledTabBarStart) {
+ if (available >= lastTabEnd) {
+ // the entire tabbar fits, reset scroll
+ scrollOffset = 0;
+ } else if (tabStart < scrolledTabBarStart) {
// Tab is outside on the left, so scroll left.
scrollOffset = tabStart - scrollRect.left();
} else if (tabEnd > scrolledTabBarEnd) {
// Tab is outside on the right, so scroll right.
- scrollOffset = tabEnd - scrollRect.right();
+ scrollOffset = qMax(0, tabEnd - scrollRect.right());
+ } else if (scrollOffset + entireScrollRect.width() > lastTabEnd + 1) {
+ // fill any free space on the right without overshooting
+ scrollOffset = qMax(0, lastTabEnd - entireScrollRect.width() + 1);
}
leftB->setEnabled(scrollOffset > -scrollRect.left());
@@ -796,13 +767,13 @@ void QTabBarPrivate::autoHideTabs()
q->setVisible(q->count() > 1);
}
-void QTabBarPrivate::_q_closeTab()
+void QTabBarPrivate::closeTab()
{
Q_Q(QTabBar);
QObject *object = q->sender();
int tabToClose = -1;
QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition)q->style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, nullptr, q);
- for (int i = 0; i < tabList.count(); ++i) {
+ for (int i = 0; i < tabList.size(); ++i) {
if (closeSide == QTabBar::LeftSide) {
if (tabList.at(i)->leftWidget == object) {
tabToClose = i;
@@ -819,26 +790,29 @@ void QTabBarPrivate::_q_closeTab()
emit q->tabCloseRequested(tabToClose);
}
-void QTabBarPrivate::_q_scrollTabs()
+void QTabBarPrivate::scrollTabs()
{
Q_Q(QTabBar);
const QObject *sender = q->sender();
const bool horizontal = !verticalTabs(shape);
- const QRect scrollRect = normalizedScrollRect();
+ const QRect scrollRect = normalizedScrollRect().translated(scrollOffset, 0);
+
int i = -1;
if (sender == leftB) {
- for (i = tabList.count() - 1; i >= 0; --i) {
+ for (i = tabList.size() - 1; i >= 0; --i) {
int start = horizontal ? tabList.at(i)->rect.left() : tabList.at(i)->rect.top();
- if (start < scrollRect.left() + scrollOffset) {
+ if (start < scrollRect.left()) {
makeVisible(i);
return;
}
}
} else if (sender == rightB) {
- for (i = 0; i < tabList.count(); ++i) {
- int end = horizontal ? tabList.at(i)->rect.right() : tabList.at(i)->rect.bottom();
- if (end > scrollRect.right() + scrollOffset) {
+ for (i = 0; i < tabList.size(); ++i) {
+ const auto tabRect = tabList.at(i)->rect;
+ int start = horizontal ? tabRect.left() : tabRect.top();
+ int end = horizontal ? tabRect.right() : tabRect.bottom();
+ if (end > scrollRect.right() && start > scrollOffset) {
makeVisible(i);
return;
}
@@ -914,7 +888,7 @@ void QTabBar::setShape(Shape shape)
\property QTabBar::drawBase
\brief defines whether or not tab bar should draw its base.
- If true then QTabBar draws a base in relation to the styles overlab.
+ If true then QTabBar draws a base in relation to the styles overlap.
Otherwise only the tabs are drawn.
\sa QStyle::pixelMetric(), QStyle::PM_TabBarBaseOverlap, QStyleOptionTabBarBase
@@ -957,7 +931,7 @@ int QTabBar::addTab(const QIcon& icon, const QString &text)
/*!
Inserts a new tab with text \a text at position \a index. If \a
- index is out of range, the new tab is appened. Returns the new
+ index is out of range, the new tab is appended. Returns the new
tab's index.
*/
int QTabBar::insertTab(int index, const QString &text)
@@ -981,7 +955,7 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
{
Q_D(QTabBar);
if (!d->validIndex(index)) {
- index = d->tabList.count();
+ index = d->tabList.size();
d->tabList.append(new QTabBarPrivate::Tab(icon, text));
} else {
d->tabList.insert(index, new QTabBarPrivate::Tab(icon, text));
@@ -991,7 +965,7 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
#endif
d->firstVisible = qMax(qMin(index, d->firstVisible), 0);
d->refresh();
- if (d->tabList.count() == 1)
+ if (d->tabList.size() == 1)
setCurrentIndex(index);
else if (index <= d->currentIndex)
++d->currentIndex;
@@ -1006,15 +980,21 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
initStyleOption(&opt, index);
ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, nullptr, this);
QAbstractButton *closeButton = new CloseButton(this);
- connect(closeButton, SIGNAL(clicked()), this, SLOT(_q_closeTab()));
+ QObjectPrivate::connect(closeButton, &CloseButton::clicked,
+ d, &QTabBarPrivate::closeTab);
setTabButton(index, closeSide, closeButton);
}
- for (const auto tab : qAsConst(d->tabList)) {
+ for (const auto tab : std::as_const(d->tabList)) {
if (tab->lastTab >= index)
++tab->lastTab;
}
+ if (tabAt(d->mousePosition) == index) {
+ d->hoverIndex = index;
+ d->hoverRect = tabRect(index);
+ }
+
tabInserted(index);
d->autoHideTabs();
return index;
@@ -1051,7 +1031,7 @@ void QTabBar::removeTab(int index)
int newIndex = removedTab->lastTab;
d->tabList.removeAt(index);
delete removedTab;
- for (auto tab : qAsConst(d->tabList)) {
+ for (auto tab : std::as_const(d->tabList)) {
if (tab->lastTab == index)
tab->lastTab = -1;
if (tab->lastTab > index)
@@ -1078,8 +1058,6 @@ void QTabBar::removeTab(int index)
break;
case SelectLeftTab:
newIndex = qBound(d->firstVisible, index-1, d->lastVisible);
- if (newIndex < 0)
- newIndex = 0;
break;
default:
break;
@@ -1090,6 +1068,9 @@ void QTabBar::removeTab(int index)
int bump = d->tabList.at(newIndex)->lastTab;
setCurrentIndex(newIndex);
d->tabList.at(newIndex)->lastTab = bump;
+ } else {
+ // we had a valid current index, but there are no visible tabs left
+ emit currentChanged(-1);
}
} else {
emit currentChanged(-1);
@@ -1099,16 +1080,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);
}
@@ -1428,13 +1408,24 @@ 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 current tab
+ // will most certainly do the same). QTBUG-6905
+ if (tabRect(index).size() != tabSizeHint(index))
+ d->layoutTabs();
update();
- d->makeVisible(index);
- tab->lastTab = oldIndex;
- if (oldIndex >= 0 && oldIndex < count())
+ if (!isVisible())
+ d->layoutDirty = true;
+ else
+ d->makeVisible(index);
+ if (d->validIndex(oldIndex)) {
+ tab->lastTab = oldIndex;
d->layoutTab(oldIndex);
+ }
d->layoutTab(index);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
if (hasFocus()) {
QAccessibleEvent focusEvent(this, QAccessible::Focus);
@@ -1487,7 +1478,7 @@ void QTabBar::setIconSize(const QSize &size)
int QTabBar::count() const
{
Q_D(const QTabBar);
- return d->tabList.count();
+ return d->tabList.size();
}
@@ -1530,10 +1521,10 @@ QSize QTabBar::minimumSizeHint() const
// Compute the most-elided possible text, for minimumSizeHint
static QString computeElidedText(Qt::TextElideMode mode, const QString &text)
{
- if (text.length() <= 3)
+ if (text.size() <= 3)
return text;
- static const QLatin1String Ellipses("...");
+ static const auto Ellipses = "..."_L1;
QString ret;
switch (mode) {
case Qt::ElideRight:
@@ -1663,6 +1654,8 @@ void QTabBar::showEvent(QShowEvent *)
d->refresh();
if (!d->validIndex(d->currentIndex))
setCurrentIndex(0);
+ else
+ d->makeVisible(d->currentIndex);
d->updateMacBorderMetrics();
}
@@ -1683,33 +1676,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)
@@ -1743,7 +1732,7 @@ bool QTabBar::event(QEvent *event)
case QEvent::Shortcut: {
QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
- for (int i = 0; i < d->tabList.count(); ++i) {
+ for (int i = 0; i < d->tabList.size(); ++i) {
const QTabBarPrivate::Tab *tab = d->tabList.at(i);
if (tab->shortcutId == se->shortcutId()) {
setCurrentIndex(i);
@@ -1783,6 +1772,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:
@@ -1799,6 +1789,8 @@ void QTabBar::resizeEvent(QResizeEvent *)
Q_D(QTabBar);
if (d->layoutDirty)
updateGeometry();
+
+ // when resizing, we want to keep the scroll offset as much as possible
d->layoutTabs();
d->makeVisible(d->currentIndex);
@@ -1825,7 +1817,7 @@ void QTabBar::paintEvent(QPaintEvent *)
selected = d->pressedIndex;
const QRect scrollRect = d->normalizedScrollRect();
- for (int i = 0; i < d->tabList.count(); ++i)
+ for (int i = 0; i < d->tabList.size(); ++i)
optTabBase.tabBarRect |= tabRect(i);
optTabBase.selectedTabRect = tabRect(selected);
@@ -1833,7 +1825,21 @@ void QTabBar::paintEvent(QPaintEvent *)
if (d->drawBase)
p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase);
- for (int i = 0; i < d->tabList.count(); ++i) {
+ // the buttons might be semi-transparent or not fill their rect, but we don't
+ // want the tab underneath to shine through, so clip the button area; QTBUG-50866
+ if (d->leftB->isVisible() || d->rightB->isVisible()) {
+ QStyleOption opt;
+ opt.initFrom(this);
+ QRegion buttonRegion;
+ if (d->leftB->isVisible())
+ buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, this);
+ if (d->rightB->isVisible())
+ buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, this);
+ if (!buttonRegion.isEmpty())
+ p.setClipRegion(QRegion(rect()) - buttonRegion);
+ }
+
+ for (int i = 0; i < d->tabList.size(); ++i) {
const auto tab = d->tabList.at(i);
if (!tab->visible)
continue;
@@ -1880,21 +1886,30 @@ void QTabBar::paintEvent(QPaintEvent *)
QStyleOptionTab tabOption;
const auto tab = d->tabList.at(selected);
initStyleOption(&tabOption, selected);
+
if (d->paintWithOffsets && tab->dragOffset != 0) {
+ // if the drag offset is != 0, a move is in progress (drag or animation)
+ // => set the tab position to Moving to preserve the rect
+ tabOption.position = QStyleOptionTab::TabPosition::Moving;
+
if (vertical)
tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
else
tabOption.rect.moveLeft(tabOption.rect.x() + tab->dragOffset);
}
- if (!d->dragInProgress)
- p.drawControl(QStyle::CE_TabBarTab, tabOption);
- else {
- int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, nullptr, this);
- if (verticalTabs(d->shape))
- d->movingTab->setGeometry(tabOption.rect.adjusted(0, -taboverlap, 0, taboverlap));
- else
- d->movingTab->setGeometry(tabOption.rect.adjusted(-taboverlap, 0, taboverlap, 0));
- }
+
+ // Calculate the rect of a moving tab
+ const int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, nullptr, this);
+ const QRect &movingRect = verticalTabs(d->shape)
+ ? tabOption.rect.adjusted(0, -taboverlap, 0, taboverlap)
+ : tabOption.rect.adjusted(-taboverlap, 0, taboverlap, 0);
+
+ // If a drag is in process, set the moving tab's geometry here
+ // (in an animation, it is already set)
+ if (d->dragInProgress)
+ d->movingTab->setGeometry(movingRect);
+
+ p.drawControl(QStyle::CE_TabBarTab, tabOption);
}
// Only draw the tear indicator if necessary. Most of the time we don't need too.
@@ -1923,18 +1938,16 @@ void QTabBarPrivate::calculateFirstLastVisible(int index, bool visible, bool rem
} else {
if (remove || (index == firstVisible)) {
firstVisible = -1;
- for (int i = 0; i < tabList.count(); ++i) {
+ for (int i = 0; i < tabList.size(); ++i) {
if (tabList.at(i)->visible) {
firstVisible = i;
break;
}
}
- if (firstVisible < 0)
- firstVisible = 0;
}
if (remove || (index == lastVisible)) {
lastVisible = -1;
- for (int i = tabList.count() - 1; i >= 0; --i) {
+ for (int i = tabList.size() - 1; i >= 0; --i) {
if (tabList.at(i)->visible) {
lastVisible = i;
break;
@@ -1952,7 +1965,7 @@ void QTabBarPrivate::calculateFirstLastVisible(int index, bool visible, bool rem
int QTabBarPrivate::selectNewCurrentIndexFrom(int fromIndex)
{
int newindex = -1;
- for (int i = fromIndex; i < tabList.count(); ++i) {
+ for (int i = fromIndex; i < tabList.size(); ++i) {
if (at(i)->visible && at(i)->enabled) {
newindex = i;
break;
@@ -2048,7 +2061,7 @@ void QTabBar::moveTab(int from, int to)
d->tabList.move(from, to);
// update lastTab locations
- for (const auto tab : qAsConst(d->tabList))
+ for (const auto tab : std::as_const(d->tabList))
tab->lastTab = d->calculateNewPosition(from, to, tab->lastTab);
// update external variables
@@ -2203,7 +2216,8 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
}
}
// Buttons needs to follow the dragged tab
- d->layoutTab(d->pressedIndex);
+ if (d->pressedIndex != -1)
+ d->layoutTab(d->pressedIndex);
update();
}
@@ -2235,7 +2249,7 @@ void QTabBarPrivate::setupMovableTab()
QStyleOptionTab tab;
q->initStyleOption(&tab, pressedIndex);
- tab.position = QStyleOptionTab::OnlyOneTab;
+ tab.position = QStyleOptionTab::Moving;
if (verticalTabs(shape))
tab.rect.moveTopLeft(QPoint(0, taboverlap));
else
@@ -2266,7 +2280,7 @@ void QTabBarPrivate::moveTabFinished(int index)
bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
bool allAnimationsFinished = true;
#if QT_CONFIG(animation)
- for (const auto tab : qAsConst(tabList)) {
+ for (const auto tab : std::as_const(tabList)) {
if (tab->animation && tab->animation->state() == QAbstractAnimation::Running) {
allAnimationsFinished = false;
break;
@@ -2276,7 +2290,7 @@ void QTabBarPrivate::moveTabFinished(int index)
if (allAnimationsFinished && cleanup) {
if (movingTab)
movingTab->setVisible(false); // We might not get a mouse release
- for (auto tab : qAsConst(tabList)) {
+ for (auto tab : std::as_const(tabList)) {
tab->dragOffset = 0;
}
if (pressedIndex != -1 && movable) {
@@ -2365,10 +2379,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);
}
}
@@ -2378,7 +2439,7 @@ void QTabBarPrivate::setCurrentNextEnabledIndex(int offset)
{
Q_Q(QTabBar);
for (int index = currentIndex + offset; validIndex(index); index += offset) {
- if (tabList.at(index)->enabled) {
+ if (tabList.at(index)->enabled && tabList.at(index)->visible) {
q->setCurrentIndex(index);
break;
}
@@ -2431,7 +2492,7 @@ void QTabBar::timerEvent(QTimerEvent *event)
This property controls how items are elided when there is not
enough space to show them for a given tab bar size.
- By default the value is style dependent.
+ By default the value is style-dependent.
\sa QTabWidget::elideMode, usesScrollButtons, QStyle::SH_TabBar_ElideMode
*/
@@ -2460,7 +2521,7 @@ void QTabBar::setElideMode(Qt::TextElideMode mode)
When there are too many tabs in a tab bar for its size, the tab bar can either choose
to expand its size or to add buttons that allow you to scroll through the tabs.
- By default the value is style dependant.
+ By default the value is style-dependent.
\sa elideMode, QTabWidget::usesScrollButtons, QStyle::SH_TabBar_PreferNoArrows
*/
@@ -2507,7 +2568,7 @@ void QTabBar::setTabsClosable(bool closable)
d->closeButtonOnTabs = closable;
ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, nullptr, this);
if (!closable) {
- for (auto tab : qAsConst(d->tabList)) {
+ for (auto tab : std::as_const(d->tabList)) {
if (closeSide == LeftSide && tab->leftWidget) {
tab->leftWidget->deleteLater();
tab->leftWidget = nullptr;
@@ -2519,12 +2580,13 @@ void QTabBar::setTabsClosable(bool closable)
}
} else {
bool newButtons = false;
- for (int i = 0; i < d->tabList.count(); ++i) {
+ for (int i = 0; i < d->tabList.size(); ++i) {
if (tabButton(i, closeSide))
continue;
newButtons = true;
QAbstractButton *closeButton = new CloseButton(this);
- connect(closeButton, SIGNAL(clicked()), this, SLOT(_q_closeTab()));
+ QObjectPrivate::connect(closeButton, &CloseButton::clicked,
+ d, &QTabBarPrivate::closeTab);
setTabButton(i, closeSide, closeButton);
}
if (newButtons)
@@ -2714,10 +2776,11 @@ void QTabBar::setChangeCurrentOnDrag(bool change)
/*!
Sets \a widget on the tab \a index. The widget is placed
- on the left or right hand side depending upon the \a position.
+ on the left or right hand side depending on the \a position.
\since 4.5
- Any previously set widget in \a position is hidden.
+ Any previously set widget in \a position is hidden. Setting \a widget
+ to \nullptr will hide the current widget at \a position.
The tab bar will take ownership of the widget and so all widgets set here
will be deleted by the tab bar when it is destroyed unless you separately
@@ -2728,7 +2791,7 @@ void QTabBar::setChangeCurrentOnDrag(bool change)
void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget)
{
Q_D(QTabBar);
- if (index < 0 || index >= d->tabList.count())
+ if (index < 0 || index >= d->tabList.size())
return;
if (widget) {
widget->setParent(this);
@@ -2765,7 +2828,7 @@ QWidget *QTabBar::tabButton(int index, ButtonPosition position) const
return nullptr;
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
/*!
Sets the accessibleName of the tab at position \a index to \a name.
*/
@@ -2791,7 +2854,7 @@ QString QTabBar::accessibleTabName(int index) const
return tab->accessibleName;
return QString();
}
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
CloseButton::CloseButton(QWidget *parent)
: QAbstractButton(parent)
diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h
index 7feea6d2a0..2759d5a318 100644
--- a/src/widgets/widgets/qtabbar.h
+++ b/src/widgets/widgets/qtabbar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABBAR_H
#define QTABBAR_H
@@ -63,7 +27,8 @@ class Q_WIDGETS_EXPORT QTabBar: public QWidget
Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
Q_PROPERTY(bool usesScrollButtons READ usesScrollButtons WRITE setUsesScrollButtons)
Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
- Q_PROPERTY(SelectionBehavior selectionBehaviorOnRemove READ selectionBehaviorOnRemove WRITE setSelectionBehaviorOnRemove)
+ Q_PROPERTY(SelectionBehavior selectionBehaviorOnRemove READ selectionBehaviorOnRemove
+ WRITE setSelectionBehaviorOnRemove)
Q_PROPERTY(bool expanding READ expanding WRITE setExpanding)
Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
@@ -175,7 +140,7 @@ public:
bool changeCurrentOnDrag() const;
void setChangeCurrentOnDrag(bool change);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QString accessibleTabName(int index) const;
void setAccessibleTabName(int index, const QString &name);
#endif
@@ -214,14 +179,12 @@ protected:
void timerEvent(QTimerEvent *event) override;
virtual void initStyleOption(QStyleOptionTab *option, int tabIndex) const;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
friend class QAccessibleTabBar;
#endif
private:
Q_DISABLE_COPY(QTabBar)
Q_DECLARE_PRIVATE(QTabBar)
- Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
- Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index eb1339a802..d76f439bd7 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABBAR_P_H
#define QTABBAR_P_H
@@ -101,6 +65,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
@@ -151,7 +119,7 @@ public:
#if QT_CONFIG(whatsthis)
QString whatsThis;
#endif
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QString accessibleName;
#endif
QIcon icon;
@@ -216,11 +184,11 @@ public:
int indexAtPos(const QPoint &p) const;
inline bool isAnimated() const { Q_Q(const QTabBar); return q->style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, q) > 0; }
- inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); }
+ inline bool validIndex(int index) const { return index >= 0 && index < tabList.size(); }
void setCurrentNextEnabledIndex(int offset);
- void _q_scrollTabs();
- void _q_closeTab();
+ void scrollTabs();
+ void closeTab();
void moveTab(int index, int offset);
void moveTabFinished(int index);
@@ -277,6 +245,14 @@ public:
};
+constexpr inline bool verticalTabs(QTabBar::Shape shape) noexcept
+{
+ return shape == QTabBar::RoundedWest
+ || shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularWest
+ || shape == QTabBar::TriangularEast;
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 34f9384cdf..5e7c266ef6 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtabwidget.h"
@@ -55,6 +19,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\class QTabWidget
\brief The QTabWidget class provides a stack of tabbed widgets.
@@ -190,9 +156,9 @@ public:
QTabWidgetPrivate();
~QTabWidgetPrivate();
void updateTabBarPosition();
- void _q_showTab(int);
- void _q_removeTab(int);
- void _q_tabMoved(int from, int to);
+ void showTab(int);
+ void removeTab(int);
+ void tabMoved(int from, int to);
void init();
bool isAutoHidden() const
{
@@ -226,14 +192,14 @@ void QTabWidgetPrivate::init()
Q_Q(QTabWidget);
stack = new QStackedWidget(q);
- stack->setObjectName(QLatin1String("qt_tabwidget_stackedwidget"));
+ stack->setObjectName("qt_tabwidget_stackedwidget"_L1);
stack->setLineWidth(0);
// hack so that QMacStyle::layoutSpacing() can detect tab widget pages
stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::TabWidget));
- QObject::connect(stack, SIGNAL(widgetRemoved(int)), q, SLOT(_q_removeTab(int)));
+ QObjectPrivate::connect(stack, &QStackedWidget::widgetRemoved, this, &QTabWidgetPrivate::removeTab);
QTabBar *tabBar = new QTabBar(q);
- tabBar->setObjectName(QLatin1String("qt_tabwidget_tabbar"));
+ tabBar->setObjectName("qt_tabwidget_tabbar"_L1);
tabBar->setDrawBase(false);
q->setTabBar(tabBar);
@@ -754,17 +720,17 @@ void QTabWidget::setTabBar(QTabBar* tb)
delete d->tabs;
d->tabs = tb;
setFocusProxy(d->tabs);
- connect(d->tabs, SIGNAL(currentChanged(int)),
- this, SLOT(_q_showTab(int)));
- connect(d->tabs, SIGNAL(tabMoved(int,int)),
- this, SLOT(_q_tabMoved(int,int)));
- connect(d->tabs, SIGNAL(tabBarClicked(int)),
- this, SIGNAL(tabBarClicked(int)));
- connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)),
- this, SIGNAL(tabBarDoubleClicked(int)));
+ QObjectPrivate::connect(d->tabs, &QTabBar::currentChanged,
+ d, &QTabWidgetPrivate::showTab);
+ QObjectPrivate::connect(d->tabs, &QTabBar::tabMoved,
+ d, &QTabWidgetPrivate::tabMoved);
+ connect(d->tabs, &QTabBar::tabBarClicked,
+ this, &QTabWidget::tabBarClicked);
+ connect(d->tabs, &QTabBar::tabBarDoubleClicked,
+ this, &QTabWidget::tabBarDoubleClicked);
if (d->tabs->tabsClosable())
- connect(d->tabs, SIGNAL(tabCloseRequested(int)),
- this, SIGNAL(tabCloseRequested(int)));
+ connect(d->tabs, &QTabBar::tabCloseRequested,
+ this, &QTabWidget::tabCloseRequested);
tb->setExpanding(!documentMode());
setUpLayout();
}
@@ -786,7 +752,7 @@ QTabBar* QTabWidget::tabBar() const
sized.
*/
-void QTabWidgetPrivate::_q_showTab(int index)
+void QTabWidgetPrivate::showTab(int index)
{
Q_Q(QTabWidget);
if (index < stack->count() && index >= 0)
@@ -794,7 +760,7 @@ void QTabWidgetPrivate::_q_showTab(int index)
emit q->currentChanged(index);
}
-void QTabWidgetPrivate::_q_removeTab(int index)
+void QTabWidgetPrivate::removeTab(int index)
{
Q_Q(QTabWidget);
tabs->removeTab(index);
@@ -802,7 +768,7 @@ void QTabWidgetPrivate::_q_removeTab(int index)
q->tabRemoved(index);
}
-void QTabWidgetPrivate::_q_tabMoved(int from, int to)
+void QTabWidgetPrivate::tabMoved(int from, int to)
{
const QSignalBlocker blocker(stack);
QWidget *w = stack->widget(from);
@@ -1173,7 +1139,7 @@ void QTabWidget::keyPressEvent(QKeyEvent *e)
) {
page = 0;
}
- if (d->tabs->isTabEnabled(page)) {
+ if (d->tabs->isTabEnabled(page) && d->tabs->isTabVisible(page)) {
setCurrentIndex(page);
break;
}
@@ -1343,7 +1309,7 @@ void QTabWidget::setIconSize(const QSize &size)
This property controls how items are elided when there is not
enough space to show them for a given tab bar size.
- By default the value is style dependant.
+ By default the value is style dependent.
\sa QTabBar::elideMode, usesScrollButtons, QStyle::SH_TabBar_ElideMode
*/
@@ -1366,7 +1332,7 @@ void QTabWidget::setElideMode(Qt::TextElideMode mode)
When there are too many tabs in a tab bar for its size, the tab bar can either choose
to expand its size or to add buttons that allow you to scroll through the tabs.
- By default the value is style dependant.
+ By default the value is style dependent.
\sa elideMode, QTabBar::usesScrollButtons, QStyle::SH_TabBar_PreferNoArrows
*/
@@ -1441,6 +1407,20 @@ void QTabWidget::clear()
removeTab(0);
}
+QTabBar::Shape _q_tb_tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position)
+{
+ const bool rounded = (shape == QTabWidget::Rounded);
+ if (position == QTabWidget::North)
+ return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth;
+ if (position == QTabWidget::South)
+ return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth;
+ if (position == QTabWidget::East)
+ return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast;
+ if (position == QTabWidget::West)
+ return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest;
+ return QTabBar::RoundedNorth;
+}
+
QT_END_NAMESPACE
#include "moc_qtabwidget.cpp"
diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h
index 7de02d3b7e..c813f8d921 100644
--- a/src/widgets/widgets/qtabwidget.h
+++ b/src/widgets/widgets/qtabwidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABWIDGET_H
#define QTABWIDGET_H
@@ -177,9 +141,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QTabWidget)
Q_DISABLE_COPY(QTabWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_showTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_removeTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_tabMoved(int, int))
void setUpLayout(bool = false);
};
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index 6b05156ea3..2c01ed2b26 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtextbrowser.h"
#include "qtextedit_p.h"
@@ -54,9 +18,12 @@
#endif
#include <qtextobject.h>
#include <qdesktopservices.h>
+#include <qstringconverter.h>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
static inline bool shouldEnableInputMethod(QTextBrowser *texbrowser)
{
#if defined (Q_OS_ANDROID)
@@ -79,6 +46,11 @@ public:
, lastKeypadScrollValue(-1)
#endif
{}
+ ~QTextBrowserPrivate()
+ {
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+ }
void init();
@@ -97,13 +69,13 @@ public:
HistoryEntry history(int i) const
{
if (i <= 0)
- if (-i < stack.count())
- return stack[stack.count()+i-1];
+ if (-i < stack.size())
+ return stack[stack.size()+i-1];
else
return HistoryEntry();
else
- if (i <= forwardStack.count())
- return forwardStack[forwardStack.count()-i];
+ if (i <= forwardStack.size())
+ return forwardStack[forwardStack.size()-i];
else
return HistoryEntry();
}
@@ -136,14 +108,14 @@ public:
QString findFile(const QUrl &name) const;
- inline void _q_documentModified()
+ inline void documentModified()
{
textOrSourceChanged = true;
forceLoadOnSourceChange = !currentURL.path().isEmpty();
}
- void _q_activateAnchor(const QString &href);
- void _q_highlightLink(const QString &href);
+ void activateAnchor(const QString &href);
+ void highlightLink(const QString &href);
void setSource(const QUrl &url, QTextDocument::ResourceType type);
@@ -162,20 +134,21 @@ public:
Q_Q(QTextBrowser);
emit q->highlighted(url);
}
+ std::array<QMetaObject::Connection, 3> connections;
};
Q_DECLARE_TYPEINFO(QTextBrowserPrivate::HistoryEntry, Q_RELOCATABLE_TYPE);
QString QTextBrowserPrivate::findFile(const QUrl &name) const
{
QString fileName;
- if (name.scheme() == QLatin1String("qrc")) {
- fileName = QLatin1String(":/") + name.path();
+ if (name.scheme() == "qrc"_L1) {
+ fileName = ":/"_L1 + name.path();
} else if (name.scheme().isEmpty()) {
fileName = name.path();
} else {
#if defined(Q_OS_ANDROID)
- if (name.scheme() == QLatin1String("assets"))
- fileName = QLatin1String("assets:") + name.path();
+ if (name.scheme() == "assets"_L1)
+ fileName = "assets:"_L1 + name.path();
else
#endif
fileName = name.toLocalFile();
@@ -187,9 +160,9 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const
if (QFileInfo(fileName).isAbsolute())
return fileName;
- for (QString path : qAsConst(searchPaths)) {
- if (!path.endsWith(QLatin1Char('/')))
- path.append(QLatin1Char('/'));
+ for (QString path : std::as_const(searchPaths)) {
+ if (!path.endsWith(u'/'))
+ path.append(u'/');
path.append(fileName);
if (QFileInfo(path).isReadable())
return path;
@@ -206,7 +179,7 @@ QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const
// For the second case QUrl can merge "#someanchor" with "foo.html"
// correctly to "foo.html#someanchor"
if (!(currentURL.isRelative()
- || (currentURL.scheme() == QLatin1String("file")
+ || (currentURL.scheme() == "file"_L1
&& !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
|| (url.hasFragment() && url.path().isEmpty())) {
return currentURL.resolved(url);
@@ -223,7 +196,7 @@ QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const
return url;
}
-void QTextBrowserPrivate::_q_activateAnchor(const QString &href)
+void QTextBrowserPrivate::activateAnchor(const QString &href)
{
if (href.isEmpty())
return;
@@ -244,11 +217,11 @@ void QTextBrowserPrivate::_q_activateAnchor(const QString &href)
#ifndef QT_NO_DESKTOPSERVICES
bool isFileScheme =
- url.scheme() == QLatin1String("file")
+ url.scheme() == "file"_L1
#if defined(Q_OS_ANDROID)
- || url.scheme() == QLatin1String("assets")
+ || url.scheme() == "assets"_L1
#endif
- || url.scheme() == QLatin1String("qrc");
+ || url.scheme() == "qrc"_L1;
if ((openExternalLinks && !isFileScheme && !url.isRelative())
|| (url.isRelative() && !currentURL.isRelative() && !isFileScheme)) {
QDesktopServices::openUrl(url);
@@ -264,7 +237,7 @@ void QTextBrowserPrivate::_q_activateAnchor(const QString &href)
q->setSource(url);
}
-void QTextBrowserPrivate::_q_highlightLink(const QString &anchor)
+void QTextBrowserPrivate::highlightLink(const QString &anchor)
{
if (anchor.isEmpty()) {
#ifndef QT_NO_CURSOR
@@ -303,9 +276,9 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType
QString fileName = url.fileName();
if (type == QTextDocument::UnknownResource) {
#if QT_CONFIG(textmarkdownreader)
- if (fileName.endsWith(QLatin1String(".md")) ||
- fileName.endsWith(QLatin1String(".mkd")) ||
- fileName.endsWith(QLatin1String(".markdown")))
+ if (fileName.endsWith(".md"_L1) ||
+ fileName.endsWith(".mkd"_L1) ||
+ fileName.endsWith(".markdown"_L1))
type = QTextDocument::MarkdownResource;
else
#endif
@@ -321,12 +294,11 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType
} else if (data.userType() == QMetaType::QByteArray) {
QByteArray ba = data.toByteArray();
if (type == QTextDocument::HtmlResource) {
- auto encoding = QStringConverter::encodingForHtml(ba);
- if (!encoding)
+ auto decoder = QStringDecoder::decoderForHtml(ba);
+ if (!decoder.isValid())
// fall back to utf8
- encoding = QStringDecoder::Utf8;
- QStringDecoder toUtf16(*encoding);
- txt = toUtf16(ba);
+ decoder = QStringDecoder(QStringDecoder::Utf8);
+ txt = decoder(ba);
} else {
txt = QString::fromUtf8(ba);
}
@@ -335,8 +307,8 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType
qWarning("QTextBrowser: No document for %s", url.toString().toLatin1().constData());
if (q->isVisible()) {
- const QStringView firstTag = QStringView{txt}.left(txt.indexOf(QLatin1Char('>')) + 1);
- if (firstTag.startsWith(QLatin1String("<qt")) && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {
+ const QStringView firstTag = QStringView{txt}.left(txt.indexOf(u'>') + 1);
+ if (firstTag.startsWith("<qt"_L1) && firstTag.contains("type"_L1) && firstTag.contains("detail"_L1)) {
#ifndef QT_NO_CURSOR
QGuiApplication::restoreOverrideCursor();
#endif
@@ -704,11 +676,14 @@ void QTextBrowserPrivate::init()
q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q));
q->setUndoRedoEnabled(false);
viewport->setMouseTracking(true);
- QObject::connect(q->document(), SIGNAL(contentsChanged()), q, SLOT(_q_documentModified()));
- QObject::connect(control, SIGNAL(linkActivated(QString)),
- q, SLOT(_q_activateAnchor(QString)));
- QObject::connect(control, SIGNAL(linkHovered(QString)),
- q, SLOT(_q_highlightLink(QString)));
+ connections = {
+ QObjectPrivate::connect(q->document(), &QTextDocument::contentsChanged,
+ this, &QTextBrowserPrivate::documentModified),
+ QObjectPrivate::connect(control, &QWidgetTextControl::linkActivated,
+ this, &QTextBrowserPrivate::activateAnchor),
+ QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered,
+ this, &QTextBrowserPrivate::highlightLink),
+ };
}
/*!
@@ -862,11 +837,11 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type
entry.vpos = 0;
d->stack.push(entry);
- emit backwardAvailable(d->stack.count() > 1);
+ emit backwardAvailable(d->stack.size() > 1);
if (!d->forwardStack.isEmpty() && d->forwardStack.top().url == url) {
d->forwardStack.pop();
- emit forwardAvailable(d->forwardStack.count() > 0);
+ emit forwardAvailable(d->forwardStack.size() > 0);
} else {
d->forwardStack.clear();
emit forwardAvailable(false);
@@ -907,7 +882,7 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type
being the new source.
Source changes happen both programmatically when calling
- setSource(), forward(), backword() or home() or when the user
+ setSource(), forward(), backward() or home() or when the user
clicks on links or presses the equivalent key sequences.
*/
@@ -940,14 +915,14 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type
void QTextBrowser::backward()
{
Q_D(QTextBrowser);
- if (d->stack.count() <= 1)
+ if (d->stack.size() <= 1)
return;
// Update the history entry
d->forwardStack.push(d->createHistoryEntry());
d->stack.pop(); // throw away the old version of the current entry
d->restoreHistoryEntry(d->stack.top()); // previous entry
- emit backwardAvailable(d->stack.count() > 1);
+ emit backwardAvailable(d->stack.size() > 1);
emit forwardAvailable(true);
emit historyChanged();
}
@@ -1190,7 +1165,7 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)
bool QTextBrowser::isBackwardAvailable() const
{
Q_D(const QTextBrowser);
- return d->stack.count() > 1;
+ return d->stack.size() > 1;
}
/*!
@@ -1277,7 +1252,7 @@ QString QTextBrowser::historyTitle(int i) const
int QTextBrowser::forwardHistoryCount() const
{
Q_D(const QTextBrowser);
- return d->forwardStack.count();
+ return d->forwardStack.size();
}
/*!
@@ -1288,7 +1263,7 @@ int QTextBrowser::forwardHistoryCount() const
int QTextBrowser::backwardHistoryCount() const
{
Q_D(const QTextBrowser);
- return d->stack.count()-1;
+ return d->stack.size()-1;
}
/*!
diff --git a/src/widgets/widgets/qtextbrowser.h b/src/widgets/widgets/qtextbrowser.h
index 1923129870..f8e9c0c301 100644
--- a/src/widgets/widgets/qtextbrowser.h
+++ b/src/widgets/widgets/qtextbrowser.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTBROWSER_H
#define QTEXTBROWSER_H
@@ -118,9 +82,6 @@ protected:
private:
Q_DISABLE_COPY(QTextBrowser)
Q_DECLARE_PRIVATE(QTextBrowser)
- Q_PRIVATE_SLOT(d_func(), void _q_documentModified())
- Q_PRIVATE_SLOT(d_func(), void _q_activateAnchor(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_highlightLink(const QString &))
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 2d3f98b4b9..90884dd438 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtextedit_p.h"
#if QT_CONFIG(lineedit)
@@ -58,7 +22,7 @@
#endif
#include <qstyle.h>
#include <qtimer.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
#include "private/qtextdocumentlayout_p.h"
@@ -124,8 +88,7 @@ QTextEditPrivate::QTextEditPrivate()
: control(nullptr),
autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
- wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
- textFormat(Qt::AutoText)
+ wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0)
{
ignoreAutomaticScrollbarAdjustment = false;
preferRichText = false;
@@ -133,6 +96,12 @@ QTextEditPrivate::QTextEditPrivate()
inDrag = false;
}
+QTextEditPrivate::~QTextEditPrivate()
+{
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+}
+
void QTextEditPrivate::createAutoBulletList()
{
QTextCursor cursor = control->textCursor();
@@ -159,24 +128,34 @@ void QTextEditPrivate::init(const QString &html)
control = new QTextEditControl(q);
control->setPalette(q->palette());
- QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
- QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
- QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
- q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
- QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
-#if QT_CONFIG(cursor)
- QObject::connect(control, SIGNAL(blockMarkerHovered(QTextBlock)), q, SLOT(_q_hoveredBlockWithMarkerChanged(QTextBlock)));
-#endif
-
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+ connections = {
+ QObjectPrivate::connect(control, &QTextEditControl::documentSizeChanged,
+ this, &QTextEditPrivate::adjustScrollbars),
+ QObjectPrivate::connect(control, &QTextEditControl::updateRequest,
+ this, &QTextEditPrivate::repaintContents),
+ QObjectPrivate::connect(control, &QTextEditControl::visibilityRequest,
+ this, &QTextEditPrivate::ensureVisible),
+ QObjectPrivate::connect(control, &QTextEditControl::blockMarkerHovered,
+ this, &QTextEditPrivate::hoveredBlockWithMarkerChanged),
+ QObjectPrivate::connect(control, &QTextEditControl::cursorPositionChanged,
+ this, &QTextEditPrivate::cursorPositionChanged),
+ QObject::connect(control, &QTextEditControl::microFocusChanged,
+ q, [q]() { q->updateMicroFocus(); }),
+ QObject::connect(control, &QTextEditControl::currentCharFormatChanged,
+ q, &QTextEdit::currentCharFormatChanged),
+ QObject::connect(control, &QTextEditControl::textChanged,
+ q, &QTextEdit::textChanged),
+ QObject::connect(control, &QTextEditControl::undoAvailable,
+ q, &QTextEdit::undoAvailable),
+ QObject::connect(control, &QTextEditControl::redoAvailable,
+ q, &QTextEdit::redoAvailable),
+ QObject::connect(control, &QTextEditControl::copyAvailable,
+ q, &QTextEdit::copyAvailable),
+ QObject::connect(control, &QTextEditControl::selectionChanged,
+ q, &QTextEdit::selectionChanged),
+ QObject::connect(control, &QTextEditControl::textChanged,
+ q, [q]() { q->updateMicroFocus(); }),
+ };
QTextDocument *doc = control->document();
// set a null page size initially to avoid any relayouting until the textedit
@@ -206,7 +185,7 @@ void QTextEditPrivate::init(const QString &html)
#endif
}
-void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
+void QTextEditPrivate::repaintContents(const QRectF &contentsRect)
{
if (!contentsRect.isValid()) {
viewport->update();
@@ -224,19 +203,19 @@ void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
viewport->update(r);
}
-void QTextEditPrivate::_q_cursorPositionChanged()
+void QTextEditPrivate::cursorPositionChanged()
{
Q_Q(QTextEdit);
emit q->cursorPositionChanged();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextCursorEvent event(q, q->textCursor().position());
QAccessible::updateAccessibility(&event);
#endif
}
-#if QT_CONFIG(cursor)
-void QTextEditPrivate::_q_hoveredBlockWithMarkerChanged(const QTextBlock &block)
+void QTextEditPrivate::hoveredBlockWithMarkerChanged(const QTextBlock &block)
{
+#if QT_CONFIG(cursor)
Q_Q(QTextEdit);
Qt::CursorShape cursor = cursorToRestoreAfterHover;
if (block.isValid() && !q->isReadOnly()) {
@@ -248,8 +227,8 @@ void QTextEditPrivate::_q_hoveredBlockWithMarkerChanged(const QTextBlock &block)
}
}
viewport->setCursor(cursor);
-}
#endif
+}
void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
{
@@ -298,7 +277,7 @@ static QSize documentSize(QWidgetTextControl *control)
return docSize;
}
-void QTextEditPrivate::_q_adjustScrollbars()
+void QTextEditPrivate::adjustScrollbars()
{
if (ignoreAutomaticScrollbarAdjustment)
return;
@@ -348,12 +327,12 @@ void QTextEditPrivate::_q_adjustScrollbars()
#endif
// rect is in content coordinates
-void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
+void QTextEditPrivate::ensureVisible(const QRectF &_rect)
{
const QRect rect = _rect.toRect();
if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
|| (hbar->isVisible() && hbar->maximum() < rect.right()))
- _q_adjustScrollbars();
+ adjustScrollbars();
const int visibleWidth = viewport->width();
const int visibleHeight = viewport->height();
const bool rtl = q_func()->isRightToLeft();
@@ -576,7 +555,7 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
of the movement keystrokes, for example, \e{Shift+Right}
will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
- \sa QTextDocument, QTextCursor, {Qt Widgets - Application Example},
+ \sa QTextDocument, QTextCursor,
{Syntax Highlighter Example}, {Rich Text Processing}
*/
@@ -749,7 +728,8 @@ QColor QTextEdit::textColor() const
QColor QTextEdit::textBackgroundColor() const
{
Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().background().color();
+ const QBrush &brush = d->control->textCursor().charFormat().background();
+ return brush.style() == Qt::NoBrush ? Qt::transparent : brush.color();
}
/*!
@@ -1100,30 +1080,38 @@ void QTextEdit::selectAll()
bool QTextEdit::event(QEvent *e)
{
Q_D(QTextEdit);
-#ifndef QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ContextMenu
- && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
- Q_D(QTextEdit);
- ensureCursorVisible();
- const QPoint cursorPos = cursorRect().center();
- QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
- ce.setAccepted(e->isAccepted());
- const bool result = QAbstractScrollArea::event(&ce);
- e->setAccepted(ce.isAccepted());
- return result;
- } else if (e->type() == QEvent::ShortcutOverride
- || e->type() == QEvent::ToolTip) {
+ switch (e->type()) {
+ case QEvent::ShortcutOverride:
+ case QEvent::ToolTip:
d->sendControlEvent(e);
- }
-#else
- Q_UNUSED(d);
+ break;
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ d->control->setPalette(palette());
+ break;
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu:
+ if (static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
+ ensureCursorVisible();
+ const QPoint cursorPos = cursorRect().center();
+ QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
+ ce.setAccepted(e->isAccepted());
+ const bool result = QAbstractScrollArea::event(&ce);
+ e->setAccepted(ce.isAccepted());
+ return result;
+ }
+ break;
#endif // QT_NO_CONTEXTMENU
#ifdef QT_KEYPAD_NAVIGATION
- if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
+ case QEvent::EnterEditFocus:
+ case QEvent::LeaveEditFocus:
if (QApplicationPrivate::keypadNavigationEnabled())
d->sendControlEvent(e);
- }
+ break;
#endif
+ default:
+ break;
+ }
return QAbstractScrollArea::event(e);
}
@@ -1407,8 +1395,8 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
const QString text = e->text();
if (cursor.atBlockStart()
&& (d->autoFormatting & AutoBulletList)
- && (text.length() == 1)
- && (text.at(0) == QLatin1Char('-') || text.at(0) == QLatin1Char('*'))
+ && (text.size() == 1)
+ && (text.at(0) == u'-' || text.at(0) == u'*')
&& (!cursor.currentList())) {
d->createAutoBulletList();
@@ -1456,8 +1444,10 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
*/
void QTextEdit::keyReleaseEvent(QKeyEvent *e)
{
-#ifdef QT_KEYPAD_NAVIGATION
Q_D(QTextEdit);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel();
+#ifdef QT_KEYPAD_NAVIGATION
if (QApplicationPrivate::keypadNavigationEnabled()) {
if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
&& d->deleteAllTimer.isActive()) {
@@ -1511,7 +1501,7 @@ void QTextEdit::resizeEvent(QResizeEvent *e)
&& alignmentProperty.userType() == QMetaType::Bool
&& !alignmentProperty.toBool()) {
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
return;
}
}
@@ -1520,7 +1510,7 @@ void QTextEdit::resizeEvent(QResizeEvent *e)
&& e->oldSize().width() != e->size().width())
d->relayoutDocument();
else
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
}
void QTextEditPrivate::relayoutDocument()
@@ -1542,7 +1532,7 @@ void QTextEditPrivate::relayoutDocument()
else
lastUsedSize = layout->documentSize().toSize();
- // ignore calls to _q_adjustScrollbars caused by an emission of the
+ // ignore calls to adjustScrollbars caused by an emission of the
// usedSizeChanged() signal in the layout, as we're calling it
// later on our own anyway (or deliberately not) .
const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
@@ -1581,7 +1571,7 @@ void QTextEditPrivate::relayoutDocument()
// its size. So a layout with less width _can_ take up less vertical space, too.
// If the wider case causes a vertical scroll bar to appear and the narrower one
// (narrower because the vertical scroll bar takes up horizontal space)) to disappear
- // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
+ // again then we have an endless loop, as adjustScrollbars sets new ranges on the
// scroll bars, the QAbstractScrollArea will find out about it and try to show/hide
// the scroll bars again. That's why we try to detect this case here and break out.
//
@@ -1594,7 +1584,7 @@ void QTextEditPrivate::relayoutDocument()
&& usedSize.height() <= viewport->height())
return;
- _q_adjustScrollbars();
+ adjustScrollbars();
}
void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
@@ -1632,6 +1622,8 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
This event handler can be reimplemented in a subclass to receive paint events passed in \a event.
It is usually unnecessary to reimplement this function in a subclass of QTextEdit.
+\note If you create a QPainter, it must operate on the \l{QAbstractScrollArea::}{viewport()}.
+
\warning The underlying text document must not be modified from within a reimplementation
of this function.
*/
@@ -1642,12 +1634,6 @@ void QTextEdit::paintEvent(QPaintEvent *e)
d->paint(&p, e);
}
-void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
-{
- Q_Q(QTextEdit);
- emit q->currentCharFormatChanged(fmt);
-}
-
void QTextEditPrivate::updateDefaultTextOption()
{
QTextDocument *doc = control->document();
@@ -1806,6 +1792,10 @@ void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
setEditFocus(true);
#endif
d->sendControlEvent(e);
+ const bool emptyEvent = e->preeditString().isEmpty() && e->commitString().isEmpty()
+ && e->attributes().isEmpty();
+ if (emptyEvent)
+ return;
ensureCursorVisible();
}
@@ -1833,8 +1823,10 @@ QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argume
{
Q_D(const QTextEdit);
switch (query) {
- case Qt::ImHints:
- case Qt::ImInputItemClipRectangle:
+ case Qt::ImEnabled:
+ return isEnabled() && !isReadOnly();
+ case Qt::ImHints:
+ case Qt::ImInputItemClipRectangle:
return QWidget::inputMethodQuery(query);
case Qt::ImReadOnly:
return isReadOnly();
@@ -2066,6 +2058,12 @@ void QTextEdit::setOverwriteMode(bool overwrite)
\since 5.10
By default, this property contains a value of 80 pixels.
+
+ Do not set a value less than the \l {QFontMetrics::}{horizontalAdvance()}
+ of the QChar::VisualTabCharacter character, otherwise the tab-character
+ will be drawn incompletely.
+
+ \sa QTextOption::ShowTabsAndSpaces, QTextDocument::defaultTextOption
*/
qreal QTextEdit::tabStopDistance() const
@@ -2107,7 +2105,7 @@ void QTextEdit::setCursorWidth(int width)
\brief whether the text edit accepts rich text insertions by the user
\since 4.1
- When this propery is set to false text edit will accept only
+ When this property is set to false text edit will accept only
plain text input from the user. For example through clipboard or drag and drop.
This property's default is true.
@@ -2231,7 +2229,7 @@ void QTextEdit::insertFromMimeData(const QMimeData *source)
bool QTextEdit::isReadOnly() const
{
Q_D(const QTextEdit);
- return !(d->control->textInteractionFlags() & Qt::TextEditable);
+ return !d->control || !(d->control->textInteractionFlags() & Qt::TextEditable);
}
void QTextEdit::setReadOnly(bool ro)
@@ -2388,7 +2386,7 @@ void QTextEdit::scrollToAnchor(const QString &name)
QPointF p = d->control->anchorPosition(name);
const int newPosition = qRound(p.y());
if ( d->vbar->maximum() < newPosition )
- d->_q_adjustScrollbars();
+ d->adjustScrollbars();
d->vbar->setValue(newPosition);
}
@@ -2602,11 +2600,14 @@ bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
\overload
Finds the next occurrence, matching the regular expression, \a exp, using the given
- \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
- use QRegularExpression::CaseInsensitiveOption instead.
+ \a options.
Returns \c true if a match was found and changes the cursor to select the match;
otherwise returns \c false.
+
+ \warning For historical reasons, the case sensitivity option set on
+ \a exp is ignored. Instead, the \a options are used to determine
+ if the search is case sensitive or not.
*/
#if QT_CONFIG(regularexpression)
bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
@@ -2670,10 +2671,7 @@ bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags opt
*/
void QTextEdit::setText(const QString &text)
{
- Q_D(QTextEdit);
- Qt::TextFormat format = d->textFormat;
- if (d->textFormat == Qt::AutoText)
- format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
+ Qt::TextFormat format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
#ifndef QT_NO_TEXTHTMLPARSER
if (format == Qt::RichText)
setHtml(text);
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index 91b7d05d9f..421eb9136b 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTEDIT_H
#define QTEXTEDIT_H
@@ -82,7 +46,8 @@ class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea
Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance)
Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText)
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags
+ WRITE setTextInteractionFlags)
Q_PROPERTY(QTextDocument *document READ document WRITE setDocument DESIGNABLE false)
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
public:
@@ -315,14 +280,6 @@ protected:
private:
Q_DISABLE_COPY(QTextEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
- Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &))
- Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
- Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &))
- Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
-#if QT_CONFIG(cursor)
- Q_PRIVATE_SLOT(d_func(), void _q_hoveredBlockWithMarkerChanged(const QTextBlock &))
-#endif
friend class QTextEditControl;
friend class QTextDocument;
friend class QWidgetTextControl;
diff --git a/src/widgets/widgets/qtextedit_p.h b/src/widgets/widgets/qtextedit_p.h
index f7b4d15318..7dd7d9c107 100644
--- a/src/widgets/widgets/qtextedit_p.h
+++ b/src/widgets/widgets/qtextedit_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTEXTEDIT_P_H
#define QTEXTEDIT_P_H
@@ -69,6 +33,8 @@
#include "private/qwidgettextcontrol_p.h"
+#include <array>
+
QT_REQUIRE_CONFIG(textedit);
QT_BEGIN_NAMESPACE
@@ -79,16 +45,17 @@ class QTextEditPrivate : public QAbstractScrollAreaPrivate
Q_DECLARE_PUBLIC(QTextEdit)
public:
QTextEditPrivate();
+ ~QTextEditPrivate();
void init(const QString &html = QString());
void paint(QPainter *p, QPaintEvent *e);
- void _q_repaintContents(const QRectF &contentsRect);
+ void repaintContents(const QRectF &contentsRect);
inline QPoint mapToContents(const QPoint &point) const
{ return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
- void _q_adjustScrollbars();
- void _q_ensureVisible(const QRectF &rect);
+ void adjustScrollbars();
+ void ensureVisible(const QRectF &rect);
void relayoutDocument();
void createAutoBulletList();
@@ -102,9 +69,8 @@ public:
inline void sendControlEvent(QEvent *e)
{ control->processEvent(e, QPointF(horizontalOffset(), verticalOffset()), viewport); }
- void _q_currentCharFormatChanged(const QTextCharFormat &format);
- void _q_cursorPositionChanged();
- void _q_hoveredBlockWithMarkerChanged(const QTextBlock &block);
+ void cursorPositionChanged();
+ void hoveredBlockWithMarkerChanged(const QTextBlock &block);
void updateDefaultTextOption();
@@ -130,15 +96,14 @@ public:
uint inDrag : 1;
uint clickCausedFocus : 1;
- // Qt3 COMPAT only, for setText
- Qt::TextFormat textFormat;
-
QString anchorToScrollToWhenVisible;
QString placeholderText;
Qt::CursorShape cursorToRestoreAfterHover = Qt::IBeamCursor;
+ std::array<QMetaObject::Connection, 13> connections;
+
#ifdef QT_KEYPAD_NAVIGATION
QBasicTimer deleteAllTimer;
#endif
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index e69c08a251..5e5ef8e8d5 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtoolbar.h"
@@ -43,6 +7,9 @@
#if QT_CONFIG(combobox)
#include <qcombobox.h>
#endif
+#if QT_CONFIG(draganddrop)
+#include <qdrag.h>
+#endif
#include <qevent.h>
#include <qlayout.h>
#include <qmainwindow.h>
@@ -50,6 +17,7 @@
#if QT_CONFIG(menubar)
#include <qmenubar.h>
#endif
+#include <qmimedata.h>
#if QT_CONFIG(rubberband)
#include <qrubberband.h>
#endif
@@ -60,6 +28,7 @@
#include <qtimer.h>
#include <private/qwidgetaction_p.h>
#include <private/qmainwindowlayout_p.h>
+#include <private/qhighdpiscaling_p.h>
#ifdef Q_OS_MACOS
#include <qpa/qplatformnativeinterface.h>
@@ -75,6 +44,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
// qmainwindow.cpp
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
@@ -140,8 +111,12 @@ void QToolBarPrivate::updateWindowFlags(bool floating, bool unplug)
flags |= Qt::FramelessWindowHint;
- if (unplug)
+#if QT_CONFIG(draganddrop)
+ // If we are performing a platform drag the flag is not needed and we want to avoid recreating
+ // the platform window when it would be removed later
+ if (unplug && !QMainWindowLayout::needsPlatformDrag())
flags |= Qt::X11BypassWindowManagerHint;
+#endif
q->setWindowFlags(flags);
}
@@ -152,8 +127,6 @@ void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &re
bool visible = !q->isHidden();
bool wasFloating = q->isFloating(); // ...is also currently using popup menus
- q->hide();
-
updateWindowFlags(floating, unplug);
if (floating != wasFloating)
@@ -207,12 +180,29 @@ void QToolBarPrivate::startDrag(bool moving)
QMainWindowLayout *layout = qt_mainwindow_layout(win);
Q_ASSERT(layout != nullptr);
+#if QT_CONFIG(draganddrop)
+ const bool wasFloating = q->isFloating();
+#endif
+
if (!moving) {
- state->widgetItem = layout->unplug(q);
+ state->widgetItem = layout->unplug(q, QDockWidgetPrivate::DragScope::Group);
Q_ASSERT(state->widgetItem != nullptr);
}
state->dragging = !moving;
state->moving = moving;
+
+#if QT_CONFIG(draganddrop)
+ if (QMainWindowLayout::needsPlatformDrag() && state->dragging) {
+ auto result = layout->performPlatformWidgetDrag(state->widgetItem, state->pressPos);
+ if (result == Qt::IgnoreAction && !wasFloating) {
+ layout->revert(state->widgetItem);
+ delete state;
+ state = nullptr;
+ } else {
+ endDrag();
+ }
+ }
+#endif
}
void QToolBarPrivate::endDrag()
@@ -278,6 +268,13 @@ bool QToolBarPrivate::mousePressEvent(QMouseEvent *event)
bool QToolBarPrivate::mouseReleaseEvent(QMouseEvent*)
{
+#if QT_CONFIG(draganddrop)
+ // if we are peforming a platform drag ignore the release here and end the drag when the actual
+ // drag ends.
+ if (QMainWindowLayout::needsPlatformDrag())
+ return false;
+#endif
+
if (state != nullptr) {
endDrag();
return true;
@@ -328,6 +325,11 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
q->grabMouse();
}
+ if (!state) {
+ q->releaseMouse();
+ return true;
+ }
+
if (state->dragging) {
QPoint pos = event->globalPosition().toPoint();
// if we are right-to-left, we move so as to keep the right edge the same distance
@@ -345,7 +347,12 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
int pos = 0;
- QPoint delta = event->globalPosition().toPoint() - globalPressPos;
+ const QWindow *handle = q->window() ? q->window()->windowHandle() : nullptr;
+ const QPoint delta = handle
+ ? QHighDpi::fromNativePixels(event->globalPosition(), handle).toPoint()
+ - QHighDpi::fromNativePixels(globalPressPos, handle)
+ : event->globalPosition().toPoint() - globalPressPos;
+
if (orientation == Qt::Vertical) {
pos = q->y() + delta.y();
} else {
@@ -388,6 +395,10 @@ void QToolBarPrivate::plug(const QRect &r)
\ingroup mainwindow-classes
\inmodule QtWidgets
+ A toolbar is typically created by calling
+ \l QMainWindow::addToolBar(const QString &title), but it can also
+ be added as the first widget in a QVBoxLayout, for example.
+
Toolbar buttons are added by adding \e actions, using addAction()
or insertAction(). Groups of buttons can be separated using
addSeparator() or insertSeparator(). If a toolbar button is not
@@ -411,7 +422,7 @@ void QToolBarPrivate::plug(const QRect &r)
addWidget(). Please use widget actions created by inheriting QWidgetAction
and implementing QWidgetAction::createWidget() instead.
- \sa QToolButton, QMenu, QAction, {Qt Widgets - Application Example}
+ \sa QToolButton, QMenu, QAction
*/
/*!
@@ -737,117 +748,6 @@ void QToolBar::clear()
}
/*!
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar.
-*/
-QAction *QToolBar::addAction(const QString &text)
-{
- QAction *action = new QAction(text, this);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar.
-*/
-QAction *QToolBar::addAction(const QIcon &icon, const QString &text)
-{
- QAction *action = new QAction(icon, text, this);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar. The action's \l{QAction::triggered()}{triggered()}
- signal is connected to \a member in \a receiver.
-*/
-QAction *QToolBar::addAction(const QString &text,
- const QObject *receiver, const char* member)
-{
- QAction *action = new QAction(text, this);
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to \a
- member in \a receiver.
-*/
-QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
- const QObject *receiver, const char* member)
-{
- QAction *action = new QAction(icon, text, this);
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QString &text, Functor functor)
-
- \since 5.6
-
- \overload
-
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor.
-*/
-
-/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QString &text, const QObject *context, Functor functor)
-
- \since 5.6
-
- \overload
-
- Creates a new action with the given \a text. This action is added
- to the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The \a functor can be a pointer to a member function
- in the \a context object.
-
- If the \a context object is destroyed, the \a functor will not be called.
-*/
-
-/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Functor functor)
-
- \since 5.6
-
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor.
-*/
-
-/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor)
-
- \since 5.6
-
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The \a functor can be a pointer to a member function
- of the \a context object.
-
- If the \a context object is destroyed, the \a functor will not be called.
-*/
-
-/*!
Adds a separator to the end of the toolbar.
\sa insertSeparator()
@@ -1164,7 +1064,7 @@ bool QToolBar::event(QEvent *event)
case QEvent::Leave:
if (d->state != nullptr && d->state->dragging) {
#ifdef Q_OS_WIN
- // This is a workaround for loosing the mouse on Vista.
+ // This is a workaround for losing the mouse on Vista.
QPoint pos = QCursor::pos();
QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
@@ -1184,6 +1084,7 @@ bool QToolBar::event(QEvent *event)
d->layout->setExpanded(false);
break;
}
+ break;
default:
break;
}
diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h
index 26cad77b64..fbad25c7c9 100644
--- a/src/widgets/widgets/qtoolbar.h
+++ b/src/widgets/widgets/qtoolbar.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICTOOLBAR_H
#define QDYNAMICTOOLBAR_H
@@ -60,8 +24,10 @@ class Q_WIDGETS_EXPORT QToolBar : public QWidget
Q_OBJECT
Q_PROPERTY(bool movable READ isMovable WRITE setMovable NOTIFY movableChanged)
- Q_PROPERTY(Qt::ToolBarAreas allowedAreas READ allowedAreas WRITE setAllowedAreas NOTIFY allowedAreasChanged)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
+ Q_PROPERTY(Qt::ToolBarAreas allowedAreas READ allowedAreas WRITE setAllowedAreas
+ NOTIFY allowedAreasChanged)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation
+ NOTIFY orientationChanged)
Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle
NOTIFY toolButtonStyleChanged)
@@ -88,58 +54,13 @@ public:
void clear();
using QWidget::addAction;
+#if QT_WIDGETS_REMOVED_SINCE(6, 3)
QAction *addAction(const QString &text);
QAction *addAction(const QIcon &icon, const QString &text);
QAction *addAction(const QString &text, const QObject *receiver, const char* member);
QAction *addAction(const QIcon &icon, const QString &text,
const QObject *receiver, const char* member);
-#ifdef Q_CLANG_QDOC
- template<typename Functor>
- QAction *addAction(const QString &text, Functor functor);
- template<typename Functor>
- QAction *addAction(const QString &text, const QObject *context, Functor functor);
- template<typename Functor>
- QAction *addAction(const QIcon &icon, const QString &text, Functor functor);
- template<typename Functor>
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor);
-#else
- // addAction(QString): Connect to a QObject slot / functor or function pointer (with context)
- template<class Obj, typename Func1>
- inline typename std::enable_if<!std::is_same<const char*, Func1>::value
- && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type
- addAction(const QString &text, const Obj *object, Func1 slot)
- {
- QAction *result = addAction(text);
- connect(result, &QAction::triggered, object, std::move(slot));
- return result;
- }
- // addAction(QString): Connect to a functor or function pointer (without context)
- template <typename Func1>
- inline QAction *addAction(const QString &text, Func1 slot)
- {
- QAction *result = addAction(text);
- connect(result, &QAction::triggered, slot);
- return result;
- }
- // addAction(QString): Connect to a QObject slot / functor or function pointer (with context)
- template<class Obj, typename Func1>
- inline typename std::enable_if<!std::is_same<const char*, Func1>::value
- && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type
- addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot)
- {
- QAction *result = addAction(actionIcon, text);
- connect(result, &QAction::triggered, object, std::move(slot));
- return result;
- }
- // addAction(QIcon, QString): Connect to a functor or function pointer (without context)
- template <typename Func1>
- inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot)
- {
- QAction *result = addAction(actionIcon, text);
- connect(result, &QAction::triggered, slot);
- return result;
- }
-#endif // !Q_CLANG_QDOC
+#endif
QAction *addSeparator();
QAction *insertSeparator(QAction *before);
diff --git a/src/widgets/widgets/qtoolbar_p.h b/src/widgets/widgets/qtoolbar_p.h
index 07f1af3fe0..2561cd8f64 100644
--- a/src/widgets/widgets/qtoolbar_p.h
+++ b/src/widgets/widgets/qtoolbar_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICTOOLBAR_P_H
#define QDYNAMICTOOLBAR_P_H
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index 6297796931..54c21b6038 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QWidgetItem>
#include <QToolBar>
@@ -106,7 +70,7 @@ QToolBarAreaLayoutLine::QToolBarAreaLayoutLine(Qt::Orientation orientation)
QSize QToolBarAreaLayoutLine::sizeHint() const
{
int a = 0, b = 0;
- for (int i = 0; i < toolBarItems.count(); ++i) {
+ for (int i = 0; i < toolBarItems.size(); ++i) {
const QToolBarAreaLayoutItem &item = toolBarItems.at(i);
if (item.skip())
continue;
@@ -126,7 +90,7 @@ QSize QToolBarAreaLayoutLine::sizeHint() const
QSize QToolBarAreaLayoutLine::minimumSize() const
{
int a = 0, b = 0;
- for (int i = 0; i < toolBarItems.count(); ++i) {
+ for (int i = 0; i < toolBarItems.size(); ++i) {
const QToolBarAreaLayoutItem &item = toolBarItems[i];
if (item.skip())
continue;
@@ -150,7 +114,7 @@ void QToolBarAreaLayoutLine::fitLayout()
int space = pick(o, rect.size());
int extra = qMax(0, space - min);
- for (int i = 0; i < toolBarItems.count(); ++i) {
+ for (int i = 0; i < toolBarItems.size(); ++i) {
QToolBarAreaLayoutItem &item = toolBarItems[i];
if (item.skip())
continue;
@@ -173,7 +137,7 @@ void QToolBarAreaLayoutLine::fitLayout()
// calculate the positions from the sizes
int pos = 0;
- for (int i = 0; i < toolBarItems.count(); ++i) {
+ for (int i = 0; i < toolBarItems.size(); ++i) {
QToolBarAreaLayoutItem &item = toolBarItems[i];
if (item.skip())
continue;
@@ -187,7 +151,7 @@ void QToolBarAreaLayoutLine::fitLayout()
bool QToolBarAreaLayoutLine::skip() const
{
- for (int i = 0; i < toolBarItems.count(); ++i) {
+ for (int i = 0; i < toolBarItems.size(); ++i) {
if (!toolBarItems.at(i).skip())
return false;
}
@@ -219,7 +183,7 @@ QToolBarAreaLayoutInfo::QToolBarAreaLayoutInfo(QInternal::DockPosition pos)
QSize QToolBarAreaLayoutInfo::sizeHint() const
{
int a = 0, b = 0;
- for (int i = 0; i < lines.count(); ++i) {
+ for (int i = 0; i < lines.size(); ++i) {
const QToolBarAreaLayoutLine &l = lines.at(i);
if (l.skip())
continue;
@@ -239,7 +203,7 @@ QSize QToolBarAreaLayoutInfo::sizeHint() const
QSize QToolBarAreaLayoutInfo::minimumSize() const
{
int a = 0, b = 0;
- for (int i = 0; i < lines.count(); ++i) {
+ for (int i = 0; i < lines.size(); ++i) {
const QToolBarAreaLayoutLine &l = lines.at(i);
if (l.skip())
continue;
@@ -264,9 +228,9 @@ void QToolBarAreaLayoutInfo::fitLayout()
bool reverse = dockPos == QInternal::RightDock || dockPos == QInternal::BottomDock;
- int i = reverse ? lines.count() - 1 : 0;
+ int i = reverse ? lines.size() - 1 : 0;
for (;;) {
- if ((reverse && i < 0) || (!reverse && i == lines.count()))
+ if ((reverse && i < 0) || (!reverse && i == lines.size()))
break;
QToolBarAreaLayoutLine &l = lines[i];
@@ -309,10 +273,10 @@ void QToolBarAreaLayoutInfo::insertItem(QToolBar *before, QLayoutItem *item)
return;
}
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
QToolBarAreaLayoutLine &line = lines[j];
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == before) {
line.toolBarItems.insert(k, item);
return;
@@ -323,17 +287,17 @@ void QToolBarAreaLayoutInfo::insertItem(QToolBar *before, QLayoutItem *item)
void QToolBarAreaLayoutInfo::removeToolBar(QToolBar *toolBar)
{
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
QToolBarAreaLayoutLine &line = lines[j];
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
QToolBarAreaLayoutItem &item = line.toolBarItems[k];
if (item.widgetItem->widget() == toolBar) {
delete item.widgetItem;
item.widgetItem = nullptr;
line.toolBarItems.removeAt(k);
- if (line.toolBarItems.isEmpty() && j < lines.count() - 1)
+ if (line.toolBarItems.isEmpty() && j < lines.size() - 1)
lines.removeAt(j);
return;
@@ -351,10 +315,10 @@ void QToolBarAreaLayoutInfo::insertToolBarBreak(QToolBar *before)
return;
}
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
QToolBarAreaLayoutLine &line = lines[j];
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == before) {
if (k == 0)
return;
@@ -372,10 +336,10 @@ void QToolBarAreaLayoutInfo::insertToolBarBreak(QToolBar *before)
void QToolBarAreaLayoutInfo::removeToolBarBreak(QToolBar *before)
{
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == before) {
if (k != 0)
return;
@@ -402,12 +366,12 @@ void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
pos -= rect.top();
//here we actually update the preferredSize for the line containing the toolbar so that we move it
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
QToolBarAreaLayoutLine &line = lines[j];
int previousIndex = -1;
int minPos = 0;
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
QToolBarAreaLayoutItem &current = line.toolBarItems[k];
if (current.widgetItem->widget() == toolbar) {
int newPos = current.pos;
@@ -419,7 +383,7 @@ void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
} else {
//we check the max value for the position (until everything at the right is "compressed")
int maxPos = pick(o, rect.size());
- for(int l = k; l < line.toolBarItems.count(); ++l) {
+ for(int l = k; l < line.toolBarItems.size(); ++l) {
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(l);
if (!item.skip()) {
maxPos -= pick(o, item.minimumSize());
@@ -487,7 +451,7 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance)
// Since we're comparing p with item.pos, we put them in the same coordinate system.
const int p = pick(o, pos - rect.topLeft());
- for (int j = 0; j < lines.count(); ++j) {
+ for (int j = 0; j < lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = lines.at(j);
if (line.skip())
continue;
@@ -495,7 +459,7 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance)
continue;
int k = 0;
- for (; k < line.toolBarItems.count(); ++k) {
+ for (; k < line.toolBarItems.size(); ++k) {
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
if (item.skip())
continue;
@@ -521,7 +485,7 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance)
*minDistance = dist;
QList<int> result;
- result << lines.count() << 0;
+ result << lines.size() << 0;
return result;
}
}
@@ -531,9 +495,9 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance)
bool QToolBarAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *item)
{
- Q_ASSERT(path.count() == 2);
+ Q_ASSERT(path.size() == 2);
int j = path.first();
- if (j == lines.count())
+ if (j == lines.size())
lines.append(QToolBarAreaLayoutLine(o));
QToolBarAreaLayoutLine &line = lines[j];
@@ -576,7 +540,7 @@ void QToolBarAreaLayoutInfo::clear()
QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const
{
- Q_ASSERT(path.count() == 2);
+ Q_ASSERT(path.size() == 2);
int j = path.at(0);
int k = path.at(1);
@@ -734,10 +698,10 @@ QLayoutItem *QToolBarAreaLayout::itemAt(int *x, int index) const
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if ((*x)++ == index)
return line.toolBarItems.at(k).widgetItem;
}
@@ -754,10 +718,10 @@ QLayoutItem *QToolBarAreaLayout::takeAt(int *x, int index)
for (int i = 0; i < QInternal::DockCount; ++i) {
QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
QToolBarAreaLayoutLine &line = dock.lines[j];
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if ((*x)++ == index) {
QLayoutItem *result = line.toolBarItems.takeAt(k).widgetItem;
if (line.toolBarItems.isEmpty())
@@ -776,10 +740,10 @@ void QToolBarAreaLayout::deleteAllLayoutItems()
for (int i = 0; i < QInternal::DockCount; ++i) {
QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
QToolBarAreaLayoutLine &line = dock.lines[j];
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
QToolBarAreaLayoutItem &item = line.toolBarItems[k];
if (!item.gap)
delete item.widgetItem;
@@ -794,10 +758,10 @@ QInternal::DockPosition QToolBarAreaLayout::findToolBar(const QToolBar *toolBar)
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == toolBar)
return static_cast<QInternal::DockPosition>(i);
}
@@ -885,12 +849,12 @@ void QToolBarAreaLayout::apply(bool animate)
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
if (line.skip())
continue;
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
if (item.skip() || item.gap)
continue;
@@ -943,10 +907,10 @@ bool QToolBarAreaLayout::toolBarBreak(QToolBar *toolBar) const
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == toolBar)
return j > 0 && k == 0;
}
@@ -961,25 +925,25 @@ void QToolBarAreaLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBa
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
if (line.toolBarItems.at(k).widgetItem->widget() == toolBar) {
- if (line.toolBarItems.count() == 1)
+ if (line.toolBarItems.size() == 1)
option->positionWithinLine = QStyleOptionToolBar::OnlyOne;
else if (k == 0)
option->positionWithinLine = QStyleOptionToolBar::Beginning;
- else if (k == line.toolBarItems.count() - 1)
+ else if (k == line.toolBarItems.size() - 1)
option->positionWithinLine = QStyleOptionToolBar::End;
else
option->positionWithinLine = QStyleOptionToolBar::Middle;
- if (dock.lines.count() == 1)
+ if (dock.lines.size() == 1)
option->positionOfLine = QStyleOptionToolBar::OnlyOne;
else if (j == 0)
option->positionOfLine = QStyleOptionToolBar::Beginning;
- else if (j == dock.lines.count() - 1)
+ else if (j == dock.lines.size() - 1)
option->positionOfLine = QStyleOptionToolBar::End;
else
option->positionOfLine = QStyleOptionToolBar::Middle;
@@ -1000,10 +964,10 @@ QList<int> QToolBarAreaLayout::indexOf(QWidget *toolBar) const
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
if (!item.gap && item.widgetItem->widget() == toolBar) {
found = true;
@@ -1052,10 +1016,10 @@ QList<int> QToolBarAreaLayout::currentGapIndex() const
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines[j];
- for (int k = 0; k < line.toolBarItems.count(); k++) {
+ for (int k = 0; k < line.toolBarItems.size(); k++) {
if (line.toolBarItems[k].gap) {
QList<int> result;
result << i << j << k;
@@ -1069,7 +1033,7 @@ QList<int> QToolBarAreaLayout::currentGapIndex() const
bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item)
{
- Q_ASSERT(path.count() == 3);
+ Q_ASSERT(path.size() == 3);
const int i = path.first();
Q_ASSERT(i >= 0 && i < QInternal::DockCount);
return docks[i].insertGap(path.mid(1), item);
@@ -1077,7 +1041,7 @@ bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item)
void QToolBarAreaLayout::remove(const QList<int> &path)
{
- Q_ASSERT(path.count() == 3);
+ Q_ASSERT(path.size() == 3);
QToolBarAreaLayoutInfo &dock = docks[path.at(0)];
QToolBarAreaLayoutLine &line = dock.lines[path.at(1)];
line.toolBarItems.removeAt(path.at(2));
@@ -1090,10 +1054,10 @@ void QToolBarAreaLayout::remove(QLayoutItem *item)
for (int i = 0; i < QInternal::DockCount; ++i) {
QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
QToolBarAreaLayoutLine &line = dock.lines[j];
- for (int k = 0; k < line.toolBarItems.count(); k++) {
+ for (int k = 0; k < line.toolBarItems.size(); k++) {
if (line.toolBarItems[k].widgetItem == item) {
line.toolBarItems.removeAt(k);
if (line.toolBarItems.isEmpty())
@@ -1114,15 +1078,15 @@ void QToolBarAreaLayout::clear()
QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList<int> &path)
{
- Q_ASSERT(path.count() == 3);
+ Q_ASSERT(path.size() == 3);
if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount)
return nullptr;
QToolBarAreaLayoutInfo &info = docks[path.at(0)];
- if (path.at(1) < 0 || path.at(1) >= info.lines.count())
+ if (path.at(1) < 0 || path.at(1) >= info.lines.size())
return nullptr;
QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
- if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.count())
+ if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.size())
return nullptr;
return &(line.toolBarItems[path.at(2)]);
}
@@ -1154,7 +1118,7 @@ QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other)
{
//other needs to be update as well
- Q_ASSERT(path.count() == 3);
+ Q_ASSERT(path.size() == 3);
QToolBarAreaLayoutItem *item = this->item(path);
Q_ASSERT(item);
@@ -1172,7 +1136,7 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayo
if (!previous.skip()) {
//we need to check if it has a previous element and a next one
//the previous will get its size changed
- for (int j = path.at(2) + 1; j < line.toolBarItems.count(); ++j) {
+ for (int j = path.at(2) + 1; j < line.toolBarItems.size(); ++j) {
const QToolBarAreaLayoutItem &next = line.toolBarItems.at(j);
if (!next.skip()) {
newExtraSpace = next.pos - previous.pos - pick(line.o, previous.sizeHint());
@@ -1257,19 +1221,19 @@ void QToolBarAreaLayout::saveState(QDataStream &stream) const
int lineCount = 0;
for (int i = 0; i < QInternal::DockCount; ++i)
- lineCount += docks[i].lines.count();
+ lineCount += docks[i].lines.size();
stream << lineCount;
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
- for (int j = 0; j < dock.lines.count(); ++j) {
+ for (int j = 0; j < dock.lines.size(); ++j) {
const QToolBarAreaLayoutLine &line = dock.lines.at(j);
- stream << i << int(line.toolBarItems.count());
+ stream << i << int(line.toolBarItems.size());
- for (int k = 0; k < line.toolBarItems.count(); ++k) {
+ for (int k = 0; k < line.toolBarItems.size(); ++k) {
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
QWidget *widget = const_cast<QLayoutItem*>(item.widgetItem)->widget();
QString objectName = widget->objectName();
@@ -1353,7 +1317,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
}
QToolBar *toolBar = nullptr;
- for (int x = 0; x < toolBars.count(); ++x) {
+ for (int x = 0; x < toolBars.size(); ++x) {
if (toolBars.at(x)->objectName() == objectName) {
toolBar = toolBars.takeAt(x);
break;
@@ -1364,10 +1328,14 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
}
if (applyingLayout) {
+ // Clear the previous widgetItem for the toolBar, so that it's
+ // assigned correctly in QWidgetItemV2 constructor.
+ auto *toolBarPrivate = QWidgetPrivate::get(toolBar);
+ toolBarPrivate->widgetItem = nullptr;
item.widgetItem = new QWidgetItemV2(toolBar);
toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
toolBar->setVisible(shown & 1);
- toolBar->d_func()->setWindowState(floating, true, rect);
+ toolBar->d_func()->setWindowState(floating, false, rect);
item.preferredSize = item.size;
line.toolBarItems.append(item);
diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index d47597d224..4318f206f3 100644
--- a/src/widgets/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTOOLBARAREALAYOUT_P_H
#define QTOOLBARAREALAYOUT_P_H
diff --git a/src/widgets/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp
index 76bc5a4773..350a900457 100644
--- a/src/widgets/widgets/qtoolbarextension.cpp
+++ b/src/widgets/widgets/qtoolbarextension.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtoolbarextension_p.h"
#include <qevent.h>
@@ -45,11 +9,13 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
QToolBarExtension::QToolBarExtension(QWidget *parent)
: QToolButton(parent)
, m_orientation(Qt::Horizontal)
{
- setObjectName(QLatin1String("qt_toolbar_ext_button"));
+ setObjectName("qt_toolbar_ext_button"_L1);
setAutoRaise(true);
setOrientation(m_orientation);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
@@ -61,9 +27,9 @@ void QToolBarExtension::setOrientation(Qt::Orientation o)
QStyleOption opt;
opt.initFrom(this);
if (o == Qt::Horizontal) {
- setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, &opt));
+ setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, &opt, this));
} else {
- setIcon(style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton, &opt));
+ setIcon(style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton, &opt, this));
}
m_orientation = o;
}
@@ -83,7 +49,7 @@ QSize QToolBarExtension::sizeHint() const
{
QStyleOption opt;
opt.initFrom(this);
- const int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt);
+ const int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, this);
return QSize(ext, ext);
}
diff --git a/src/widgets/widgets/qtoolbarextension_p.h b/src/widgets/widgets/qtoolbarextension_p.h
index 146e0e58c1..c2afd3fc62 100644
--- a/src/widgets/widgets/qtoolbarextension_p.h
+++ b/src/widgets/widgets/qtoolbarextension_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICTOOLBAREXTENSION_P_H
#define QDYNAMICTOOLBAREXTENSION_P_H
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index c5af8697dc..cc842e2657 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qapplication.h>
#include <qaction.h>
@@ -168,14 +132,14 @@ void QToolBarLayout::addItem(QLayoutItem*)
QLayoutItem *QToolBarLayout::itemAt(int index) const
{
- if (index < 0 || index >= items.count())
+ if (index < 0 || index >= items.size())
return nullptr;
return items.at(index);
}
QLayoutItem *QToolBarLayout::takeAt(int index)
{
- if (index < 0 || index >= items.count())
+ if (index < 0 || index >= items.size())
return nullptr;
QToolBarItem *item = items.takeAt(index);
@@ -198,7 +162,7 @@ QLayoutItem *QToolBarLayout::takeAt(int index)
void QToolBarLayout::insertAction(int index, QAction *action)
{
index = qMax(0, index);
- index = qMin(items.count(), index);
+ index = qMin(items.size(), index);
QToolBarItem *item = createItem(action);
if (item) {
@@ -209,7 +173,7 @@ void QToolBarLayout::insertAction(int index, QAction *action)
int QToolBarLayout::indexOf(const QAction *action) const
{
- for (int i = 0; i < items.count(); ++i) {
+ for (int i = 0; i < items.size(); ++i) {
if (items.at(i)->action == action)
return i;
}
@@ -218,7 +182,7 @@ int QToolBarLayout::indexOf(const QAction *action) const
int QToolBarLayout::count() const
{
- return items.count();
+ return items.size();
}
bool QToolBarLayout::isEmpty() const
@@ -282,10 +246,10 @@ void QToolBarLayout::updateGeomArray() const
that->expanding = false;
that->empty = false;
- QList<QLayoutStruct> a(items.count() + 1); // + 1 for the stretch
+ QList<QLayoutStruct> a(items.size() + 1); // + 1 for the stretch
int count = 0;
- for (int i = 0; i < items.count(); ++i) {
+ for (int i = 0; i < items.size(); ++i) {
QToolBarItem *item = items.at(i);
QSize max = item->maximumSize();
@@ -332,7 +296,7 @@ void QToolBarLayout::updateGeomArray() const
rpick(o, that->minSize) += handleExtent;
that->minSize += QSize(pick(Qt::Horizontal, margins), pick(Qt::Vertical, margins));
- if (items.count() > 1)
+ if (items.size() > 1)
rpick(o, that->minSize) += spacing + extensionExtent;
rpick(o, that->hint) += handleExtent;
@@ -467,7 +431,7 @@ bool QToolBarLayout::layoutActions(const QSize &size)
int rows = 0;
int rowPos = perp(o, rect.topLeft()) + perp(o, QSize(margins.top(), margins.left()));
int i = 0;
- while (i < items.count()) {
+ while (i < items.size()) {
QList<QLayoutStruct> a = geomArray;
int start = i;
@@ -477,7 +441,7 @@ bool QToolBarLayout::layoutActions(const QSize &size)
int count = 0;
int maximumSize = 0;
bool expansiveRow = false;
- for (; i < items.count(); ++i) {
+ for (; i < items.size(); ++i) {
if (a[i].empty)
continue;
@@ -548,7 +512,7 @@ bool QToolBarLayout::layoutActions(const QSize &size)
}
if (!expanded) {
- for (int j = i; j < items.count(); ++j) {
+ for (int j = i; j < items.size(); ++j) {
QToolBarItem *item = items.at(j);
if (!item->widget()->isHidden())
hideWidgets << item->widget();
@@ -573,9 +537,9 @@ bool QToolBarLayout::layoutActions(const QSize &size)
extension->setEnabled(popupMenu == nullptr || !extensionMenuContainsOnlyWidgetActions);
// we have to do the show/hide here, because it triggers more calls to setGeometry :(
- for (int i = 0; i < showWidgets.count(); ++i)
+ for (int i = 0; i < showWidgets.size(); ++i)
showWidgets.at(i)->show();
- for (int i = 0; i < hideWidgets.count(); ++i)
+ for (int i = 0; i < hideWidgets.size(); ++i)
hideWidgets.at(i)->hide();
return ranOutOfSpace;
@@ -602,7 +566,7 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
int total_w = 0;
int count = 0;
- for (int x = 0; x < items.count(); ++x) {
+ for (int x = 0; x < items.size(); ++x) {
if (!geomArray[x].empty) {
total_w += (count == 0 ? 0 : spacing) + geomArray[x].minimumSize;
++count;
@@ -623,12 +587,12 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
int w = 0;
int h = 0;
int i = 0;
- while (i < items.count()) {
+ while (i < items.size()) {
int count = 0;
int size = 0;
int prev = -1;
int rowHeight = 0;
- for (; i < items.count(); ++i) {
+ for (; i < items.size(); ++i) {
if (geomArray[i].empty)
continue;
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
index a8535d1a9b..a7d3810d61 100644
--- a/src/widgets/widgets/qtoolbarlayout_p.h
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTOOLBARLAYOUT_P_H
#define QTOOLBARLAYOUT_P_H
diff --git a/src/widgets/widgets/qtoolbarseparator.cpp b/src/widgets/widgets/qtoolbarseparator.cpp
index 92cd08317a..0e70c21361 100644
--- a/src/widgets/widgets/qtoolbarseparator.cpp
+++ b/src/widgets/widgets/qtoolbarseparator.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtoolbarseparator_p.h"
diff --git a/src/widgets/widgets/qtoolbarseparator_p.h b/src/widgets/widgets/qtoolbarseparator_p.h
index 60b51a28cb..d43c241015 100644
--- a/src/widgets/widgets/qtoolbarseparator_p.h
+++ b/src/widgets/widgets/qtoolbarseparator_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDYNAMICTOOLBARSEPARATOR_P_H
#define QDYNAMICTOOLBARSEPARATOR_P_H
diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp
index 787554551d..e0fac9be0f 100644
--- a/src/widgets/widgets/qtoolbox.cpp
+++ b/src/widgets/widgets/qtoolbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtoolbox.h"
@@ -56,6 +20,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QToolBoxButton : public QAbstractButton
{
Q_OBJECT
@@ -351,7 +317,7 @@ int QToolBox::insertItem(int index, QWidget *widget, const QIcon &icon, const QS
auto &c = *newPage;
c.widget = widget;
c.button = new QToolBoxButton(this);
- c.button->setObjectName(QLatin1String("qt_toolbox_toolboxbutton"));
+ c.button->setObjectName("qt_toolbox_toolboxbutton"_L1);
connect(c.button, SIGNAL(clicked()), this, SLOT(_q_buttonClicked()));
c.sv = new QScrollArea(this);
diff --git a/src/widgets/widgets/qtoolbox.h b/src/widgets/widgets/qtoolbox.h
index e572c7835a..a295dad2fd 100644
--- a/src/widgets/widgets/qtoolbox.h
+++ b/src/widgets/widgets/qtoolbox.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTOOLBOX_H
#define QTOOLBOX_H
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index b9d31bd657..e0775afd26 100644
--- a/src/widgets/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtoolbutton.h"
@@ -67,20 +31,22 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QToolButtonPrivate : public QAbstractButtonPrivate
{
Q_DECLARE_PUBLIC(QToolButton)
public:
void init();
#if QT_CONFIG(menu)
- void _q_buttonPressed();
- void _q_buttonReleased();
+ void onButtonPressed();
+ void onButtonReleased();
void popupTimerDone();
- void _q_updateButtonDown();
- void _q_menuTriggered(QAction *);
+ void updateButtonDown();
+ void onMenuTriggered(QAction *);
#endif
bool updateHoverControl(const QPoint &pos);
- void _q_actionTriggered();
+ void onActionTriggered();
QStyle::SubControl newHoverControl(const QPoint &pos);
QStyle::SubControl hoverControl;
QRect hoverRect;
@@ -169,8 +135,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
*/
/*!
@@ -222,8 +187,10 @@ void QToolButtonPrivate::init()
QSizePolicy::ToolButton));
#if QT_CONFIG(menu)
- QObject::connect(q, SIGNAL(pressed()), q, SLOT(_q_buttonPressed()));
- QObject::connect(q, SIGNAL(released()), q, SLOT(_q_buttonReleased()));
+ QObjectPrivate::connect(q, &QAbstractButton::pressed,
+ this, &QToolButtonPrivate::onButtonPressed);
+ QObjectPrivate::connect(q, &QAbstractButton::released,
+ this, &QToolButtonPrivate::onButtonReleased);
#endif
setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem);
@@ -348,7 +315,7 @@ QSize QToolButton::sizeHint() const
if (opt.toolButtonStyle != Qt::ToolButtonIconOnly) {
QSize textSize = fm.size(Qt::TextShowMnemonic, text());
- textSize.setWidth(textSize.width() + fm.horizontalAdvance(QLatin1Char(' '))*2);
+ textSize.setWidth(textSize.width() + fm.horizontalAdvance(u' ') * 2);
if (opt.toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
h += 4 + textSize.height();
if (textSize.width() > w)
@@ -470,7 +437,8 @@ void QToolButton::actionEvent(QActionEvent *event)
setDefaultAction(action); // update button state
break;
case QEvent::ActionAdded:
- connect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
+ QObjectPrivate::connect(action, &QAction::triggered, d,
+ &QToolButtonPrivate::onActionTriggered);
break;
case QEvent::ActionRemoved:
if (d->defaultAction == action)
@@ -515,7 +483,7 @@ bool QToolButtonPrivate::updateHoverControl(const QPoint &pos)
return !doesHover;
}
-void QToolButtonPrivate::_q_actionTriggered()
+void QToolButtonPrivate::onActionTriggered()
{
Q_Q(QToolButton);
if (QAction *action = qobject_cast<QAction *>(q->sender()))
@@ -616,8 +584,10 @@ void QToolButton::mousePressEvent(QMouseEvent *e)
void QToolButton::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QToolButton);
+ QPointer<QAbstractButton> guard(this);
QAbstractButton::mouseReleaseEvent(e);
- d->buttonPressed = QToolButtonPrivate::NoButtonPressed;
+ if (guard)
+ d->buttonPressed = QToolButtonPrivate::NoButtonPressed;
}
/*!
@@ -702,7 +672,7 @@ void QToolButton::showMenu()
d->popupTimerDone();
}
-void QToolButtonPrivate::_q_buttonPressed()
+void QToolButtonPrivate::onButtonPressed()
{
Q_Q(QToolButton);
if (!hasMenu())
@@ -715,7 +685,7 @@ void QToolButtonPrivate::_q_buttonPressed()
q->showMenu();
}
-void QToolButtonPrivate::_q_buttonReleased()
+void QToolButtonPrivate::onButtonReleased()
{
popupTimer.stop();
}
@@ -725,7 +695,7 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal,
{
QPoint p;
const QRect rect = q->rect(); // Find screen via point in case of QGraphicsProxyWidget.
- const QRect screen = QWidgetPrivate::availableScreenGeometry(q);
+ const QRect screen = QWidgetPrivate::availableScreenGeometry(q, q->mapToGlobal(rect.center()));
if (horizontal) {
if (q->isRightToLeft()) {
if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) {
@@ -757,8 +727,13 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal,
}
}
}
+
+ // QTBUG-118695 Force point inside the current screen. If the returned point
+ // is not found inside any screen, QMenu's positioning logic kicks in without
+ // taking the QToolButton's screen into account. This can cause the menu to
+ // end up on primary monitor, even if the QToolButton is on a non-primary monitor.
p.rx() = qMax(screen.left(), qMin(p.x(), screen.right() - sh.width()));
- p.ry() += 1;
+ p.ry() = qMax(screen.top(), qMin(p.y() + 1, screen.bottom()));
return p;
}
@@ -792,9 +767,12 @@ void QToolButtonPrivate::popupTimerDone()
#endif
QPointer<QToolButton> that = q;
actualMenu->setNoReplayFor(q);
- if (!mustDeleteActualMenu) //only if action are not in this widget
- QObject::connect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*)));
- QObject::connect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown()));
+ if (!mustDeleteActualMenu) { //only if action are not in this widget
+ QObjectPrivate::connect(actualMenu, &QMenu::triggered,
+ this, &QToolButtonPrivate::onMenuTriggered);
+ }
+ QObjectPrivate::connect(actualMenu, &QMenu::aboutToHide,
+ this, &QToolButtonPrivate::updateButtonDown);
actualMenu->d_func()->causedPopup.widget = q;
actualMenu->d_func()->causedPopup.action = defaultAction;
actionsCopy = q->actions(); //(the list of action may be modified in slots)
@@ -808,11 +786,14 @@ void QToolButtonPrivate::popupTimerDone()
if (!that)
return;
- QObject::disconnect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown()));
- if (mustDeleteActualMenu)
+ QObjectPrivate::disconnect(actualMenu, &QMenu::aboutToHide,
+ this, &QToolButtonPrivate::updateButtonDown);
+ if (mustDeleteActualMenu) {
delete actualMenu;
- else
- QObject::disconnect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*)));
+ } else {
+ QObjectPrivate::disconnect(actualMenu, &QMenu::triggered,
+ this, &QToolButtonPrivate::onMenuTriggered);
+ }
actionsCopy.clear();
@@ -820,7 +801,7 @@ void QToolButtonPrivate::popupTimerDone()
q->setAutoRepeat(true);
}
-void QToolButtonPrivate::_q_updateButtonDown()
+void QToolButtonPrivate::updateButtonDown()
{
Q_Q(QToolButton);
menuButtonDown = false;
@@ -830,7 +811,7 @@ void QToolButtonPrivate::_q_updateButtonDown()
q->repaint();
}
-void QToolButtonPrivate::_q_menuTriggered(QAction *action)
+void QToolButtonPrivate::onMenuTriggered(QAction *action)
{
Q_Q(QToolButton);
if (action && !actionsCopy.contains(action))
@@ -940,7 +921,7 @@ void QToolButton::setDefaultAction(QAction *action)
// If iconText() is generated from text(), we need to escape any '&'s so they
// don't turn into shortcuts
if (QActionPrivate::get(action)->iconText.isEmpty())
- buttonText.replace(QLatin1String("&"), QLatin1String("&&"));
+ buttonText.replace("&"_L1, "&&"_L1);
setText(buttonText);
setIcon(action->icon());
#if QT_CONFIG(tooltip)
@@ -979,7 +960,15 @@ QAction *QToolButton::defaultAction() const
return d->defaultAction;
}
-
+/*!
+ \reimp
+ */
+void QToolButton::checkStateSet()
+{
+ Q_D(QToolButton);
+ if (d->defaultAction && d->defaultAction->isCheckable())
+ d->defaultAction->setChecked(isChecked());
+}
/*!
\reimp
diff --git a/src/widgets/widgets/qtoolbutton.h b/src/widgets/widgets/qtoolbutton.h
index 96702c145f..72429620ad 100644
--- a/src/widgets/widgets/qtoolbutton.h
+++ b/src/widgets/widgets/qtoolbutton.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTOOLBUTTON_H
#define QTOOLBUTTON_H
@@ -118,20 +82,13 @@ protected:
void changeEvent(QEvent *) override;
bool hitButton(const QPoint &pos) const override;
+ void checkStateSet() override;
void nextCheckState() override;
virtual void initStyleOption(QStyleOptionToolButton *option) const;
private:
Q_DISABLE_COPY(QToolButton)
Q_DECLARE_PRIVATE(QToolButton)
-#if QT_CONFIG(menu)
- Q_PRIVATE_SLOT(d_func(), void _q_buttonPressed())
- Q_PRIVATE_SLOT(d_func(), void _q_buttonReleased())
- Q_PRIVATE_SLOT(d_func(), void _q_updateButtonDown())
- Q_PRIVATE_SLOT(d_func(), void _q_menuTriggered(QAction*))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
-
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
index 9a4045196c..d45215dee3 100644
--- a/src/widgets/widgets/qwidgetanimator.cpp
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwidgetanimator_p.h"
@@ -93,7 +57,7 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
animate = animate && !r.isNull() && !_final_geometry.isNull();
- // might make the wigdet go away by sending it to negative space
+ // might make the widget go away by sending it to negative space
const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
@@ -109,7 +73,8 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->setEndValue(final_geometry);
m_animation_map[widget] = anim;
- connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
+ connect(anim, &QPropertyAnimation::finished,
+ this, &QWidgetAnimator::animationFinished);
anim->start(QPropertyAnimation::DeleteWhenStopped);
} else
#endif // animation
diff --git a/src/widgets/widgets/qwidgetanimator_p.h b/src/widgets/widgets/qwidgetanimator_p.h
index 9d08d03593..c7af3855b0 100644
--- a/src/widgets/widgets/qwidgetanimator_p.h
+++ b/src/widgets/widgets/qwidgetanimator_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGET_ANIMATOR_P_H
#define QWIDGET_ANIMATOR_P_H
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 77c62b106b..ce1b8706ae 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwidgetlinecontrol_p.h"
@@ -49,7 +13,7 @@
#endif
#include <qpa/qplatformtheme.h>
#include <qstylehints.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include "qaccessible.h"
#endif
@@ -98,7 +62,7 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate)
if (m_echoMode == QLineEdit::Password) {
str.fill(m_passwordCharacter);
- if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.length()) {
+ if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.size()) {
int cursor = m_cursor - 1;
QChar uc = m_text.at(cursor);
str[cursor] = uc;
@@ -118,11 +82,10 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate)
// drawing boxes when using fonts that don't have glyphs for such
// characters)
QChar* uc = str.data();
- for (int i = 0; i < (int)str.length(); ++i) {
+ for (int i = 0; i < (int)str.size(); ++i) {
if ((uc[i].unicode() < 0x20 && uc[i].unicode() != 0x09)
|| uc[i] == QChar::LineSeparator
- || uc[i] == QChar::ParagraphSeparator
- || uc[i] == QChar::ObjectReplacementCharacter)
+ || uc[i] == QChar::ParagraphSeparator)
uc[i] = QChar(0x0020);
}
@@ -278,7 +241,7 @@ void QWidgetLineControl::clear()
{
int priorState = m_undoState;
m_selstart = 0;
- m_selend = m_text.length();
+ m_selend = m_text.size();
removeSelectedText();
separate();
finishChange(priorState, /*update*/false, /*edited*/false);
@@ -322,7 +285,7 @@ void QWidgetLineControl::setSelection(int start, int length)
if (start == m_selstart && start + length == m_selend && m_cursor == m_selend)
return;
m_selstart = start;
- m_selend = qMin(start + length, (int)m_text.length());
+ m_selend = qMin(start + length, (int)m_text.size());
m_cursor = m_selend;
} else if (length < 0){
if (start == m_selend && start + length == m_selstart && m_cursor == m_selstart)
@@ -365,7 +328,7 @@ void QWidgetLineControl::init(const QString &txt)
m_textLayout.setCacheEnabled(true);
m_text = txt;
updateDisplayText();
- m_cursor = m_text.length();
+ m_cursor = m_text.size();
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
m_keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
m_passwordMaskDelay = theme->themeHint(QPlatformTheme::PasswordMaskDelay).toInt();
@@ -419,7 +382,7 @@ QRect QWidgetLineControl::rectForPos(int pos) const
int w = m_cursorWidth;
int ch = l.height() + 1;
- return QRect(cix-5, 0, w+9, ch);
+ return QRect(cix - 5, 0, w + 9, ch);
}
/*!
@@ -527,14 +490,14 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
if (echoMode() == QLineEdit::PasswordEchoOnEdit && !passwordEchoEditing()) {
updatePasswordEchoEditing(true);
m_selstart = 0;
- m_selend = m_text.length();
+ m_selend = m_text.size();
}
removeSelectedText();
}
int c = m_cursor; // cursor position after insertion of commit string
if (event->replacementStart() <= 0)
- c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
+ c += event->commitString().size() - qMin(-event->replacementStart(), event->replacementLength());
m_cursor += event->replacementStart();
if (m_cursor < 0)
@@ -550,15 +513,15 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
internalInsert(event->commitString());
cursorPositionChanged = true;
} else {
- m_cursor = qBound(0, c, m_text.length());
+ m_cursor = qBound(0, c, m_text.size());
}
for (int i = 0; i < event->attributes().size(); ++i) {
const QInputMethodEvent::Attribute &a = event->attributes().at(i);
if (a.type == QInputMethodEvent::Selection) {
- m_cursor = qBound(0, a.start + a.length, m_text.length());
+ m_cursor = qBound(0, a.start + a.length, m_text.size());
if (a.length) {
- m_selstart = qMax(0, qMin(a.start, m_text.length()));
+ m_selstart = qMax(0, qMin(a.start, m_text.size()));
m_selend = m_cursor;
if (m_selend < m_selstart) {
qSwap(m_selstart, m_selend);
@@ -573,10 +536,24 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
}
}
#ifndef QT_NO_IM
- setPreeditArea(m_cursor, event->preeditString());
+ // in NoEcho mode, the cursor is always at the beginning of the lineedit
+ switch (m_echoMode) {
+ case QLineEdit::NoEcho:
+ setPreeditArea(0, QString());
+ break;
+ case QLineEdit::Password: {
+ QString preeditString = event->preeditString();
+ preeditString.fill(m_passwordCharacter);
+ setPreeditArea(m_cursor, preeditString);
+ break;
+ }
+ default:
+ setPreeditArea(m_cursor, event->preeditString());
+ break;
+ }
#endif //QT_NO_IM
const int oldPreeditCursor = m_preeditCursor;
- m_preeditCursor = event->preeditString().length();
+ m_preeditCursor = event->preeditString().size();
m_hideCursor = false;
QList<QTextLayout::FormatRange> formats;
formats.reserve(event->attributes().size());
@@ -717,7 +694,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
}
#endif
if (validateFromState >= 0 && wasValidInput && !m_validInput) {
- if (m_transactions.count())
+ if (m_transactions.size())
return false;
internalUndo(validateFromState);
m_history.erase(m_history.begin() + m_undoState, m_history.end());
@@ -741,7 +718,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
emit selectionChanged();
}
if (m_cursor == m_lastCursorPos)
- updateMicroFocus();
+ emit updateMicroFocus();
emitCursorPositionChanged();
return true;
}
@@ -759,7 +736,7 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
QString oldText = m_text;
if (m_maskData) {
m_text = maskString(0, txt, true);
- m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ m_text += clearString(m_text.size(), m_maxLength - m_text.size());
if (edited && oldText == m_text)
emit inputRejected();
} else {
@@ -767,11 +744,11 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
}
m_history.clear();
m_modifiedState = m_undoState = 0;
- m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_cursor = (pos < 0 || pos > m_text.size()) ? m_text.size() : pos;
m_textDirty = (oldText != m_text);
const bool changed = finishChange(-1, true, edited);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (changed) {
if (oldText.isEmpty()) {
QAccessibleTextInsertEvent event(accessibleObject(), 0, txt);
@@ -841,35 +818,35 @@ void QWidgetLineControl::internalInsert(const QString &s)
QString ms = maskString(m_cursor, s);
if (ms.isEmpty() && !s.isEmpty())
emit inputRejected();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms);
QAccessible::updateAccessibility(&insertEvent);
#endif
- for (int i = 0; i < (int) ms.length(); ++i) {
+ for (int i = 0; i < (int) ms.size(); ++i) {
addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
}
- m_text.replace(m_cursor, ms.length(), ms);
- m_cursor += ms.length();
+ m_text.replace(m_cursor, ms.size(), ms);
+ m_cursor += ms.size();
m_cursor = nextMaskBlank(m_cursor);
m_textDirty = true;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextCursorEvent event(accessibleObject(), m_cursor);
QAccessible::updateAccessibility(&event);
#endif
} else {
- int remaining = m_maxLength - m_text.length();
+ int remaining = m_maxLength - m_text.size();
if (remaining != 0) {
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, s);
QAccessible::updateAccessibility(&insertEvent);
#endif
m_text.insert(m_cursor, s.left(remaining));
- for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ for (int i = 0; i < (int) s.left(remaining).size(); ++i)
addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
m_textDirty = true;
}
- if (s.length() > remaining)
+ if (s.size() > remaining)
emit inputRejected();
}
}
@@ -887,13 +864,13 @@ void QWidgetLineControl::internalInsert(const QString &s)
*/
void QWidgetLineControl::internalDelete(bool wasBackspace)
{
- if (m_cursor < (int) m_text.length()) {
+ if (m_cursor < (int) m_text.size()) {
cancelPasswordEchoTimer();
if (hasSelectedText())
addCommand(Command(SetSelection, m_cursor, u'\0', m_selstart, m_selend));
addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
m_cursor, m_text.at(m_cursor), -1, -1));
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextRemoveEvent event(accessibleObject(), m_cursor, m_text.at(m_cursor));
QAccessible::updateAccessibility(&event);
#endif
@@ -918,7 +895,7 @@ void QWidgetLineControl::internalDelete(bool wasBackspace)
*/
void QWidgetLineControl::removeSelectedText()
{
- if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ if (m_selstart < m_selend && m_selend <= (int) m_text.size()) {
cancelPasswordEchoTimer();
separate();
int i ;
@@ -934,7 +911,7 @@ void QWidgetLineControl::removeSelectedText()
for (i = m_selend-1; i >= m_selstart; --i)
addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessibleTextRemoveEvent event(accessibleObject(), m_selstart, m_text.mid(m_selstart, m_selend - m_selstart));
QAccessible::updateAccessibility(&event);
#endif
@@ -960,7 +937,7 @@ void QWidgetLineControl::removeSelectedText()
*/
void QWidgetLineControl::parseInputMask(const QString &maskFields)
{
- int delimiter = maskFields.indexOf(QLatin1Char(';'));
+ qsizetype delimiter = maskFields.indexOf(u';');
if (maskFields.isEmpty() || delimiter == 0) {
if (m_maskData) {
m_maskData.reset();
@@ -971,17 +948,17 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
}
if (delimiter == -1) {
- m_blank = QLatin1Char(' ');
+ m_blank = u' ';
m_inputMask = maskFields;
} else {
m_inputMask = maskFields.left(delimiter);
- m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ m_blank = (delimiter + 1 < maskFields.size()) ? maskFields[delimiter + 1] : u' ';
}
// calculate m_maxLength / m_maskData length
m_maxLength = 0;
bool escaped = false;
- for (int i=0; i<m_inputMask.length(); i++) {
+ for (int i=0; i<m_inputMask.size(); i++) {
const auto c = m_inputMask.at(i);
if (escaped) {
++m_maxLength;
@@ -994,10 +971,8 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
continue;
}
- if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
- c != QLatin1Char('<') && c != QLatin1Char('>') &&
- c != QLatin1Char('{') && c != QLatin1Char('}') &&
- c != QLatin1Char('[') && c != QLatin1Char(']'))
+ if (c != u'\\' && c != u'!' && c != u'<' && c != u'>' &&
+ c != u'{' && c != u'}' && c != u'[' && c != u']')
m_maxLength++;
}
@@ -1007,7 +982,7 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
bool s;
bool escape = false;
int index = 0;
- for (int i = 0; i < m_inputMask.length(); i++) {
+ for (int i = 0; i < m_inputMask.size(); i++) {
const auto c = m_inputMask.at(i);
if (escape) {
s = true;
@@ -1016,13 +991,13 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
m_maskData[index].caseMode = m;
index++;
escape = false;
- } else if (c == QLatin1Char('<')) {
- m = MaskInputData::Lower;
- } else if (c == QLatin1Char('>')) {
+ } else if (c == u'<') {
+ m = MaskInputData::Lower;
+ } else if (c == u'>') {
m = MaskInputData::Upper;
- } else if (c == QLatin1Char('!')) {
+ } else if (c == u'!') {
m = MaskInputData::NoCaseMode;
- } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
+ } else if (c != u'{' && c != u'}' && c != u'[' && c != u']') {
switch (c.unicode()) {
case 'A':
case 'a':
@@ -1110,23 +1085,23 @@ bool QWidgetLineControl::isValidInput(QChar key, QChar mask) const
return true;
break;
case '#':
- if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
+ if (key.isNumber() || key == u'+' || key == u'-' || key == m_blank)
return true;
break;
case 'B':
- if (key == QLatin1Char('0') || key == QLatin1Char('1'))
+ if (key == u'0' || key == u'1')
return true;
break;
case 'b':
- if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
+ if (key == u'0' || key == u'1' || key == m_blank)
return true;
break;
case 'H':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
+ if (key.isNumber() || (key >= u'a' && key <= u'f') || (key >= u'A' && key <= u'F'))
return true;
break;
case 'h':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
+ if (key.isNumber() || (key >= u'a' && key <= u'f') || (key >= u'A' && key <= u'F') || key == m_blank)
return true;
break;
default:
@@ -1156,7 +1131,7 @@ bool QWidgetLineControl::hasAcceptableInput(const QString &str) const
if (!m_maskData)
return true;
- if (str.length() != m_maxLength)
+ if (str.size() != m_maxLength)
return false;
for (int i=0; i < m_maxLength; ++i) {
@@ -1191,47 +1166,47 @@ QString QWidgetLineControl::maskString(int pos, const QString &str, bool clear)
QString s = QString::fromLatin1("");
int i = pos;
while (i < m_maxLength) {
- if (strIndex < str.length()) {
+ if (strIndex < str.size()) {
if (m_maskData[i].separator) {
s += m_maskData[i].maskChar;
- if (str[(int)strIndex] == m_maskData[i].maskChar)
+ if (str[strIndex] == m_maskData[i].maskChar)
strIndex++;
++i;
} else {
- if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
+ if (isValidInput(str[strIndex], m_maskData[i].maskChar)) {
switch (m_maskData[i].caseMode) {
case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
+ s += str[strIndex].toUpper();
break;
case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
+ s += str[strIndex].toLower();
break;
default:
- s += str[(int)strIndex];
+ s += str[strIndex];
}
++i;
} else {
// search for separator first
- int n = findInMask(i, true, true, str[(int)strIndex]);
+ int n = findInMask(i, true, true, str[strIndex]);
if (n != -1) {
- if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
+ if (str.size() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[strIndex]))) {
s += QStringView{fill}.mid(i, n - i + 1);
i = n + 1; // update i to find + 1
}
} else {
// search for valid m_blank if not
- n = findInMask(i, true, false, str[(int)strIndex]);
+ n = findInMask(i, true, false, str[strIndex]);
if (n != -1) {
s += QStringView{fill}.mid(i, n - i);
switch (m_maskData[n].caseMode) {
case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
+ s += str[strIndex].toUpper();
break;
case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
+ s += str[strIndex].toLower();
break;
default:
- s += str[(int)strIndex];
+ s += str[strIndex];
}
i = n + 1; // updates i to find + 1
}
@@ -1282,7 +1257,7 @@ QString QWidgetLineControl::stripString(const QString &str) const
return str;
QString s;
- int end = qMin(m_maxLength, (int)str.length());
+ int end = qMin(m_maxLength, (int)str.size());
for (int i = 0; i < end; ++i)
if (m_maskData[i].separator)
s += m_maskData[i].maskChar;
@@ -1420,8 +1395,8 @@ void QWidgetLineControl::emitCursorPositionChanged()
if (m_cursor != m_lastCursorPos) {
const int oldLast = m_lastCursorPos;
m_lastCursorPos = m_cursor;
- cursorPositionChanged(oldLast, m_cursor);
-#ifndef QT_NO_ACCESSIBILITY
+ emit cursorPositionChanged(oldLast, m_cursor);
+#if QT_CONFIG(accessibility)
// otherwise we send a selection update which includes the cursor
if (!hasSelectedText()) {
QAccessibleTextCursorEvent event(accessibleObject(), m_cursor);
@@ -1469,7 +1444,7 @@ void QWidgetLineControl::complete(int key)
return;
int n = 0;
if (key == Qt::Key_Up || key == Qt::Key_Down) {
- if (textAfterSelection().length())
+ if (textAfterSelection().size())
return;
QString prefix = hasSelectedText() ? textBeforeSelection()
: text;
@@ -1658,10 +1633,12 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
break;
#endif
if (!m_completer->currentCompletion().isEmpty() && hasSelectedText()
+ && !m_completer->completionPrefix().isEmpty()
&& textAfterSelection().isEmpty()) {
setText(m_completer->currentCompletion());
inlineCompletionAccepted = true;
}
+ break;
default:
break; // normal key processing
}
@@ -1833,13 +1810,18 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
}
else if (event == QKeySequence::DeleteEndOfWord) {
if (!isReadOnly()) {
- cursorWordForward(true);
- del();
+ if (!hasSelectedText())
+ cursorWordForward(true);
+
+ if (hasSelectedText())
+ del();
}
}
else if (event == QKeySequence::DeleteStartOfWord) {
if (!isReadOnly()) {
- cursorWordBackward(true);
+ if (!hasSelectedText())
+ cursorWordBackward(true);
+
if (hasSelectedText())
del();
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index bb24fe4d5b..2ce0fe7d94 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGETLINECONTROL_P_H
#define QWIDGETLINECONTROL_P_H
@@ -72,6 +36,9 @@
#include <vector>
#include <memory>
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+#endif
#ifdef DrawText
# undef DrawText
#endif
@@ -148,7 +115,7 @@ public:
bool isModified() const { return m_modifiedState != m_undoState; }
void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
- bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
+ bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.size(); }
bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
@@ -183,7 +150,7 @@ public:
}
int start() const { return 0; }
- int end() const { return m_text.length(); }
+ int end() const { return m_text.size(); }
#ifndef QT_NO_CLIPBOARD
void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
@@ -219,7 +186,7 @@ public:
void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
void home(bool mark) { moveCursor(0, mark); }
- void end(bool mark) { moveCursor(m_text.length(), mark); }
+ void end(bool mark) { moveCursor(m_text.size(), mark); }
int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
QRect rectForPos(int pos) const;
@@ -264,7 +231,7 @@ public:
void backspace();
void del();
void deselect() { internalDeselect(); finishChange(); }
- void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
+ void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(), true); }
void insert(const QString &);
void clear();
@@ -310,7 +277,7 @@ public:
#endif
int cursorPosition() const { return m_cursor; }
- void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
+ void setCursorPosition(int pos) { if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
bool fixup();
@@ -320,8 +287,8 @@ public:
QString mask;
if (m_maskData) {
mask = m_inputMask;
- if (m_blank != QLatin1Char(' ')) {
- mask += QLatin1Char(';');
+ if (m_blank != u' ') {
+ mask += u';';
mask += m_blank;
}
}
@@ -549,6 +516,8 @@ private:
// accessibility events are sent for this object
QObject *m_accessibleObject;
+
+ friend class QLineEdit;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index 0cf9457a57..b7ee494e99 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwidgetresizehandler_p.h"
@@ -52,6 +16,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
#define RANGE 4
static bool resizeHorizontalDirectionFixed = false;
@@ -219,7 +185,7 @@ void QWidgetResizeHandler::mouseMoveEvent(QMouseEvent *e)
QPoint pp = globalPos - moveOffset;
// Workaround for window managers which refuse to move a tool window partially offscreen.
- if (QGuiApplication::platformName() == QLatin1String("xcb")) {
+ if (QGuiApplication::platformName() == "xcb"_L1) {
const QRect desktop = QWidgetPrivate::availableScreenGeometry(widget);
pp.rx() = qMax(pp.x(), desktop.left());
pp.ry() = qMax(pp.y(), desktop.top());
diff --git a/src/widgets/widgets/qwidgetresizehandler_p.h b/src/widgets/widgets/qwidgetresizehandler_p.h
index 2390ba074a..d7780a55e6 100644
--- a/src/widgets/widgets/qwidgetresizehandler_p.h
+++ b/src/widgets/widgets/qwidgetresizehandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGETRESIZEHANDLER_P_H
#define QWIDGETRESIZEHANDLER_P_H
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index c9c4c848fc..6dcaeee0c8 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwidgettextcontrol_p.h"
#include "qwidgettextcontrol_p_p.h"
@@ -60,6 +24,7 @@
#endif
#include "qtextdocument.h"
#include "private/qtextdocument_p.h"
+#include "private/qtextdocumentfragment_p.h"
#include "qtextlist.h"
#include "private/qwidgettextcontrol_p.h"
#if QT_CONFIG(style_stylesheet)
@@ -98,10 +63,9 @@
#include "private/qapplication_p.h"
#include "private/qshortcutmap_p.h"
#include <qkeysequence.h>
-#define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) \
- && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \
+#define ACCEL_KEY(k) (!QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) \
&& !QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(k) ? \
- QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
+ u'\t' + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
#else
#define ACCEL_KEY(k) QString()
@@ -111,6 +75,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
// could go into QTextCursor...
static QTextLine currentTextLine(const QTextCursor &cursor)
{
@@ -447,25 +413,30 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
if (!doc) {
if (document) {
doc = document;
- clearDocument = false;
} else {
palette = QApplication::palette("QWidgetTextControl");
doc = new QTextDocument(q);
}
+ clearDocument = false;
_q_documentLayoutChanged();
cursor = QTextCursor(doc);
// #### doc->documentLayout()->setPaintDevice(viewport);
- QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
- QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
- QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
+ QObjectPrivate::connect(doc, &QTextDocument::contentsChanged, this,
+ &QWidgetTextControlPrivate::_q_updateCurrentCharFormatAndSelection);
+ QObjectPrivate::connect(doc, &QTextDocument::cursorPositionChanged, this,
+ &QWidgetTextControlPrivate::_q_emitCursorPosChanged);
+ QObjectPrivate::connect(doc, &QTextDocument::documentLayoutChanged, this,
+ &QWidgetTextControlPrivate::_q_documentLayoutChanged);
// convenience signal forwards
- QObject::connect(doc, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(doc, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(doc, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool)));
- QObject::connect(doc, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int)));
+ QObject::connect(doc, &QTextDocument::undoAvailable, q, &QWidgetTextControl::undoAvailable);
+ QObject::connect(doc, &QTextDocument::redoAvailable, q, &QWidgetTextControl::redoAvailable);
+ QObject::connect(doc, &QTextDocument::modificationChanged, q,
+ &QWidgetTextControl::modificationChanged);
+ QObject::connect(doc, &QTextDocument::blockCountChanged, q,
+ &QWidgetTextControl::blockCountChanged);
}
bool previousUndoRedoState = doc->isUndoRedoEnabled();
@@ -527,7 +498,8 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
q->ensureCursorVisible();
emit q->cursorPositionChanged();
- QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)), Qt::UniqueConnection);
+ QObjectPrivate::connect(doc, &QTextDocument::contentsChange, this,
+ &QWidgetTextControlPrivate::_q_contentsChanged, Qt::UniqueConnection);
}
void QWidgetTextControlPrivate::startDrag()
@@ -607,7 +579,7 @@ void QWidgetTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged
Q_Q(QWidgetTextControl);
if (forceEmitSelectionChanged) {
emit q->selectionChanged();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (q->parent() && q->parent()->isWidgetType()) {
QAccessibleTextSelectionEvent ev(q->parent(), cursor.anchor(), cursor.position());
QAccessible::updateAccessibility(&ev);
@@ -630,7 +602,7 @@ void QWidgetTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged
&& (cursor.position() != lastSelectionPosition
|| cursor.anchor() != lastSelectionAnchor)))) {
emit q->selectionChanged();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (q->parent() && q->parent()->isWidgetType()) {
QAccessibleTextSelectionEvent ev(q->parent(), cursor.anchor(), cursor.position());
QAccessible::updateAccessibility(&ev);
@@ -671,7 +643,7 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC
void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded)
{
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
Q_Q(QWidgetTextControl);
if (QAccessible::isActive() && q->parent() && q->parent()->isWidgetType()) {
@@ -683,7 +655,7 @@ void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, i
QString newText = tmp.selectedText();
// always report the right number of removed chars, but in lack of the real string use spaces
- QString oldText = QString(charsRemoved, QLatin1Char(' '));
+ QString oldText = QString(charsRemoved, u' ');
QAccessibleEvent *ev = nullptr;
if (charsRemoved == 0) {
@@ -707,10 +679,12 @@ void QWidgetTextControlPrivate::_q_documentLayoutChanged()
{
Q_Q(QWidgetTextControl);
QAbstractTextDocumentLayout *layout = doc->documentLayout();
- QObject::connect(layout, SIGNAL(update(QRectF)), q, SIGNAL(updateRequest(QRectF)));
- QObject::connect(layout, SIGNAL(updateBlock(QTextBlock)), q, SLOT(_q_updateBlock(QTextBlock)));
- QObject::connect(layout, SIGNAL(documentSizeChanged(QSizeF)), q, SIGNAL(documentSizeChanged(QSizeF)));
-
+ QObject::connect(layout, &QAbstractTextDocumentLayout::update, q,
+ &QWidgetTextControl::updateRequest);
+ QObjectPrivate::connect(layout, &QAbstractTextDocumentLayout::updateBlock, this,
+ &QWidgetTextControlPrivate::_q_updateBlock);
+ QObject::connect(layout, &QAbstractTextDocumentLayout::documentSizeChanged, q,
+ &QWidgetTextControl::documentSizeChanged);
}
void QWidgetTextControlPrivate::setCursorVisible(bool visible)
@@ -941,6 +915,8 @@ void QWidgetTextControl::setTextCursor(const QTextCursor &cursor, bool selection
#ifndef QT_NO_CLIPBOARD
if (selectionClipboard)
d->setClipboardSelection();
+#else
+ Q_UNUSED(selectionClipboard);
#endif
}
@@ -991,9 +967,12 @@ void QWidgetTextControl::selectAll()
{
Q_D(QWidgetTextControl);
const int selectionLength = qAbs(d->cursor.position() - d->cursor.anchor());
+ const int oldCursorPos = d->cursor.position();
d->cursor.select(QTextCursor::Document);
d->selectionChanged(selectionLength != qAbs(d->cursor.position() - d->cursor.anchor()));
d->cursorIsFocusIndicator = false;
+ if (d->cursor.position() != oldCursorPos)
+ emit cursorPositionChanged();
emit updateRequest();
}
@@ -1282,7 +1261,7 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
// example)
repaintSelection();
- if (e->key() == Qt::Key_Backspace && !(e->modifiers() & ~Qt::ShiftModifier)) {
+ if (e->key() == Qt::Key_Backspace && !(e->modifiers() & ~(Qt::ShiftModifier | Qt::GroupSwitchModifier))) {
QTextBlockFormat blockFmt = cursor.blockFormat();
QTextList *list = cursor.currentList();
if (list && cursor.atBlockStart() && !cursor.hasSelection()) {
@@ -1300,7 +1279,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) {
@@ -1427,16 +1406,14 @@ QRectF QWidgetTextControlPrivate::rectForPosition(int position) const
if (relativePos == preeditPos)
relativePos += preeditCursor;
else if (relativePos > preeditPos)
- relativePos += layout->preeditAreaText().length();
+ relativePos += layout->preeditAreaText().size();
}
QTextLine line = layout->lineForTextPosition(relativePos);
int cursorWidth;
{
bool ok = false;
-#ifndef QT_NO_PROPERTIES
cursorWidth = docLayout->property("cursorWidth").toInt(&ok);
-#endif
if (!ok)
cursorWidth = 1;
}
@@ -1450,7 +1427,7 @@ QRectF QWidgetTextControlPrivate::rectForPosition(int position) const
if (relativePos < line.textLength() - line.textStart())
w = line.cursorToX(relativePos + 1) - x;
else
- w = QFontMetrics(block.layout()->font()).horizontalAdvance(QLatin1Char(' ')); // in sync with QTextLine::draw()
+ w = QFontMetrics(block.layout()->font()).horizontalAdvance(u' '); // in sync with QTextLine::draw()
}
r = QRectF(layoutPos.x() + x, layoutPos.y() + line.y(),
cursorWidth + w, line.height());
@@ -1844,25 +1821,36 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but
}
if (interactionFlags & Qt::LinksAccessibleByMouse) {
- if (!(button & Qt::LeftButton))
+
+ // Ignore event unless left button has been pressed
+ if (!(button & Qt::LeftButton)) {
+ e->ignore();
return;
+ }
const QString anchor = q->anchorAt(pos);
- if (anchor.isEmpty())
+ // Ignore event without selection anchor
+ if (anchor.isEmpty()) {
+ e->ignore();
return;
+ }
if (!cursor.hasSelection()
|| (anchor == anchorOnMousePress && hadSelectionOnMousePress)) {
const int anchorPos = q->hitTest(pos, Qt::ExactHit);
- if (anchorPos != -1) {
- cursor.setPosition(anchorPos);
- QString anchor = anchorOnMousePress;
- anchorOnMousePress = QString();
- activateLinkUnderCursor(anchor);
+ // Ignore event without valid anchor position
+ if (anchorPos < 0) {
+ e->ignore();
+ return;
}
+
+ cursor.setPosition(anchorPos);
+ QString anchor = anchorOnMousePress;
+ anchorOnMousePress = QString();
+ activateLinkUnderCursor(anchor);
}
}
}
@@ -1926,7 +1914,7 @@ bool QWidgetTextControlPrivate::sendMouseEventToInputContext(
QTextLayout *layout = cursor.block().layout();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
- if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length())
+ if (cursorPos < 0 || cursorPos > layout->preeditAreaText().size())
cursorPos = -1;
if (cursorPos >= 0) {
@@ -2047,6 +2035,11 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
|| e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
+ if (!isGettingInput && e->attributes().isEmpty()) {
+ e->ignore();
+ return;
+ }
+
int oldCursorPos = cursor.position();
cursor.beginEditBlock();
@@ -2086,7 +2079,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
QList<QTextLayout::FormatRange> overrides;
overrides.reserve(e->attributes().size());
const int oldPreeditCursor = preeditCursor;
- preeditCursor = e->preeditString().length();
+ preeditCursor = e->preeditString().size();
hideCursor = false;
for (int i = 0; i < e->attributes().size(); ++i) {
const QInputMethodEvent::Attribute &a = e->attributes().at(i);
@@ -2121,7 +2114,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
if (cursor.charFormat().isValid()) {
int start = cursor.position() - block.position();
- int end = start + e->preeditString().length();
+ int end = start + e->preeditString().size();
QList<QTextLayout::FormatRange>::iterator it = overrides.begin();
while (it != overrides.end()) {
@@ -2194,12 +2187,12 @@ QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVa
QTextCursor tmpCursor = d->cursor;
int localPos = d->cursor.position() - block.position();
QString result = block.text().mid(localPos);
- while (result.length() < maxLength) {
+ while (result.size() < maxLength) {
int currentBlock = tmpCursor.blockNumber();
tmpCursor.movePosition(QTextCursor::NextBlock);
if (tmpCursor.blockNumber() == currentBlock)
break;
- result += QLatin1Char('\n') + tmpCursor.block().text();
+ result += u'\n' + tmpCursor.block().text();
}
return QVariant(result);
}
@@ -2220,7 +2213,7 @@ QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVa
}
QString result;
while (numBlocks) {
- result += tmpCursor.block().text() + QLatin1Char('\n');
+ result += tmpCursor.block().text() + u'\n';
tmpCursor.movePosition(QTextCursor::NextBlock);
--numBlocks;
}
@@ -2311,7 +2304,7 @@ void QWidgetTextControlPrivate::editFocusEvent(QEvent *e)
#endif
#ifndef QT_NO_CONTEXTMENU
-static inline void setActionIcon(QAction *action, const QString &name)
+void setActionIcon(QAction *action, const QString &name)
{
const QIcon icon = QIcon::fromTheme(name);
if (!icon.isNull())
@@ -2469,24 +2462,16 @@ void QWidgetTextControl::setOverwriteMode(bool overwrite)
int QWidgetTextControl::cursorWidth() const
{
-#ifndef QT_NO_PROPERTIES
Q_D(const QWidgetTextControl);
return d->doc->documentLayout()->property("cursorWidth").toInt();
-#else
- return 1;
-#endif
}
void QWidgetTextControl::setCursorWidth(int width)
{
Q_D(QWidgetTextControl);
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(width);
-#else
if (width == -1)
- width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr);
+ width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr, qobject_cast<QWidget *>(parent()));
d->doc->documentLayout()->setProperty("cursorWidth", width);
-#endif
d->repaintCursor();
}
@@ -2509,12 +2494,12 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio
Q_D(QWidgetTextControl);
QMultiHash<int, int> hash;
- for (int i = 0; i < d->extraSelections.count(); ++i) {
+ for (int i = 0; i < d->extraSelections.size(); ++i) {
const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i);
hash.insert(esel.cursor.anchor(), i);
}
- for (int i = 0; i < selections.count(); ++i) {
+ for (int i = 0; i < selections.size(); ++i) {
const QTextEdit::ExtraSelection &sel = selections.at(i);
const auto it = hash.constFind(sel.cursor.anchor());
if (it != hash.cend()) {
@@ -2543,8 +2528,8 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio
emit updateRequest(r);
}
- d->extraSelections.resize(selections.count());
- for (int i = 0; i < selections.count(); ++i) {
+ d->extraSelections.resize(selections.size());
+ for (int i = 0; i < selections.size(); ++i) {
d->extraSelections[i].cursor = selections.at(i).cursor;
d->extraSelections[i].format = selections.at(i).format;
}
@@ -2554,7 +2539,7 @@ QList<QTextEdit::ExtraSelection> QWidgetTextControl::extraSelections() const
{
Q_D(const QWidgetTextControl);
QList<QTextEdit::ExtraSelection> selections;
- const int numExtraSelections = d->extraSelections.count();
+ const int numExtraSelections = d->extraSelections.size();
selections.reserve(numExtraSelections);
for (int i = 0; i < numExtraSelections; ++i) {
QTextEdit::ExtraSelection sel;
@@ -2718,8 +2703,8 @@ bool QWidgetTextControl::canInsertFromMimeData(const QMimeData *source) const
if (d->acceptRichText)
return (source->hasText() && !source->text().isEmpty())
|| source->hasHtml()
- || source->hasFormat(QLatin1String("application/x-qrichtext"))
- || source->hasFormat(QLatin1String("application/x-qt-richtext"));
+ || source->hasFormat("application/x-qrichtext"_L1)
+ || source->hasFormat("application/x-qt-richtext"_L1);
else
return source->hasText() && !source->text().isEmpty();
}
@@ -2732,26 +2717,33 @@ void QWidgetTextControl::insertFromMimeData(const QMimeData *source)
bool hasData = false;
QTextDocumentFragment fragment;
+#if QT_CONFIG(textmarkdownreader)
+ const auto formats = source->formats();
+ if (formats.size() && formats.first() == "text/markdown"_L1) {
+ auto s = QString::fromUtf8(source->data("text/markdown"_L1));
+ fragment = QTextDocumentFragment::fromMarkdown(s);
+ hasData = true;
+ } else
+#endif
#ifndef QT_NO_TEXTHTMLPARSER
- if (source->hasFormat(QLatin1String("application/x-qrichtext")) && d->acceptRichText) {
+ if (source->hasFormat("application/x-qrichtext"_L1) && d->acceptRichText) {
// x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore).
- const QString richtext = QLatin1String("<meta name=\"qrichtext\" content=\"1\" />")
- + QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext")));
+ const QString richtext = "<meta name=\"qrichtext\" content=\"1\" />"_L1
+ + QString::fromUtf8(source->data("application/x-qrichtext"_L1));
fragment = QTextDocumentFragment::fromHtml(richtext, d->doc);
hasData = true;
} else if (source->hasHtml() && d->acceptRichText) {
fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc);
hasData = true;
- } else {
- QString text = source->text();
+ }
+#endif // QT_NO_TEXTHTMLPARSER
+ if (!hasData) {
+ const QString text = source->text();
if (!text.isNull()) {
fragment = QTextDocumentFragment::fromPlainText(text);
hasData = true;
}
}
-#else
- fragment = QTextDocumentFragment::fromPlainText(source->text());
-#endif // QT_NO_TEXTHTMLPARSER
if (hasData)
d->cursor.insertFragment(fragment);
@@ -3199,6 +3191,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);
@@ -3425,9 +3460,12 @@ void QUnicodeControlCharacterMenu::menuActionTriggered()
QStringList QTextEditMimeData::formats() const
{
if (!fragment.isEmpty())
- return QStringList() << QString::fromLatin1("text/plain") << QString::fromLatin1("text/html")
+ return QStringList() << u"text/plain"_s << u"text/html"_s
+#if QT_CONFIG(textmarkdownwriter)
+ << u"text/markdown"_s
+#endif
#ifndef QT_NO_TEXTODFWRITER
- << QString::fromLatin1("application/vnd.oasis.opendocument.text")
+ << u"application/vnd.oasis.opendocument.text"_s
#endif
;
else
@@ -3445,7 +3483,10 @@ void QTextEditMimeData::setup() const
{
QTextEditMimeData *that = const_cast<QTextEditMimeData *>(this);
#ifndef QT_NO_TEXTHTMLPARSER
- that->setData(QLatin1String("text/html"), fragment.toHtml().toUtf8());
+ that->setData("text/html"_L1, fragment.toHtml().toUtf8());
+#endif
+#if QT_CONFIG(textmarkdownwriter)
+ that->setData("text/markdown"_L1, fragment.toMarkdown().toUtf8());
#endif
#ifndef QT_NO_TEXTODFWRITER
{
@@ -3453,7 +3494,7 @@ void QTextEditMimeData::setup() const
QTextDocumentWriter writer(&buffer, "ODF");
writer.write(fragment);
buffer.close();
- that->setData(QLatin1String("application/vnd.oasis.opendocument.text"), buffer.data());
+ that->setData("application/vnd.oasis.opendocument.text"_L1, buffer.data());
}
#endif
that->setText(fragment.toPlainText());
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index 54428e542b..9df4c0c810 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGETTEXTCONTROL_P_H
#define QWIDGETTEXTCONTROL_P_H
@@ -93,9 +57,11 @@ class Q_WIDGETS_EXPORT QWidgetTextControl : public QInputControl
Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText)
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags
+ WRITE setTextInteractionFlags)
Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
- Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents WRITE setIgnoreUnusedNavigationEvents)
+ Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents
+ WRITE setIgnoreUnusedNavigationEvents)
public:
explicit QWidgetTextControl(QObject *parent = nullptr);
explicit QWidgetTextControl(const QString &text, QObject *parent = nullptr);
@@ -274,13 +240,8 @@ protected:
private:
Q_DISABLE_COPY_MOVE(QWidgetTextControl)
- Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection())
- Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &))
Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
- Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
- Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int))
};
@@ -315,6 +276,11 @@ private:
mutable QTextDocumentFragment fragment;
};
+#ifndef QT_NO_CONTEXTMENU
+// also used by QLineEdit
+void setActionIcon(QAction *action, const QString &name);
+#endif // QT_NO_CONTEXTMENU
+
QT_END_NAMESPACE
#endif // QWidgetTextControl_H
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
index cc4f867e8e..955a70ecad 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGETTEXTCONTROL_P_P_H
#define QWIDGETTEXTCONTROL_P_P_H
@@ -73,8 +37,9 @@ class QAbstractScrollArea;
class QWidgetTextControlPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QWidgetTextControl)
public:
+ Q_DECLARE_PUBLIC(QWidgetTextControl)
+
QWidgetTextControlPrivate();
bool cursorMoveKeyEvent(QKeyEvent *e);
@@ -178,6 +143,7 @@ public:
bool isPreediting() const;
void commitPreedit();
+ void insertParagraphSeparator();
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
QTextDocument *doc;