diff options
Diffstat (limited to 'src/widgets/widgets')
29 files changed, 371 insertions, 111 deletions
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index f059980c5c..1eafb73ba8 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -100,6 +100,16 @@ QT_BEGIN_NAMESPACE integer value to signify how many steps were taken. E.g. Pressing Qt::Key_Down will trigger a call to stepBy(-1). + When the user triggers a step whilst holding the Qt::ControlModifier, + QAbstractSpinBox steps by 10 instead of making a single step. This + step modifier affects wheel events, key events and interaction with + the spinbox buttons. Note that on macOS, Control corresponds to the + Command key. + + Since Qt 5.12, QStyle::SH_SpinBox_StepModifier can be used to select + which Qt::KeyboardModifier increases the step rate. Qt::NoModifier + disables this feature. + QAbstractSpinBox also provide a virtual function stepEnabled() to determine whether stepping up/down is allowed at any point. This function returns a bitset of StepEnabled. @@ -117,6 +127,13 @@ QT_BEGIN_NAMESPACE */ /*! + \enum QAbstractSpinBox::StepType + + \value DefaultStepType + \value AdaptiveDecimalStepType +*/ + +/*! \fn void QAbstractSpinBox::editingFinished() This signal is emitted editing is finished. This happens when the @@ -640,7 +657,15 @@ void QAbstractSpinBox::stepBy(int steps) e = AlwaysEmit; } if (!dontstep) { - d->setValue(d->bound(d->value + (d->singleStep * steps), old, steps), e); + QVariant singleStep; + switch (d->stepType) { + case QAbstractSpinBox::StepType::AdaptiveDecimalStepType: + singleStep = d->calculateAdaptiveDecimalStep(steps); + break; + default: + singleStep = d->singleStep; + } + d->setValue(d->bound(d->value + (singleStep * steps), old, steps), e); } else if (e == AlwaysEmit) { d->emitSignals(e, old); } @@ -826,9 +851,13 @@ void QAbstractSpinBox::changeEvent(QEvent *event) style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this); if (d->edit) d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this)); + d->stepModifier = static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier, nullptr, this)); d->reset(); d->updateEditFieldGeometry(); break; + case QEvent::LocaleChange: + d->updateEdit(); + break; case QEvent::EnabledChange: if (!isEnabled()) { d->reset(); @@ -1008,6 +1037,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 +1165,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 +1282,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 +1422,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 +1675,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 +1947,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/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 04a44e1f37..e20a0892b4 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3160,7 +3160,6 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) #endif // We've restricted the next couple of lines, because by not calling // viewContainer(), we avoid creating the QComboBoxPrivateContainer. - viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval()); viewContainer()->initialClickPosition = q->mapToGlobal(e->pos()); #ifdef QT_KEYPAD_NAVIGATION } @@ -3169,8 +3168,10 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) // 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. - if (viewContainer()) + if (viewContainer()) { + viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval()); viewContainer()->maybeIgnoreMouseButtonRelease = false; + } } else { #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && lineEdit) { diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 75289e9d1f..3026a5b7d6 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2629,8 +2629,9 @@ void QDockAreaLayout::removePlaceHolder(const QString &name) QList<int> index = indexOfPlaceHolder(name); if (!index.isEmpty()) remove(index); - foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>( - QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) { index = dwgw->layoutInfo()->indexOfPlaceHolder(name); if (!index.isEmpty()) { dwgw->layoutInfo()->remove(index); @@ -3065,8 +3066,9 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { QDockAreaLayoutItem *item = 0; - foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>( - QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) { QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName()); if (!index.isEmpty()) { dockWidget->setParent(dwgw); @@ -3175,7 +3177,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks, if (!info->tabbed && info->o == o) { info->item_list[path.constLast()].size = size; int totalSize = 0; - foreach (const QDockAreaLayoutItem &item, info->item_list) { + for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) { if (!item.skip()) { if (totalSize != 0) totalSize += sep; diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 5d09e14073..60f88df9af 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -288,7 +288,7 @@ void QLabel::setText(const QString &text) return; QWidgetTextControl *oldControl = d->control; - d->control = 0; + d->control = nullptr; d->clearContents(); d->text = text; @@ -303,7 +303,7 @@ void QLabel::setText(const QString &text) d->ensureTextControl(); } else { delete d->control; - d->control = 0; + d->control = nullptr; } if (d->isRichText) { @@ -714,7 +714,7 @@ void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags) d->ensureTextControl(); } else { delete d->control; - d->control = 0; + d->control = nullptr; } if (d->control) @@ -1021,13 +1021,13 @@ void QLabel::paintEvent(QPaintEvent *) QStyleOption opt; opt.initFrom(this); #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) { + if (QStyleSheetStyle* cssStyle = qt_styleSheet(style)) cssStyle->styleSheetPalette(this, &opt, &opt.palette); - } #endif if (d->control) { #ifndef QT_NO_SHORTCUT - const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0); + const bool underline = static_cast<bool>(style->styleHint(QStyle::SH_UnderlineShortcut, + nullptr, this, nullptr)); if (d->shortcutId != 0 && underline != d->shortcutCursor.charFormat().fontUnderline()) { QTextCharFormat fmt; @@ -1294,20 +1294,20 @@ void QLabel::setMovie(QMovie *movie) void QLabelPrivate::clearContents() { delete control; - control = 0; + control = nullptr; isTextLabel = false; hasShortcut = false; #ifndef QT_NO_PICTURE delete picture; - picture = 0; + picture = nullptr; #endif delete scaledpixmap; - scaledpixmap = 0; + scaledpixmap = nullptr; delete cachedimage; - cachedimage = 0; + cachedimage = nullptr; delete pixmap; - pixmap = 0; + pixmap = nullptr; text.clear(); Q_Q(QLabel); @@ -1321,7 +1321,7 @@ void QLabelPrivate::clearContents() QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize))); QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect))); } - movie = 0; + movie = nullptr; #endif #ifndef QT_NO_CURSOR if (onAnchor) { @@ -1428,9 +1428,9 @@ void QLabel::setScaledContents(bool enable) d->scaledcontents = enable; if (!enable) { delete d->scaledpixmap; - d->scaledpixmap = 0; + d->scaledpixmap = nullptr; delete d->cachedimage; - d->cachedimage = 0; + d->cachedimage = nullptr; } update(contentsRect()); } @@ -1629,7 +1629,7 @@ QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos) } if (linkToCopy.isEmpty() && !control) - return 0; + return nullptr; return control->createStandardContextMenu(p, q_func()); } diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index ca6aacc16c..190ff8d2c5 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -497,6 +497,8 @@ void QLineEdit::setClearButtonEnabled(bool enable) d->removeAction(clearAction); delete clearAction; } +#else + Q_UNUSED(enable); #endif // QT_CONFIG(action) } @@ -1676,6 +1678,21 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) */ /*! + \fn void QLineEdit::inputRejected() + + This signal is emitted when the user presses a key that is not + considered to be acceptable input. For example, if a key press + results in a validator's validate() call to return Invalid. + Another case is when trying to enter in more characters beyond the + maximum length of the line edit. + + Note: This signal will still be emitted in a case where part of + the text is accepted but not all of it is. For example, if there + is a maximum length set and the clipboard text is longer than the + maximum length when it is pasted. +*/ + +/*! Converts the given key press \a event into a line edit action. If Return or Enter is pressed and the current text is valid (or @@ -1946,8 +1963,7 @@ void QLineEdit::paintEvent(QPaintEvent *) if (!d->placeholderText.isEmpty()) { const Qt::LayoutDirection layoutDir = d->placeholderText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; const Qt::Alignment alignPhText = QStyle::visualAlignment(layoutDir, QFlag(d->alignment)); - QColor col = pal.text().color(); - col.setAlpha(128); + const QColor col = pal.placeholderText().color(); QPen oldpen = p.pen(); p.setPen(col); Qt::LayoutDirection oldLayoutDir = p.layoutDirection(); @@ -2002,7 +2018,7 @@ void QLineEdit::paintEvent(QPaintEvent *) // draw text, selections and cursors #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) { + if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) { cssStyle->styleSheetPalette(this, &panel, &pal); } #endif diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index 6c70a8f44a..de82927f74 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -207,6 +207,7 @@ Q_SIGNALS: void returnPressed(); void editingFinished(); void selectionChanged(); + void inputRejected(); protected: void mousePressEvent(QMouseEvent *) override; diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 0eeff196a8..33d542abc0 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -216,6 +216,7 @@ void QLineEditPrivate::init(const QString& txt) QObject::connect(control, SIGNAL(updateNeeded(QRect)), q, SLOT(_q_updateNeeded(QRect))); + QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected())); QStyleOptionFrame opt; q->initStyleOption(&opt); @@ -348,11 +349,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *) QWindow *window = nullptr; if (const QWidget *nativeParent = nativeParentWidget()) window = nativeParent->windowHandle(); - // Note isDown should really use the active state but in most styles - // this has no proper feedback QIcon::Mode state = QIcon::Disabled; if (isEnabled()) - state = isDown() ? QIcon::Selected : QIcon::Normal; + state = isDown() ? QIcon::Active : QIcon::Normal; const QLineEditPrivate *lep = lineEditPrivate(); const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16; const QSize iconSize(iconWidth, iconWidth); @@ -466,6 +465,8 @@ void QLineEditPrivate::setClearButtonEnabled(bool enabled) break; } } +#else + Q_UNUSED(enabled); #endif } @@ -483,6 +484,8 @@ void QLineEditPrivate::positionSideWidgets() #if QT_CONFIG(action) if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); +#else + Q_UNUSED(delta); #endif } widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin); @@ -596,6 +599,8 @@ void QLineEditPrivate::removeAction(QAction *action) if (!hasSideWidgets()) // Last widget, remove connection QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); q->update(); +#else + Q_UNUSED(action); #endif // QT_CONFIG(action) } diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 2014bdabf3..aca38884a7 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -1312,8 +1312,12 @@ bool QMainWindow::restoreState(const QByteArray &state, int version) bool QMainWindow::event(QEvent *event) { Q_D(QMainWindow); + +#if QT_CONFIG(dockwidget) if (d->layout && d->layout->windowEvent(event)) return true; +#endif + switch (event->type()) { #if QT_CONFIG(toolbar) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 43c22910f9..053bfbf024 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -426,7 +426,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() } // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent - foreach (QDockWidget *dw, findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly)) { + const auto dockWidgets = findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidget *dw : dockWidgets) { bool wasFloating = dw->isFloating(); bool wasHidden = dw->isHidden(); dw->setParent(parentWidget()); @@ -445,7 +446,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() dw->show(); } #if QT_CONFIG(tabbar) - foreach (QTabBar *tb, findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly)) + const auto tabBars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly); + for (QTabBar *tb : tabBars) tb->setParent(parentWidget()); #endif deleteLater(); @@ -1037,10 +1039,10 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const #if QT_CONFIG(dockwidget) dockAreaLayout.saveState(stream); #if QT_CONFIG(tabbar) - QList<QDockWidgetGroupWindow *> floatingTabs = + const QList<QDockWidgetGroupWindow *> floatingTabs = mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); - foreach (QDockWidgetGroupWindow *floating, floatingTabs) { + for (QDockWidgetGroupWindow *floating : floatingTabs) { if (floating->layoutInfo()->isEmpty()) continue; stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry(); @@ -1528,9 +1530,9 @@ void QMainWindowLayout::setDocumentMode(bool enabled) _documentMode = enabled; // Update the document mode for all tab bars - foreach (QTabBar *bar, usedTabBars) + for (QTabBar *bar : qAsConst(usedTabBars)) bar->setDocumentMode(_documentMode); - foreach (QTabBar *bar, unusedTabBars) + for (QTabBar *bar : qAsConst(unusedTabBars)) bar->setDocumentMode(_documentMode); } #endif // QT_CONFIG(tabbar) @@ -1809,8 +1811,9 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget) QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); if (info) return info; - foreach (QDockWidgetGroupWindow *dwgw, - parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) { info = dwgw->layoutInfo()->info(widget); if (info) return info; @@ -2077,8 +2080,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) layoutState.remove(previousPath); previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget); // Let's remove the widget from any possible group window - foreach (QDockWidgetGroupWindow *dwgw, - parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) { if (dwgw == currentHoveredFloat) continue; QList<int> path = dwgw->layoutInfo()->indexOf(widget); @@ -2106,8 +2110,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) #if QT_CONFIG(dockwidget) // Let's remove the widget from any possible group window - foreach (QDockWidgetGroupWindow *dwgw, - parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) { QList<int> path = dwgw->layoutInfo()->indexOf(widget); if (!path.isEmpty()) dwgw->layoutInfo()->remove(path); @@ -2249,7 +2254,8 @@ void QMainWindowLayout::animationFinished(QWidget *widget) #if QT_CONFIG(dockwidget) parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); #if QT_CONFIG(tabbar) - foreach (QTabBar *tab_bar, usedTabBars) + const auto usedTabBarsCopy = usedTabBars; // list potentially modified by animations + for (QTabBar *tab_bar : usedTabBarsCopy) tab_bar->show(); #endif // QT_CONFIG(tabbar) #endif // QT_CONFIG(dockwidget) @@ -2533,7 +2539,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) // Check if we are over another floating dock widget QVarLengthArray<QWidget *, 10> candidates; - foreach (QObject *c, parentWidget()->children()) { + const auto siblings = parentWidget()->children(); + for (QObject *c : siblings) { QWidget *w = qobject_cast<QWidget*>(c); if (!w) continue; @@ -2543,7 +2550,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) candidates << w; if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) { // Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent. - foreach (QObject *c, group->children()) { + const auto groupChildren = group->children(); + for (QObject *c : groupChildren) { if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) { if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized()) candidates << dw; @@ -2671,14 +2679,14 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat { #if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget) QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars(); - foreach (QDockWidgetGroupWindow *dwgw, - parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + const auto groups = + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly); + for (QDockWidgetGroupWindow *dwgw : groups) used += dwgw->layoutInfo()->usedTabBars(); - } - QSet<QTabBar*> retired = usedTabBars - used; + const QSet<QTabBar*> retired = usedTabBars - used; usedTabBars = used; - foreach (QTabBar *tab_bar, retired) { + for (QTabBar *tab_bar : retired) { tab_bar->hide(); while (tab_bar->count() > 0) tab_bar->removeTab(0); @@ -2686,10 +2694,10 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat } if (sep == 1) { - QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets(); - QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps; + const QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets(); + const QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps; usedSeparatorWidgets = usedSeps; - foreach (QWidget *sepWidget, retiredSeps) { + for (QWidget *sepWidget : retiredSeps) { unusedSeparatorWidgets.append(sepWidget); } } @@ -2731,7 +2739,7 @@ bool QMainWindowLayout::restoreState(QDataStream &stream) #if QT_CONFIG(dockwidget) if (parentWidget()->isVisible()) { #if QT_CONFIG(tabbar) - foreach (QTabBar *tab_bar, usedTabBars) + for (QTabBar *tab_bar : qAsConst(usedTabBars)) tab_bar->show(); #endif diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 4ccfb1786e..72cbec2350 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -92,6 +92,7 @@ public: QPoint hoverPos; #if QT_CONFIG(dockwidget) + #if QT_CONFIG(cursor) QCursor separatorCursor(const QList<int> &path); void adjustCursor(const QPoint &pos); @@ -108,13 +109,15 @@ public: bool startSeparatorMove(const QPoint &pos); bool separatorMove(const QPoint &pos); bool endSeparatorMove(const QPoint &pos); + bool windowEvent(QEvent *e); #endif // QT_CONFIG(dockwidget) - bool windowEvent(QEvent *e); }; -#if QT_CONFIG(dockwidget) && QT_CONFIG(cursor) +#if QT_CONFIG(dockwidget) + +#if QT_CONFIG(cursor) template <typename Layout> QCursor QMainWindowLayoutSeparatorHelper<Layout>::separatorCursor(const QList<int> &path) { @@ -187,14 +190,13 @@ void QMainWindowLayoutSeparatorHelper<Layout>::adjustCursor(const QPoint &pos) } } } -#endif // QT_CONFIG(cursor) && QT_CONFIG(dockwidget) +#endif // QT_CONFIG(cursor) template <typename Layout> bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) { QWidget *w = window(); switch (event->type()) { -#if QT_CONFIG(dockwidget) case QEvent::Paint: { QPainter p(w); QRegion r = static_cast<QPaintEvent *>(event)->region(); @@ -290,14 +292,12 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) return true; } break; -#endif // QT_CONFIG(dockwidget) default: break; } return false; } -#if QT_CONFIG(dockwidget) template <typename Layout> bool QMainWindowLayoutSeparatorHelper<Layout>::startSeparatorMove(const QPoint &pos) { diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index 45c01dec80..8639f57ea1 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -471,8 +471,8 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end()); result.reserve(ylist.size() * xlist.size()); - foreach (int y, ylist) - foreach (int x, xlist) + for (int y : qAsConst(ylist)) + for (int x : qAsConst(xlist)) result << QRect(QPoint(x, y), size); return result; } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 363647aee0..96635ae505 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2433,7 +2433,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) atAction = d->defaultAction; // TODO: This works for first level menus, not yet sub menus } else { - foreach (QAction *action, d->actions) + for (QAction *action : qAsConst(d->actions)) if (action->isEnabled()) { atAction = action; break; diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 86d927e919..628f818b5e 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -46,7 +46,7 @@ #include <QtGui/qicon.h> #include <QtWidgets/qaction.h> -#ifdef Q_OS_OSX +#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC) Q_FORWARD_DECLARE_OBJC_CLASS(NSMenu); #endif @@ -81,7 +81,7 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); -#ifdef Q_QDOC +#ifdef Q_CLANG_QDOC template<typename PointerToMemberFunction> QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); template<typename Functor> @@ -151,7 +151,7 @@ public: connect(result, &QAction::triggered, std::move(slot)); return result; } -#endif // !Q_QDOC +#endif // !Q_CLANG_QDOC QAction *addMenu(QMenu *menu); QMenu *addMenu(const QString &title); @@ -211,7 +211,7 @@ public: QPlatformMenu *platformMenu(); void setPlatformMenu(QPlatformMenu *platformMenu); -#ifdef Q_OS_OSX +#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC) NSMenu* toNSMenu(); void setAsDockMenu(); #endif diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 0d680fb4dc..0872da803d 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -73,6 +73,7 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla /*! + \fn NSMenu *QMenu::toNSMenu() \since 5.2 Returns the native NSMenu for this menu. Available on \macos only. @@ -94,6 +95,7 @@ NSMenu *QMenu::toNSMenu() /*! + \fn void QMenu::setAsDockMenu() \since 5.2 Set this menu to be the dock menu available by option-clicking @@ -149,6 +151,7 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* #if QT_CONFIG(menubar) /*! + \fn NSMenu *QMenuBar::toNSMenu() \since 5.2 Returns the native NSMenu for this menu bar. Available on \macos only. diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h index 2f071e7e3b..cf6663f94a 100644 --- a/src/widgets/widgets/qmenubar.h +++ b/src/widgets/widgets/qmenubar.h @@ -67,7 +67,7 @@ public: QAction *addAction(const QString &text); QAction *addAction(const QString &text, const QObject *receiver, const char* member); -#ifdef Q_QDOC +#ifdef Q_CLANG_QDOC template<typename Obj, typename PointerToMemberFunctionOrFunctor> QAction *addAction(const QString &text, const Obj *receiver, PointerToMemberFunctionOrFunctor method); template<typename Functor> @@ -91,7 +91,7 @@ public: connect(result, &QAction::triggered, std::move(slot)); return result; } -#endif // !Q_QDOC +#endif // !Q_CLANG_QDOC QAction *addMenu(QMenu *menu); QMenu *addMenu(const QString &title); @@ -121,7 +121,7 @@ public: void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner); QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; -#ifdef Q_OS_OSX +#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC) NSMenu* toNSMenu(); #endif diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index a4c463fb5b..252d5a79df 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -48,6 +48,7 @@ #include <qdrag.h> #endif #include <qclipboard.h> +#include <qmath.h> #if QT_CONFIG(menu) #include <qmenu.h> #endif @@ -382,6 +383,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block) line.setLineWidth(availableWidth); line.setPosition(QPointF(margin, height)); height += line.height(); + if (line.leading() < 0) + height += qCeil(line.leading()); blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin); } tl->endLayout(); @@ -1927,8 +1930,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) painter.setClipRect(er); if (d->placeholderVisible) { - QColor col = d->control->palette().text().color(); - col.setAlpha(128); + const QColor col = d->control->palette().placeholderText().color(); painter.setPen(col); painter.setClipRect(e->rect()); const int margin = int(document()->documentMargin()); diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index 561215ec85..dcf3906dd7 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,47 @@ void QSpinBox::setRange(int minimum, int maximum) } /*! + Sets the step type for the spin box to \a stepType, which is 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. + + \since 5.12 +*/ + +void QSpinBox::setStepType(QAbstractSpinBox::StepType stepType) +{ + Q_D(QSpinBox); + d->stepType = stepType; +} + +/*! + \property QSpinBox::stepType + \brief The step type. + + The step type can be single step or adaptive decimal step. +*/ + +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 +894,50 @@ void QDoubleSpinBox::setRange(double minimum, double maximum) } /*! + Sets the step type for the spin box to \a stepType, which is 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. + + \since 5.12 +*/ + +void QDoubleSpinBox::setStepType(StepType stepType) +{ + Q_D(QDoubleSpinBox); + d->stepType = stepType; +} + +/*! + \property QDoubleSpinBox::stepType + \brief The step type. + + The step type can be single step or adaptive decimal step. +*/ + +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 +1169,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 +1410,27 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const return q->textFromValue(f.toDouble()); } +QVariant QDoubleSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const +{ + const double doubleValue = value.toDouble(); + const double minStep = std::pow(10, -decimals); + double absValue = qAbs(doubleValue); + + if (absValue < minStep) + return minStep; + + const bool valueNegative = doubleValue < 0; + const bool stepsNegative = steps < 0; + if (valueNegative != stepsNegative) + absValue /= 1.01; + + const double shift = std::pow(10, 1 - std::floor(std::log10(absValue))); + const double absRounded = round(absValue * shift) / shift; + const double log = floorf(std::log10(absRounded)) - 1; + + return std::max(minStep, std::pow(10, log)); +} + /*! \reimp */ bool QSpinBox::event(QEvent *event) { diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h index 73489c9a68..d2eac903fb 100644 --- a/src/widgets/widgets/qspinbox.h +++ b/src/widgets/widgets/qspinbox.h @@ -58,6 +58,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox Q_PROPERTY(int minimum READ minimum WRITE setMinimum) Q_PROPERTY(int maximum READ maximum WRITE setMaximum) Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep) + Q_PROPERTY(StepType stepType READ stepType WRITE setStepType) Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true) Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase) @@ -86,6 +87,9 @@ public: void setRange(int min, int max); + StepType stepType() const; + void setStepType(StepType stepType); + int displayIntegerBase() const; void setDisplayIntegerBase(int base); @@ -121,6 +125,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox Q_PROPERTY(double minimum READ minimum WRITE setMinimum) Q_PROPERTY(double maximum READ maximum WRITE setMaximum) Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) + Q_PROPERTY(StepType stepType READ stepType WRITE setStepType) Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true) public: explicit QDoubleSpinBox(QWidget *parent = nullptr); @@ -147,6 +152,9 @@ public: void setRange(double min, double max); + StepType stepType() const; + void setStepType(StepType stepType); + int decimals() const; void setDecimals(int prec); diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index 44b9f7d9a1..277d2fd99f 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -327,7 +327,13 @@ void QSplashScreen::drawContents(QPainter *painter) cursor.select(QTextCursor::Document); QTextBlockFormat fmt; fmt.setAlignment(Qt::Alignment(d->currAlign)); + fmt.setLayoutDirection(layoutDirection()); cursor.mergeBlockFormat(fmt); + const QSizeF txtSize = doc.size(); + if (d->currAlign & Qt::AlignBottom) + r.setTop(r.height() - txtSize.height()); + else if (d->currAlign & Qt::AlignVCenter) + r.setTop(r.height() / 2 - txtSize.height() / 2); painter->save(); painter->translate(r.topLeft()); doc.drawContents(painter); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 6ee49aa9f0..9e38c8f18a 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -826,7 +826,7 @@ QSplitterLayoutStruct *QSplitterPrivate::findWidget(QWidget *w) const if (list.at(i)->widget == w) return list.at(i); } - return 0; + return nullptr; } @@ -855,7 +855,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w) { Q_Q(QSplitter); - QSplitterLayoutStruct *sls = 0; + QSplitterLayoutStruct *sls = nullptr; int i; int last = list.count(); for (i = 0; i < list.size(); ++i) { @@ -872,12 +872,9 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w) if (sls) { list.move(i,index); } else { - QSplitterHandle *newHandle = 0; sls = new QSplitterLayoutStruct; - QString tmp = QLatin1String("qt_splithandle_"); - tmp += w->objectName(); - newHandle = q->createHandle(); - newHandle->setObjectName(tmp); + QSplitterHandle *newHandle = q->createHandle(); + newHandle->setObjectName(QLatin1String("qt_splithandle_") + w->objectName()); sls->handle = newHandle; sls->widget = w; w->lower(); @@ -1248,7 +1245,7 @@ QSplitterHandle *QSplitter::handle(int index) const { Q_D(const QSplitter); if (index < 0 || index >= d->list.size()) - return 0; + return nullptr; return d->list.at(index)->handle; } @@ -1262,7 +1259,7 @@ QWidget *QSplitter::widget(int index) const { Q_D(const QSplitter); if (index < 0 || index >= d->list.size()) - return 0; + return nullptr; return d->list.at(index)->widget; } @@ -1463,7 +1460,7 @@ void QSplitter::moveSplitter(int pos, int index) void QSplitter::getRange(int index, int *min, int *max) const { Q_D(const QSplitter); - d->getRange(index, min, 0, 0, max); + d->getRange(index, min, nullptr, nullptr, max); } diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 8af70d0f9c..5959dd0ae4 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -74,6 +74,23 @@ QT_BEGIN_NAMESPACE +namespace { +class CloseButton : public QAbstractButton +{ + Q_OBJECT + +public: + explicit CloseButton(QWidget *parent = 0); + + QSize sizeHint() const override; + QSize minimumSizeHint() const override + { return sizeHint(); } + void enterEvent(QEvent *event) override; + void leaveEvent(QEvent *event) override; + void paintEvent(QPaintEvent *event) override; +}; +} + QMovableTabWidget::QMovableTabWidget(QWidget *parent) : QWidget(parent) { @@ -2686,7 +2703,7 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant &cu priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); } -void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State newState) +void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State) { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); } @@ -2695,5 +2712,4 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State QT_END_NAMESPACE #include "moc_qtabbar.cpp" - -#include "moc_qtabbar_p.cpp" +#include "qtabbar.moc" diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index 1092878f2c..3948b42bc1 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -144,7 +144,7 @@ public: void updateCurrentValue(const QVariant ¤t) override; - void updateState(State, State newState) override; + void updateState(State newState, State) override; private: //these are needed for the callbacks Tab *tab; @@ -271,21 +271,6 @@ public: }; -class CloseButton : public QAbstractButton -{ - Q_OBJECT - -public: - explicit CloseButton(QWidget *parent = 0); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override - { return sizeHint(); } - void enterEvent(QEvent *event) override; - void leaveEvent(QEvent *event) override; - void paintEvent(QPaintEvent *event) override; -}; - QT_END_NAMESPACE #endif diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index fa4dd14c92..46b973bae7 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -163,10 +163,13 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const fileName = name.toLocalFile(); } + if (fileName.isEmpty()) + return fileName; + if (QFileInfo(fileName).isAbsolute()) return fileName; - foreach (QString path, searchPaths) { + for (QString path : qAsConst(searchPaths)) { if (!path.endsWith(QLatin1Char('/'))) path.append(QLatin1Char('/')); path.append(fileName); @@ -1089,6 +1092,8 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name) QByteArray data; QString fileName = d->findFile(d->resolveUrl(name)); + if (fileName.isEmpty()) + return QVariant(); QFile f(fileName); if (f.open(QFile::ReadOnly)) { data = f.readAll(); diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index 5790b1e32e..3a368651de 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -1518,8 +1518,7 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e) layout->setViewport(QRect()); if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) { - QColor col = control->palette().text().color(); - col.setAlpha(128); + const QColor col = control->palette().placeholderText().color(); p->setPen(col); const int margin = int(doc->documentMargin()); p->drawText(viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, placeholderText); diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h index b813cd5e2c..a788d30450 100644 --- a/src/widgets/widgets/qtoolbarlayout_p.h +++ b/src/widgets/widgets/qtoolbarlayout_p.h @@ -97,7 +97,7 @@ public: void insertAction(int index, QAction *action); int indexOf(QAction *action) const; - int indexOf(QWidget *widget) const override { return QLayout::indexOf(widget); } + using QLayout::indexOf; // bring back the hidden members bool layoutActions(const QSize &size); QSize expandedSize(const QSize &size) const; diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index c4a928410b..cf2d885b52 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -711,10 +711,12 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid); if (m_validInput) { if (m_text != textCopy) { - internalSetText(textCopy, cursorCopy, false); + internalSetText(textCopy, cursorCopy, edited); return true; } m_cursor = cursorCopy; + } else { + emit inputRejected(); } } #endif @@ -762,6 +764,8 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite if (m_maskData) { m_text = maskString(0, txt, true); m_text += clearString(m_text.length(), m_maxLength - m_text.length()); + if (edited && oldText == m_text) + emit inputRejected(); } else { m_text = txt.isEmpty() ? txt : txt.left(m_maxLength); } @@ -839,6 +843,8 @@ void QWidgetLineControl::internalInsert(const QString &s) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); if (m_maskData) { QString ms = maskString(m_cursor, s); + if (ms.isEmpty() && !s.isEmpty()) + emit inputRejected(); #ifndef QT_NO_ACCESSIBILITY QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms); QAccessible::updateAccessibility(&insertEvent); @@ -867,6 +873,8 @@ void QWidgetLineControl::internalInsert(const QString &s) addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1)); m_textDirty = true; } + if (s.length() > remaining) + emit inputRejected(); } } diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index ca70e2c02f..3e33bc0605 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -545,6 +545,7 @@ Q_SIGNALS: void accepted(); void editingFinished(); void updateNeeded(const QRect &); + void inputRejected(); #ifdef QT_KEYPAD_NAVIGATION void editFocusChange(bool); |