diff options
author | Liang Qi <liang.qi@qt.io> | 2018-02-06 12:38:51 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2018-02-10 15:55:52 +0100 |
commit | 32b506d1db1f8cee748a27b548ba8208f2928058 (patch) | |
tree | 2d5b23baafe22ccc3518719f8f5d19bb846b2b61 /src/widgets | |
parent | 2cb1db64370989fffeec313c196fe573c479e6aa (diff) | |
parent | c0948d508e7179e2e23c893ba6152c40400de060 (diff) |
Merge remote-tracking branch 'origin/dev' into 5.11
Conflicts:
src/corelib/tools/qvarlengtharray.qdoc
src/corelib/tools/qvector.qdoc
Resolved documentation changes in favor of 017569f702b6dd0,
which keeps the move overloads along with its const-ref sibling.
Change-Id: I0835b0b3211a418e5e50defc4cf315f0964fab79
Diffstat (limited to 'src/widgets')
22 files changed, 247 insertions, 171 deletions
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index f0423ca825..efcf4cdc8b 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -704,6 +704,8 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const } if (str.isEmpty()) str = QAccessibleWidget::text(t); + if (str.isEmpty() && t == QAccessible::Description) + str = lineEdit()->placeholderText(); return str; } diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index bb13d4eb01..cc82f42850 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -167,6 +167,13 @@ public: explicit QFileInfoGatherer(QObject *parent = 0); ~QFileInfoGatherer(); +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) + QStringList watchedFiles() const { return watcher->files(); } + QStringList watchedDirectories() const { return watcher->directories(); } + void watchPaths(const QStringList &paths) { watcher->addPaths(paths); } + void unwatchPaths(const QStringList &paths) { watcher->removePaths(paths); } +#endif // filesystemwatcher && Q_OS_WIN + // only callable from this->thread(): void clear(); void removePath(const QString &path); diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 14ac6ad31b..33b8b51216 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -207,14 +207,17 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) const QString path = d->filePath(aindex); const QFileInfo fileInfo(path); +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) + // QTBUG-65683: Remove file system watchers prior to deletion to prevent + // failure due to locked files on Windows. + const QStringList watchedPaths = d->unwatchPathsAt(aindex); +#endif // filesystemwatcher && Q_OS_WIN const bool success = (fileInfo.isFile() || fileInfo.isSymLink()) ? QFile::remove(path) : QDir(path).removeRecursively(); -#ifndef QT_NO_FILESYSTEMWATCHER - if (success) { - QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func()); - d->fileInfoGatherer.removePath(path); - } -#endif +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) + if (!success) + d->watchPaths(watchedPaths); +#endif // filesystemwatcher && Q_OS_WIN return success; } @@ -851,6 +854,20 @@ QIcon QFileSystemModelPrivate::icon(const QModelIndex &index) const return node(index)->icon(); } +static void displayRenameFailedMessage(const QString &newName) +{ +#if QT_CONFIG(messagebox) + const QString message = + QFileSystemModel::tr("<b>The name \"%1\" cannot be used.</b>" + "<p>Try using another name, with fewer characters or no punctuation marks.") + .arg(newName); + QMessageBox::information(nullptr, QFileSystemModel::tr("Invalid filename"), + message, QMessageBox::Ok); +#else + Q_UNUSED(newName) +#endif // QT_CONFIG(messagebox) +} + /*! \reimp */ @@ -871,15 +888,21 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in const QString parentPath = filePath(parent(idx)); - if (newName.isEmpty() - || QDir::toNativeSeparators(newName).contains(QDir::separator()) - || !QDir(parentPath).rename(oldName, newName)) { -#if QT_CONFIG(messagebox) - QMessageBox::information(0, QFileSystemModel::tr("Invalid filename"), - QFileSystemModel::tr("<b>The name \"%1\" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks.") - .arg(newName), - QMessageBox::Ok); -#endif // QT_CONFIG(messagebox) + if (newName.isEmpty() || QDir::toNativeSeparators(newName).contains(QDir::separator())) { + displayRenameFailedMessage(newName); + return false; + } + +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) + // QTBUG-65683: Remove file system watchers prior to renaming to prevent + // failure due to locked files on Windows. + const QStringList watchedPaths = d->unwatchPathsAt(idx); +#endif // filesystemwatcher && Q_OS_WIN + if (!QDir(parentPath).rename(oldName, newName)) { +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) + d->watchPaths(watchedPaths); +#endif + displayRenameFailedMessage(newName); return false; } else { /* @@ -1882,6 +1905,46 @@ void QFileSystemModelPrivate::_q_resolvedName(const QString &fileName, const QSt resolvedSymLinks[fileName] = resolvedName; } +#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN) +// Remove file system watchers at/below the index and return a list of previously +// watched files. This should be called prior to operations like rename/remove +// which might fail due to watchers on platforms like Windows. The watchers +// should be restored on failure. +QStringList QFileSystemModelPrivate::unwatchPathsAt(const QModelIndex &index) +{ + const QFileSystemModelPrivate::QFileSystemNode *indexNode = node(index); + if (indexNode == nullptr) + return QStringList(); + const Qt::CaseSensitivity caseSensitivity = indexNode->caseSensitive() + ? Qt::CaseSensitive : Qt::CaseInsensitive; + const QString path = indexNode->fileInfo().absoluteFilePath(); + + QStringList result; + const auto filter = [path, caseSensitivity] (const QString &watchedPath) + { + const int pathSize = path.size(); + if (pathSize == watchedPath.size()) { + return path.compare(watchedPath, caseSensitivity) == 0; + } else if (watchedPath.size() > pathSize) { + return watchedPath.at(pathSize) == QLatin1Char('/') + && watchedPath.startsWith(path, caseSensitivity); + } + return false; + }; + + const QStringList &watchedFiles = fileInfoGatherer.watchedFiles(); + std::copy_if(watchedFiles.cbegin(), watchedFiles.cend(), + std::back_inserter(result), filter); + + const QStringList &watchedDirectories = fileInfoGatherer.watchedDirectories(); + std::copy_if(watchedDirectories.cbegin(), watchedDirectories.cend(), + std::back_inserter(result), filter); + + fileInfoGatherer.unwatchPaths(result); + return result; +} +#endif // filesystemwatcher && Q_OS_WIN + /*! \internal */ diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h index e8bae4f659..a2a02e2d41 100644 --- a/src/widgets/dialogs/qfilesystemmodel_p.h +++ b/src/widgets/dialogs/qfilesystemmodel_p.h @@ -297,9 +297,13 @@ public: static int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs); QDir rootDir; -#ifndef QT_NO_FILESYSTEMWATCHER +#if QT_CONFIG(filesystemwatcher) +# ifdef Q_OS_WIN + QStringList unwatchPathsAt(const QModelIndex &); + void watchPaths(const QStringList &paths) { fileInfoGatherer.watchPaths(paths); } +# endif // Q_OS_WIN QFileInfoGatherer fileInfoGatherer; -#endif +#endif // filesystemwatcher QTimer delayedSortTimer; bool forceSort; int sortColumn; diff --git a/src/widgets/doc/snippets/common-table-model/model.cpp b/src/widgets/doc/snippets/common-table-model/model.cpp index 96df100f26..2f6e9f1144 100644 --- a/src/widgets/doc/snippets/common-table-model/model.cpp +++ b/src/widgets/doc/snippets/common-table-model/model.cpp @@ -68,7 +68,7 @@ TableModel::TableModel(int rows, int columns, QObject *parent) QStringList newList; for (int column = 0; column < qMax(1, columns); ++column) { - newList.append(""); + newList.append(QString()); } for (int row = 0; row < qMax(1, rows); ++row) { @@ -129,9 +129,9 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, return QVariant(); if (orientation == Qt::Horizontal) - return QString("Column %1").arg(section); + return QStringLiteral("Column %1").arg(section); else - return QString("Row %1").arg(section); + return QStringLiteral("Row %1").arg(section); } /*! @@ -164,7 +164,7 @@ bool TableModel::setData(const QModelIndex &index, return false; rowList[index.row()][index.column()] = value.toString(); - emit dataChanged(index, index); + emit dataChanged(index, index, {role}); return true; } @@ -180,7 +180,7 @@ bool TableModel::insertRows(int position, int rows, const QModelIndex &parent) for (int row = 0; row < rows; ++row) { QStringList items; for (int column = 0; column < columns; ++column) - items.append(""); + items.append(QString()); rowList.insert(position, items); } @@ -202,7 +202,7 @@ bool TableModel::insertColumns(int position, int columns, for (int row = 0; row < rows; ++row) { for (int column = position; column < columns; ++column) { - rowList[row].insert(position, ""); + rowList[row].insert(position, QString()); } } diff --git a/src/widgets/doc/snippets/common-table-model/model.h b/src/widgets/doc/snippets/common-table-model/model.h index 68e6c00702..5f152e0e78 100644 --- a/src/widgets/doc/snippets/common-table-model/model.h +++ b/src/widgets/doc/snippets/common-table-model/model.h @@ -60,22 +60,22 @@ class TableModel : public QAbstractTableModel Q_OBJECT public: - TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + TableModel(int rows = 1, int columns = 1, QObject *parent = nullptr); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; + int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &index) const; + Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole); + int role = Qt::EditRole) override; - bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); - bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override; + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()) override; + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override; + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()) override; private: QList<QStringList> rowList; diff --git a/src/widgets/doc/snippets/stringlistmodel/model.cpp b/src/widgets/doc/snippets/stringlistmodel/model.cpp index f07f6b254f..52e78847d2 100644 --- a/src/widgets/doc/snippets/stringlistmodel/model.cpp +++ b/src/widgets/doc/snippets/stringlistmodel/model.cpp @@ -135,9 +135,9 @@ QVariant StringListModel::headerData(int section, Qt::Orientation orientation, return QVariant(); if (orientation == Qt::Horizontal) - return QString("Column %1").arg(section); + return QStringLiteral("Column %1").arg(section); else - return QString("Row %1").arg(section); + return QStringLiteral("Row %1").arg(section); } //! [2] @@ -174,7 +174,7 @@ bool StringListModel::setData(const QModelIndex &index, if (index.isValid() && role == Qt::EditRole) { stringList.replace(index.row(), value.toString()); - emit dataChanged(index, index); + emit dataChanged(index, index, {role}); return true; } //! [4] //! [5] diff --git a/src/widgets/doc/snippets/stringlistmodel/model.h b/src/widgets/doc/snippets/stringlistmodel/model.h index 50769ef67f..7012152b27 100644 --- a/src/widgets/doc/snippets/stringlistmodel/model.h +++ b/src/widgets/doc/snippets/stringlistmodel/model.h @@ -61,26 +61,26 @@ class StringListModel : public QAbstractListModel Q_OBJECT public: - StringListModel(const QStringList &strings, QObject *parent = 0) + StringListModel(const QStringList &strings, QObject *parent = nullptr) : QAbstractListModel(parent), stringList(strings) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, //! [0] //! [1] - int role = Qt::DisplayRole) const; + int role = Qt::DisplayRole) const override; //! [1] //! [2] - Qt::ItemFlags flags(const QModelIndex &index) const; + Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, //! [2] //! [3] - int role = Qt::EditRole); + int role = Qt::EditRole) override; //! [3] //! [4] - bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); - bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; //! [4] //! [5] diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index 5ecd2baab8..8efbcd273e 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -288,11 +288,7 @@ protected: QWidget *widget = nullptr); protected Q_SLOTS: - // ### Qt 6: make unconditional -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - virtual -#endif - bool focusNextPrevChild(bool next); + QT6_VIRTUAL bool focusNextPrevChild(bool next); Q_SIGNALS: void changed(const QList<QRectF> ®ion); diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 50287df6e0..585cfddff5 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2848,14 +2848,18 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex && isHeaderArrowOnTheSide) margin += style()->pixelMetric(QStyle::PM_HeaderMarkSize, 0, this); - if (d->textElideMode != Qt::ElideNone) - opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin); - - QVariant variant = d->model->headerData(logicalIndex, d->orientation, - Qt::DecorationRole); + const QVariant variant = d->model->headerData(logicalIndex, d->orientation, + Qt::DecorationRole); opt.icon = qvariant_cast<QIcon>(variant); if (opt.icon.isNull()) opt.icon = qvariant_cast<QPixmap>(variant); + if (!opt.icon.isNull()) // see CT_HeaderSection + margin += style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this) + + style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this); + + if (d->textElideMode != Qt::ElideNone) + opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin); + QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation, Qt::ForegroundRole); if (foregroundBrush.canConvert<QBrush>()) diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index ad8aac1415..1fedad80aa 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -412,10 +412,10 @@ QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator( return std::lower_bound(begin, end, item, QListModelGreaterThan()); } -void QListModel::itemChanged(QListWidgetItem *item) +void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles) { - QModelIndex idx = index(item); - emit dataChanged(idx, idx); + const QModelIndex idx = index(item); + emit dataChanged(idx, idx, roles); } QStringList QListModel::mimeTypes() const @@ -711,8 +711,12 @@ void QListWidgetItem::setData(int role, const QVariant &value) } if (!found) d->values.append(QWidgetItemData(role, value)); - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) - model->itemChanged(this); + if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : nullptr)) { + const QVector<int> roles((role == Qt::DisplayRole) ? + QVector<int>({Qt::DisplayRole, Qt::EditRole}) : + QVector<int>({role})); + model->itemChanged(this, roles); + } } /*! @@ -954,7 +958,8 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) \sa Qt::ItemFlags */ -void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { +void QListWidgetItem::setFlags(Qt::ItemFlags aflags) +{ itemFlags = aflags; if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) model->itemChanged(this); diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h index 3caa5ce6f2..8a31411429 100644 --- a/src/widgets/itemviews/qlistwidget.h +++ b/src/widgets/itemviews/qlistwidget.h @@ -269,6 +269,7 @@ Q_SIGNALS: void itemDoubleClicked(QListWidgetItem *item); void itemActivated(QListWidgetItem *item); void itemEntered(QListWidgetItem *item); + // ### Qt 6: add changed roles void itemChanged(QListWidgetItem *item); void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h index 492b05ff07..30b5016db6 100644 --- a/src/widgets/itemviews/qlistwidget_p.h +++ b/src/widgets/itemviews/qlistwidget_p.h @@ -119,7 +119,7 @@ public: const QList<QListWidgetItem*>::iterator &end, Qt::SortOrder order, QListWidgetItem *item); - void itemChanged(QListWidgetItem *item); + void itemChanged(QListWidgetItem *item, const QVector<int> &roles = QVector<int>()); // dnd QStringList mimeTypes() const override; diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 853e27cd6e..967b0b8dde 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE */ static QString qt_strippedText(QString s) { - s.remove(QStringLiteral("...")); + s.remove(QLatin1String("...")); for (int i = 0; i < s.size(); ++i) { if (s.at(i) == QLatin1Char('&')) s.remove(i, 1); diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index abadf2e69d..bcc33a0811 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -126,8 +126,8 @@ public: bool isEmpty() const override; QSizePolicy::ControlTypes controlTypes() const override; - // ### Qt 6 make this function virtual - QLayoutItem *replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options = Qt::FindChildrenRecursively); + QT6_VIRTUAL QLayoutItem *replaceWidget(QWidget *from, QWidget *to, + Qt::FindChildOptions options = Qt::FindChildrenRecursively); int totalHeightForWidth(int w) const; QSize totalMinimumSize() const; diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 12b60c634c..670a23e78f 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -743,8 +743,9 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q % QLatin1String(metaObject()->className()), opt, QSize(size, size)) % HexString<uint>(pe); if (!QPixmapCache::find(pixmapName, pixmap)) { - int border = size/5; - int sqsize = 2*(size/2); + qreal pixelRatio = p->device()->devicePixelRatioF(); + int border = qRound(pixelRatio*(size/5)); + int sqsize = qRound(pixelRatio*(2*(size/2))); QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied); image.fill(0); QPainter imagePainter(&image); @@ -796,6 +797,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q imagePainter.drawPolygon(a); imagePainter.end(); pixmap = QPixmap::fromImage(image); + pixmap.setDevicePixelRatio(pixelRatio); QPixmapCache::insert(pixmapName, pixmap); } int xOffset = r.x() + (r.width() - size)/2; @@ -1581,10 +1583,11 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, aligned.width() * pixmap.devicePixelRatio(), pixmap.height() * pixmap.devicePixelRatio()); + const int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget); if (header->direction == Qt::LeftToRight) - rect.setLeft(rect.left() + pixw + 2); + rect.setLeft(rect.left() + pixw + margin); else - rect.setRight(rect.right() - pixw - 2); + rect.setRight(rect.right() - pixw - margin); } if (header->state & QStyle::State_On) { QFont fnt = p->font(); @@ -4165,14 +4168,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex #if QT_CONFIG(combobox) case CC_ComboBox: if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { - int x = cb->rect.x(), - y = cb->rect.y(), - wi = cb->rect.width(), - he = cb->rect.height(); - int xpos = x; - int margin = cb->frame ? 3 : 0; - int bmarg = cb->frame ? 2 : 0; - xpos += wi - bmarg - 16; + const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); + const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3)) : 0; + const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2)) : 0; + const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16)); switch (sc) { @@ -4180,10 +4179,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex ret = cb->rect; break; case SC_ComboBoxArrow: - ret.setRect(xpos, y + bmarg, 16, he - 2*bmarg); + ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16)), he - 2*bmarg); break; case SC_ComboBoxEditField: - ret.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin); + ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16)), he - 2 * margin); break; case SC_ComboBoxListBoxPopup: ret = cb->rect; diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index a2b94d59d4..26f651906a 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -2737,6 +2737,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption pixmapName += QLatin1String("-editable"); if (isEnabled) pixmapName += QLatin1String("-enabled"); + if (!comboBox->frame) + pixmapName += QLatin1String("-frameless"); if (!QPixmapCache::find(pixmapName, cache)) { cache = styleCachePixmap(comboBox->rect.size()); @@ -2762,7 +2764,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption buttonOption.state &= ~State_MouseOver; } - proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget); + if (comboBox->frame) + proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget); // Draw button clipped cachePainter.save(); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 7a84a4dcf8..89011350ec 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -798,9 +798,10 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, break; case PE_FrameDefaultButton: { QPen oldPen = p->pen(); - p->setPen(opt->palette.shadow().color()); - QRect rect = opt->rect; - rect.adjust(0, 0, -1, -1); + p->setPen(QPen(opt->palette.shadow().color(), 0)); + QRectF rect = opt->rect; + rect.adjust(QStyleHelper::dpiScaled(0.5), QStyleHelper::dpiScaled(0.5), + QStyleHelper::dpiScaled(-1.5), QStyleHelper::dpiScaled(-1.5)); p->drawRect(rect); p->setPen(oldPen); break; @@ -843,22 +844,16 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } #endif // QT_CONFIG(itemviews) if (!(opt->state & State_Off)) { - QLineF lines[7]; - int i, xx, yy; - xx = opt->rect.x() + 3; - yy = opt->rect.y() + 5; - for (i = 0; i < 3; ++i) { - lines[i] = QLineF(xx, yy, xx, yy + 2); - ++xx; - ++yy; - } - yy -= 2; - for (i = 3; i < 7; ++i) { - lines[i] = QLineF(xx, yy, xx, yy + 2); - ++xx; - --yy; - } - p->drawLines(lines, 7); + QPointF points[6]; + points[0] = { opt->rect.x() + QStyleHelper::dpiScaled(3.5), opt->rect.y() + QStyleHelper::dpiScaled(5.5) }; + points[1] = { points[0].x(), points[0].y() + QStyleHelper::dpiScaled(2) }; + points[2] = { points[1].x() + QStyleHelper::dpiScaled(2), points[1].y() + QStyleHelper::dpiScaled(2) }; + points[3] = { points[2].x() + QStyleHelper::dpiScaled(4), points[2].y() - QStyleHelper::dpiScaled(4) }; + points[4] = { points[3].x(), points[3].y() - QStyleHelper::dpiScaled(2) }; + points[5] = { points[4].x() - QStyleHelper::dpiScaled(4), points[4].y() + QStyleHelper::dpiScaled(4) }; + p->setPen(QPen(opt->palette.text().color(), 0)); + p->setBrush(opt->palette.text().color()); + p->drawPolygon(points, 6); } if (doRestore) p->restore(); @@ -890,86 +885,57 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, break; case PE_IndicatorRadioButton: { -#define PTSARRLEN(x) sizeof(x)/(sizeof(QPoint)) - static const QPoint pts1[] = { // dark lines - QPoint(1, 9), QPoint(1, 8), QPoint(0, 7), QPoint(0, 4), QPoint(1, 3), QPoint(1, 2), - QPoint(2, 1), QPoint(3, 1), QPoint(4, 0), QPoint(7, 0), QPoint(8, 1), QPoint(9, 1) - }; - static const QPoint pts2[] = { // black lines - QPoint(2, 8), QPoint(1, 7), QPoint(1, 4), QPoint(2, 3), QPoint(2, 2), QPoint(3, 2), - QPoint(4, 1), QPoint(7, 1), QPoint(8, 2), QPoint(9, 2) - }; - static const QPoint pts3[] = { // background lines - QPoint(2, 9), QPoint(3, 9), QPoint(4, 10), QPoint(7, 10), QPoint(8, 9), QPoint(9, 9), - QPoint(9, 8), QPoint(10, 7), QPoint(10, 4), QPoint(9, 3) - }; - static const QPoint pts4[] = { // white lines - QPoint(2, 10), QPoint(3, 10), QPoint(4, 11), QPoint(7, 11), QPoint(8, 10), - QPoint(9, 10), QPoint(10, 9), QPoint(10, 8), QPoint(11, 7), QPoint(11, 4), - QPoint(10, 3), QPoint(10, 2) - }; - static const QPoint pts5[] = { // inner fill - QPoint(4, 2), QPoint(7, 2), QPoint(9, 4), QPoint(9, 7), QPoint(7, 9), QPoint(4, 9), - QPoint(2, 7), QPoint(2, 4) - }; - - // make sure the indicator is square - QRect ir = opt->rect; - - if (opt->rect.width() < opt->rect.height()) { - ir.setTop(opt->rect.top() + (opt->rect.height() - opt->rect.width()) / 2); - ir.setHeight(opt->rect.width()); - } else if (opt->rect.height() < opt->rect.width()) { - ir.setLeft(opt->rect.left() + (opt->rect.width() - opt->rect.height()) / 2); - ir.setWidth(opt->rect.height()); - } - + QRect r = opt->rect; p->save(); - p->setRenderHint(QPainter::Qt4CompatiblePainting); - bool down = opt->state & State_Sunken; - bool enabled = opt->state & State_Enabled; - bool on = opt->state & State_On; - QPolygon a; - - //center when rect is larger than indicator size - int xOffset = 0; - int yOffset = 0; - int indicatorWidth = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth); - int indicatorHeight = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight); - if (ir.width() > indicatorWidth) - xOffset += (ir.width() - indicatorWidth)/2; - if (ir.height() > indicatorHeight) - yOffset += (ir.height() - indicatorHeight)/2; - p->translate(xOffset, yOffset); - - p->translate(ir.x(), ir.y()); - + p->setRenderHint(QPainter::Antialiasing, true); + + QPointF circleCenter = r.center() + QPoint(1, 1); + qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1; + + QPainterPath path1; + path1.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path2; + path2.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path3; + path3.addEllipse(circleCenter, radius, radius); + radius *= 0.5; + QPainterPath path4; + path4.addEllipse(circleCenter, radius, radius); + + QPolygon topLeftPol, bottomRightPol; + topLeftPol.setPoints(3, r.x(), r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y()); + bottomRightPol.setPoints(3, r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y()); + + p->setClipRegion(QRegion(topLeftPol)); p->setPen(opt->palette.dark().color()); - p->drawPolyline(pts1, PTSARRLEN(pts1)); - + p->setBrush(opt->palette.dark().color()); + p->drawPath(path1); p->setPen(opt->palette.shadow().color()); - p->drawPolyline(pts2, PTSARRLEN(pts2)); + p->setBrush(opt->palette.shadow().color()); + p->drawPath(path2); + p->setClipRegion(QRegion(bottomRightPol)); + p->setPen(opt->palette.light().color()); + p->setBrush(opt->palette.light().color()); + p->drawPath(path1); p->setPen(opt->palette.midlight().color()); - p->drawPolyline(pts3, PTSARRLEN(pts3)); + p->setBrush(opt->palette.midlight().color()); + p->drawPath(path2); - p->setPen(opt->palette.light().color()); - p->drawPolyline(pts4, PTSARRLEN(pts4)); + QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ? + opt->palette.button().color() : opt->palette.base().color(); - QColor fillColor = (down || !enabled) - ? opt->palette.button().color() - : opt->palette.base().color(); + p->setClipping(false); p->setPen(fillColor); - p->setBrush(fillColor) ; - p->drawPolygon(pts5, PTSARRLEN(pts5)); + p->setBrush(fillColor); + p->drawPath(path3); - p->translate(-ir.x(), -ir.y()); // restore translate - - if (on) { - p->setPen(Qt::NoPen); + if (opt->state & State_On) { + p->setPen(opt->palette.text().color()); p->setBrush(opt->palette.text()); - p->drawRect(ir.x() + 5, ir.y() + 4, 2, 4); - p->drawRect(ir.x() + 4, ir.y() + 5, 4, 2); + p->drawPath(path4); } p->restore(); break; diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 156b0e331c..e3b348f0ef 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1466,6 +1466,8 @@ bool QLineEdit::event(QEvent * e) #endif } else if (e->type() == QEvent::Resize) { d->positionSideWidgets(); + } else if (e->type() == QEvent::StyleChange) { + d->initMouseYThreshold(); } #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) { @@ -1546,7 +1548,17 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e) const bool select = (d->imHints & Qt::ImhNoPredictiveText); #endif #ifndef QT_NO_IM - if (d->control->composeMode() && select) { + if (d->mouseYThreshold > 0 && e->pos().y() > d->mousePressPos.y() + d->mouseYThreshold) { + if (layoutDirection() == Qt::RightToLeft) + d->control->home(select); + else + d->control->end(select); + } else if (d->mouseYThreshold > 0 && e->pos().y() + d->mouseYThreshold < d->mousePressPos.y()) { + if (layoutDirection() == Qt::RightToLeft) + d->control->end(select); + else + d->control->home(select); + } else if (d->control->composeMode() && select) { int startPos = d->xToPos(d->mousePressPos.x()); int currentPos = d->xToPos(e->pos().x()); if (startPos != currentPos) diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index c66b842223..6a8af53c97 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -56,6 +56,7 @@ #endif #include <qpainter.h> #include <qpropertyanimation.h> +#include <qstylehints.h> #include <qvalidator.h> QT_BEGIN_NAMESPACE @@ -232,6 +233,13 @@ void QLineEditPrivate::init(const QString& txt) q->setAcceptDrops(true); q->setAttribute(Qt::WA_MacShowFocusRect); + + initMouseYThreshold(); +} + +void QLineEditPrivate::initMouseYThreshold() +{ + mouseYThreshold = QGuiApplication::styleHints()->mouseQuickSelectionThreshold(); } QRect QLineEditPrivate::adjustedContentsRect() const diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index a3f549ad31..39f670b0b0 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -141,7 +141,7 @@ public: dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0), alignment(Qt::AlignLeading | Qt::AlignVCenter), leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0), - lastTextSize(0) + lastTextSize(0), mouseYThreshold(0) { } @@ -155,6 +155,7 @@ public: QPointer<QAction> selectAllAction; #endif void init(const QString&); + void initMouseYThreshold(); QRect adjustedControlRect(const QRect &) const; @@ -253,6 +254,7 @@ private: SideWidgetEntryList leadingSideWidgets; SideWidgetEntryList trailingSideWidgets; int lastTextSize; + int mouseYThreshold; }; Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetLocation, Q_PRIMITIVE_TYPE); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 0c11afdc61..b0a75288e8 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1080,6 +1080,10 @@ void QMenuBar::mouseReleaseEvent(QMouseEvent *e) d->mouseDown = false; QAction *action = d->actionAt(e->pos()); + + // do noting if the action is hidden + if (!d->isVisible(action)) + return; if((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) { //we set the current action before activating //so that we let the leave event set the current back to 0 |