diff options
Diffstat (limited to 'src/widgets')
26 files changed, 345 insertions, 86 deletions
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index a04189513a..79a7c23e0d 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -2077,7 +2077,8 @@ void QFileSystemModelPrivate::init() #endif // filesystemwatcher q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection); - roleNames.insertMulti(QFileSystemModel::FileIconRole, QByteArrayLiteral("fileIcon")); // == Qt::decoration + roleNames.insert(QFileSystemModel::FileIconRole, + QByteArrayLiteral("fileIcon")); // == Qt::decoration roleNames.insert(QFileSystemModel::FilePathRole, QByteArrayLiteral("filePath")); roleNames.insert(QFileSystemModel::FileNameRole, QByteArrayLiteral("fileName")); roleNames.insert(QFileSystemModel::FilePermissions, QByteArrayLiteral("filePermissions")); diff --git a/src/widgets/doc/snippets/javastyle.cpp b/src/widgets/doc/snippets/javastyle.cpp index 8657d5ed29..3d1b1e0030 100644 --- a/src/widgets/doc/snippets/javastyle.cpp +++ b/src/widgets/doc/snippets/javastyle.cpp @@ -2589,7 +2589,7 @@ int JavaStyle::styleHint(StyleHint hint, const QStyleOption *option, switch (hint) { case SH_Table_GridLineColor: { - ret = static_cast<int>(option->palette.color(QPalette::Mid).rgb()); + ret = static_cast<int>(option->palette.color(QPalette::Mid).rgba()); break; } case QStyle::SH_Menu_Scrollable: diff --git a/src/widgets/doc/snippets/qsplashscreen/main.cpp b/src/widgets/doc/snippets/qsplashscreen/main.cpp index 843932ca83..2512035879 100644 --- a/src/widgets/doc/snippets/qsplashscreen/main.cpp +++ b/src/widgets/doc/snippets/qsplashscreen/main.cpp @@ -71,3 +71,10 @@ int main(int argc, char *argv[]) return app.exec(); } //! [1] + +//! [2] +QScreen *screen = QGuiApplication::screens().at(1); +QPixmap pixmap(":/splash.png"); +QSplashScreen splash(screen, pixmap); +splash.show(); +//! [2] diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index c8f374a1b1..35bad6786a 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -993,6 +993,9 @@ \li Supports the \l{box model}. Supports the \l{#default-ps}{:default}, \l{#flat-ps}{:flat}, \l{#checked-ps}{:checked} pseudo states. + Since 5.15, the \l{#icon-prop}{icon} property can be set to + override the button icon. + For QPushButton with a menu, the menu indicator is styled using the \l{#menu-indicator-sub}{::menu-indicator} subcontrol. Appearance of checkable push buttons can be @@ -1946,6 +1949,20 @@ See also \l{#width-prop}{width}. \row + \li \b{\c icon} \target icon-prop + \li \l{#Url}{Url}+ + \li The icon that is used, for widgets that have an icon. + + The only widget currently supporting this property is QPushButton. + + \note It's the application's responsibilty to assign an icon to a + button (using the QAbstractButton API), and not the style's. So be + careful setting it unless your stylesheet is targeting a specific + application. + + Available since 5.15. + + \row \li \b{\c icon-size} \target icon-size-prop \li \l{#Length}{Length} \li The width and height of the icon in a widget. diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 31dde8832b..eecc18e5c7 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -387,44 +387,46 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index) { - Q_D(QAbstractItemDelegate); - Q_UNUSED(d); - Q_UNUSED(index); - Q_UNUSED(option); - if (!event || !view) return false; + Q_D(QAbstractItemDelegate); switch (event->type()) { #ifndef QT_NO_TOOLTIP case QEvent::ToolTip: { QHelpEvent *he = static_cast<QHelpEvent*>(event); const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp - const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision); - if (!tooltip.isEmpty()) { - QToolTip::showText(he->globalPos(), tooltip, view); - return true; + const QString tooltip = index.isValid() ? + d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) : + QString(); + QRect rect; + if (index.isValid()) { + const QRect r = view->visualRect(index); + rect = QRect(view->mapToGlobal(r.topLeft()), r.size()); + } + QToolTip::showText(he->globalPos(), tooltip, view, rect); + event->setAccepted(!tooltip.isEmpty()); + break; } - break;} #endif #if QT_CONFIG(whatsthis) - case QEvent::QueryWhatsThis: { - if (index.data(Qt::WhatsThisRole).isValid()) - return true; - break; } + case QEvent::QueryWhatsThis: + event->setAccepted(index.data(Qt::WhatsThisRole).isValid()); + break; case QEvent::WhatsThis: { QHelpEvent *he = static_cast<QHelpEvent*>(event); const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp - const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision); - if (!whatsthis.isEmpty()) { - QWhatsThis::showText(he->globalPos(), whatsthis, view); - return true; + const QString whatsthis = index.isValid() ? + d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision) : + QString(); + QWhatsThis::showText(he->globalPos(), whatsthis, view); + event->setAccepted(!whatsthis.isEmpty()); + break; } - break ; } #endif default: break; } - return false; + return event->isAccepted(); } /*! diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index 13a1bbd8eb..c9e7c7b7a6 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -39,6 +39,8 @@ #include "qdirmodel.h" +#if QT_DEPRECATED_SINCE(5, 15) + #include <qfile.h> #include <qfilesystemmodel.h> #include <qurl.h> @@ -1160,7 +1162,7 @@ void QDirModelPrivate::init() root.parent = 0; root.info = QFileInfo(); clear(&root); - roleNames.insertMulti(QDirModel::FileIconRole, QByteArrayLiteral("fileIcon")); // == Qt::decoration + roleNames.insert(QDirModel::FileIconRole, QByteArrayLiteral("fileIcon")); // == Qt::decoration roleNames.insert(QDirModel::FilePathRole, QByteArrayLiteral("filePath")); roleNames.insert(QDirModel::FileNameRole, QByteArrayLiteral("fileName")); } @@ -1372,3 +1374,5 @@ QFileInfo QDirModelPrivate::resolvedInfo(QFileInfo info) QT_END_NAMESPACE #include "moc_qdirmodel.cpp" + +#endif // QT_DEPRECATED_SINCE(5, 15) diff --git a/src/widgets/itemviews/qdirmodel.h b/src/widgets/itemviews/qdirmodel.h index ab91bbd763..665a622dbe 100644 --- a/src/widgets/itemviews/qdirmodel.h +++ b/src/widgets/itemviews/qdirmodel.h @@ -45,6 +45,8 @@ #include <QtCore/qdir.h> #include <QtWidgets/qfileiconprovider.h> +#if QT_DEPRECATED_SINCE(5, 15) + QT_REQUIRE_CONFIG(dirmodel); QT_BEGIN_NAMESPACE @@ -65,9 +67,10 @@ public: FileNameRole }; - QDirModel(const QStringList &nameFilters, QDir::Filters filters, - QDir::SortFlags sort, QObject *parent = nullptr); - explicit QDirModel(QObject *parent = nullptr); + QT_DEPRECATED_VERSION_X_5_15("Use QFileSystemModel") QDirModel(const QStringList &nameFilters, + QDir::Filters filters, QDir::SortFlags sort, + QObject *parent = nullptr); + QT_DEPRECATED_VERSION_X_5_15("Use QFileSystemModel") explicit QDirModel(QObject *parent = nullptr); ~QDirModel(); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; @@ -144,4 +147,6 @@ private: QT_END_NAMESPACE +#endif // QT_DEPRECATED_SINCE(5, 15) + #endif // QDIRMODEL_H diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 11c5be10fd..81fceba8dc 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1431,7 +1431,7 @@ void QTableView::paintEvent(QPaintEvent *event) const bool showGrid = d->showGrid; const int gridSize = showGrid ? 1 : 0; const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this); - const QColor gridColor = static_cast<QRgb>(gridHint); + const QColor gridColor = QColor::fromRgba(static_cast<QRgb>(gridHint)); const QPen gridPen = QPen(gridColor, 0, d->gridStyle); const QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index dfa1bc23b1..6d4baacfef 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3660,7 +3660,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) // send to all application event filters if (threadRequiresCoreApplication() - && receiver->d_func()->threadData->thread.loadAcquire() == mainThread() + && receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread() && sendThroughApplicationEventFilters(receiver, e)) { filtered = true; return filtered; diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 3ce81a390b..bd06ead6f7 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -583,18 +583,18 @@ static bool removeWidgetRecursively(QLayoutItem *li, QObject *w) } -void QLayoutPrivate::doResize(const QSize &r) +void QLayoutPrivate::doResize() { Q_Q(QLayout); - int mbh = menuBarHeightForWidth(menubar, r.width()); QWidget *mw = q->parentWidget(); QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect(); + const int mbh = menuBarHeightForWidth(menubar, rect.width()); const int mbTop = rect.top(); rect.setTop(mbTop + mbh); q->setGeometry(rect); #if QT_CONFIG(menubar) if (menubar) - menubar->setGeometry(rect.left(), mbTop, r.width(), mbh); + menubar->setGeometry(rect.left(), mbTop, rect.width(), mbh); #endif } @@ -613,12 +613,10 @@ void QLayout::widgetEvent(QEvent *e) switch (e->type()) { case QEvent::Resize: - if (d->activated) { - QResizeEvent *r = (QResizeEvent *)e; - d->doResize(r->size()); - } else { + if (d->activated) + d->doResize(); + else activate(); - } break; case QEvent::ChildRemoved: { @@ -1116,7 +1114,7 @@ bool QLayout::activate() break; } - d->doResize(mw->size()); + d->doResize(); if (md->extra) { md->extra->explicitMinSize = explMin; diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h index 8e1d773355..2b19af48be 100644 --- a/src/widgets/kernel/qlayout_p.h +++ b/src/widgets/kernel/qlayout_p.h @@ -73,7 +73,7 @@ public: QLayoutPrivate(); void getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const; - void doResize(const QSize &); + void doResize(); void reparentChildWidgets(QWidget *mw); bool checkWidget(QWidget *widget) const; bool checkLayout(QLayout *otherLayout) const; diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index eec65c8625..d469279ea5 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -419,6 +419,76 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge \sa activated() */ +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. +*/ +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. + + The \a functor can be a pointer to a member function of the \a context object. + + If the \a context object is destroyed, the \a functor will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor and \a FunctorAmbiguous can be a pointer to a member + function of the \a context object. + + If the \a context object is destroyed, the \a functor and + \a FunctorAmbiguous will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor can be a pointer to a member function of the + \a context1 object. + The \a FunctorAmbiguous can be a pointer to a member function of the + \a context2 object. + + If the \a context1 object is destroyed, the \a functor will not be called. + If the \a context2 object is destroyed, the \a FunctorAmbiguous + will not be called. +*/ + /* \internal Private data accessed through d-pointer. @@ -479,13 +549,13 @@ QShortcut::QShortcut(QWidget *parent) */ QShortcut::QShortcut(const QKeySequence &key, QWidget *parent, const char *member, const char *ambiguousMember, - Qt::ShortcutContext context) + Qt::ShortcutContext shortcutContext) : QShortcut(parent) { QAPP_CHECK("QShortcut"); Q_D(QShortcut); - d->sc_context = context; + d->sc_context = shortcutContext; d->sc_sequence = key; d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); if (member) diff --git a/src/widgets/kernel/qshortcut.h b/src/widgets/kernel/qshortcut.h index 6dcf4971b2..4f9c5ba0f7 100644 --- a/src/widgets/kernel/qshortcut.h +++ b/src/widgets/kernel/qshortcut.h @@ -61,9 +61,65 @@ class Q_WIDGETS_EXPORT QShortcut : public QObject Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) public: explicit QShortcut(QWidget *parent); - QShortcut(const QKeySequence& key, QWidget *parent, + QShortcut(const QKeySequence &key, QWidget *parent, const char *member = nullptr, const char *ambiguousMember = nullptr, - Qt::ShortcutContext context = Qt::WindowShortcut); + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); +#ifdef Q_CLANG_QDOC + template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QWidget *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); +#else + template<typename Func1> + QShortcut(const QKeySequence &key, QWidget *parent, + Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, std::move(slot1)); + } + template<class Obj1, typename Func1> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + } + template<class Obj1, typename Func1, typename Func2> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object1, std::move(slot2)); + } + template<class Obj1, typename Func1, class Obj2, typename Func2> + QShortcut(const QKeySequence &key, QWidget *parent, + const Obj1 *object1, Func1 slot1, + const Obj2 *object2, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object2, std::move(slot2)); + } +#endif ~QShortcut(); void setKey(const QKeySequence& key); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 271b43fe89..861dd7a54c 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5143,7 +5143,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_Table_GridLineColor: if (opt) - ret = opt->palette.color(QPalette::Mid).rgb(); + ret = opt->palette.color(QPalette::Mid).rgba(); else ret = -1; break; diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index b58dc1660a..0f01a70faa 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3733,7 +3733,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW return 0; case SH_Table_GridLineColor: - return option ? option->palette.window().color().darker(120).rgb() : 0; + return option ? option->palette.window().color().darker(120).rgba() : 0; case SH_MessageBox_TextInteractionFlags: return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 6cbed34c3a..d2f5ac76f9 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1835,7 +1835,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_LineEdit_PasswordMaskDelay Determines the delay before visible character is masked with password character, in milliseconds. This enum value was added in Qt 5.4. - \value SH_Table_GridLineColor The RGB value of the grid for a table. + \value SH_Table_GridLineColor The RGBA value of the grid for a table. \value SH_UnderlineShortcut Whether shortcuts are underlined. diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 3f57992311..0568d749c8 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -534,6 +534,7 @@ public: const QStyleSheetOutlineData *outline() const { return ou; } const QStyleSheetGeometryData *geometry() const { return geo; } const QStyleSheetPositionData *position() const { return p; } + const QStyleSheetImageData *icon() const { return iconPtr; } bool hasModification() const; @@ -569,6 +570,7 @@ public: bool hasGeometry() const { return geo != 0; } bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); } bool hasImage() const { return img != 0; } + bool hasIcon() const { return iconPtr != 0; } QSize minimumContentsSize() const { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); } @@ -628,6 +630,7 @@ public: QSharedDataPointer<QStyleSheetGeometryData> geo; QSharedDataPointer<QStyleSheetPositionData> p; QSharedDataPointer<QStyleSheetImageData> img; + QSharedDataPointer<QStyleSheetImageData> iconPtr; int clipset; QPainterPath clipPath; @@ -969,11 +972,16 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject if (v.extractPalette(&fg, &sfg, &sbg, &abg)) pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg); - QIcon icon; + QIcon imgIcon; alignment = Qt::AlignCenter; + QSize imgSize; + if (v.extractImage(&imgIcon, &alignment, &imgSize)) + img = new QStyleSheetImageData(imgIcon, alignment, imgSize); + + QIcon icon; QSize size; - if (v.extractImage(&icon, &alignment, &size)) - img = new QStyleSheetImageData(icon, alignment, size); + if (v.extractIcon(&icon, &size)) + iconPtr = new QStyleSheetImageData(icon, Qt::AlignCenter, size); int adj = -255; hasFont = v.extractFont(&font, &adj); @@ -3521,15 +3529,25 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (rule.hasFont) p->setFont(rule.font.resolve(p->font())); - if (rule.hasPosition() && rule.position()->textAlignment != 0) { - Qt::Alignment textAlignment = rule.position()->textAlignment; - QRect textRect = button->rect; + if (rule.hasPosition() || rule.hasIcon()) { uint tf = Qt::TextShowMnemonic; + QRect textRect = button->rect; + + const uint horizontalAlignMask = Qt::AlignHCenter | Qt::AlignLeft | Qt::AlignRight; const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft; - tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; - if (!styleHint(SH_UnderlineShortcut, button, w)) - tf |= Qt::TextHideMnemonic; - if (!button->icon.isNull()) { + + if (rule.hasPosition() && rule.position()->textAlignment != 0) { + Qt::Alignment textAlignment = rule.position()->textAlignment; + tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; + tf |= (textAlignment & horizontalAlignMask) ? (textAlignment & horizontalAlignMask) : Qt::AlignHCenter; + if (!styleHint(SH_UnderlineShortcut, button, w)) + tf |= Qt::TextHideMnemonic; + } else { + tf |= Qt::AlignVCenter | Qt::AlignHCenter; + } + + QIcon icon = rule.hasIcon() ? rule.icon()->icon : button->icon; + if (!icon.isNull()) { //Group both icon and text QRect iconRect; QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; @@ -3539,7 +3557,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (button->state & State_On) state = QIcon::On; - QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state); + QPixmap pixmap = icon.pixmap(button->iconSize, mode, state); int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); int labelWidth = pixmapWidth; @@ -3550,10 +3568,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q labelWidth += (textWidth + iconSpacing); //Determine label alignment: - if (textAlignment & Qt::AlignLeft) { /*left*/ + if (tf & Qt::AlignLeft) { /*left*/ iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); - } else if (textAlignment & Qt::AlignHCenter) { /* center */ + } else if (tf & Qt::AlignHCenter) { /* center */ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); @@ -3565,7 +3583,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect = visualRect(button->direction, textRect, iconRect); - tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead + // Left align, adjust the text-rect according to the icon instead + tf &= ~horizontalAlignMask; + tf |= Qt::AlignLeft; if (button->direction == Qt::RightToLeft) textRect.setRight(iconRect.left() - iconSpacing); @@ -3576,9 +3596,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); p->drawPixmap(iconRect, pixmap); - } else { - tf |= textAlignment; } + if (button->state & (State_On | State_Sunken)) textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 7b69eff30c..3c0271e7c2 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -473,7 +473,7 @@ QMatchData QCompletionEngine::filterHistory() if (curParts.count() <= 1 || c->proxy->showAll || !source) return QMatchData(); -#if QT_CONFIG(dirmodel) +#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15) const bool isDirModel = (qobject_cast<QDirModel *>(source) != nullptr); #else const bool isDirModel = false; @@ -903,7 +903,7 @@ void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted) QModelIndex si = proxy->mapToSource(index); si = si.sibling(si.row(), column); // for clicked() completion = q->pathFromIndex(si); -#if QT_CONFIG(dirmodel) +#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15) // add a trailing separator in inline if (mode == QCompleter::InlineCompletion) { if (qobject_cast<QDirModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir()) @@ -1125,7 +1125,7 @@ void QCompleter::setModel(QAbstractItemModel *model) setPopup(d->popup); // set the model and make new connections if (oldModel && oldModel->QObject::parent() == this) delete oldModel; -#if QT_CONFIG(dirmodel) +#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15) if (qobject_cast<QDirModel *>(model)) { #if defined(Q_OS_WIN) setCaseSensitivity(Qt::CaseInsensitive); @@ -1846,7 +1846,7 @@ QString QCompleter::pathFromIndex(const QModelIndex& index) const return QString(); bool isDirModel = false; bool isFsModel = false; -#if QT_CONFIG(dirmodel) +#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15) isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr; #endif #if QT_CONFIG(filesystemmodel) @@ -1895,7 +1895,7 @@ QStringList QCompleter::splitPath(const QString& path) const { bool isDirModel = false; bool isFsModel = false; -#if QT_CONFIG(dirmodel) +#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15) Q_D(const QCompleter); isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr; #endif diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index fd18888870..ae81cc5661 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -367,8 +367,6 @@ bool QSystemTrayIcon::event(QEvent *e) This signal is emitted when the message displayed using showMessage() was clicked by the user. - Currently this signal is not sent on \macos. - \note We follow Microsoft Windows behavior, so the signal is also emitted when the user clicks on a tray icon with a balloon message displayed. diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index 6f807e1696..2d5ba05d40 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -45,3 +45,5 @@ testcocoon { MODULE_PLUGIN_TYPES += \ styles load(qt_module) + +CONFIG += metatypes install_metatypes diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 9a0e969e1c..2d21187317 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -368,6 +368,8 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const } if (minimumContentsLength > 0) sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.horizontalAdvance(QLatin1Char('X')) + (hasIcon ? iconSize.width() + 4 : 0))); + if (!placeholderText.isEmpty()) + sh.setWidth(qMax(sh.width(), fm.boundingRect(placeholderText).width())); // height @@ -1110,8 +1112,9 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int q->updateGeometry(); } - // set current index if combo was previously empty - if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid()) { + // set current index if combo was previously empty and there is no placeholderText + if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid() && + placeholderText.isEmpty()) { q->setCurrentIndex(0); // need to emit changed if model updated index "silently" } else if (currentIndex.row() != indexBeforeChange) { @@ -1214,10 +1217,9 @@ void QComboBox::initStyleOption(QStyleOptionComboBox *option) const } else { option->activeSubControls = d->hoverControl; } - if (d->currentIndex.isValid()) { - option->currentText = currentText(); + option->currentText = currentText(); + if (d->currentIndex.isValid()) option->currentIcon = d->itemIcon(d->currentIndex); - } option->iconSize = iconSize(); if (d->container && d->container->isVisible()) option->state |= QStyle::State_On; @@ -1772,6 +1774,45 @@ void QComboBox::setIconSize(const QSize &size) } /*! + \property QComboBox::placeholderText + \brief Sets a \a placeholderText text shown when no valid index is set + + The \a placeholderText will be shown when an invalid index is set. The + text is not accessible in the dropdown list. When this function is called + before items are added the placeholder text will be shown, otherwise you + have to call setCurrentIndex(-1) programmatically if you want to show the + placeholder text. + Set an empty placeholder text to reset the setting. + + When the QComboBox is editable, use QLineEdit::setPlaceholderText() + instead. + + \since 5.15 +*/ +void QComboBox::setPlaceholderText(const QString &placeholderText) +{ + Q_D(QComboBox); + if (placeholderText == d->placeholderText) + return; + + d->placeholderText = placeholderText; + if (currentIndex() == -1) { + if (d->placeholderText.isEmpty() && currentIndex() == -1) + setCurrentIndex(0); + else + update(); + } else { + updateGeometry(); + } +} + +QString QComboBox::placeholderText() const +{ + Q_D(const QComboBox); + return d->placeholderText; +} + +/*! \property QComboBox::editable \brief whether the combo box can be edited by the user @@ -2249,7 +2290,7 @@ QString QComboBox::currentText() const else if (d->currentIndex.isValid()) return d->itemText(d->currentIndex); else - return QString(); + return d->placeholderText; } /*! @@ -3079,6 +3120,9 @@ void QComboBox::paintEvent(QPaintEvent *) initStyleOption(&opt); painter.drawComplexControl(QStyle::CC_ComboBox, opt); + if (currentIndex() < 0) + opt.palette.setBrush(QPalette::ButtonText, opt.palette.brush(QPalette::ButtonText).color().lighter()); + // draw the icon and text painter.drawControl(QStyle::CE_ComboBoxLabel, opt); } diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 286772c091..4f89d7f542 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -71,6 +71,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy) Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength) Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) #if QT_CONFIG(completer) #if QT_DEPRECATED_SINCE(5, 13) @@ -148,6 +149,9 @@ public: QSize iconSize() const; void setIconSize(const QSize &size); + void setPlaceholderText(const QString &placeholderText); + QString placeholderText() const; + bool isEditable() const; void setEditable(bool editable); void setLineEdit(QLineEdit *edit); diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 5967776a61..00211d70aa 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -417,6 +417,7 @@ public: int maxVisibleItems; int maxCount; int modelColumn; + QString placeholderText; bool inserting; mutable QSize minimumSizeHint; mutable QSize sizeHint; diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 3d31a3b73a..69b1c5896f 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -324,15 +324,10 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst) QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1))); QSize popup_size = activeMenu->sizeHint(); //we put the popup menu on the screen containing the bottom-center of the action rect - QScreen *popupScreen = q->window()->windowHandle()->screen(); - QPoint bottomMiddlePos = pos + QPoint(adjustedActionRect.width() / 2, 0); - const auto &siblings = popupScreen->virtualSiblings(); - for (QScreen *sibling : siblings) { - if (sibling->geometry().contains(bottomMiddlePos)) { - popupScreen = sibling; - break; - } - } + QScreen *menubarScreen = q->window()->windowHandle()->screen(); + QScreen *popupScreen = menubarScreen->virtualSiblingAt(pos + QPoint(adjustedActionRect.width() / 2, 0)); + if (!popupScreen) + popupScreen = menubarScreen; QRect screenRect = popupScreen->geometry(); pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y())); const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top()); diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index e39ef6d1cd..b7c3426e08 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -123,6 +123,11 @@ public: wish to do your own drawing you can get a pointer to the pixmap used in the splash screen with pixmap(). Alternatively, you can subclass QSplashScreen and reimplement drawContents(). + + In case of having multiple screens, it is also possible to show the + splash screen on a different screen than the primary one. For example: + + \snippet qsplashscreen/main.cpp 2 */ /*! @@ -139,6 +144,23 @@ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f) /*! \overload + \since 5.15 + + This function allows you to specify the screen for your splashscreen. The + typical use for this constructor is if you have multiple screens and + prefer to have the splash screen on a different screen than your primary + one. In that case pass the proper \a screen. +*/ +QSplashScreen::QSplashScreen(QScreen *screen, const QPixmap &pixmap, Qt::WindowFlags f) + : QWidget(*(new QSplashScreenPrivate()), nullptr, Qt::SplashScreen | Qt::FramelessWindowHint | f) +{ + d_func()->setPixmap(pixmap, screen); +} + +#if QT_DEPRECATED_SINCE(5, 15) +/*! + \overload + \obsolete This function allows you to specify a parent for your splashscreen. The typical use for this constructor is if you have a multiple screens and @@ -152,6 +174,7 @@ QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap, Qt::WindowF // is still 0 here due to QWidget's special handling. d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(parent)); } +#endif /*! Destructor. @@ -286,26 +309,35 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap) } // In setPixmap(), resize and try to position on a screen according to: -// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on +// 1) If the screen for the given widget is available, use that +// 2) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on // QSplashScreen(QWidget *, QPixmap). -// 2) If a widget with associated QWindow is found, use that -// 3) When nothing can be found, try to center it over the cursor +// 3) If a widget with associated QWindow is found, use that +// 4) When nothing can be found, try to center it over the cursor +#if QT_DEPRECATED_SINCE(5, 15) static inline int screenNumberOf(const QDesktopScreenWidget *dsw) { auto desktopWidgetPrivate = static_cast<QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop())); return desktopWidgetPrivate->screens.indexOf(const_cast<QDesktopScreenWidget *>(dsw)); } +#endif const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w) { + if (w && w->screen()) + return w->screen(); + for (const QWidget *p = w; p !=nullptr ; p = p->parentWidget()) { +#if QT_DEPRECATED_SINCE(5, 15) if (auto dsw = qobject_cast<const QDesktopScreenWidget *>(p)) return QGuiApplication::screens().value(screenNumberOf(dsw)); +#endif if (QWindow *window = p->windowHandle()) return window->screen(); } + #if QT_CONFIG(cursor) // Note: We could rely on QPlatformWindow::initialGeometry() to center it // over the cursor, but not all platforms (namely Android) use that. diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h index 8bdf4e7749..1877493fcf 100644 --- a/src/widgets/widgets/qsplashscreen.h +++ b/src/widgets/widgets/qsplashscreen.h @@ -55,7 +55,11 @@ class Q_WIDGETS_EXPORT QSplashScreen : public QWidget Q_OBJECT public: explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); + QSplashScreen(QScreen *screen, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_VERSION_X_5_15("Use the constructor taking a QScreen *") QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); +#endif virtual ~QSplashScreen(); void setPixmap(const QPixmap &pixmap); |