diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/dialogs/qfilesystemmodel.cpp | 7 | ||||
-rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 2 | ||||
-rw-r--r-- | src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc | 10 | ||||
-rw-r--r-- | src/widgets/itemviews/qtreeview.cpp | 4 | ||||
-rw-r--r-- | src/widgets/itemviews/qtreewidget.cpp | 18 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 5 | ||||
-rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 9 | ||||
-rw-r--r-- | src/widgets/widgets/qcombobox.cpp | 43 | ||||
-rw-r--r-- | src/widgets/widgets/qcombobox_p.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qdockwidget.cpp | 22 | ||||
-rw-r--r-- | src/widgets/widgets/qmdisubwindow.cpp | 31 | ||||
-rw-r--r-- | src/widgets/widgets/qmdisubwindow_p.h | 1 |
12 files changed, 113 insertions, 40 deletions
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 0db06e9b71..c083b0eff1 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -397,8 +397,11 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (absolutePath.endsWith(QLatin1Char('/'))) trailingSeparator = QLatin1String("\\"); int r = 0; - QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); - if (!root.children.contains(host.toLower())) { + auto rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); + auto it = root.children.constFind(host); + if (it != root.children.cend()) { + host = it.key(); // Normalize case for lookup in visibleLocation() + } else { if (pathElements.count() == 1 && !absolutePath.endsWith(QLatin1Char('/'))) return rootNode; QFileInfo info(host); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 4e7a4a65e3..be6b4a2398 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -2046,7 +2046,7 @@ int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon ico void QMessageBoxPrivate::retranslateStrings() { #if QT_CONFIG(textedit) - if (detailsButton) + if (detailsButton && detailsText) detailsButton->setLabel(detailsText->isHidden() ? ShowLabel : HideLabel); #endif } diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index 3319b032cc..8dc68117aa 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -2167,7 +2167,7 @@ subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSizeGrip, QSpinBox, - QSplitter, QStatusBar, QTextEdit, and QToolTip. + QSplitter, QStatusBar, QTextEdit, QToolButton, and QToolTip. If this property is not specified, the minimum height is derived based on the widget's contents and the style. @@ -2179,6 +2179,9 @@ \snippet code/doc_src_stylesheet.qdoc 66 + \note Setting this property might allow widgets to shrink + smaller than the space required for the contents. + See also \l{#min-width-prop}{min-width}. \row @@ -2190,7 +2193,7 @@ subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSizeGrip, QSpinBox, - QSplitter, QStatusBar, QTextEdit, and QToolTip. + QSplitter, QStatusBar, QTextEdit, QToolButton, and QToolTip. If this property is not specified, the minimum width is derived based on the widget's contents and the style. @@ -2202,6 +2205,9 @@ \snippet code/doc_src_stylesheet.qdoc 67 + \note Setting this property might allow widgets to shrink + smaller than the space required for the contents. + See also \l{#min-height-prop}{min-height}. \row diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index b778ef9a47..69ab0bb958 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1448,7 +1448,8 @@ void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, c void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const { Q_D(const QTreeView); - const QVector<QTreeViewItem> viewItems = d->viewItems; + // d->viewItems changes when posted layouts are executed in itemDecorationAt, so don't copy + const QVector<QTreeViewItem> &viewItems = d->viewItems; QStyleOptionViewItem option = d->viewOptionsV1(); const QStyle::State state = option.state; @@ -3459,6 +3460,7 @@ int QTreeViewPrivate::indentationForItem(int item) const int QTreeViewPrivate::itemHeight(int item) const { + Q_ASSERT(item < viewItems.count()); if (uniformRowHeights) return defaultItemHeight; if (viewItems.isEmpty()) diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index b795b79c28..81aed27361 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -508,22 +508,18 @@ bool QTreeModel::insertColumns(int column, int count, const QModelIndex &parent) bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) { if (count < 1 || row < 0 || (row + count) > rowCount(parent)) return false; - - beginRemoveRows(parent, row, row + count - 1); - - QSignalBlocker blocker(this); - - QTreeWidgetItem *itm = item(parent); + QTreeWidgetItem *parentItem = item(parent); + // if parentItem is valid, begin/end RemoveRows is handled by takeChild below + if (!parentItem) + beginRemoveRows(parent, row, row + count - 1); for (int i = row + count - 1; i >= row; --i) { - QTreeWidgetItem *child = itm ? itm->takeChild(i) : rootItem->children.takeAt(i); + QTreeWidgetItem *child = parentItem ? parentItem->takeChild(i) : rootItem->children.takeAt(i); Q_ASSERT(child); child->view = nullptr; delete child; - child = nullptr; } - blocker.unblock(); - - endRemoveRows(); + if (!parentItem) + endRemoveRows(); return true; } diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index d4ff9083f1..09bc15da32 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1386,6 +1386,11 @@ QRect QLayout::alignmentRect(const QRect &r) const */ void QLayout::removeWidget(QWidget *widget) { + if (Q_UNLIKELY(!widget)) { + qWarning("QLayout::removeWidget: Cannot remove a null widget."); + return; + } + int i = 0; QLayoutItem *child; while ((child = itemAt(i))) { diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 34f23d1b19..2ab9756f8d 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -121,6 +121,9 @@ #if QT_CONFIG(toolbar) #include <QtWidgets/qtoolbar.h> #endif +#if QT_CONFIG(pushbutton) +#include <QtWidgets/qpushbutton.h> +#endif #include <QtGui/qpainterpath.h> #include <QtGui/qscreen.h> @@ -2928,6 +2931,12 @@ void QStyleSheetStyle::polish(QWidget *w) if (!rule.hasBackground() || rule.background()->isTransparent() || rule.hasBox() || (!rule.hasNativeBorder() && !rule.border()->isOpaque())) w->setAttribute(Qt::WA_OpaquePaintEvent, false); + if (rule.hasBox() || !rule.hasNativeBorder() +#if QT_CONFIG(pushbutton) + || (qobject_cast<QPushButton *>(w)) +#endif + ) + w->setAttribute(Qt::WA_MacShowFocusRect, false); } } diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 9bc346704f..7a496c27e0 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -547,8 +547,6 @@ 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))); @@ -561,7 +559,7 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView // Some styles (Mac) have a margin at the top and bottom of the popup. layout->insertSpacing(0, 0); layout->addSpacing(0); - updateTopBottomMargin(); + updateStyleSettings(); } void QComboBoxPrivateContainer::scrollItemView(int action) @@ -744,14 +742,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); } @@ -2896,13 +2900,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() @@ -2945,6 +2951,11 @@ void QComboBox::showPopup() } } container->show(); + if (!neededHorizontalScrollBar && needHorizontalScrollBar()) { + listRect.adjust(0, 0, 0, sb->height()); + container->setGeometry(listRect); + } + container->updateScrollers(); view()->setFocus(); @@ -3114,6 +3125,8 @@ 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: diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index d7b2457c49..45580ba943 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -223,6 +223,7 @@ public: int topMargin() const; int bottomMargin() const { return topMargin(); } void updateTopBottomMargin(); + void updateStyleSettings(); QTimer blockMouseReleaseTimer; QBasicTimer adjustSizeTimer; diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 4663eda9eb..807d84db95 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -973,13 +973,27 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) && mwlayout->pluggingWidget == nullptr && (event->pos() - state->pressPos).manhattanLength() > QApplication::startDragDistance()) { - startDrag(); - q->grabMouse(); - ret = true; + +#ifdef Q_OS_MACOS + if (windowHandle()) { + // 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 + { + startDrag(); + 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->globalPos() - state->pressPos - windowMarginOffset; diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index c34d0ec8fc..15ef120d5e 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -259,11 +259,28 @@ 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(""); } @@ -278,11 +295,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; } } diff --git a/src/widgets/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h index d3513b6708..043cf92201 100644 --- a/src/widgets/widgets/qmdisubwindow_p.h +++ b/src/widgets/widgets/qmdisubwindow_p.h @@ -286,6 +286,7 @@ public: #endif void updateInternalWindowTitle(); QString originalWindowTitle(); + QString originalWindowTitleHelper() const; void setNewWindowTitle(); inline int titleBarHeight() const |