summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp56
-rw-r--r--src/widgets/widgets/qabstractspinbox.h7
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h4
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp12
-rw-r--r--src/widgets/widgets/qlabel.cpp3
-rw-r--r--src/widgets/widgets/qlineedit.cpp20
-rw-r--r--src/widgets/widgets/qlineedit.h1
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp5
-rw-r--r--src/widgets/widgets/qmainwindow.cpp4
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp56
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h12
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp6
-rw-r--r--src/widgets/widgets/qspinbox.cpp116
-rw-r--r--src/widgets/widgets/qspinbox.h8
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp6
-rw-r--r--src/widgets/widgets/qsplitter.cpp17
-rw-r--r--src/widgets/widgets/qtabbar.cpp2
-rw-r--r--src/widgets/widgets/qtabbar_p.h2
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp7
-rw-r--r--src/widgets/widgets/qtextedit.cpp3
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp10
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h1
24 files changed, 293 insertions, 71 deletions
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index f059980c5c..0459eadfff 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -100,6 +100,12 @@ QT_BEGIN_NAMESPACE
integer value to signify how many steps were taken. E.g. Pressing
Qt::Key_Down will trigger a call to stepBy(-1).
+ When the user triggers a step whilst holding the Qt::ControlModifier,
+ QAbstractSpinBox steps by 10 instead of making a single step. This
+ step modifier affects wheel events, key events and interaction with
+ the spinbox buttons. Note that on macOS, Control corresponds to the
+ Command key.
+
QAbstractSpinBox also provide a virtual function stepEnabled() to
determine whether stepping up/down is allowed at any point. This
function returns a bitset of StepEnabled.
@@ -640,7 +646,15 @@ void QAbstractSpinBox::stepBy(int steps)
e = AlwaysEmit;
}
if (!dontstep) {
- d->setValue(d->bound(d->value + (d->singleStep * steps), old, steps), e);
+ QVariant singleStep;
+ switch (d->stepType) {
+ case QAbstractSpinBox::StepType::AdaptiveDecimalStepType:
+ singleStep = d->calculateAdaptiveDecimalStep(steps);
+ break;
+ default:
+ singleStep = d->singleStep;
+ }
+ d->setValue(d->bound(d->value + (singleStep * steps), old, steps), e);
} else if (e == AlwaysEmit) {
d->emitSignals(e, old);
}
@@ -829,6 +843,9 @@ void QAbstractSpinBox::changeEvent(QEvent *event)
d->reset();
d->updateEditFieldGeometry();
break;
+ case QEvent::LocaleChange:
+ d->updateEdit();
+ break;
case QEvent::EnabledChange:
if (!isEnabled()) {
d->reset();
@@ -1008,6 +1025,8 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up);
if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled)))
return;
+ if (!isPgUpOrDown && (event->modifiers() & d->stepModifier))
+ steps *= 10;
if (!up)
steps *= -1;
if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
@@ -1134,11 +1153,24 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
void QAbstractSpinBox::wheelEvent(QWheelEvent *event)
{
Q_D(QAbstractSpinBox);
+#ifdef Q_OS_MACOS
+ // If the event comes from a real mouse wheel, rather than a track pad
+ // (Qt::MouseEventSynthesizedBySystem), the shift modifier changes the
+ // scroll orientation to horizontal.
+ // Convert horizontal events back to vertical whilst shift is held.
+ if ((event->modifiers() & Qt::ShiftModifier)
+ && event->source() == Qt::MouseEventNotSynthesized) {
+ d->wheelDeltaRemainder += event->angleDelta().x();
+ } else {
+ d->wheelDeltaRemainder += event->angleDelta().y();
+ }
+#else
d->wheelDeltaRemainder += event->angleDelta().y();
+#endif
const int steps = d->wheelDeltaRemainder / 120;
d->wheelDeltaRemainder -= steps * 120;
if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled))
- stepBy(event->modifiers() & Qt::ControlModifier ? steps * 10 : steps);
+ stepBy(event->modifiers() & d->stepModifier ? steps * 10 : steps);
event->accept();
}
#endif
@@ -1238,18 +1270,19 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
}
if (doStep) {
+ const bool increaseStepRate = QGuiApplication::keyboardModifiers() & d->stepModifier;
const StepEnabled st = stepEnabled();
if (d->buttonState & Up) {
if (!(st & StepUpEnabled)) {
d->reset();
} else {
- stepBy(1);
+ stepBy(increaseStepRate ? 10 : 1);
}
} else if (d->buttonState & Down) {
if (!(st & StepDownEnabled)) {
d->reset();
} else {
- stepBy(-1);
+ stepBy(increaseStepRate ? -10 : -1);
}
}
return;
@@ -1377,8 +1410,9 @@ QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
- acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0),
- showGroupSeparator(0), wheelDeltaRemainder(0)
+ stepModifier(Qt::ControlModifier), acceleration(0), hoverControl(QStyle::SC_None),
+ buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0), showGroupSeparator(0),
+ wheelDeltaRemainder(0)
{
}
@@ -1629,7 +1663,10 @@ void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false
: QAbstractSpinBox::StepDownEnabled))) {
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
- q->stepBy(up ? 1 : -1);
+ int steps = up ? 1 : -1;
+ if (QGuiApplication::keyboardModifiers() & stepModifier)
+ steps *= 10;
+ q->stepBy(steps);
#ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(q, value);
QAccessible::updateAccessibility(&event);
@@ -1898,6 +1935,11 @@ void QAbstractSpinBoxPrivate::clearCache() const
cachedState = QValidator::Acceptable;
}
+QVariant QAbstractSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ Q_UNUSED(steps)
+ return singleStep;
+}
// --- QSpinBoxValidator ---
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 83bf83d779..87d46c7326 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -127,6 +127,13 @@ public:
virtual void fixup(QString &input) const;
virtual void stepBy(int steps);
+
+ enum StepType {
+ DefaultStepType,
+ AdaptiveDecimalStepType
+ };
+ Q_ENUM(StepType)
+
public Q_SLOTS:
void stepUp();
void stepDown();
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index 8f312fa900..fce88e43f4 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -122,6 +122,8 @@ public:
static int variantCompare(const QVariant &arg1, const QVariant &arg2);
static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max);
+ virtual QVariant calculateAdaptiveDecimalStep(int steps) const;
+
QLineEdit *edit;
QString prefix, suffix, specialValueText;
QVariant value, minimum, maximum, singleStep;
@@ -143,6 +145,8 @@ public:
uint cleared : 1;
uint ignoreUpdateEdit : 1;
QAbstractSpinBox::CorrectionMode correctionMode;
+ QAbstractSpinBox::StepType stepType = QAbstractSpinBox::StepType::DefaultStepType;
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
int acceleration;
QStyle::SubControl hoverControl;
QRect hoverRect;
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 75289e9d1f..3026a5b7d6 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -2629,8 +2629,9 @@ void QDockAreaLayout::removePlaceHolder(const QString &name)
QList<int> index = indexOfPlaceHolder(name);
if (!index.isEmpty())
remove(index);
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
if (!index.isEmpty()) {
dwgw->layoutInfo()->remove(index);
@@ -3065,8 +3066,9 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
{
QDockAreaLayoutItem *item = 0;
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
if (!index.isEmpty()) {
dockWidget->setParent(dwgw);
@@ -3175,7 +3177,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
if (!info->tabbed && info->o == o) {
info->item_list[path.constLast()].size = size;
int totalSize = 0;
- foreach (const QDockAreaLayoutItem &item, info->item_list) {
+ for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) {
if (!item.skip()) {
if (totalSize != 0)
totalSize += sep;
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 947da273dd..c624187190 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -1021,9 +1021,8 @@ void QLabel::paintEvent(QPaintEvent *)
QStyleOption opt;
opt.initFrom(this);
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
cssStyle->styleSheetPalette(this, &opt, &opt.palette);
- }
#endif
if (d->control) {
#ifndef QT_NO_SHORTCUT
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ca6aacc16c..27a94740ac 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1676,6 +1676,21 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
*/
/*!
+ \fn void QLineEdit::inputRejected()
+
+ This signal is emitted when the user presses a key that is not
+ considered to be acceptable input. For example, if a key press
+ results in a validator's validate() call to return Invalid.
+ Another case is when trying to enter in more characters beyond the
+ maximum length of the line edit.
+
+ Note: This signal will still be emitted in a case where part of
+ the text is accepted but not all of it is. For example, if there
+ is a maximum length set and the clipboard text is longer than the
+ maximum length when it is pasted.
+*/
+
+/*!
Converts the given key press \a event into a line edit action.
If Return or Enter is pressed and the current text is valid (or
@@ -1946,8 +1961,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
if (!d->placeholderText.isEmpty()) {
const Qt::LayoutDirection layoutDir = d->placeholderText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
const Qt::Alignment alignPhText = QStyle::visualAlignment(layoutDir, QFlag(d->alignment));
- QColor col = pal.text().color();
- col.setAlpha(128);
+ const QColor col = pal.placeholderText().color();
QPen oldpen = p.pen();
p.setPen(col);
Qt::LayoutDirection oldLayoutDir = p.layoutDirection();
@@ -2002,7 +2016,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
// draw text, selections and cursors
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) {
cssStyle->styleSheetPalette(this, &panel, &pal);
}
#endif
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index 6c70a8f44a..de82927f74 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -207,6 +207,7 @@ Q_SIGNALS:
void returnPressed();
void editingFinished();
void selectionChanged();
+ void inputRejected();
protected:
void mousePressEvent(QMouseEvent *) override;
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 0eeff196a8..17d7e298a1 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -216,6 +216,7 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(updateNeeded(QRect)),
q, SLOT(_q_updateNeeded(QRect)));
+ QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected()));
QStyleOptionFrame opt;
q->initStyleOption(&opt);
@@ -348,11 +349,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *)
QWindow *window = nullptr;
if (const QWidget *nativeParent = nativeParentWidget())
window = nativeParent->windowHandle();
- // Note isDown should really use the active state but in most styles
- // this has no proper feedback
QIcon::Mode state = QIcon::Disabled;
if (isEnabled())
- state = isDown() ? QIcon::Selected : QIcon::Normal;
+ state = isDown() ? QIcon::Active : QIcon::Normal;
const QLineEditPrivate *lep = lineEditPrivate();
const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
const QSize iconSize(iconWidth, iconWidth);
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 2014bdabf3..aca38884a7 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1312,8 +1312,12 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
bool QMainWindow::event(QEvent *event)
{
Q_D(QMainWindow);
+
+#if QT_CONFIG(dockwidget)
if (d->layout && d->layout->windowEvent(event))
return true;
+#endif
+
switch (event->type()) {
#if QT_CONFIG(toolbar)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 43c22910f9..053bfbf024 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -426,7 +426,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
}
// Make sure to reparent the possibly floating or hidden QDockWidgets to the parent
- foreach (QDockWidget *dw, findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto dockWidgets = findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidget *dw : dockWidgets) {
bool wasFloating = dw->isFloating();
bool wasHidden = dw->isHidden();
dw->setParent(parentWidget());
@@ -445,7 +446,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
dw->show();
}
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tb, findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly))
+ const auto tabBars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QTabBar *tb : tabBars)
tb->setParent(parentWidget());
#endif
deleteLater();
@@ -1037,10 +1039,10 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const
#if QT_CONFIG(dockwidget)
dockAreaLayout.saveState(stream);
#if QT_CONFIG(tabbar)
- QList<QDockWidgetGroupWindow *> floatingTabs =
+ const QList<QDockWidgetGroupWindow *> floatingTabs =
mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
- foreach (QDockWidgetGroupWindow *floating, floatingTabs) {
+ for (QDockWidgetGroupWindow *floating : floatingTabs) {
if (floating->layoutInfo()->isEmpty())
continue;
stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry();
@@ -1528,9 +1530,9 @@ void QMainWindowLayout::setDocumentMode(bool enabled)
_documentMode = enabled;
// Update the document mode for all tab bars
- foreach (QTabBar *bar, usedTabBars)
+ for (QTabBar *bar : qAsConst(usedTabBars))
bar->setDocumentMode(_documentMode);
- foreach (QTabBar *bar, unusedTabBars)
+ for (QTabBar *bar : qAsConst(unusedTabBars))
bar->setDocumentMode(_documentMode);
}
#endif // QT_CONFIG(tabbar)
@@ -1809,8 +1811,9 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget)
QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget);
if (info)
return info;
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
info = dwgw->layoutInfo()->info(widget);
if (info)
return info;
@@ -2077,8 +2080,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
layoutState.remove(previousPath);
previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget);
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
if (dwgw == currentHoveredFloat)
continue;
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
@@ -2106,8 +2110,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
#if QT_CONFIG(dockwidget)
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
if (!path.isEmpty())
dwgw->layoutInfo()->remove(path);
@@ -2249,7 +2254,8 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
#if QT_CONFIG(dockwidget)
parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ const auto usedTabBarsCopy = usedTabBars; // list potentially modified by animations
+ for (QTabBar *tab_bar : usedTabBarsCopy)
tab_bar->show();
#endif // QT_CONFIG(tabbar)
#endif // QT_CONFIG(dockwidget)
@@ -2533,7 +2539,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
// Check if we are over another floating dock widget
QVarLengthArray<QWidget *, 10> candidates;
- foreach (QObject *c, parentWidget()->children()) {
+ const auto siblings = parentWidget()->children();
+ for (QObject *c : siblings) {
QWidget *w = qobject_cast<QWidget*>(c);
if (!w)
continue;
@@ -2543,7 +2550,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
candidates << w;
if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) {
// Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent.
- foreach (QObject *c, group->children()) {
+ const auto groupChildren = group->children();
+ for (QObject *c : groupChildren) {
if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) {
if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized())
candidates << dw;
@@ -2671,14 +2679,14 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
{
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars();
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups)
used += dwgw->layoutInfo()->usedTabBars();
- }
- QSet<QTabBar*> retired = usedTabBars - used;
+ const QSet<QTabBar*> retired = usedTabBars - used;
usedTabBars = used;
- foreach (QTabBar *tab_bar, retired) {
+ for (QTabBar *tab_bar : retired) {
tab_bar->hide();
while (tab_bar->count() > 0)
tab_bar->removeTab(0);
@@ -2686,10 +2694,10 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
}
if (sep == 1) {
- QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
- QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
+ const QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
+ const QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
usedSeparatorWidgets = usedSeps;
- foreach (QWidget *sepWidget, retiredSeps) {
+ for (QWidget *sepWidget : retiredSeps) {
unusedSeparatorWidgets.append(sepWidget);
}
}
@@ -2731,7 +2739,7 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
#if QT_CONFIG(dockwidget)
if (parentWidget()->isVisible()) {
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ for (QTabBar *tab_bar : qAsConst(usedTabBars))
tab_bar->show();
#endif
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 4ccfb1786e..72cbec2350 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -92,6 +92,7 @@ public:
QPoint hoverPos;
#if QT_CONFIG(dockwidget)
+
#if QT_CONFIG(cursor)
QCursor separatorCursor(const QList<int> &path);
void adjustCursor(const QPoint &pos);
@@ -108,13 +109,15 @@ public:
bool startSeparatorMove(const QPoint &pos);
bool separatorMove(const QPoint &pos);
bool endSeparatorMove(const QPoint &pos);
+ bool windowEvent(QEvent *e);
#endif // QT_CONFIG(dockwidget)
- bool windowEvent(QEvent *e);
};
-#if QT_CONFIG(dockwidget) && QT_CONFIG(cursor)
+#if QT_CONFIG(dockwidget)
+
+#if QT_CONFIG(cursor)
template <typename Layout>
QCursor QMainWindowLayoutSeparatorHelper<Layout>::separatorCursor(const QList<int> &path)
{
@@ -187,14 +190,13 @@ void QMainWindowLayoutSeparatorHelper<Layout>::adjustCursor(const QPoint &pos)
}
}
}
-#endif // QT_CONFIG(cursor) && QT_CONFIG(dockwidget)
+#endif // QT_CONFIG(cursor)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
{
QWidget *w = window();
switch (event->type()) {
-#if QT_CONFIG(dockwidget)
case QEvent::Paint: {
QPainter p(w);
QRegion r = static_cast<QPaintEvent *>(event)->region();
@@ -290,14 +292,12 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
return true;
}
break;
-#endif // QT_CONFIG(dockwidget)
default:
break;
}
return false;
}
-#if QT_CONFIG(dockwidget)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::startSeparatorMove(const QPoint &pos)
{
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 45c01dec80..8639f57ea1 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -471,8 +471,8 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const
ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end());
result.reserve(ylist.size() * xlist.size());
- foreach (int y, ylist)
- foreach (int x, xlist)
+ for (int y : qAsConst(ylist))
+ for (int x : qAsConst(xlist))
result << QRect(QPoint(x, y), size);
return result;
}
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 363647aee0..96635ae505 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2433,7 +2433,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
atAction = d->defaultAction;
// TODO: This works for first level menus, not yet sub menus
} else {
- foreach (QAction *action, d->actions)
+ for (QAction *action : qAsConst(d->actions))
if (action->isEnabled()) {
atAction = action;
break;
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 903a9349ec..f15a846b5e 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -48,6 +48,7 @@
#include <qdrag.h>
#endif
#include <qclipboard.h>
+#include <qmath.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
#endif
@@ -382,6 +383,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
line.setLineWidth(availableWidth);
line.setPosition(QPointF(margin, height));
height += line.height();
+ if (line.leading() < 0)
+ height += qCeil(line.leading());
blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
}
tl->endLayout();
@@ -1927,8 +1930,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
painter.setClipRect(er);
if (d->placeholderVisible) {
- QColor col = d->control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = d->control->palette().placeholderText().color();
painter.setPen(col);
painter.setClipRect(e->rect());
const int margin = int(document()->documentMargin());
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 561215ec85..7f29c0c52c 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -45,6 +45,8 @@
#include <qvalidator.h>
#include <qdebug.h>
+#include <algorithm>
+#include <cmath>
#include <float.h>
QT_BEGIN_NAMESPACE
@@ -75,6 +77,8 @@ public:
}
int displayIntegerBase;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@@ -100,6 +104,8 @@ public:
// When fiddling with the decimals property, we may lose precision in these properties.
double actualMin;
double actualMax;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
@@ -415,6 +421,41 @@ void QSpinBox::setRange(int minimum, int maximum)
}
/*!
+ Sets the step type for the spin box: single step or adaptive
+ decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \sa QAbstractSpinBox::groupSeparator()
+ \since 5.12
+*/
+
+void QSpinBox::setStepType(QAbstractSpinBox::StepType stepType)
+{
+ Q_D(QSpinBox);
+ d->stepType = stepType;
+}
+
+QAbstractSpinBox::StepType QSpinBox::stepType() const
+{
+ Q_D(const QSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QSpinBox::displayIntegerBase
\brief the base used to display the value of the spin box
@@ -847,6 +888,44 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
}
/*!
+ Sets the step type for the spin box: single step or adaptive
+ decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ It also works for any decimal values, 0.041 is increased to 0.042
+ by stepping once.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \sa QAbstractSpinBox::groupSeparator()
+ \since 5.12
+*/
+
+void QDoubleSpinBox::setStepType(StepType stepType)
+{
+ Q_D(QDoubleSpinBox);
+ d->stepType = stepType;
+}
+
+QAbstractSpinBox::StepType QDoubleSpinBox::stepType() const
+{
+ Q_D(const QDoubleSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QDoubleSpinBox::decimals
\brief the precision of the spin box, in decimals
@@ -1078,6 +1157,22 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
return cachedValue;
}
+QVariant QSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const int intValue = value.toInt();
+ const int absValue = qAbs(intValue);
+
+ if (absValue < 100)
+ return 1;
+
+ const bool valueNegative = intValue < 0;
+ const bool stepsNegative = steps < 0;
+ const int signCompensation = (valueNegative == stepsNegative) ? 0 : 1;
+
+ const int log = static_cast<int>(std::log10(absValue - signCompensation)) - 1;
+ return static_cast<int>(std::pow(10, log));
+}
+
// --- QDoubleSpinBoxPrivate ---
/*!
@@ -1303,6 +1398,27 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
return q->textFromValue(f.toDouble());
}
+QVariant QDoubleSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const double doubleValue = value.toDouble();
+ const double minStep = std::pow(10, -decimals);
+ double absValue = qAbs(doubleValue);
+
+ if (absValue < minStep)
+ return minStep;
+
+ const bool valueNegative = doubleValue < 0;
+ const bool stepsNegative = steps < 0;
+ if (valueNegative != stepsNegative)
+ absValue /= 1.01;
+
+ const double shift = std::pow(10, 1 - std::floor(std::log10(absValue)));
+ const double absRounded = round(absValue * shift) / shift;
+ const double log = floorf(std::log10(absRounded)) - 1;
+
+ return std::max(minStep, std::pow(10, log));
+}
+
/*! \reimp */
bool QSpinBox::event(QEvent *event)
{
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index 73489c9a68..d2eac903fb 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -58,6 +58,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
@@ -86,6 +87,9 @@ public:
void setRange(int min, int max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int displayIntegerBase() const;
void setDisplayIntegerBase(int base);
@@ -121,6 +125,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox
Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
public:
explicit QDoubleSpinBox(QWidget *parent = nullptr);
@@ -147,6 +152,9 @@ public:
void setRange(double min, double max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int decimals() const;
void setDecimals(int prec);
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index 468fc272b5..3dc396395f 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -327,7 +327,13 @@ void QSplashScreen::drawContents(QPainter *painter)
cursor.select(QTextCursor::Document);
QTextBlockFormat fmt;
fmt.setAlignment(Qt::Alignment(d->currAlign));
+ fmt.setLayoutDirection(layoutDirection());
cursor.mergeBlockFormat(fmt);
+ const QSizeF txtSize = doc.size();
+ if (d->currAlign & Qt::AlignBottom)
+ r.setTop(r.height() - txtSize.height());
+ else if (d->currAlign & Qt::AlignVCenter)
+ r.setTop(r.height() / 2 - txtSize.height() / 2);
painter->save();
painter->translate(r.topLeft());
doc.drawContents(painter);
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 6ee49aa9f0..9e38c8f18a 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -826,7 +826,7 @@ QSplitterLayoutStruct *QSplitterPrivate::findWidget(QWidget *w) const
if (list.at(i)->widget == w)
return list.at(i);
}
- return 0;
+ return nullptr;
}
@@ -855,7 +855,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show
QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
{
Q_Q(QSplitter);
- QSplitterLayoutStruct *sls = 0;
+ QSplitterLayoutStruct *sls = nullptr;
int i;
int last = list.count();
for (i = 0; i < list.size(); ++i) {
@@ -872,12 +872,9 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
if (sls) {
list.move(i,index);
} else {
- QSplitterHandle *newHandle = 0;
sls = new QSplitterLayoutStruct;
- QString tmp = QLatin1String("qt_splithandle_");
- tmp += w->objectName();
- newHandle = q->createHandle();
- newHandle->setObjectName(tmp);
+ QSplitterHandle *newHandle = q->createHandle();
+ newHandle->setObjectName(QLatin1String("qt_splithandle_") + w->objectName());
sls->handle = newHandle;
sls->widget = w;
w->lower();
@@ -1248,7 +1245,7 @@ QSplitterHandle *QSplitter::handle(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->handle;
}
@@ -1262,7 +1259,7 @@ QWidget *QSplitter::widget(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->widget;
}
@@ -1463,7 +1460,7 @@ void QSplitter::moveSplitter(int pos, int index)
void QSplitter::getRange(int index, int *min, int *max) const
{
Q_D(const QSplitter);
- d->getRange(index, min, 0, 0, max);
+ d->getRange(index, min, nullptr, nullptr, max);
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 8af70d0f9c..c92e38f74a 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -2686,7 +2686,7 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant &cu
priv->moveTab(priv->tabList.indexOf(*tab), current.toInt());
}
-void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State newState)
+void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State)
{
if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab));
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 1092878f2c..f303ed54d1 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -144,7 +144,7 @@ public:
void updateCurrentValue(const QVariant &current) override;
- void updateState(State, State newState) override;
+ void updateState(State newState, State) override;
private:
//these are needed for the callbacks
Tab *tab;
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index fa4dd14c92..46b973bae7 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -163,10 +163,13 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const
fileName = name.toLocalFile();
}
+ if (fileName.isEmpty())
+ return fileName;
+
if (QFileInfo(fileName).isAbsolute())
return fileName;
- foreach (QString path, searchPaths) {
+ for (QString path : qAsConst(searchPaths)) {
if (!path.endsWith(QLatin1Char('/')))
path.append(QLatin1Char('/'));
path.append(fileName);
@@ -1089,6 +1092,8 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)
QByteArray data;
QString fileName = d->findFile(d->resolveUrl(name));
+ if (fileName.isEmpty())
+ return QVariant();
QFile f(fileName);
if (f.open(QFile::ReadOnly)) {
data = f.readAll();
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 8a9a0eaf96..bbcd3ca386 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1518,8 +1518,7 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
layout->setViewport(QRect());
if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
- QColor col = control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = control->palette().placeholderText().color();
p->setPen(col);
const int margin = int(doc->documentMargin());
p->drawText(viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, placeholderText);
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 623ca5b0a1..b5af8e36aa 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -711,10 +711,12 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
if (m_validInput) {
if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy, false);
+ internalSetText(textCopy, cursorCopy, edited);
return true;
}
m_cursor = cursorCopy;
+ } else {
+ emit inputRejected();
}
}
#endif
@@ -762,6 +764,8 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
if (m_maskData) {
m_text = maskString(0, txt, true);
m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ if (edited && oldText == m_text)
+ emit inputRejected();
} else {
m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
}
@@ -839,6 +843,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
if (m_maskData) {
QString ms = maskString(m_cursor, s);
+ if (ms.isEmpty() && !s.isEmpty())
+ emit inputRejected();
#ifndef QT_NO_ACCESSIBILITY
QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms);
QAccessible::updateAccessibility(&insertEvent);
@@ -867,6 +873,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
m_textDirty = true;
}
+ if (s.length() > remaining)
+ emit inputRejected();
}
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index ca70e2c02f..3e33bc0605 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -545,6 +545,7 @@ Q_SIGNALS:
void accepted();
void editingFinished();
void updateNeeded(const QRect &);
+ void inputRejected();
#ifdef QT_KEYPAD_NAVIGATION
void editFocusChange(bool);