From 0d9208cecbbd9ed08e4ffb6540729668e3bd7754 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 15 Jan 2018 12:59:22 -0800 Subject: QMacStyle: Revert state changes for PE_IndicatorMenuCheckMark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The changes introduced in 0e810e27a5e5a6c2e244ca439fbdf4f4ccc5b3da turn out to be incompatible with our style sheets styling. We partially revert the style option state check, so that the look for a highlighted PE_IndicatorMenuCheckMark only depends on State_On, as it's expected in QWindowsStyle and QCommonStyle. [ChangeLog][QtWidgets][QMacStyle] PE_IndicatorMenuCheckMark goes back to only depend on State_On for its highlighted look. Change-Id: I20f8e712196b5515bd5528ff6eedcdca9df5856f Task-number: QTBUG-65773 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/styles/qmacstyle_mac.mm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index f45bf7011f..e6436f82a6 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3389,13 +3389,12 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } break; case PE_IndicatorMenuCheckMark: { - if (!(opt->state & State_On)) - break; QColor pc; - if (opt->state & State_Selected) + if (opt->state & State_On) pc = opt->palette.highlightedText().color(); else pc = opt->palette.text().color(); + QCFType checkmarkColor = CGColorCreateGenericRGB(static_cast(pc.redF()), static_cast(pc.greenF()), static_cast(pc.blueF()), @@ -4493,8 +4492,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter const int xp = contentRect.x() + macItemFrame; checkmarkOpt.rect = QRect(xp, contentRect.y() - checkmarkOpt.fontMetrics.descent(), mw, mh); - checkmarkOpt.state |= State_On; // Always on. Never rendered when off. - checkmarkOpt.state.setFlag(State_Selected, active); + checkmarkOpt.state.setFlag(State_On, active); checkmarkOpt.state.setFlag(State_Enabled, enabled); if (widgetSize == QAquaSizeMini) checkmarkOpt.state |= State_Mini; -- cgit v1.2.3 From 9de2ef6f5ab3b21b4e1679e010ee488193cb41e4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Jan 2018 08:23:55 +0100 Subject: QWidget: Fix a crash when platform window creation fails Add a check on the platform window to QWidgetPrivate::create_sys(). Task-number: QTBUG-65783 Change-Id: I077882e1cf22ef49bb6f578f7460493ef48c9627 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b38565493e..1fea3836ec 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1480,7 +1480,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (q->windowType() != Qt::Desktop || q->testAttribute(Qt::WA_NativeWindow)) { win->create(); // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. - win->handle()->setFrameStrutEventsEnabled(true); + if (QPlatformWindow *platformWindow = win->handle()) + platformWindow->setFrameStrutEventsEnabled(true); } data.window_flags = win->flags(); -- cgit v1.2.3 From 631f68c97280436b4d241865d9a1d33fc9444691 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 15 Jan 2018 13:34:28 -0800 Subject: QFusionStyle: Set alpha on color before creating pen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This affected PE_IndicatorCheckBox in some cases. Change-Id: I6f10dabd2ca4093f4c1bdaa2bd0ebf73c02e8d12 Task-number: QTBUG-65737 Reviewed-by: Friedemann Kleint Reviewed-by: Yulong Bai Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qfusionstyle.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 0b56c1e3a8..e6ad0fc898 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -798,16 +798,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->setPen(QPen(checkMarkColor, 1)); painter->setBrush(gradient); painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding)); - - } else if (checkbox->state & (State_On)) { + } else if (checkbox->state & State_On) { qreal penWidth = QStyleHelper::dpiScaled(1.8); penWidth = qMax(penWidth , 0.18 * rect.height()); penWidth = qMin(penWidth , 0.30 * rect.height()); - QPen checkPen = QPen(checkMarkColor, penWidth); checkMarkColor.setAlpha(210); - painter->translate(-0.8, 0.5); - painter->setPen(checkPen); + painter->setPen(QPen(checkMarkColor, penWidth)); painter->setBrush(Qt::NoBrush); + painter->translate(-0.8, 0.5); // Draw checkmark QPainterPath path; -- cgit v1.2.3 From 0236e3ab94508b700a11ab83fab7bbd39ee651bf Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 15 Jan 2018 18:03:36 -0800 Subject: QStyleSheetsStyle: Avoid possible division by zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5a7588c07106227e2a8b5e1f180230ef5b0342d1 Task-number: QTBUG-65228 Reviewed-by: Friedemann Kleint Reviewed-by: Alexandru Croitor Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qstylesheetstyle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 8ff8ab65a6..f70313d49e 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3971,10 +3971,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q x += reverse ? -chunkWidth : chunkWidth; --chunkCount; }; - } else { + } else if (chunkWidth > 0) { + const int chunkCount = ceil(qreal(fillWidth)/chunkWidth); int x = reverse ? r.left() + r.width() - chunkWidth : r.x(); - for (int i = 0; i < ceil(qreal(fillWidth)/chunkWidth); ++i) { + for (int i = 0; i < chunkCount; ++i) { r.setRect(x, rect.y(), chunkWidth, rect.height()); r = m.mapRect(QRectF(r)).toRect(); subRule.drawRule(p, r); -- cgit v1.2.3 From c4b596fb7902abfb9d53e7819612b9a83ac5a8d6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Jan 2018 16:04:46 +0100 Subject: Document licenses for all Qt modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the example of the other modules and explicitly mention the valid licenses on each module landing page, optionally combining it with trademark information. Change-Id: I9f1fea0f002e0ab607da89a0cbfe7c53060582d7 Reviewed-by: Leena Miettinen Reviewed-by: Topi Reiniö --- src/widgets/doc/src/qtwidgets-index.qdoc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/doc/src/qtwidgets-index.qdoc b/src/widgets/doc/src/qtwidgets-index.qdoc index 9f9a25140b..31dd3dcf40 100644 --- a/src/widgets/doc/src/qtwidgets-index.qdoc +++ b/src/widgets/doc/src/qtwidgets-index.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -128,6 +128,15 @@ interfaces \image graphicsview-items.png + \section1 Licenses + + The Qt Widgets module is available under commercial licenses from \l{The Qt Company}. + In addition, it is available under free software licenses. Since Qt 5.4, + these free software licenses are + \l{GNU Lesser General Public License, version 3}, or + the \l{GNU General Public License, version 2}. + See \l{Qt Licensing} for further details. + \section1 Related Information \section2 Tutorials -- cgit v1.2.3 From 089969540f4877c778172ee0ccbd69960a179b43 Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Fri, 26 Jan 2018 19:10:46 +0300 Subject: Remove traces of Growl in QSystemTrayIcon code and documentation Growl support was removed in Qt 5.8. Change-Id: I00a36cd955194ca8ceee52841a89ca579da01284 Reviewed-by: Jake Petroules --- src/widgets/util/qsystemtrayicon.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index f7d048edcd..884bed2e68 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -107,9 +107,7 @@ static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon) \li All X11 desktop environments that implement the D-Bus \l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem} specification, including recent versions of KDE and Unity. - \li All supported versions of \macos. Note that the Growl - notification system must be installed for - QSystemTrayIcon::showMessage() to display messages on \macos prior to 10.8 (Mountain Lion). + \li All supported versions of \macos. \endlist To check whether a system tray is present on the user's desktop, @@ -399,9 +397,6 @@ bool QSystemTrayIcon::supportsMessages() On Windows, the \a millisecondsTimeoutHint is usually ignored by the system when the application has focus. - On \macos, the Growl notification system must be installed for this function to - display messages. - Has been turned into a slot in Qt 5.2. \sa show(), supportsMessages() -- cgit v1.2.3 From b1a58b20ae109fac2756101fea4dcd8ee0b96531 Mon Sep 17 00:00:00 2001 From: Igor Mironchik Date: Thu, 25 Jan 2018 15:43:40 +0300 Subject: Fix missing update of QTreeView on setTreePosition() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was missing update in setTreePosition() or better to say update was but in not that part of QTreeView that needed. Now QTreeView correctly updates and paints tree decoration in a new place on changing tree position. [ChangeLog][QtWidgets][QTreeView] Fixed missing update of QTreeView on changing tree position. Task-number: QTBUG-65980 Change-Id: Id79ab8fcb39d511245a551068640684dd2a10cb9 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qtreeview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 4795d9f1b1..8d27305071 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -987,7 +987,7 @@ void QTreeView::setTreePosition(int index) { Q_D(QTreeView); d->treePosition = index; - update(); + d->viewport->update(); } /*! -- cgit v1.2.3 From 3adfcbf1ed9b63c3ce41d7417658db3836fd3530 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 21 Jan 2018 19:55:40 +0100 Subject: QHeaderView: properly restore section data after layoutChanged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QHeaderView is doing a complete rebuild of the sections when the layout changed because everything could have happened. But since layoutChanged is also called during e.g. sorting, the old data must be restored when possible. Task-number: QTBUG-65478 Change-Id: I088d4d843cad362b97df6dc5e0dcb9819b13547f Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 88 ++++++++++++++++++++++++++--------- src/widgets/itemviews/qheaderview_p.h | 11 +++-- 2 files changed, 73 insertions(+), 26 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 0905a20812..e1aec3f4bd 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -351,7 +351,7 @@ void QHeaderView::setModel(QAbstractItemModel *model) if (model == this->model()) return; Q_D(QHeaderView); - d->persistentHiddenSections.clear(); + d->layoutChangePersistentSections.clear(); if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) { if (d->orientation == Qt::Horizontal) { QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)), @@ -2072,14 +2072,28 @@ void QHeaderViewPrivate::_q_layoutAboutToBeChanged() || model->columnCount(root) == 0) return; - if (hiddenSectionSize.count() == 0) - return; + layoutChangePersistentSections.clear(); + layoutChangePersistentSections.reserve(std::min(10, sectionItems.count())); + // after layoutChanged another section can be last stretched section + if (stretchLastSection) { + const int visual = visualIndex(lastSectionLogicalIdx); + sectionItems[visual].size = lastSectionSize; + } + for (int i = 0; i < sectionItems.size(); ++i) { + const auto &s = sectionItems.at(i); + // only add if the section is not default and not visually moved + if (s.size == defaultSectionSize && !s.isHidden && s.resizeMode == globalResizeMode) + continue; - for (int i = 0; i < sectionItems.count(); ++i) - if (isVisualIndexHidden(i)) // ### note that we are using column or row 0 - persistentHiddenSections.append(orientation == Qt::Horizontal - ? model->index(0, logicalIndex(i), root) - : model->index(logicalIndex(i), 0, root)); + // ### note that we are using column or row 0 + layoutChangePersistentSections.append({orientation == Qt::Horizontal + ? model->index(0, logicalIndex(i), root) + : model->index(logicalIndex(i), 0, root), + s}); + + if (layoutChangePersistentSections.size() > 1000) + break; + } } void QHeaderViewPrivate::_q_layoutChanged() @@ -2087,25 +2101,57 @@ void QHeaderViewPrivate::_q_layoutChanged() Q_Q(QHeaderView); viewport->update(); - const auto hiddenSections = persistentHiddenSections; - persistentHiddenSections.clear(); - - clear(); - q->initializeSections(); - invalidateCachedSizeHint(); + const auto oldPersistentSections = layoutChangePersistentSections; + layoutChangePersistentSections.clear(); - if (modelIsEmpty()) { + const int newCount = modelSectionCount(); + const int oldCount = sectionItems.size(); + if (newCount == 0) { + clear(); + if (oldCount != 0) + emit q->sectionCountChanged(oldCount, 0); return; } - for (const auto &index : hiddenSections) { - if (index.isValid()) { - const int logical = (orientation == Qt::Horizontal - ? index.column() - : index.row()); - q->setSectionHidden(logical, true); + // adjust section size + if (newCount != oldCount) { + const int min = qBound(0, oldCount, newCount - 1); + q->initializeSections(min, newCount - 1); + } + // reset sections + sectionItems.fill(SectionItem(defaultSectionSize, globalResizeMode), newCount); + + // all hidden sections are in oldPersistentSections + hiddenSectionSize.clear(); + + for (const auto &item : oldPersistentSections) { + const auto &index = item.index; + if (!index.isValid()) + continue; + + const int newLogicalIndex = (orientation == Qt::Horizontal + ? index.column() + : index.row()); + // the new visualIndices are already adjusted / reset by initializeSections() + const int newVisualIndex = visualIndex(newLogicalIndex); + auto &newSection = sectionItems[newVisualIndex]; + newSection = item.section; + + if (newSection.isHidden) { + // otherwise setSectionHidden will return without doing anything + newSection.isHidden = false; + q->setSectionHidden(newLogicalIndex, true); } } + + recalcSectionStartPos(); + length = headerLength(); + + if (stretchLastSection) { + // force rebuild of stretched section later on + lastSectionLogicalIdx = -1; + maybeRestorePrevLastSectionAndStretchLast(); + } } /*! diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index 8fc8b88aa5..c9c2cf8493 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -231,10 +231,6 @@ public: : model->rowCount(root)); } - inline bool modelIsEmpty() const { - return (model->rowCount(root) == 0 || model->columnCount(root) == 0); - } - inline void doDelayedResizeSections() { if (!delayedResize.isActive()) delayedResize.start(0, q_func()); @@ -304,7 +300,6 @@ public: QLabel *sectionIndicator; #endif QHeaderView::ResizeMode globalResizeMode; - QList persistentHiddenSections; mutable bool sectionStartposRecalc; int resizeContentsPrecision; // header sections @@ -335,6 +330,11 @@ public: }; QVector sectionItems; + struct LayoutChangeItem { + QPersistentModelIndex index; + SectionItem section; + }; + QVector layoutChangePersistentSections; void createSectionItems(int start, int end, int size, QHeaderView::ResizeMode mode); void removeSectionsFromSectionItems(int start, int end); @@ -388,6 +388,7 @@ public: }; Q_DECLARE_TYPEINFO(QHeaderViewPrivate::SectionItem, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QHeaderViewPrivate::LayoutChangeItem, Q_MOVABLE_TYPE); QT_END_NAMESPACE -- cgit v1.2.3 From 4cd90a3579986ae7441c3e982a5f34cdfd92c152 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 17 Jan 2017 22:31:04 +0000 Subject: Fix native QFileDialog initial selection for remote URLs When using QFileDialog::getOpenFileUrl() with dir set to e.g. "sftp://foo/bar.cpp" we call q->selectDirectoryUrl("sftp://foo") followed by q->selectFile("bar.cpp"). Inside QFileDialog::selectFile() we unconditionally convert "bar.cpp" to an absolute URL and then call d->selectFile_sys("$CWD/bar.cpp") This then calls platform integration that detects that an absolute URL is being passed to selectFile() and therefore overrides the initial directory. Initially reported as https://bugs.kde.org/show_bug.cgi?id=374913 This is a regression that appeared some time between Qt 5.7.0 and 5.7.1. I have not had time to bisect this but the only commit that may have change behavior in that time range appears to be 007f92c6eef6191c48da0c44916591d48813ae62. Change-Id: I6968abe9ed5c5b9de067c453a7e9d2c5cdb3a190 Reviewed-by: Christoph Resch Reviewed-by: David Faure --- src/widgets/dialogs/qfiledialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 8d37969be4..cb2c534b24 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2830,7 +2830,10 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter, if (!nameFilter.isEmpty()) q->setNameFilter(nameFilter); q->setDirectoryUrl(workingDirectory(directory)); - q->selectFile(initialSelection(directory)); + if (directory.isLocalFile()) + q->selectFile(initialSelection(directory)); + else + q->selectUrl(directory); #ifndef QT_NO_SETTINGS // Try to restore from the FileDialog settings group; if it fails, fall back -- cgit v1.2.3 From 1cc15c4b6d65a22ab4018226a96baf843feb1f00 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 2 Feb 2018 10:00:27 +0100 Subject: QComboBoxPrivate::showNativePopup(): Scale target rectangle The QPlatform* classes operate in native pixels. Task-number: QTBUG-55251 Change-Id: I80490fa802fbc77a1e02c176528cc047630f9a7d Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qcombobox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index e0bc198d2e..7ab3565a00 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -2550,7 +2551,8 @@ bool QComboBoxPrivate::showNativePopup() else if (q->testAttribute(Qt::WA_MacMiniSize)) offset = QPoint(-2, 6); - m_platformMenu->showPopup(tlw, QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()), currentItem); + const QRect targetRect = QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()); + m_platformMenu->showPopup(tlw, QHighDpi::toNativePixels(targetRect, tlw), currentItem); #ifdef Q_OS_OSX // The Cocoa popup will swallow any mouse release event. -- cgit v1.2.3