diff options
Diffstat (limited to 'src/widgets')
135 files changed, 1942 insertions, 1202 deletions
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 840a990799..94cf58ae3b 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -44,7 +44,9 @@ #include "qaction.h" #include "qapplication.h" #include "qgroupbox.h" +#if QT_CONFIG(label) #include "qlabel.h" +#endif #include "qtooltip.h" #include "qwhatsthis.h" #include "qwidget.h" @@ -81,7 +83,7 @@ static QString buddyString(const QWidget *widget) QWidget *parent = widget->parentWidget(); if (!parent) return QString(); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) && QT_CONFIG(label) for (QObject *o : parent->children()) { QLabel *label = qobject_cast<QLabel*>(o); if (label && label->buddy() == widget) @@ -309,7 +311,7 @@ QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRel if (match & QAccessible::Label) { const QAccessible::Relation rel = QAccessible::Label; if (QWidget *parent = widget()->parentWidget()) { -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) && QT_CONFIG(label) // first check for all siblings that are labels to us // ideally we would go through all objects and check, but that // will be too expensive diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index da184fd90d..c95b5b1097 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -45,7 +45,6 @@ #include "complexwidgets_p.h" #include "itemviews_p.h" -#include <qpushbutton.h> #include <qtoolbutton.h> #include <qtreeview.h> #include <qvariant.h> @@ -184,8 +183,10 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje } else if (classname == QLatin1String("QMdiSubWindow")) { iface = new QAccessibleMdiSubWindow(widget); #endif +#if QT_CONFIG(dialogbuttonbox) } else if (classname == QLatin1String("QDialogButtonBox")) { iface = new QAccessibleDialogButtonBox(widget); +#endif #ifndef QT_NO_DIAL } else if (classname == QLatin1String("QDial")) { iface = new QAccessibleDial(widget); diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 4c48ecb465..40aca37f11 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -54,7 +54,9 @@ #include <QToolBox> #include <QMdiArea> #include <QMdiSubWindow> +#if QT_CONFIG(dialogbuttonbox) #include <QDialogButtonBox> +#endif #include <limits.h> #include <QRubberBand> #include <QTextBrowser> @@ -480,7 +482,7 @@ QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const } #endif // QT_NO_MDIAREA -#ifndef QT_NO_DIALOGBUTTONBOX +#if QT_CONFIG(dialogbuttonbox) // ======================= QAccessibleDialogButtonBox ====================== QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) : QAccessibleWidget(widget, QAccessible::Grouping) @@ -488,7 +490,7 @@ QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) Q_ASSERT(qobject_cast<QDialogButtonBox*>(widget)); } -#endif // QT_NO_DIALOGBUTTONBOX +#endif // QT_CONFIG(dialogbuttonbox) #if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) diff --git a/src/widgets/accessible/qaccessiblewidgets_p.h b/src/widgets/accessible/qaccessiblewidgets_p.h index 052958d4c7..4d945a2016 100644 --- a/src/widgets/accessible/qaccessiblewidgets_p.h +++ b/src/widgets/accessible/qaccessiblewidgets_p.h @@ -248,11 +248,13 @@ protected: }; #endif // QT_NO_MDIAREA +#if QT_CONFIG(dialogbuttonbox) class QAccessibleDialogButtonBox : public QAccessibleWidget { public: explicit QAccessibleDialogButtonBox(QWidget *widget); }; +#endif #if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) class QAccessibleTextBrowser : public QAccessibleTextEdit diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index a806cb7af6..600754f90c 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -40,14 +40,22 @@ #include "simplewidgets_p.h" #include <qabstractbutton.h> +#if QT_CONFIG(checkbox) #include <qcheckbox.h> +#endif +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#endif #include <qprogressbar.h> #include <qstatusbar.h> +#if QT_CONFIG(radiobutton) #include <qradiobutton.h> +#endif #include <qtoolbutton.h> #include <qmenu.h> +#if QT_CONFIG(label) #include <qlabel.h> +#endif #include <qgroupbox.h> #include <qlcdnumber.h> #include <qlineedit.h> @@ -109,7 +117,7 @@ QString QAccessibleButton::text(QAccessible::Text t) const switch (t) { case QAccessible::Accelerator: { -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) && QT_CONFIG(pushbutton) QPushButton *pb = qobject_cast<QPushButton*>(object()); if (pb && pb->isDefault()) str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText); @@ -136,15 +144,20 @@ QAccessible::State QAccessibleButton::state() const QAccessible::State state = QAccessibleWidget::state(); QAbstractButton *b = button(); +#if QT_CONFIG(checkbox) QCheckBox *cb = qobject_cast<QCheckBox *>(b); +#endif if (b->isCheckable()) state.checkable = true; if (b->isChecked()) state.checked = true; +#if QT_CONFIG(checkbox) else if (cb && cb->checkState() == Qt::PartiallyChecked) state.checkStateMixed = true; +#endif if (b->isDown()) state.pressed = true; +#if QT_CONFIG(pushbutton) QPushButton *pb = qobject_cast<QPushButton*>(b); if (pb) { if (pb->isDefault()) @@ -154,6 +167,7 @@ QAccessible::State QAccessibleButton::state() const state.hasPopup = true; #endif } +#endif return state; } @@ -164,17 +178,22 @@ QRect QAccessibleButton::rect() const if (!ab->isVisible()) return QRect(); +#if QT_CONFIG(checkbox) if (QCheckBox *cb = qobject_cast<QCheckBox *>(ab)) { QPoint wpos = cb->mapToGlobal(QPoint(0, 0)); QStyleOptionButton opt; cb->initStyleOption(&opt); return cb->style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, cb).translated(wpos); - } else if (QRadioButton *rb = qobject_cast<QRadioButton *>(ab)) { + } +#endif +#if QT_CONFIG(radiobutton) + else if (QRadioButton *rb = qobject_cast<QRadioButton *>(ab)) { QPoint wpos = rb->mapToGlobal(QPoint(0, 0)); QStyleOptionButton opt; rb->initStyleOption(&opt); return rb->style()->subElementRect(QStyle::SE_RadioButtonClickRect, &opt, rb).translated(wpos); } +#endif return QAccessibleWidget::rect(); } @@ -390,6 +409,7 @@ QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role) QAccessible::Role QAccessibleDisplay::role() const { +#if QT_CONFIG(label) QLabel *l = qobject_cast<QLabel*>(object()); if (l) { if (l->pixmap()) @@ -411,6 +431,7 @@ QAccessible::Role QAccessibleDisplay::role() const return QAccessible::StatusBar; #endif } +#endif return QAccessibleWidget::role(); } @@ -421,7 +442,9 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const case QAccessible::Name: str = widget()->accessibleName(); if (str.isEmpty()) { - if (qobject_cast<QLabel*>(object())) { + if (false) { +#if QT_CONFIG(label) + } else if (qobject_cast<QLabel*>(object())) { QLabel *label = qobject_cast<QLabel*>(object()); str = label->text(); #ifndef QT_NO_TEXTHTMLPARSER @@ -436,6 +459,7 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const if (label->buddy()) str = qt_accStripAmp(str); #endif +#endif // QT_CONFIG(label) #ifndef QT_NO_LCDNUMBER } else if (qobject_cast<QLCDNumber*>(object())) { QLCDNumber *l = qobject_cast<QLCDNumber*>(object()); @@ -470,21 +494,15 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const { QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match); +#if QT_CONFIG(shortcut) && QT_CONFIG(label) if (match & QAccessible::Labelled) { - QVarLengthArray<QObject *, 4> relatedObjects; - -#ifndef QT_NO_SHORTCUT if (QLabel *label = qobject_cast<QLabel*>(object())) { - relatedObjects.append(label->buddy()); - } -#endif - for (int i = 0; i < relatedObjects.count(); ++i) { const QAccessible::Relation rel = QAccessible::Labelled; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i)); - if (iface) + if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(label->buddy())) rels.append(qMakePair(iface, rel)); } } +#endif return rels; } @@ -501,33 +519,41 @@ QString QAccessibleDisplay::imageDescription() const #ifndef QT_NO_TOOLTIP return widget()->toolTip(); #else - return QString::null; + return QString(); #endif } /*! \internal */ QSize QAccessibleDisplay::imageSize() const { +#if QT_CONFIG(label) QLabel *label = qobject_cast<QLabel *>(widget()); if (!label) +#endif return QSize(); +#if QT_CONFIG(label) const QPixmap *pixmap = label->pixmap(); if (!pixmap) return QSize(); return pixmap->size(); +#endif } /*! \internal */ QPoint QAccessibleDisplay::imagePosition() const { +#if QT_CONFIG(label) QLabel *label = qobject_cast<QLabel *>(widget()); if (!label) +#endif return QPoint(); +#if QT_CONFIG(label) const QPixmap *pixmap = label->pixmap(); if (!pixmap) return QPoint(); return QPoint(label->mapToGlobal(label->pos())); +#endif } #ifndef QT_NO_GROUPBOX @@ -670,11 +696,13 @@ void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text) } QString newText = text; +#if QT_CONFIG(validator) if (lineEdit()->validator()) { int pos = 0; if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable) return; } +#endif lineEdit()->setText(newText); } diff --git a/src/widgets/configure.json b/src/widgets/configure.json index e7007f71b7..99e1bd6940 100644 --- a/src/widgets/configure.json +++ b/src/widgets/configure.json @@ -117,11 +117,18 @@ "condition": "features.tableview", "output": [ "publicFeature", "feature" ] }, + "commandlinkbutton": { + "label": "QCommandLinkButton", + "purpose": "Provides a Vista style command link button.", + "section": "Widgets", + "condition": "features.pushbutton", + "output": [ "publicFeature" ] + }, "datetimeedit": { "label": "QDateTimeEdit", "purpose": "Supports editing dates and times.", "section": "Widgets", - "condition": "features.calendarwidget && features.datestring", + "condition": "features.calendarwidget && features.datestring && features.textdate", "output": [ "publicFeature", "feature" ] }, "stackedwidget": { @@ -150,6 +157,19 @@ "condition": "features.rubberband", "output": [ "publicFeature", "feature" ] }, + "label": { + "label": "QLabel", + "purpose": "Provides a text or image display.", + "section": "Widgets", + "output": [ "publicFeature" ] + }, + "formlayout": { + "label": "QFormLayout", + "purpose": "Manages forms of input widgets and their associated labels.", + "section": "Widgets", + "condition": "features.label", + "output": [ "publicFeature" ] + }, "lcdnumber": { "label": "QLCDNumber", "purpose": "Provides LCD-like digits.", @@ -160,7 +180,7 @@ "label": "QMenu", "purpose": "Provides popup-menus.", "section": "Widgets", - "condition": "features.action", + "condition": "features.action && features.pushbutton", "output": [ "publicFeature", "feature" ] }, "lineedit": { @@ -169,6 +189,12 @@ "section": "Widgets", "output": [ "publicFeature", "feature" ] }, + "radiobutton": { + "label": "QRadioButton", + "purpose": "Provides a radio button with a text label.", + "section": "Widgets", + "output": [ "publicFeature" ] + }, "spinbox": { "label": "QSpinBox", "purpose": "Provides spin boxes handling integers and discrete sets of values.", @@ -204,6 +230,19 @@ "condition": "features.combobox && features.stringlistmodel", "output": [ "publicFeature", "feature" ] }, + "checkbox": { + "label": "QCheckBox(", + "purpose": "Provides a checkbox with a text label.", + "section": "Widgets", + "output": [ "publicFeature" ] + }, + "pushbutton": { + "label": "QPushButton", + "purpose": "Provides a command button.", + "section": "Widgets", + "condition": "features.action", + "output": [ "publicFeature" ] + }, "toolbutton": { "label": "QToolButton", "purpose": "Provides quick-access buttons to commands and options.", @@ -291,10 +330,17 @@ "section": "Widgets", "output": [ "publicFeature", "feature" ] }, + "abstractslider": { + "label": "QAbstractSlider", + "purpose": "Common super class for widgets like QScrollBar, QSlider and QDial.", + "section": "Widgets", + "output": [ "publicFeature" ] + }, "slider": { "label": "QSlider", "purpose": "Provides sliders controlling a bounded value.", "section": "Widgets", + "condition": "features.abstractslider", "output": [ "publicFeature", "feature" ] }, "scrollbar": { @@ -318,6 +364,12 @@ "condition": "features.scrollbar", "output": [ "publicFeature", "feature" ] }, + "scroller": { + "label": "QScroller", + "purpose": "Enables kinetic scrolling for any scrolling widget or graphics item.", + "section": "Widgets", + "output": [ "publicFeature" ] + }, "graphicsview": { "label": "QGraphicsView", "purpose": "Provides a canvas/sprite framework.", @@ -356,6 +408,7 @@ "label": "QToolTip", "purpose": "Supports presentation of tooltips.", "section": "Widgets", + "condition": "features.label", "output": [ "publicFeature", "feature" ] }, "statustip": { @@ -381,7 +434,15 @@ "label": "QCalendarWidget", "purpose": "Provides a monthly based calendar widget allowing the user to select a date.", "section": "Widgets", - "condition": "features.tableview && features.menu && features.textdate && features.spinbox && features.toolbutton", + "condition": [ + "features.label", + "features.menu", + "features.pushbutton", + "features.spinbox", + "features.tableview", + "features.textdate", + "features.toolbutton" + ], "output": [ "publicFeature", "feature" ] }, "keysequenceedit": { @@ -391,59 +452,119 @@ "condition": "features.lineedit && features.shortcut", "output": [ "publicFeature", "feature" ] }, + "dialogbuttonbox": { + "label": "QDialogButtonBox", + "purpose": "Presents buttons in a layout that is appropriate for the current widget style.", + "section": "Dialogs", + "condition": "features.pushbutton", + "output": [ "publicFeature" ] + }, "messagebox": { "label": "QMessageBox", "purpose": "Provides message boxes displaying informative messages and simple questions.", "section": "Dialogs", + "condition" : [ + "features.checkbox", + "features.dialogbuttonbox", + "features.label", + "features.pushbutton" + ], "output": [ "publicFeature", "feature" ] }, "colordialog": { "label": "QColorDialog", "purpose": "Provides a dialog widget for specifying colors.", "section": "Dialogs", - "condition": "features.spinbox", + "condition": [ + "features.dialogbuttonbox", + "features.label", + "features.pushbutton", + "features.spinbox" + ], "output": [ "publicFeature", "feature" ] }, "filedialog": { "label": "QFileDialog", "purpose": "Provides a dialog widget for selecting files or directories.", "section": "Dialogs", - "condition": "features.dirmodel && features.treeview && features.combobox && features.toolbutton && features.buttongroup && features.tooltip && features.splitter && features.stackedwidget && features.proxymodel", + "condition": [ + "features.buttongroup", + "features.combobox", + "features.dialogbuttonbox", + "features.dirmodel", + "features.label", + "features.proxymodel", + "features.splitter", + "features.stackedwidget", + "features.treeview", + "features.toolbutton" + ], "output": [ "publicFeature", "feature" ] }, "fontdialog": { "label": "QFontDialog", "purpose": "Provides a dialog widget for selecting fonts.", "section": "Dialogs", - "condition": "features.stringlistmodel && features.combobox && features.validator && features.groupbox", + "condition": [ + "features.checkbox", + "features.combobox", + "features.dialogbuttonbox", + "features.groupbox", + "features.label", + "features.pushbutton", + "features.stringlistmodel", + "features.validator" + ], "output": [ "publicFeature", "feature" ] }, "progressdialog": { "label": "QProgressDialog", "purpose": "Provides feedback on the progress of a slow operation.", "section": "Dialogs", - "condition": "features.progressbar", + "condition": [ + "features.label", + "features.pushbutton", + "features.progressbar" + ], "output": [ "publicFeature", "feature" ] }, "inputdialog": { "label": "QInputDialog", "purpose": "Provides a simple convenience dialog to get a single value from the user.", "section": "Dialogs", - "condition": "features.combobox && features.spinbox && features.stackedwidget && features.textedit", + "condition": [ + "features.combobox", + "features.dialogbuttonbox", + "features.label", + "features.pushbutton", + "features.spinbox", + "features.stackedwidget", + "features.textedit" + ], "output": [ "publicFeature", "feature" ] }, "errormessage": { "label": "QErrorMessage", "purpose": "Provides an error message display dialog.", "section": "Dialogs", - "condition": "features.textedit", + "condition": [ + "features.checkbox", + "features.textedit", + "features.label", + "features.pushbutton", + "features.textedit" + ], "output": [ "publicFeature", "feature" ] }, "wizard": { "label": "QWizard", "purpose": "Provides a framework for multi-page click-through dialogs.", "section": "Dialogs", - "condition": "features.properties", + "condition": [ + "features.pushbutton", + "features.properties", + "features.label" + ], "output": [ "publicFeature", "feature" ] }, "dirmodel": { diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 39eacae596..dbcd2d7fe2 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -355,7 +355,7 @@ void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect) paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw)); } -/*! +/* Reimplement this function to change the contents of the well array. */ void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r) @@ -441,16 +441,12 @@ void QWellArray::focusInEvent(QFocusEvent*) emit currentChanged(curRow, curCol); } -/*!\reimp -*/ void QWellArray::focusOutEvent(QFocusEvent*) { updateCell(curRow, curCol); } -/*\reimp -*/ void QWellArray::keyPressEvent(QKeyEvent* e) { switch(e->key()) { // Look at the key code @@ -2250,10 +2246,13 @@ bool QColorDialogPrivate::handleColorPickingMouseButtonRelease(QMouseEvent *e) bool QColorDialogPrivate::handleColorPickingKeyPress(QKeyEvent *e) { Q_Q(QColorDialog); +#if QT_CONFIG(shortcut) if (e->matches(QKeySequence::Cancel)) { releaseColorPicking(); q->setCurrentColor(beforeScreenColorPicking); - } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { + } else +#endif + if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { q->setCurrentColor(grabScreenColor(QCursor::pos())); releaseColorPicking(); } diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index e5715ecd57..8e74c659fa 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -43,7 +43,6 @@ #include "qevent.h" #include "qdesktopwidget.h" -#include "qpushbutton.h" #include "qapplication.h" #include "qlayout.h" #include "qsizegrip.h" @@ -367,6 +366,7 @@ QDialog::~QDialog() default default button becomes the default button. This is what a push button calls when it loses focus. */ +#if QT_CONFIG(pushbutton) void QDialogPrivate::setDefault(QPushButton *pushButton) { Q_Q(QDialog); @@ -411,6 +411,7 @@ void QDialogPrivate::hideDefault() list.at(i)->setDefault(false); } } +#endif void QDialogPrivate::resetModalitySetByOpen() { @@ -644,6 +645,7 @@ void QDialog::keyPressEvent(QKeyEvent *e) #endif if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) { switch (e->key()) { +#if QT_CONFIG(pushbutton) case Qt::Key_Enter: case Qt::Key_Return: { QList<QPushButton*> list = findChildren<QPushButton*>(); @@ -657,6 +659,7 @@ void QDialog::keyPressEvent(QKeyEvent *e) } } break; +#endif default: e->ignore(); return; @@ -716,6 +719,7 @@ void QDialog::setVisible(bool visible) and actually catches most cases... If not, then they simply have to use [widget*]->setFocus() themselves... */ +#if QT_CONFIG(pushbutton) if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) { QWidget *first = fw; while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus) @@ -733,6 +737,7 @@ void QDialog::setVisible(bool visible) } } } +#endif if (fw && !fw->hasFocus()) { QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason); QApplication::sendEvent(fw, &e); @@ -760,10 +765,12 @@ void QDialog::setVisible(bool visible) d->eventLoop->exit(); } +#if QT_CONFIG(pushbutton) const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); if (d->mainDef && isActiveWindow() && theme->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool()) QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center())); +#endif } /*!\reimp */ diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index ae9e3bcc93..6723edae38 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -56,7 +56,9 @@ #include "QtCore/qeventloop.h" #include "QtCore/qpointer.h" #include "QtWidgets/qdialog.h" +#if QT_CONFIG(pushbutton) #include "QtWidgets/qpushbutton.h" +#endif #include <qpa/qplatformdialoghelper.h> QT_BEGIN_NAMESPACE @@ -69,7 +71,11 @@ class Q_WIDGETS_EXPORT QDialogPrivate : public QWidgetPrivate public: QDialogPrivate() - : mainDef(0), orientation(Qt::Horizontal),extension(0), doShowExtension(false), + : +#if QT_CONFIG(pushbutton) + mainDef(0), +#endif + orientation(Qt::Horizontal),extension(0), doShowExtension(false), #ifndef QT_NO_SIZEGRIP resizer(0), sizeGripEnabled(false), @@ -84,7 +90,9 @@ public: QVariant styleHint(QPlatformDialogHelper::StyleHint hint) const; void deletePlatformHelper(); +#if QT_CONFIG(pushbutton) QPointer<QPushButton> mainDef; +#endif Qt::Orientation orientation; QWidget *extension; bool doShowExtension; @@ -95,9 +103,11 @@ public: #endif QPoint lastRMBPress; +#if QT_CONFIG(pushbutton) void setDefault(QPushButton *); void setMainDefault(QPushButton *); void hideDefault(); +#endif void resetModalitySetByOpen(); int rescode; diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp index 5fcbe3fe9d..8200135abe 100644 --- a/src/widgets/dialogs/qerrormessage.cpp +++ b/src/widgets/dialogs/qerrormessage.cpp @@ -62,6 +62,13 @@ QT_BEGIN_NAMESPACE +namespace { +struct Message { + QString content; + QString type; +}; +} + class QErrorMessagePrivate : public QDialogPrivate { Q_DECLARE_PUBLIC(QErrorMessage) @@ -70,7 +77,7 @@ public: QCheckBox * again; QTextEdit * errors; QLabel * icon; - std::queue<QPair<QString, QString> > pending; + std::queue<Message> pending; QSet<QString> doNotShow; QSet<QString> doNotShowType; QString currentMessage; @@ -163,14 +170,20 @@ static void jump(QtMsgType t, const QMessageLogContext & /*context*/, const QStr switch (t) { case QtDebugMsg: - default: rich = QErrorMessage::tr("Debug Message:"); break; case QtWarningMsg: rich = QErrorMessage::tr("Warning:"); break; + case QtCriticalMsg: + rich = QErrorMessage::tr("Critical Error:"); + break; case QtFatalMsg: rich = QErrorMessage::tr("Fatal Error:"); + break; + case QtInfoMsg: + rich = QErrorMessage::tr("Information:"); + break; } rich = QString::fromLatin1("<p><b>%1</b></p>").arg(rich); rich += Qt::convertFromPlainText(m, Qt::WhiteSpaceNormal); @@ -297,9 +310,8 @@ bool QErrorMessagePrivate::isMessageToBeShown(const QString &message, const QStr bool QErrorMessagePrivate::nextPending() { while (!pending.empty()) { - QPair<QString,QString> &pendingMessage = pending.front(); - QString message = qMove(pendingMessage.first); - QString type = qMove(pendingMessage.second); + QString message = std::move(pending.front().content); + QString type = std::move(pending.front().type); pending.pop(); if (isMessageToBeShown(message, type)) { #ifndef QT_NO_TEXTHTMLPARSER @@ -349,7 +361,7 @@ void QErrorMessage::showMessage(const QString &message, const QString &type) Q_D(QErrorMessage); if (!d->isMessageToBeShown(message, type)) return; - d->pending.push(qMakePair(message, type)); + d->pending.push({message, type}); if (!isVisible() && d->nextPending()) show(); } diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 5892ec6a75..78e304950a 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -860,7 +860,7 @@ void QFileDialog::setVisible(bool visible) } } - if (d->usingWidgets()) + if (visible && d->usingWidgets()) d->qFileDialogUi->fileNameEdit->setFocus(); QDialog::setVisible(visible); @@ -1461,6 +1461,19 @@ void QFileDialog::selectNameFilter(const QString &filter) } /*! + * \since 5.9 + * \return The mimetype of the file that the user selected in the file dialog. + */ +QString QFileDialog::selectedMimeTypeFilter() const +{ + Q_D(const QFileDialog); + if (!d->usingWidgets()) + return d->selectedMimeTypeFilter_sys(); + + return d->options->initiallySelectedMimeTypeFilter(); +} + +/*! \since 4.4 Returns the filter that the user selected in the file dialog. @@ -1579,9 +1592,19 @@ QStringList QFileDialog::mimeTypeFilters() const */ void QFileDialog::selectMimeTypeFilter(const QString &filter) { - const QString text = nameFilterForMime(filter); - if (!text.isEmpty()) - selectNameFilter(text); + Q_D(QFileDialog); + d->options->setInitiallySelectedMimeTypeFilter(filter); + + const QString filterForMime = nameFilterForMime(filter); + + if (!d->usingWidgets()) { + d->selectMimeTypeFilter_sys(filter); + if (d->selectedMimeTypeFilter_sys().isEmpty() && !filterForMime.isEmpty()) { + selectNameFilter(filterForMime); + } + } else if (!filterForMime.isEmpty()) { + selectNameFilter(filterForMime); + } } #endif // QT_NO_MIMETYPE @@ -2223,7 +2246,7 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, } /*! - This is a convenience static function that will return or or more existing + This is a convenience static function that will return one or more existing files selected by the user. If the user presses Cancel, it returns an empty list. @@ -3790,12 +3813,12 @@ void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory) bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { Q_Q(QFileDialog); - +#if QT_CONFIG(shortcut) if (event->matches(QKeySequence::Cancel)) { q->reject(); return true; } - +#endif switch (event->key()) { case Qt::Key_Backspace: _q_navigateToParent(); @@ -3997,7 +4020,9 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e) int key = e->key(); QLineEdit::keyPressEvent(e); +#if QT_CONFIG(shortcut) if (!e->matches(QKeySequence::Cancel) && key != Qt::Key_Back) +#endif e->accept(); } diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 4ade50793d..7959eebd7b 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -62,7 +62,6 @@ class QAbstractProxyModel; class Q_WIDGETS_EXPORT QFileDialog : public QDialog { Q_OBJECT - Q_FLAGS(Options) Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode) Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode) Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode) @@ -97,6 +96,7 @@ public: }; Q_ENUM(Option) Q_DECLARE_FLAGS(Options, Option) + Q_FLAG(Options) QFileDialog(QWidget *parent, Qt::WindowFlags f); explicit QFileDialog(QWidget *parent = Q_NULLPTR, @@ -125,6 +125,7 @@ public: void setNameFilters(const QStringList &filters); QStringList nameFilters() const; void selectNameFilter(const QString &filter); + QString selectedMimeTypeFilter() const; QString selectedNameFilter() const; #ifndef QT_NO_MIMETYPE diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index afebad4457..b665b54a9b 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -258,6 +258,8 @@ public: void selectFile_sys(const QUrl &filename); QList<QUrl> selectedFiles_sys() const; void setFilter_sys(); + void selectMimeTypeFilter_sys(const QString &filter); + QString selectedMimeTypeFilter_sys() const; void selectNameFilter_sys(const QString &filter); QString selectedNameFilter_sys() const; ////////////////////////////////////////////// @@ -400,6 +402,20 @@ inline void QFileDialogPrivate::setFilter_sys() helper->setFilter(); } +inline void QFileDialogPrivate::selectMimeTypeFilter_sys(const QString &filter) +{ + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) + helper->selectMimeTypeFilter(filter); +} + +QString QFileDialogPrivate::selectedMimeTypeFilter_sys() const +{ + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) + return helper->selectedMimeTypeFilter(); + + return QString(); +} + inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter) { if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index 6df020dd58..08c5a40c7c 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -65,6 +65,18 @@ Q_AUTOTEST_EXPORT bool qt_test_isFetchedRoot() } #endif +static QString translateDriveName(const QFileInfo &drive) +{ + QString driveName = drive.absoluteFilePath(); +#ifdef Q_OS_WIN + if (driveName.startsWith(QLatin1Char('/'))) // UNC host + return drive.fileName(); + if (driveName.endsWith(QLatin1Char('/'))) + driveName.chop(1); +#endif // Q_OS_WIN + return driveName; +} + /*! Creates thread */ @@ -82,6 +94,16 @@ QFileInfoGatherer::QFileInfoGatherer(QObject *parent) watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(list(QString))); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(updateFile(QString))); + +# if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + const QVariant listener = watcher->property("_q_driveListener"); + if (listener.canConvert<QObject *>()) { + if (QObject *driveListener = listener.value<QObject *>()) { + connect(driveListener, SIGNAL(driveAdded()), this, SLOT(driveAdded())); + connect(driveListener, SIGNAL(driveRemoved(QString)), this, SLOT(driveRemoved())); + } + } +# endif // Q_OS_WIN && !Q_OS_WINRT #endif start(LowPriority); } @@ -106,6 +128,20 @@ void QFileInfoGatherer::setResolveSymlinks(bool enable) #endif } +void QFileInfoGatherer::driveAdded() +{ + fetchExtendedInformation(QString(), QStringList()); +} + +void QFileInfoGatherer::driveRemoved() +{ + QStringList drives; + const QFileInfoList driveInfoList = QDir::drives(); + for (const QFileInfo &fi : driveInfoList) + drives.append(translateDriveName(fi)); + newListOfFiles(QString(), drives); +} + bool QFileInfoGatherer::resolveSymlinks() const { #ifdef Q_OS_WIN @@ -260,18 +296,6 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const return info; } -static QString translateDriveName(const QFileInfo &drive) -{ - QString driveName = drive.absoluteFilePath(); -#if defined(Q_OS_WIN) - if (driveName.startsWith(QLatin1Char('/'))) // UNC host - return drive.fileName(); - if (driveName.endsWith(QLatin1Char('/'))) - driveName.chop(1); -#endif - return driveName; -} - /* Get specific file info's, batch the files so update when we have 100 items and every 200ms after that diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 3186e9d015..0018b6c387 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -180,6 +180,10 @@ public Q_SLOTS: void setResolveSymlinks(bool enable); void setIconProvider(QFileIconProvider *provider); +private Q_SLOTS: + void driveAdded(); + void driveRemoved(); + private: void run() Q_DECL_OVERRIDE; // called by run(): diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 955e93a26f..b20a1449eb 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -867,8 +867,7 @@ QFont QFontDialog::selectedFont() const \value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".) \value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's - native font panel. (Currently, the native dialog is never used, - but this is likely to change in future Qt releases.) + native font panel. \value ScalableFonts Show scalable fonts \value NonScalableFonts Show non scalable fonts \value MonospacedFonts Show monospaced fonts diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 98d070e493..3b0a71518d 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1405,7 +1405,7 @@ void QMessageBox::changeEvent(QEvent *ev) void QMessageBox::keyPressEvent(QKeyEvent *e) { Q_D(QMessageBox); - +#if QT_CONFIG(shortcut) if (e->matches(QKeySequence::Cancel)) { if (d->detectedEscapeButton) { #ifdef Q_OS_MAC @@ -1416,7 +1416,7 @@ void QMessageBox::keyPressEvent(QKeyEvent *e) } return; } - +#endif // QT_CONFIG(shortcut) #if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT) diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h index c6a55964fe..3e561a5161 100644 --- a/src/widgets/dialogs/qmessagebox.h +++ b/src/widgets/dialogs/qmessagebox.h @@ -56,7 +56,6 @@ class QCheckBox; class Q_WIDGETS_EXPORT QMessageBox : public QDialog { Q_OBJECT - Q_FLAGS(StandardButtons) Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(Icon icon READ icon WRITE setIcon) Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap) @@ -131,6 +130,7 @@ public: typedef StandardButton Button; // obsolete Q_DECLARE_FLAGS(StandardButtons, StandardButton) + Q_FLAG(StandardButtons) explicit QMessageBox(QWidget *parent = Q_NULLPTR); QMessageBox(Icon icon, const QString &title, const QString &text, diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index 713ccb6556..9bb046db61 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -274,7 +274,7 @@ void QUrlModel::addUrls(const QList<QUrl> &list, int row, bool move) continue; insertRows(row, 1); setUrl(index(row, 0), url, idx); - watching.append(qMakePair(idx, cleanUrl)); + watching.append({idx, cleanUrl}); } } @@ -326,7 +326,7 @@ void QUrlModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto { QModelIndex parent = topLeft.parent(); for (int i = 0; i < watching.count(); ++i) { - QModelIndex index = watching.at(i).first; + QModelIndex index = watching.at(i).index; if (index.model() && topLeft.model()) { Q_ASSERT(index.model() == topLeft.model()); } @@ -335,7 +335,7 @@ void QUrlModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto && index.column() >= topLeft.column() && index.column() <= bottomRight.column() && index.parent() == parent) { - changed(watching.at(i).second); + changed(watching.at(i).path); } } } @@ -349,12 +349,12 @@ void QUrlModel::layoutChanged() const int numPaths = watching.count(); paths.reserve(numPaths); for (int i = 0; i < numPaths; ++i) - paths.append(watching.at(i).second); + paths.append(watching.at(i).path); watching.clear(); for (int i = 0; i < numPaths; ++i) { QString path = paths.at(i); QModelIndex newIndex = fileSystemModel->index(path); - watching.append(QPair<QModelIndex, QString>(newIndex, path)); + watching.append({newIndex, path}); if (newIndex.isValid()) changed(path); } diff --git a/src/widgets/dialogs/qsidebar_p.h b/src/widgets/dialogs/qsidebar_p.h index 3e177e7e68..0685e81b2b 100644 --- a/src/widgets/dialogs/qsidebar_p.h +++ b/src/widgets/dialogs/qsidebar_p.h @@ -108,9 +108,16 @@ private: void changed(const QString &path); void addIndexToWatch(const QString &path, const QModelIndex &index); QFileSystemModel *fileSystemModel; - QVector<QPair<QModelIndex, QString> > watching; + struct WatchItem { + QModelIndex index; + QString path; + }; + friend class QTypeInfo<WatchItem>; + + QVector<WatchItem> watching; QList<QUrl> invalidUrls; }; +Q_DECLARE_TYPEINFO(QUrlModel::WatchItem, Q_MOVABLE_TYPE); class Q_AUTOTEST_EXPORT QSidebar : public QListView { diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 9153d7ea41..5e598ba990 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -1465,8 +1465,10 @@ void QWizardPrivate::updateButtonTexts() // Vista: Add shortcut for 'next'. Note: native dialogs use ALT-Right // even in RTL mode, so do the same, even if it might be counter-intuitive. // The shortcut for 'back' is set in class QVistaBackButton. +#if QT_CONFIG(shortcut) if (btns[QWizard::NextButton]) btns[QWizard::NextButton]->setShortcut(isVistaThemeEnabled() ? QKeySequence(Qt::ALT | Qt::Key_Right) : QKeySequence()); +#endif } void QWizardPrivate::updateButtonLayout() @@ -3255,7 +3257,7 @@ void QWizard::paintEvent(QPaintEvent * event) #endif } -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) /*! \reimp */ diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h index 9ce68b6566..7915c9e7f8 100644 --- a/src/widgets/dialogs/qwizard.h +++ b/src/widgets/dialogs/qwizard.h @@ -55,7 +55,6 @@ class QWizardPrivate; class Q_WIDGETS_EXPORT QWizard : public QDialog { Q_OBJECT - Q_FLAGS(WizardOptions) Q_PROPERTY(WizardStyle wizardStyle READ wizardStyle WRITE setWizardStyle) Q_PROPERTY(WizardOptions options READ options WRITE setOptions) Q_PROPERTY(Qt::TextFormat titleFormat READ titleFormat WRITE setTitleFormat) @@ -120,6 +119,7 @@ public: Q_ENUM(WizardOption) Q_DECLARE_FLAGS(WizardOptions, WizardOption) + Q_FLAG(WizardOptions) explicit QWizard(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QWizard(); @@ -188,7 +188,7 @@ protected: bool event(QEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) bool nativeEvent(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; #endif void done(int result) Q_DECL_OVERRIDE; diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 80e37dab25..4ab01aca66 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -49,6 +49,7 @@ #include "qwizard.h" #include "qpaintengine.h" #include "qapplication.h" +#include <QtCore/QOperatingSystemVersion> #include <QtCore/QVariant> #include <QtCore/QDebug> #include <QtGui/QMouseEvent> @@ -214,8 +215,7 @@ void QVistaHelper::disconnectBackButton() QColor QVistaHelper::basicWindowFrameColor() { DWORD rgb; - HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); - const HANDLE hTheme = OpenThemeData(handle, L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE, wizard->isActiveWindow() ? TMT_FILLCOLORHINT : TMT_BORDERCOLORHINT, &rgb); BYTE r = GetRValue(rgb); @@ -257,8 +257,7 @@ static LOGFONT getCaptionLogFont(HANDLE hTheme) static bool getCaptionQFont(int dpi, QFont *result) { - const HANDLE hTheme = - OpenThemeData(QApplicationPrivate::getHWNDForWidget(QApplication::desktop()), L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); if (!hTheme) return false; // Call into QWindowsNativeInterface to convert the LOGFONT into a QFont. @@ -589,8 +588,7 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q if (vistaState() == VistaAero) { const QRect rectDp = QRect(rect.topLeft() * QVistaHelper::m_devicePixelRatio, rect.size() * QVistaHelper::m_devicePixelRatio); - HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); - const HANDLE hTheme = OpenThemeData(handle, L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); if (!hTheme) return false; // Set up a memory DC and bitmap that we'll draw into HDC dcMem; @@ -718,7 +716,7 @@ int QVistaHelper::topOffset() if (vistaState() != VistaAero) return titleBarSize() + 3; static const int aeroOffset = - QSysInfo::WindowsVersion == QSysInfo::WV_WINDOWS7 ? + QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8 ? QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13); return aeroOffset + titleBarSize(); } diff --git a/src/widgets/effects/qgraphicseffect.h b/src/widgets/effects/qgraphicseffect.h index 06ee78f2a0..8e07e51dca 100644 --- a/src/widgets/effects/qgraphicseffect.h +++ b/src/widgets/effects/qgraphicseffect.h @@ -62,7 +62,6 @@ class QGraphicsEffectPrivate; class Q_WIDGETS_EXPORT QGraphicsEffect : public QObject { Q_OBJECT - Q_FLAGS(ChangeFlags) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) public: enum ChangeFlag { @@ -72,6 +71,7 @@ public: SourceInvalidated = 0x8 }; Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) + Q_FLAG(ChangeFlags) enum PixmapPadMode { NoPad, @@ -155,7 +155,6 @@ class QGraphicsBlurEffectPrivate; class Q_WIDGETS_EXPORT QGraphicsBlurEffect: public QGraphicsEffect { Q_OBJECT - Q_FLAGS(BlurHint BlurHints) Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged) Q_PROPERTY(BlurHints blurHints READ blurHints WRITE setBlurHints NOTIFY blurHintsChanged) public: @@ -164,7 +163,9 @@ public: QualityHint = 0x01, AnimationHint = 0x02 }; + Q_FLAG(BlurHint) Q_DECLARE_FLAGS(BlurHints, BlurHint) + Q_FLAG(BlurHints) QGraphicsBlurEffect(QObject *parent = Q_NULLPTR); ~QGraphicsBlurEffect(); diff --git a/src/widgets/graphicsview/qgraph_p.h b/src/widgets/graphicsview/qgraph_p.h index b0bf3c91c9..b42d4cf2e3 100644 --- a/src/widgets/graphicsview/qgraph_p.h +++ b/src/widgets/graphicsview/qgraph_p.h @@ -250,7 +250,7 @@ public: } strVertices += QString::fromLatin1("\"%1\" [label=\"%2\"]\n").arg(v->toString()).arg(v->toString()); } - return QString::fromLatin1("%1\n%2\n").arg(strVertices).arg(edges); + return QString::fromLatin1("%1\n%2\n").arg(strVertices, edges); } #endif diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp index 6e10d18e11..60e9039b4a 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp @@ -892,7 +892,7 @@ bool QGraphicsAnchorLayoutPrivate::replaceVertex(Orientation orientation, Anchor AnchorVertex *otherV = replaceVertex_helper(ad, oldV, newV); #if defined(QT_DEBUG) - ad->name = QString::fromLatin1("%1 --to--> %2").arg(ad->from->toString()).arg(ad->to->toString()); + ad->name = QString::fromLatin1("%1 --to--> %2").arg(ad->from->toString(), ad->to->toString()); #endif bool newFeasible; @@ -1755,7 +1755,7 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt data->from = v1; data->to = v2; #ifdef QT_DEBUG - data->name = QString::fromLatin1("%1 --to--> %2").arg(v1->toString()).arg(v2->toString()); + data->name = QString::fromLatin1("%1 --to--> %2").arg(v1->toString(), v2->toString()); #endif // ### bit to track internal anchors, since inside AnchorData methods // we don't have access to the 'q' pointer. @@ -2575,10 +2575,12 @@ void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> & for (const AnchorData *ad : visited) identifyNonFloatItems_helper(ad, &nonFloating); - QSet<QGraphicsLayoutItem *> allItems; - foreach (QGraphicsLayoutItem *item, items) - allItems.insert(item); - m_floatItems[orientation] = allItems - nonFloating; + QSet<QGraphicsLayoutItem *> floatItems; + for (QGraphicsLayoutItem *item : qAsConst(items)) { + if (!nonFloating.contains(item)) + floatItems.insert(item); + } + m_floatItems[orientation] = std::move(floatItems); } diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h index b6d8a12658..8da338dff7 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h @@ -260,7 +260,7 @@ inline QString AnchorVertex::toString() const { if (m_type == Pair) { const AnchorVertexPair *vp = static_cast<const AnchorVertexPair *>(this); - return QString::fromLatin1("(%1, %2)").arg(vp->m_first->toString()).arg(vp->m_second->toString()); + return QString::fromLatin1("(%1, %2)").arg(vp->m_first->toString(), vp->m_second->toString()); } else if (!m_item) { return QString::fromLatin1("NULL_%1").arg(quintptr(this)); } diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 4fc52e6ad4..f2b8b66fed 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -7191,9 +7191,6 @@ void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) } } -/*! - obsolete -*/ bool _qt_movableAncestorIsSelected(const QGraphicsItem *item) { const QGraphicsItem *parent = item->parentItem(); diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 41f5eddd99..9d7412340f 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -2996,12 +2996,12 @@ void QGraphicsView::contextMenuEvent(QContextMenuEvent *event) } #endif // QT_NO_CONTEXTMENU +#if QT_CONFIG(draganddrop) /*! \reimp */ void QGraphicsView::dropEvent(QDropEvent *event) { -#ifndef QT_NO_DRAGANDDROP Q_D(QGraphicsView); if (!d->scene || !d->sceneInteractionAllowed) return; @@ -3020,10 +3020,6 @@ void QGraphicsView::dropEvent(QDropEvent *event) delete d->lastDragDropEvent; d->lastDragDropEvent = 0; - -#else - Q_UNUSED(event) -#endif } /*! @@ -3031,7 +3027,6 @@ void QGraphicsView::dropEvent(QDropEvent *event) */ void QGraphicsView::dragEnterEvent(QDragEnterEvent *event) { -#ifndef QT_NO_DRAGANDDROP Q_D(QGraphicsView); if (!d->scene || !d->sceneInteractionAllowed) return; @@ -3054,9 +3049,6 @@ void QGraphicsView::dragEnterEvent(QDragEnterEvent *event) event->setAccepted(true); event->setDropAction(sceneEvent.dropAction()); } -#else - Q_UNUSED(event) -#endif } /*! @@ -3064,7 +3056,6 @@ void QGraphicsView::dragEnterEvent(QDragEnterEvent *event) */ void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event) { -#ifndef QT_NO_DRAGANDDROP Q_D(QGraphicsView); if (!d->scene || !d->sceneInteractionAllowed) return; @@ -3094,9 +3085,6 @@ void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event) // Accept the originating event if the scene accepted the scene event. if (sceneEvent.isAccepted()) event->setAccepted(true); -#else - Q_UNUSED(event) -#endif } /*! @@ -3104,7 +3092,6 @@ void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event) */ void QGraphicsView::dragMoveEvent(QDragMoveEvent *event) { -#ifndef QT_NO_DRAGANDDROP Q_D(QGraphicsView); if (!d->scene || !d->sceneInteractionAllowed) return; @@ -3123,10 +3110,8 @@ void QGraphicsView::dragMoveEvent(QDragMoveEvent *event) event->setAccepted(sceneEvent.isAccepted()); if (sceneEvent.isAccepted()) event->setDropAction(sceneEvent.dropAction()); -#else - Q_UNUSED(event) -#endif } +#endif // QT_CONFIG(draganddrop) /*! \reimp diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h index 327a75c374..64d5f5b430 100644 --- a/src/widgets/graphicsview/qgraphicsview.h +++ b/src/widgets/graphicsview/qgraphicsview.h @@ -244,10 +244,12 @@ protected: #ifndef QT_NO_CONTEXTMENU void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; #endif +#if QT_CONFIG(draganddrop) void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent *event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; +#endif void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; bool focusNextPrevChild(bool next) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 8cd2a957be..f63e258e8e 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -537,11 +537,13 @@ bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor) #ifndef QT_NO_LINEEDIT if (QLineEdit *e = qobject_cast<QLineEdit*>(editor)) { if (!e->hasAcceptableInput()) { +#if QT_CONFIG(validator) if (const QValidator *validator = e->validator()) { QString text = e->text(); validator->fixup(text); e->setText(text); } +#endif return e->hasAcceptableInput(); } } diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 6ecf5a664f..939e2a3d79 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -64,7 +64,7 @@ #ifndef QT_NO_ACCESSIBILITY #include <qaccessible.h> #endif -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) # include <qscroller.h> #endif @@ -196,7 +196,7 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index } } -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) // stores and restores the selection and current item when flicking void QAbstractItemViewPrivate::_q_scrollerStateChanged() @@ -1736,7 +1736,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event) break; case QEvent::ScrollPrepare: executeDelayedItemsLayout(); -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection); #endif break; diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index d6c5d58934..f315ea6e4c 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -62,7 +62,6 @@ class QAbstractItemViewPrivate; class Q_WIDGETS_EXPORT QAbstractItemView : public QAbstractScrollArea { Q_OBJECT - Q_FLAGS(EditTriggers) Q_PROPERTY(bool autoScroll READ hasAutoScroll WRITE setAutoScroll) Q_PROPERTY(int autoScrollMargin READ autoScrollMargin WRITE setAutoScrollMargin) Q_PROPERTY(EditTriggers editTriggers READ editTriggers WRITE setEditTriggers) @@ -118,6 +117,7 @@ public: }; Q_DECLARE_FLAGS(EditTriggers, EditTrigger) + Q_FLAG(EditTriggers) enum ScrollMode { ScrollPerItem, @@ -367,7 +367,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) #endif diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index d21ae573cd..5e3858f491 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -89,18 +89,6 @@ class QTypeInfo<QItemViewPaintPair> : public QTypeInfoMerger<QItemViewPaintPair, typedef QVector<QItemViewPaintPair> QItemViewPaintPairs; -class QEmptyModel : public QAbstractItemModel -{ -public: - explicit QEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {} - QModelIndex index(int, int, const QModelIndex &) const override { return QModelIndex(); } - QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); } - int rowCount(const QModelIndex &) const override { return 0; } - int columnCount(const QModelIndex &) const override { return 0; } - bool hasChildren(const QModelIndex &) const override { return false; } - QVariant data(const QModelIndex &, int) const override { return QVariant(); } -}; - class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QAbstractItemView) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 1310a060ea..d2f9618c29 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2479,7 +2479,10 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e) if (d->shouldAutoScroll(e->pos())) d->startAutoScroll(); if (qAbs(pos - d->firstPos) >= QApplication::startDragDistance() - || !d->sectionIndicator->isHidden()) { +#if QT_CONFIG(label) + || !d->sectionIndicator->isHidden() +#endif + ) { int visual = visualIndexAt(pos); if (visual == -1) return; @@ -2548,7 +2551,11 @@ void QHeaderView::mouseReleaseEvent(QMouseEvent *e) int pos = d->orientation == Qt::Horizontal ? e->x() : e->y(); switch (d->state) { case QHeaderViewPrivate::MoveSection: - if (!d->sectionIndicator->isHidden()) { // moving + if (true +#if QT_CONFIG(label) + && !d->sectionIndicator->isHidden() +#endif + ) { // moving int from = visualIndex(d->section); Q_ASSERT(from != -1); int to = visualIndex(d->target); @@ -3138,9 +3145,11 @@ int QHeaderViewPrivate::sectionHandleAt(int position) void QHeaderViewPrivate::setupSectionIndicator(int section, int position) { Q_Q(QHeaderView); +#if QT_CONFIG(label) if (!sectionIndicator) { sectionIndicator = new QLabel(viewport); } +#endif int w, h; int p = q->sectionViewportPosition(section); @@ -3151,7 +3160,9 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position) w = viewport->width(); h = q->sectionSize(section); } +#if QT_CONFIG(label) sectionIndicator->resize(w, h); +#endif QPixmap pm(w, h); pm.fill(QColor(0, 0, 0, 45)); @@ -3162,12 +3173,15 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position) q->paintSection(&painter, rect, section); painter.end(); +#if QT_CONFIG(label) sectionIndicator->setPixmap(pm); +#endif sectionIndicatorOffset = position - qMax(p, 0); } void QHeaderViewPrivate::updateSectionIndicator(int section, int position) { +#if QT_CONFIG(label) if (!sectionIndicator) return; @@ -3182,6 +3196,7 @@ void QHeaderViewPrivate::updateSectionIndicator(int section, int position) sectionIndicator->move(0, position - sectionIndicatorOffset); sectionIndicator->show(); +#endif } /*! diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index 6affe7af95..d6b119512c 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -58,7 +58,9 @@ #include "QtCore/qbitarray.h" #include "QtWidgets/qapplication.h" +#if QT_CONFIG(label) #include "QtWidgets/qlabel.h" +#endif QT_BEGIN_NAMESPACE @@ -99,7 +101,9 @@ public: lastSectionSize(0), lastSectionLogicalIdx(-1), // Only trust when we stretch last section sectionIndicatorOffset(0), +#if QT_CONFIG(label) sectionIndicator(0), +#endif globalResizeMode(QHeaderView::Interactive), sectionStartposRecalc(true), resizeContentsPrecision(1000) @@ -296,7 +300,9 @@ public: int lastSectionLogicalIdx; // Only trust if we stretch LastSection int sectionIndicatorOffset; Qt::Alignment defaultAlignment; +#if QT_CONFIG(label) QLabel *sectionIndicator; +#endif QHeaderView::ResizeMode globalResizeMode; QList<QPersistentModelIndex> persistentHiddenSections; mutable bool sectionStartposRecalc; diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp index 5356ce3ad0..c044d37575 100644 --- a/src/widgets/itemviews/qitemeditorfactory.cpp +++ b/src/widgets/itemviews/qitemeditorfactory.cpp @@ -45,7 +45,9 @@ #include <qcombobox.h> #include <qdatetimeedit.h> +#if QT_CONFIG(label) #include <qlabel.h> +#endif #include <qlineedit.h> #include <qspinbox.h> #include <limits.h> @@ -261,8 +263,10 @@ QWidget *QDefaultItemEditorFactory::createEditor(int userType, QWidget *parent) ed->setFrame(false); return ed; } #endif +#if QT_CONFIG(label) case QVariant::Pixmap: return new QLabel(parent); +#endif #ifndef QT_NO_SPINBOX case QVariant::Double: { QDoubleSpinBox *sb = new QDoubleSpinBox(parent); diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 65421bfb67..653b03ef0d 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1992,7 +1992,9 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView: QListModeViewBase::QListModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d) { +#if QT_CONFIG(draganddrop) dd->defaultDropAction = Qt::CopyAction; +#endif } #ifndef QT_NO_DRAGANDDROP @@ -2335,13 +2337,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max) { doStaticLayout(info); - if (batchStartRow > max) { // stop items layout - flowPositions.resize(flowPositions.count()); - segmentPositions.resize(segmentPositions.count()); - segmentStartRows.resize(segmentStartRows.count()); - return true; // done - } - return false; // not done + return batchStartRow > max; // returning true stops items layout } QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) const @@ -2475,9 +2471,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info) if (info.wrap && (flowPosition + deltaFlowPosition >= segEndPosition)) { segmentExtents.append(flowPosition); flowPosition = info.spacing + segStartPosition; - segPosition += deltaSegPosition; - if (info.wrap) - segPosition += info.spacing; + segPosition += info.spacing + deltaSegPosition; segmentPositions.append(segPosition); segmentStartRows.append(row); deltaSegPosition = 0; diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h index c70e0522b7..85ca639e50 100644 --- a/src/widgets/itemviews/qlistwidget.h +++ b/src/widgets/itemviews/qlistwidget.h @@ -252,8 +252,9 @@ public: bool isItemHidden(const QListWidgetItem *item) const; void setItemHidden(const QListWidgetItem *item, bool hide); +#if QT_CONFIG(draganddrop) void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; - +#endif public Q_SLOTS: void scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible); void clear(); diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h index 5dde93f628..b91bcf7ce4 100644 --- a/src/widgets/itemviews/qtablewidget.h +++ b/src/widgets/itemviews/qtablewidget.h @@ -331,8 +331,9 @@ protected: QModelIndex indexFromItem(QTableWidgetItem *item) const; QTableWidgetItem *itemFromIndex(const QModelIndex &index) const; +#if QT_CONFIG(draganddrop) void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; - +#endif private: void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index 36ba9985bd..fc0bccf2fe 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -360,8 +360,9 @@ protected: QModelIndex indexFromItem(const QTreeWidgetItem *item, int column = 0) const; QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const; // ### Qt 6: remove QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const; +#if QT_CONFIG(draganddrop) void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; - +#endif private: void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index ad2180bbfd..c91be918b6 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -15,7 +15,6 @@ HEADERS += \ kernel/qwidgetbackingstore_p.h \ kernel/qboxlayout.h \ kernel/qdesktopwidget.h \ - kernel/qformlayout.h \ kernel/qgridlayout.h \ kernel/qlayout.h \ kernel/qlayout_p.h \ @@ -45,7 +44,6 @@ SOURCES += \ kernel/qapplication.cpp \ kernel/qwidgetbackingstore.cpp \ kernel/qboxlayout.cpp \ - kernel/qformlayout.cpp \ kernel/qgridlayout.cpp \ kernel/qlayout.cpp \ kernel/qlayoutengine.cpp \ @@ -84,3 +82,8 @@ qtConfig(opengl) { HEADERS += kernel/qopenglwidget.h SOURCES += kernel/qopenglwidget.cpp } + +qtConfig(formlayout) { + HEADERS += kernel/qformlayout.h + SOURCES += kernel/qformlayout.cpp +} diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index e0700d877e..4582a55394 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -625,7 +625,7 @@ QActionGroup *QAction::actionGroup() const it is displayed to the left of the menu text. There is no default icon. - If a null icon (QIcon::isNull() is passed into this function, + If a null icon (QIcon::isNull()) is passed into this function, the icon of the action is cleared. */ void QAction::setIcon(const QIcon &icon) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 5908d3036b..0e4ee30c19 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -408,7 +408,6 @@ QWidget *QApplicationPrivate::focus_widget = 0; // has keyboard input foc QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show() QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus #ifndef QT_NO_WHEELEVENT -int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll QPointer<QWidget> QApplicationPrivate::wheel_widget; #endif bool qt_in_tab_key_event = false; @@ -642,19 +641,12 @@ void QApplicationPrivate::initialize() if (qEnvironmentVariableIntValue("QT_USE_NATIVE_WINDOWS") > 0) QCoreApplication::setAttribute(Qt::AA_NativeWindows); -#ifndef QT_NO_WHEELEVENT - QApplicationPrivate::wheel_scroll_lines = 3; -#endif - if (qt_is_gui_used) initializeMultitouch(); if (QApplication::desktopSettingsAware()) if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { QApplicationPrivate::enabledAnimations = theme->themeHint(QPlatformTheme::UiEffects).toInt(); -#ifndef QT_NO_WHEELEVENT - QApplicationPrivate::wheel_scroll_lines = theme->themeHint(QPlatformTheme::WheelScrollLines).toInt(); -#endif } is_app_running = true; // no longer starting up @@ -2169,11 +2161,14 @@ QWidget *qt_tlw_for_window(QWindow *wnd) // QTBUG-32177, wnd might be a QQuickView embedded via window container. while (wnd && !wnd->isTopLevel()) { QWindow *parent = wnd->parent(); + if (!parent) + break; + // Don't end up in windows not belonging to this application - if (parent && parent->type() != Qt::ForeignWindow) - wnd = wnd->parent(); - else + if (parent->handle() && parent->handle()->isForeignWindow()) break; + + wnd = wnd->parent(); } if (wnd) { const auto tlws = qApp->topLevelWidgets(); @@ -2455,26 +2450,11 @@ bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWin for (int i = 0; i < modalWindowList.count(); ++i) { QWindow *modalWindow = modalWindowList.at(i); - { - // check if the modal window is our window or a (transient) parent of our window - QWindow *w = window; - while (w) { - if (w == modalWindow) { - *blockingWindow = 0; - return false; - } - QWindow *p = w->parent(); - if (!p) - p = w->transientParent(); - w = p; - } - - // Embedded in-process windows are not visible in normal parent-child chain, - // so check the native parent chain, too. - const QPlatformWindow *platWin = window->handle(); - const QPlatformWindow *modalPlatWin = modalWindow->handle(); - if (platWin && modalPlatWin && platWin->isEmbedded(modalPlatWin)) - return false; + // A window is not blocked by another modal window if the two are + // the same, or if the window is a child of the modal window. + if (window == modalWindow || modalWindow->isAncestorOf(window, QWindow::IncludeTransients)) { + *blockingWindow = 0; + return false; } Qt::WindowModality windowModality = modalWindow->modality(); @@ -3202,17 +3182,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) if (!w->hasMouseTracking() && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) { // but still send them through all application event filters (normally done by notify_helper) - for (int i = 0; d->extraData && i < d->extraData->eventFilters.size(); ++i) { - QObject *obj = d->extraData->eventFilters.at(i); - if (!obj) - continue; - if (Q_UNLIKELY(obj->d_func()->threadData != w->d_func()->threadData)) { - qWarning("QApplication: Object event filter cannot be in a different thread."); - continue; - } - if (obj->eventFilter(w, w == receiver ? mouse : &me)) - break; - } + d->sendThroughApplicationEventFilters(w, w == receiver ? mouse : &me); res = true; } else { w->setAttribute(Qt::WA_NoMouseReplay, false); @@ -3558,9 +3528,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->setTarget(widget); for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) { QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i]; - QRectF rect = pt.rect(); - rect.translate(offset); - pt.d->rect = rect; + pt.d->pos = pt.pos() + offset; pt.d->startPos = pt.startPos() + offset; pt.d->lastPos = pt.lastPos() + offset; } @@ -4066,16 +4034,18 @@ int QApplication::keyboardInputInterval() or \l{QAbstractItemView::ScrollPerPixel}{scroll one pixel}. By default, this property has a value of 3. + + \sa QStyleHints::wheelScrollLines() */ #ifndef QT_NO_WHEELEVENT int QApplication::wheelScrollLines() { - return QApplicationPrivate::wheel_scroll_lines; + return styleHints()->wheelScrollLines(); } void QApplication::setWheelScrollLines(int lines) { - QApplicationPrivate::wheel_scroll_lines = lines; + styleHints()->setWheelScrollLines(lines); } #endif @@ -4257,12 +4227,10 @@ bool QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i]; // preserve the sub-pixel resolution - QRectF rect = touchPoint.screenRect(); - const QPointF screenPos = rect.center(); + const QPointF screenPos = touchPoint.screenRect().center(); const QPointF delta = screenPos - screenPos.toPoint(); - rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta); - touchPoint.d->rect = rect; + touchPoint.d->pos = widget->mapFromGlobal(screenPos.toPoint()) + delta; touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta; touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta; diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 73c75bbc14..271844a23e 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -91,12 +91,6 @@ extern Q_GUI_EXPORT bool qt_is_gui_used; extern QClipboard *qt_clipboard; #endif -#if defined (Q_OS_WIN32) || defined (Q_OS_CYGWIN) -extern QSysInfo::WinVersion qt_winver; -#elif defined (Q_OS_MAC) -extern QSysInfo::MacVersion qt_macver; -#endif - typedef QHash<QByteArray, QFont> FontHash; FontHash *qt_app_fonts_hash(); diff --git a/src/widgets/kernel/qdesktopwidget_p.h b/src/widgets/kernel/qdesktopwidget_p.h index 4846a868aa..dade4fe45e 100644 --- a/src/widgets/kernel/qdesktopwidget_p.h +++ b/src/widgets/kernel/qdesktopwidget_p.h @@ -56,6 +56,7 @@ #include "private/qwidget_p.h" #include <QtCore/qalgorithms.h> +#include <QtGui/qscreen.h> QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 6b134379c6..c66a6d5673 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -1167,12 +1167,12 @@ QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem) */ /*! - \since 5.8 - \struct QFormLayout::TakeRowResult + \class QFormLayout::TakeRowResult \brief Contains the result of a QFormLayout::takeRow() call. - + \inmodule QtWidgets + \since 5.8 \sa QFormLayout::takeRow() */ diff --git a/src/widgets/kernel/qformlayout.h b/src/widgets/kernel/qformlayout.h index b4185374fd..5ec27433d3 100644 --- a/src/widgets/kernel/qformlayout.h +++ b/src/widgets/kernel/qformlayout.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/QLayout> +QT_REQUIRE_CONFIG(formlayout); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qgesture.cpp b/src/widgets/kernel/qgesture.cpp index 2f33066389..3962cbe6c5 100644 --- a/src/widgets/kernel/qgesture.cpp +++ b/src/widgets/kernel/qgesture.cpp @@ -819,7 +819,6 @@ void QTapAndHoldGesture::setPosition(const QPointF &value) later the touch is still down, it will trigger the QTapAndHoldGesture. The default value is 700 milliseconds. */ -// static void QTapAndHoldGesture::setTimeout(int msecs) { QTapAndHoldGesturePrivate::Timeout = msecs; @@ -832,7 +831,6 @@ void QTapAndHoldGesture::setTimeout(int msecs) later the touch is still down, it will trigger the QTapAndHoldGesture. The default value is 700 milliseconds. */ -// static int QTapAndHoldGesture::timeout() { return QTapAndHoldGesturePrivate::Timeout; diff --git a/src/widgets/kernel/qgesture.h b/src/widgets/kernel/qgesture.h index 034d1d88c1..4dd6e82fd1 100644 --- a/src/widgets/kernel/qgesture.h +++ b/src/widgets/kernel/qgesture.h @@ -135,7 +135,6 @@ class Q_WIDGETS_EXPORT QPinchGesture : public QGesture { Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) - Q_FLAGS(ChangeFlags ChangeFlag) public: enum ChangeFlag { @@ -143,7 +142,9 @@ public: RotationAngleChanged = 0x2, CenterPointChanged = 0x4 }; + Q_FLAG(ChangeFlag) Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) + Q_FLAG(ChangeFlags) Q_PROPERTY(ChangeFlags totalChangeFlags READ totalChangeFlags WRITE setTotalChangeFlags) Q_PROPERTY(ChangeFlags changeFlags READ changeFlags WRITE setChangeFlags) diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 1a341d155b..b90be2b4f1 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -49,7 +49,9 @@ #include "qvariant.h" #include "qwidget_p.h" #include "qlayout_p.h" +#if QT_CONFIG(formlayout) #include "qformlayout.h" +#endif QT_BEGIN_NAMESPACE @@ -320,8 +322,10 @@ int QLayout::spacing() const return boxlayout->spacing(); } else if (const QGridLayout* gridlayout = qobject_cast<const QGridLayout*>(this)) { return gridlayout->spacing(); +#if QT_CONFIG(formlayout) } else if (const QFormLayout* formlayout = qobject_cast<const QFormLayout*>(this)) { return formlayout->spacing(); +#endif } else { Q_D(const QLayout); if (d->insideSpacing >=0) { @@ -347,8 +351,10 @@ void QLayout::setSpacing(int spacing) boxlayout->setSpacing(spacing); } else if (QGridLayout* gridlayout = qobject_cast<QGridLayout*>(this)) { gridlayout->setSpacing(spacing); +#if QT_CONFIG(formlayout) } else if (QFormLayout* formlayout = qobject_cast<QFormLayout*>(this)) { formlayout->setSpacing(spacing); +#endif } else { Q_D(QLayout); d->insideSpacing = spacing; diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index e902bb522c..b5a0cd3940 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -232,7 +232,7 @@ QT_BEGIN_NAMESPACE Returns the control type associated with the widget for which this size policy applies. */ -QSizePolicy::ControlType QSizePolicy::controlType() const +QSizePolicy::ControlType QSizePolicy::controlType() const Q_DECL_NOTHROW { return QSizePolicy::ControlType(1 << bits.ctype); } @@ -253,30 +253,9 @@ QSizePolicy::ControlType QSizePolicy::controlType() const \sa QStyle::layoutSpacing() */ -void QSizePolicy::setControlType(ControlType type) +void QSizePolicy::setControlType(ControlType type) Q_DECL_NOTHROW { - /* - The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, - etc. In memory, we pack it onto the available bits (CTSize) in - setControlType(), and unpack it here. - - Example: - - 0x00000001 maps to 0 - 0x00000002 maps to 1 - 0x00000004 maps to 2 - 0x00000008 maps to 3 - etc. - */ - - int i = 0; - while (true) { - if (type & (0x1 << i)) { - bits.ctype = i; - return; - } - ++i; - } + bits.ctype = toControlTypeFieldValue(type); } /*! @@ -395,6 +374,18 @@ void QSizePolicy::setControlType(ControlType type) \fn void QSizePolicy::transpose() Swaps the horizontal and vertical policies and stretches. + + \sa transposed() +*/ + +/*! + \fn QSizePolicy QSizePolicy::transposed() const + \since 5.9 + + Returns a size policy object with the horizontal and vertical + policies and stretches swapped. + + \sa transpose() */ /*! diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 63b578fbf3..6cb4e147e9 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -42,9 +42,25 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtCore/qobject.h> +#include <QtCore/qalgorithms.h> QT_BEGIN_NAMESPACE +// gcc < 4.8.0 has problems with init'ing variant members in constexpr ctors +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54922 +#if !defined(Q_CC_GNU) || defined(Q_CC_INTEL) || defined(Q_CC_CLANG) || Q_CC_GNU >= 408 +# define QT_SIZEPOLICY_CONSTEXPR Q_DECL_CONSTEXPR +# if defined(Q_COMPILER_UNIFORM_INIT) +# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT Q_DECL_CONSTEXPR +# endif // uniform-init +#endif + +#ifndef QT_SIZEPOLICY_CONSTEXPR +# define QT_SIZEPOLICY_CONSTEXPR +#endif +#ifndef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT +# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT +#endif class QVariant; class QSizePolicy; @@ -54,7 +70,6 @@ Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) Q_DECL_N class Q_WIDGETS_EXPORT QSizePolicy { Q_GADGET - Q_FLAGS(ControlTypes) public: enum PolicyFlag { @@ -93,57 +108,92 @@ public: ToolButton = 0x00004000 }; Q_DECLARE_FLAGS(ControlTypes, ControlType) + Q_FLAG(ControlTypes) - QSizePolicy() : data(0) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy() Q_DECL_NOTHROW : data(0) { } - QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) +#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC) + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW + : bits{0, 0, quint32(horizontal), quint32(vertical), + type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0} + {} +#else + QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW : data(0) { bits.horPolicy = horizontal; bits.verPolicy = vertical; setControlType(type); } - Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); } - Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); } - ControlType controlType() const; +#endif // uniform-init + QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const Q_DECL_NOTHROW { return static_cast<Policy>(bits.horPolicy); } + QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const Q_DECL_NOTHROW { return static_cast<Policy>(bits.verPolicy); } + ControlType controlType() const Q_DECL_NOTHROW; - void setHorizontalPolicy(Policy d) { bits.horPolicy = d; } - void setVerticalPolicy(Policy d) { bits.verPolicy = d; } - void setControlType(ControlType type); + Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) Q_DECL_NOTHROW { bits.horPolicy = d; } + Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) Q_DECL_NOTHROW { bits.verPolicy = d; } + void setControlType(ControlType type) Q_DECL_NOTHROW; - Qt::Orientations expandingDirections() const { + QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const Q_DECL_NOTHROW { return ( (verticalPolicy() & ExpandFlag) ? Qt::Vertical : Qt::Orientations() ) | ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ; } - void setHeightForWidth(bool b) { bits.hfw = b; } - bool hasHeightForWidth() const { return bits.hfw; } - void setWidthForHeight(bool b) { bits.wfh = b; } - bool hasWidthForHeight() const { return bits.wfh; } + Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) Q_DECL_NOTHROW { bits.hfw = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const Q_DECL_NOTHROW { return bits.hfw; } + Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) Q_DECL_NOTHROW { bits.wfh = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const Q_DECL_NOTHROW { return bits.wfh; } - bool operator==(const QSizePolicy& s) const { return data == s.data; } - bool operator!=(const QSizePolicy& s) const { return data != s.data; } + QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const Q_DECL_NOTHROW { return data == s.data; } + QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const Q_DECL_NOTHROW { return data != s.data; } friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) Q_DECL_NOTHROW { return qHash(key.data, seed); } operator QVariant() const; - int horizontalStretch() const { return static_cast<int>(bits.horStretch); } - int verticalStretch() const { return static_cast<int>(bits.verStretch); } - void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } - void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } - - bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; } - void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; } + QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const Q_DECL_NOTHROW { return static_cast<int>(bits.horStretch); } + QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const Q_DECL_NOTHROW { return static_cast<int>(bits.verStretch); } + Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } + Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } - void transpose(); + QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const Q_DECL_NOTHROW { return bits.retainSizeWhenHidden; } + Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) Q_DECL_NOTHROW { bits.retainSizeWhenHidden = retainSize; } + Q_DECL_RELAXED_CONSTEXPR void transpose() Q_DECL_NOTHROW { *this = transposed(); } +#ifndef Q_QDOC + QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT +#endif + QSizePolicy transposed() const Q_DECL_NOTHROW Q_REQUIRED_RESULT + { + return QSizePolicy(bits.transposed()); + } private: #ifndef QT_NO_DATASTREAM friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &); friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &); #endif - QSizePolicy(int i) : data(i) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) Q_DECL_NOTHROW : data(i) { } + struct Bits; + QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { } + + static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW + { + /* + The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, + etc. In memory, we pack it onto the available bits (CTSize) in + setControlType(), and unpack it here. + + Example: + + 0x00000001 maps to 0 + 0x00000002 maps to 1 + 0x00000004 maps to 2 + 0x00000008 maps to 3 + etc. + */ + + return qCountTrailingZeroBits(static_cast<quint32>(type)); + } struct Bits { quint32 horStretch : 8; @@ -154,6 +204,19 @@ private: quint32 hfw : 1; quint32 wfh : 1; quint32 retainSizeWhenHidden : 1; + + QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT + Bits transposed() const Q_DECL_NOTHROW + { + return {verStretch, // \ swap + horStretch, // / + verPolicy, // \ swap + horPolicy, // / + ctype, + hfw, // \ don't swap (historic behavior) + wfh, // / + retainSizeWhenHidden}; + } }; union { Bits bits; @@ -163,6 +226,8 @@ private: #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) // Can't add in Qt 5, as QList<QSizePolicy> would be BiC: Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE); +#else +Q_DECLARE_TYPEINFO(QSizePolicy, Q_RELOCATABLE_TYPE); #endif Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes) @@ -176,16 +241,9 @@ Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &); Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSizePolicy &); #endif -inline void QSizePolicy::transpose() { - Policy hData = horizontalPolicy(); - Policy vData = verticalPolicy(); - int hStretch = horizontalStretch(); - int vStretch = verticalStretch(); - setHorizontalPolicy(vData); - setVerticalPolicy(hData); - setHorizontalStretch(vStretch); - setVerticalStretch(hStretch); -} + +#undef QT_SIZEPOLICY_CONSTEXPR +#undef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT QT_END_NAMESPACE diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index a92dc2cbf7..48afeb1dcc 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -43,18 +43,19 @@ #include <qapplication.h> #include <qdesktopwidget.h> #include <qevent.h> -#include <qlabel.h> #include <qpointer.h> #include <qstyle.h> #include <qstyleoption.h> #include <qstylepainter.h> #include <qtimer.h> -#include <qtooltip.h> #include <private/qeffects_p.h> #include <qtextdocument.h> #include <qdebug.h> #include <private/qstylesheetstyle_p.h> + #ifndef QT_NO_TOOLTIP +#include <qlabel.h> +#include <qtooltip.h> #if 0 // Used to be included in Qt4 for Q_WS_MAC # include <private/qcore_mac_p.h> diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index 6061af5f38..4286019717 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -462,11 +462,13 @@ bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e) case QEvent::KeyPress: { QKeyEvent* kev = (QKeyEvent*)e; - +#if QT_CONFIG(shortcut) if (kev->matches(QKeySequence::Cancel)) { QWhatsThis::leaveWhatsThisMode(); return true; - } else if (customWhatsThis) { + } else +#endif + if (customWhatsThis) { return false; } else if (kev->key() == Qt::Key_Menu || (kev->key() == Qt::Key_F10 && diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index cf90df6b9b..17f87ef87c 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1477,12 +1477,16 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ? QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive; - win->create(); - // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. - if ((flags & Qt::Desktop) == Qt::Window) + + 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); + } data.window_flags = win->flags(); + if (!win->isTopLevel()) // In a Widget world foreign windows can only be top level + data.window_flags &= ~Qt::ForeignWindow; if (!topData()->role.isNull()) QXcbWindowFunctions::setWmWindowRole(win, topData()->role.toLatin1()); @@ -1499,10 +1503,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } setWindowModified_helper(); - WId id = win->winId(); - // See the QPlatformWindow::winId() documentation - Q_ASSERT(id != WId(0)); - setWinId(id); + + if (win->handle()) { + WId id = win->winId(); + // See the QPlatformWindow::winId() documentation + Q_ASSERT(id != WId(0)); + setWinId(id); + } // Check children and create windows for them if necessary q_createNativeChildrenAndSetParent(q); @@ -5246,8 +5253,6 @@ static void sendResizeEvents(QWidget *target) \sa render(), QPixmap */ - -/* INVOKABLE since used by QPixmap::grabWidget(). */ QPixmap QWidget::grab(const QRect &rectangle) { Q_D(QWidget); @@ -6382,6 +6387,24 @@ void QWidget::setWindowRole(const QString &role) \sa mouseMoveEvent() */ +/*! + \property QWidget::tabletTracking + \brief whether tablet tracking is enabled for the widget + \since 5.9 + + If tablet tracking is disabled (the default), the widget only + receives tablet move events when the stylus is in contact with + the tablet, or at least one stylus button is pressed, + while the stylus is being moved. + + If tablet tracking is enabled, the widget receives tablet move + events even while hovering in proximity. This is useful for + monitoring position as well as the auxiliary properties such + as rotation and tilt, and providing feedback in the UI. + + \sa tabletEvent() +*/ + /*! Sets the widget's focus proxy to widget \a w. If \a w is 0, the @@ -6593,11 +6616,6 @@ void QWidget::setFocus(Qt::FocusReason reason) } else { f->d_func()->updateFocusChild(); } - - if (QTLWExtra *extra = f->window()->d_func()->maybeTopData()) { - if (extra->window) - emit extra->window->focusObjectChanged(f); - } } void QWidgetPrivate::setFocus_sys() @@ -6632,6 +6650,11 @@ void QWidgetPrivate::updateFocusChild() w = w->isWindow() ? 0 : w->parentWidget(); } } + + if (QTLWExtra *extra = q->window()->d_func()->maybeTopData()) { + if (extra->window) + emit extra->window->focusObjectChanged(q); + } } /*! @@ -6673,9 +6696,15 @@ void QWidget::clearFocus() w->d_func()->focus_child = 0; w = w->parentWidget(); } - // Since focus_child is the basis for the top level QWidgetWindow's focusObject() - // we need to report this change to the rest of Qt, but we match setFocus() and - // do it at the end of the function. + + // Since we've unconditionally cleared the focus_child of our parents, we need + // to report this to the rest of Qt. Note that the focus_child is not the same + // thing as the application's focusWidget, which is why this piece of code is + // not inside the hasFocus() block below. + if (QTLWExtra *extra = window()->d_func()->maybeTopData()) { + if (extra->window) + emit extra->window->focusObjectChanged(extra->window->focusObject()); + } #ifndef QT_NO_GRAPHICSVIEW QWExtra *topData = d_func()->extra; @@ -6698,15 +6727,6 @@ void QWidget::clearFocus() #endif } } - - // Since we've unconditionally cleared the focus_child of our parents, we need - // to report this to the rest of Qt. Note that the focus_child is not the same - // thing as the application's focusWidget, which is why this piece of code is - // not inside the hasFocus() block above. - if (QTLWExtra *extra = window()->d_func()->maybeTopData()) { - if (extra->window) - emit extra->window->focusObjectChanged(extra->window->focusObject()); - } } @@ -8786,6 +8806,9 @@ bool QWidget::event(QEvent *event) #endif #ifndef QT_NO_TABLETEVENT case QEvent::TabletMove: + if (static_cast<QTabletEvent *>(event)->buttons() == Qt::NoButton && !testAttribute(Qt::WA_TabletTracking)) + break; + Q_FALLTHROUGH(); case QEvent::TabletPress: case QEvent::TabletRelease: tabletEvent((QTabletEvent*)event); @@ -9018,6 +9041,7 @@ bool QWidget::event(QEvent *event) case QEvent::IconTextChange: case QEvent::ModifiedChange: case QEvent::MouseTrackingChange: + case QEvent::TabletTrackingChange: case QEvent::ParentChange: case QEvent::LocaleChange: case QEvent::MacSizeChange: @@ -9189,6 +9213,7 @@ bool QWidget::event(QEvent *event) const QWindow *win = te->window; d->setWinId((win && win->handle()) ? win->handle()->winId() : 0); } + d->updateFont(d->data.fnt); #ifndef QT_NO_OPENGL d->renderToTextureReallyDirty = 1; #endif @@ -9422,7 +9447,13 @@ void QWidget::wheelEvent(QWheelEvent *event) The default implementation ignores the event. - \sa QEvent::ignore(), QEvent::accept(), event(), + If tablet tracking is switched off, tablet move events only occur if the + stylus is in contact with the tablet, or at least one stylus button is + pressed, while the stylus is being moved. If tablet tracking is switched on, + tablet move events occur even while the stylus is hovering in proximity of + the tablet, with no buttons pressed. + + \sa QEvent::ignore(), QEvent::accept(), event(), setTabletTracking(), QTabletEvent */ @@ -10353,7 +10384,7 @@ void QWidget::updateGeometry() a window, causing the widget to be hidden. You must call show() to make the widget visible again.. - \sa windowType(), {Window Flags Example} + \sa windowType(), setWindowFlag(), {Window Flags Example} */ void QWidget::setWindowFlags(Qt::WindowFlags flags) { @@ -10361,6 +10392,23 @@ void QWidget::setWindowFlags(Qt::WindowFlags flags) d->setWindowFlags(flags); } +/*! + \since 5.9 + + Sets the window flag \a flag on this widget if \a on is true; + otherwise clears the flag. + + \sa setWindowFlags(), windowFlags(), windowType() +*/ +void QWidget::setWindowFlag(Qt::WindowType flag, bool on) +{ + Q_D(QWidget); + if (on) + d->setWindowFlags(data->window_flags | flag); + else + d->setWindowFlags(data->window_flags & ~flag); +} + /*! \internal Implemented in QWidgetPrivate so that QMdiSubWindowPrivate can reimplement it. @@ -11174,6 +11222,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QEvent e(QEvent::MouseTrackingChange); QApplication::sendEvent(this, &e); break; } + case Qt::WA_TabletTracking: { + QEvent e(QEvent::TabletTrackingChange); + QApplication::sendEvent(this, &e); + break; } case Qt::WA_NativeWindow: { d->createTLExtra(); if (on) @@ -12710,7 +12762,6 @@ void QWidget::activateWindow() } /*! - \fn int QWidget::metric(PaintDeviceMetric m) const Internal implementation of the virtual QPaintDevice::metric() function. @@ -12719,8 +12770,6 @@ void QWidget::activateWindow() */ int QWidget::metric(PaintDeviceMetric m) const { - Q_D(const QWidget); - QWindow *topLevelWindow = 0; QScreen *screen = 0; if (QWidget *topLevel = window()) { @@ -12748,16 +12797,16 @@ int QWidget::metric(PaintDeviceMetric m) const } else if (m == PdmDepth) { return screen->depth(); } else if (m == PdmDpiX) { - if (d->extra && d->extra->customDpiX) - return d->extra->customDpiX; - else if (d->parent) - return static_cast<QWidget *>(d->parent)->metric(m); + for (const QWidget *p = this; p; p = p->parentWidget()) { + if (p->d_func()->extra && p->d_func()->extra->customDpiX) + return p->d_func()->extra->customDpiX; + } return qRound(screen->logicalDotsPerInchX()); } else if (m == PdmDpiY) { - if (d->extra && d->extra->customDpiY) - return d->extra->customDpiY; - else if (d->parent) - return static_cast<QWidget *>(d->parent)->metric(m); + for (const QWidget *p = this; p; p = p->parentWidget()) { + if (p->d_func()->extra && p->d_func()->extra->customDpiY) + return p->d_func()->extra->customDpiY; + } return qRound(screen->logicalDotsPerInchY()); } else if (m == PdmPhysicalDpiX) { return qRound(screen->physicalDotsPerInchX()); @@ -12934,6 +12983,9 @@ void QWidget::setMask(const QBitmap &bitmap) */ void QWidget::clearMask() { + Q_D(QWidget); + if (!d->extra || !d->extra->hasMask) + return; setMask(QRegion()); } diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 58413c6bd3..1c378924a0 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -161,6 +161,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor) #endif Q_PROPERTY(bool mouseTracking READ hasMouseTracking WRITE setMouseTracking) + Q_PROPERTY(bool tabletTracking READ hasTabletTracking WRITE setTabletTracking) Q_PROPERTY(bool isActiveWindow READ isActiveWindow) Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy) Q_PROPERTY(bool focus READ hasFocus) @@ -328,6 +329,9 @@ public: bool hasMouseTracking() const; bool underMouse() const; + void setTabletTracking(bool enable); + bool hasTabletTracking() const; + void setMask(const QBitmap &); void setMask(const QRegion &); QRegion mask() const; @@ -562,6 +566,7 @@ public: void setWindowFlags(Qt::WindowFlags type); inline Qt::WindowFlags windowFlags() const; + void setWindowFlag(Qt::WindowType, bool on = true); void overrideWindowFlags(Qt::WindowFlags type); inline Qt::WindowType windowType() const; @@ -808,6 +813,12 @@ inline bool QWidget::hasMouseTracking() const inline bool QWidget::underMouse() const { return testAttribute(Qt::WA_UnderMouse); } +inline void QWidget::setTabletTracking(bool enable) +{ setAttribute(Qt::WA_TabletTracking, enable); } + +inline bool QWidget::hasTabletTracking() const +{ return testAttribute(Qt::WA_TabletTracking); } + inline bool QWidget::updatesEnabled() const { return !testAttribute(Qt::WA_UpdatesDisabled); } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 910704498c..781ad9600d 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -164,23 +164,11 @@ static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec return; const HDC hdc = reinterpret_cast<HDC>(hdcV); - HBRUSH brush; - static int i = 0; - switch (i) { - case 0: - brush = CreateSolidBrush(RGB(255, 255, 0)); - break; - case 1: - brush = CreateSolidBrush(RGB(255, 200, 55)); - break; - case 2: - brush = CreateSolidBrush(RGB(200, 255, 55)); - break; - case 3: - brush = CreateSolidBrush(RGB(200, 200, 0)); - break; - } - i = (i + 1) & 3; + static const COLORREF colors[] = {RGB(255, 255, 0), RGB(255, 200, 55), RGB(200, 255, 55), RGB(200, 200, 0)}; + + static size_t i = 0; + const HBRUSH brush = CreateSolidBrush(colors[i]); + i = (i + 1) % (sizeof(colors) / sizeof(colors[0])); for (const QRect &rect : region) { RECT winRect; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 3e15b6977a..31f2d672bb 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -285,6 +285,7 @@ bool QWidgetWindow::event(QEvent *event) return true; case QEvent::WindowStateChange: + QWindow::event(event); // Update QWindow::Visibility and emit signals. handleWindowStateChangedEvent(static_cast<QWindowStateChangeEvent *>(event)); return true; @@ -957,8 +958,8 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event // Sent event if the state changed (that is, it is not triggered by // QWidget::setWindowState(), which also sends an event to the widget). - if (widgetState != int(m_widget->data->window_state)) { - m_widget->data->window_state = widgetState; + if (widgetState != Qt::WindowStates::Int(m_widget->data->window_state)) { + m_widget->data->window_state = uint(widgetState); QWindowStateChangeEvent widgetEvent(eventState); QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent); } @@ -973,22 +974,26 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long void QWidgetWindow::handleTabletEvent(QTabletEvent *event) { static QPointer<QWidget> qt_tablet_target = 0; - if (event->type() == QEvent::TabletPress) { - QWidget *widget = m_widget->childAt(event->pos()); - if (!widget) - widget = m_widget; - qt_tablet_target = widget; + QWidget *widget = qt_tablet_target; + + if (!widget) { + widget = m_widget->childAt(event->pos()); + if (event->type() == QEvent::TabletPress) { + if (!widget) + widget = m_widget; + qt_tablet_target = widget; + } } - if (qt_tablet_target) { + if (widget) { QPointF delta = event->globalPosF() - event->globalPos(); - QPointF mapped = qt_tablet_target->mapFromGlobal(event->globalPos()) + delta; + QPointF mapped = widget->mapFromGlobal(event->globalPos()) + delta; QTabletEvent ev(event->type(), mapped, event->globalPosF(), event->device(), event->pointerType(), event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(), event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons()); ev.setTimestamp(event->timestamp()); - QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev); + QGuiApplication::sendSpontaneousEvent(widget, &ev); event->setAccepted(ev.isAccepted()); } diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index edf2383596..a81355160e 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -56,6 +56,7 @@ #include <QtCore/private/qobject_p.h> #include <QtGui/private/qevent_p.h> +#include <QtWidgets/qwidget.h> QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index bb25a3a986..7ae63e54b3 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -241,6 +241,14 @@ QWindow *QWindowContainer::containedWindow() const QWindowContainer::~QWindowContainer() { Q_D(QWindowContainer); + + // Call destroy() explicitly first. The dtor would do this too, but + // QEvent::PlatformSurface delivery relies on virtuals. Getting + // SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc. + // QWindow subclasses in particular. Keep these working. + if (d->window) + d->window->destroy(); + delete d->window; } diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 7971bd0b8b..604422dc4f 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -48,8 +48,14 @@ #include <qcache.h> #include <qdockwidget.h> #include <qdrawutil.h> +#if QT_CONFIG(dialogbuttonbox) #include <qdialogbuttonbox.h> +#endif +#if QT_CONFIG(formlayout) #include <qformlayout.h> +#else +#include <qlayout.h> +#endif #include <qgroupbox.h> #include <qmath.h> #include <qmenu.h> @@ -1099,7 +1105,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w || opt->shape == QTabBar::TriangularEast || opt->shape == QTabBar::TriangularWest; if (verticalTabs) - tr.setRect(0, 0, tr.height(), tr.width()); //0, 0 as we will have a translate transform + tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget); int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget); @@ -1122,7 +1128,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w // right widget if (!opt->rightButtonSize.isEmpty()) { tr.setRight(tr.right() - 4 - - (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width())); + (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width())); } // icon @@ -1134,12 +1140,12 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w } QSize tabIconSize = opt->icon.actualSize(iconSize, (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled, - (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off ); - // High-dpi icons do not need adjustmet; make sure tabIconSize is not larger than iconSize + (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off); + // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height())); *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2, - tabIconSize.width(), tabIconSize .height()); + tabIconSize.width(), tabIconSize.height()); if (!verticalTabs) *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect); tr.setLeft(tr.left() + tabIconSize.width() + 4); @@ -4872,6 +4878,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, QRect decorationRect, displayRect, checkRect; d->viewItemLayout(vopt, &checkRect, &decorationRect, &displayRect, true); sz = (decorationRect|displayRect|checkRect).size(); + if (decorationRect.isValid() && sz.height() == decorationRect.height()) + sz.rheight() += 2; // Prevent icons from overlapping. } break; #endif // QT_NO_ITEMVIEWS @@ -4920,9 +4928,11 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_ScrollBar_ContextMenu: ret = true; break; +#if QT_CONFIG(dialogbuttonbox) case SH_DialogButtons_DefaultButton: // This value not used anywhere. ret = QDialogButtonBox::AcceptRole; break; +#endif #ifndef QT_NO_GROUPBOX case SH_GroupBox_TextLabelVerticalAlignment: ret = Qt::AlignVCenter; @@ -5110,11 +5120,13 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_TabBar_ElideMode: ret = Qt::ElideNone; break; +#if QT_CONFIG(dialogbuttonbox) case SH_DialogButtonLayout: ret = QDialogButtonBox::WinLayout; if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) ret = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt(); break; +#endif case SH_ComboBox_PopupFrameStyle: ret = QFrame::StyledPanel | QFrame::Plain; break; @@ -5160,12 +5172,14 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget ret = QWizard::ClassicStyle; break; #endif +#if QT_CONFIG(formlayout) case SH_FormLayoutWrapPolicy: ret = QFormLayout::DontWrapRows; break; case SH_FormLayoutFieldGrowthPolicy: ret = QFormLayout::AllNonFixedFieldsGrow; break; +#endif case SH_FormLayoutFormAlignment: ret = Qt::AlignLeft | Qt::AlignTop; break; @@ -5237,6 +5251,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget return ret; } +#if QT_CONFIG(imageformat_xpm) static QPixmap cachedPixmapFromXPM(const char * const *xpm) { QPixmap result; @@ -5249,6 +5264,7 @@ static QPixmap cachedPixmapFromXPM(const char * const *xpm) } static inline QPixmap titleBarMenuCachedPixmapFromXPM() { return cachedPixmapFromXPM(qt_menu_xpm); } +#endif // QT_CONFIG(imageformat_xpm) #ifndef QT_NO_IMAGEFORMAT_PNG static inline QString clearText16IconPath() diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp index fa80a7a6ca..0b0583ea94 100644 --- a/src/widgets/styles/qdrawutil.cpp +++ b/src/widgets/styles/qdrawutil.cpp @@ -797,7 +797,11 @@ typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, - const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) + const QTileRules &rules +#ifndef Q_CLANG_QDOC + , QDrawBorderPixmap::DrawingHints hints +#endif + ) { QPainter::PixmapFragment d; d.opacity = 1.0; diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h index 121221dfc9..d5582f2c90 100644 --- a/src/widgets/styles/qdrawutil.h +++ b/src/widgets/styles/qdrawutil.h @@ -119,7 +119,7 @@ struct QTileRules Qt::TileRule vertical; }; -#ifndef Q_QDOC +#ifndef Q_CLANG_QDOC // For internal use only. namespace QDrawBorderPixmap { @@ -151,7 +151,7 @@ Q_WIDGETS_EXPORT void qDrawBorderPixmap(QPainter *painter, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules = QTileRules() -#ifndef Q_QDOC +#ifndef Q_CLANG_QDOC , QDrawBorderPixmap::DrawingHints hints = QDrawBorderPixmap::DrawingHints() #endif ); diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index f1cd48556c..95fd0e5b2f 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -43,7 +43,11 @@ #if QT_CONFIG(style_fusion) || defined(QT_PLUGIN) #include "qcommonstyle_p.h" #include <qcombobox.h> +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#else +#include <qabstractbutton.h> +#endif #include <qpainter.h> #include <qdir.h> #include <qstyleoption.h> @@ -52,9 +56,11 @@ #include <qfont.h> #include <qgroupbox.h> #include <qpixmapcache.h> -#include <qdialogbuttonbox.h> #include <qscrollbar.h> #include <qspinbox.h> +#if QT_CONFIG(abstractslider) +#include <qabstractslider.h> +#endif #include <qslider.h> #include <qsplitter.h> #include <qprogressbar.h> @@ -84,7 +90,7 @@ static const int windowsRightBorder = 15; // right border on windows static const int groupBoxBottomMargin = 0; // space below the groupbox static const int groupBoxTopMargin = 3; - +#if QT_CONFIG(imageformat_xpm) /* XPM */ static const char * const dock_widget_close_xpm[] = { "11 13 7 1", @@ -171,7 +177,7 @@ static const char * const qt_titlebar_context_help[] = { " ", " ## ", " ## "}; - +#endif // QT_CONFIG(imageformat_xpm) static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50) { @@ -2366,6 +2372,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver); bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken); qt_fusion_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken); +#if QT_CONFIG(imageformat_xpm) QImage image(qt_titlebar_context_help); QColor alpha = textColor; alpha.setAlpha(128); @@ -2373,6 +2380,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption image.setColor(2, alpha.rgba()); painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image); +#endif } } @@ -2435,7 +2443,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption int oldMin = styleObject->property("_q_stylemin").toInt(); int oldMax = styleObject->property("_q_stylemax").toInt(); QRect oldRect = styleObject->property("_q_stylerect").toRect(); - int oldState = styleObject->property("_q_stylestate").toInt(); + QStyle::State oldState = static_cast<QStyle::State>(styleObject->property("_q_stylestate").value<QStyle::State::Int>()); uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt(); // a scrollbar is transient when the the scrollbar itself and @@ -2458,7 +2466,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption styleObject->setProperty("_q_stylemin", scrollBar->minimum); styleObject->setProperty("_q_stylemax", scrollBar->maximum); styleObject->setProperty("_q_stylerect", scrollBar->rect); - styleObject->setProperty("_q_stylestate", static_cast<int>(scrollBar->state)); + styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(scrollBar->state)); styleObject->setProperty("_q_stylecontrols", static_cast<uint>(scrollBar->activeSubControls)); #ifndef QT_NO_ANIMATION @@ -3287,7 +3295,9 @@ void QFusionStyle::polish(QWidget *widget) #if QT_CONFIG(splitter) || qobject_cast<QSplitterHandle *>(widget) #endif +#if QT_CONFIG(abstractslider) || qobject_cast<QAbstractSlider *>(widget) +#endif #if QT_CONFIG(spinbox) || qobject_cast<QAbstractSpinBox *>(widget) #endif @@ -3326,7 +3336,9 @@ void QFusionStyle::unpolish(QWidget *widget) #if QT_CONFIG(splitter) || qobject_cast<QSplitterHandle *>(widget) #endif +#if QT_CONFIG(abstractslider) || qobject_cast<QAbstractSlider *>(widget) +#endif #if QT_CONFIG(spinbox) || qobject_cast<QAbstractSpinBox *>(widget) #endif diff --git a/src/widgets/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc index f8bd1f57a9..a77843a4dd 100644 --- a/src/widgets/styles/qmacstyle.qdoc +++ b/src/widgets/styles/qmacstyle.qdoc @@ -143,45 +143,6 @@ \reimp */ -/*! - \enum QMacStyle::FocusRectPolicy - - This type is used to signify a widget's focus rectangle policy. - - \value FocusEnabled show a focus rectangle when the widget has focus. - \value FocusDisabled never show a focus rectangle for the widget. - \value FocusDefault show a focus rectangle when the widget has - focus and the widget is a QSpinWidget, QDateTimeEdit, QLineEdit, - QListBox, QListView, editable QTextEdit, or one of their - subclasses. -*/ - -/*! \fn void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy) - \obsolete - Sets the focus rectangle policy of \a w. The \a policy can be one of - \l{QMacStyle::FocusRectPolicy}. - - This is now simply an interface to the Qt::WA_MacShowFocusRect attribute and the - FocusDefault value does nothing anymore. If you want to set a widget back - to its default value, you must save the old value of the attribute before - you change it. - - \sa focusRectPolicy(), QWidget::setAttribute() -*/ - -/*! \fn QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w) - \obsolete - Returns the focus rectangle policy for the widget \a w. - - The focus rectangle policy can be one of \l{QMacStyle::FocusRectPolicy}. - - In 4.3 and up this function will simply test for the - Qt::WA_MacShowFocusRect attribute and will never return - QMacStyle::FocusDefault. - - \sa setFocusRectPolicy(), QWidget::testAttribute() -*/ - /*! \fn void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy) \obsolete diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index f23f6c00b2..a9aab10e0f 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -52,12 +52,14 @@ #include <private/qcore_mac_p.h> #include <private/qcombobox_p.h> +#include <private/qtabbar_p.h> #include <private/qpainter_p.h> #include <qapplication.h> #include <qbitmap.h> -#include <qcheckbox.h> #include <qcombobox.h> +#if QT_CONFIG(dialogbuttonbox) #include <qdialogbuttonbox.h> +#endif #include <qdockwidget.h> #include <qevent.h> #include <qfocusframe.h> @@ -74,7 +76,9 @@ #include <qpixmapcache.h> #include <qpointer.h> #include <qprogressbar.h> +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#endif #include <qradiobutton.h> #include <qrubberband.h> #include <qscrollbar.h> @@ -84,6 +88,7 @@ #include <qtoolbutton.h> #include <qtreeview.h> #include <qtableview.h> +#include <qoperatingsystemversion.h> #include <qwizard.h> #include <qdebug.h> #include <qlibrary.h> @@ -186,11 +191,33 @@ static const QColor mainWindowGradientEnd(200, 200, 200); static const int DisclosureOffset = 4; +// Tab bar colors +// active: window is active +// selected: tab is selected +// hovered: tab is hovered +static const QColor tabBarTabBackgroundActive(190, 190, 190); +static const QColor tabBarTabBackgroundActiveHovered(178, 178, 178); +static const QColor tabBarTabBackgroundActiveSelected(211, 211, 211); +static const QColor tabBarTabBackground(227, 227, 227); +static const QColor tabBarTabBackgroundSelected(246, 246, 246); +static const QColor tabBarTabLineActive(160, 160, 160); +static const QColor tabBarTabLineActiveHovered(150, 150, 150); +static const QColor tabBarTabLine(210, 210, 210); +static const QColor tabBarTabLineSelected(189, 189, 189); +static const QColor tabBarCloseButtonBackgroundHovered(162, 162, 162); +static const QColor tabBarCloseButtonBackgroundPressed(153, 153, 153); +static const QColor tabBarCloseButtonBackgroundSelectedHovered(192, 192, 192); +static const QColor tabBarCloseButtonBackgroundSelectedPressed(181, 181, 181); +static const QColor tabBarCloseButtonCross(100, 100, 100); +static const QColor tabBarCloseButtonCrossSelected(115, 115, 115); + +static const int closeButtonSize = 14; +static const qreal closeButtonCornerRadius = 2.0; + // Resolve these at run-time, since the functions was moved in Leopard. typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *); static PtrHIShapeGetBounds ptrHIShapeGetBounds = 0; -static int closeButtonSize = 12; #ifndef QT_NO_TABBAR static bool isVerticalTabs(const QTabBar::Shape shape) { return (shape == QTabBar::RoundedEast @@ -213,41 +240,35 @@ static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) } -void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected) +void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pressed) { - // draw background circle p->setRenderHints(QPainter::Antialiasing); QRect rect(0, 0, closeButtonSize, closeButtonSize); - QColor background; + const int width = rect.width(); + const int height = rect.height(); + if (hover) { - background = QColor(124, 124, 124); - } else { - if (active) { - if (selected) - background = QColor(104, 104, 104); - else - background = QColor(83, 83, 83); + // draw background circle + QColor background; + if (selected) { + background = pressed ? tabBarCloseButtonBackgroundSelectedPressed : tabBarCloseButtonBackgroundSelectedHovered; } else { - if (selected) - background = QColor(144, 144, 144); - else - background = QColor(114, 114, 114); + background = pressed ? tabBarCloseButtonBackgroundPressed : tabBarCloseButtonBackgroundHovered; } + p->setPen(Qt::transparent); + p->setBrush(background); + p->drawRoundedRect(rect, closeButtonCornerRadius, closeButtonCornerRadius); } - p->setPen(Qt::transparent); - p->setBrush(background); - p->drawEllipse(rect); // draw cross - int min = 3; - int max = 9; + const int margin = 3; QPen crossPen; - crossPen.setColor(QColor(194, 194, 194)); - crossPen.setWidthF(1.3); + crossPen.setColor(selected ? tabBarCloseButtonCrossSelected : tabBarCloseButtonCross); + crossPen.setWidthF(1.1); crossPen.setCapStyle(Qt::FlatCap); p->setPen(crossPen); - p->drawLine(min, min, max, max); - p->drawLine(min, max, max, min); + p->drawLine(margin, margin, width - margin, height - margin); + p->drawLine(margin, height - margin, width - margin, margin); } #ifndef QT_NO_TABBAR @@ -274,108 +295,71 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect) return tabRect; } -void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified) +void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, int tabOverlap) { - QRect r = tabOpt->rect; - p->translate(tabOpt->rect.x(), tabOpt->rect.y()); - r.moveLeft(0); - r.moveTop(0); - QRect tabRect = rotateTabPainter(p, tabOpt->shape, r); + QRect rect = tabOpt->rect; + + switch (tabOpt->shape) { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + rect.adjust(-tabOverlap, 0, 0, 0); + break; + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + rect.adjust(0, -tabOverlap, 0, 0); + break; + default: + break; + } - int width = tabRect.width(); - int height = 20; - bool active = (tabOpt->state & QStyle::State_Active); - bool selected = (tabOpt->state & QStyle::State_Selected); + p->translate(rect.x(), rect.y()); + rect.moveLeft(0); + rect.moveTop(0); + const QRect tabRect = rotateTabPainter(p, tabOpt->shape, rect); - if (selected) { - QRect rect(1, 0, width - 2, height); + const int width = tabRect.width(); + const int height = tabRect.height(); + const bool active = (tabOpt->state & QStyle::State_Active); + const bool selected = (tabOpt->state & QStyle::State_Selected); + const QRect bodyRect(1, 1, width - 2, height - 2); + const QRect topLineRect(1, 0, width - 2, 1); + const QRect bottomLineRect(1, height - 1, width - 2, 1); + if (selected) { // fill body if (tabOpt->documentMode && isUnified) { p->save(); p->setCompositionMode(QPainter::CompositionMode_Source); - p->fillRect(rect, QColor(Qt::transparent)); + p->fillRect(tabRect, QColor(Qt::transparent)); p->restore(); } else if (active) { - p->fillRect(rect, QColor(167, 167, 167)); + p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected); + // top line + p->fillRect(topLineRect, tabBarTabLineSelected); } else { - QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); - gradient.setColorAt(0, QColor(216, 216, 216)); - gradient.setColorAt(0.5, QColor(215, 215, 215)); - gradient.setColorAt(1, QColor(210, 210, 210)); - p->fillRect(rect, gradient); - } - - // draw border - QColor borderSides; - QColor borderBottom; - if (active) { - borderSides = QColor(88, 88, 88); - borderBottom = QColor(88, 88, 88); - } else { - borderSides = QColor(121, 121, 121); - borderBottom = QColor(116, 116, 116); + p->fillRect(bodyRect, tabBarTabBackgroundSelected); } - - p->setPen(borderSides); - - int bottom = height; - // left line - p->drawLine(0, 1, 0, bottom-2); - // right line - p->drawLine(width-1, 1, width-1, bottom-2); - - // bottom line - if (active) { - p->setPen(QColor(168, 168, 168)); - p->drawLine(3, bottom-1, width-3, bottom-1); - } - p->setPen(borderBottom); - p->drawLine(2, bottom, width-2, bottom); - - int w = 3; - QRectF rectangleLeft(1, height - w, w, w); - QRectF rectangleRight(width - 2, height - 1, w, w); - int startAngle = 180 * 16; - int spanAngle = 90 * 16; - p->setRenderHint(QPainter::Antialiasing); - p->drawArc(rectangleLeft, startAngle, spanAngle); - p->drawArc(rectangleRight, startAngle, -spanAngle); } else { // when the mouse is over non selected tabs they get a new color - bool hover = (tabOpt->state & QStyle::State_MouseOver); + const bool hover = (tabOpt->state & QStyle::State_MouseOver); if (hover) { - QRect rect(1, 2, width - 1, height - 1); - p->fillRect(rect, QColor(110, 110, 110)); - } - - // seperator lines between tabs - bool west = (tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest); - bool drawOnRight = !west; - if ((!drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected) - || (drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)) { - QColor borderColor; - QColor borderHighlightColor; - if (active) { - borderColor = QColor(64, 64, 64); - borderHighlightColor = QColor(140, 140, 140); - } else { - borderColor = QColor(135, 135, 135); - borderHighlightColor = QColor(178, 178, 178); - } - - int x = drawOnRight ? width : 0; - - // tab seperator line - p->setPen(borderColor); - p->drawLine(x, 2, x, height + 1); - - // tab seperator highlight - p->setPen(borderHighlightColor); - p->drawLine(x-1, 2, x-1, height + 1); - p->drawLine(x+1, 2, x+1, height + 1); + // fill body + p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered); + // bottom line + p->fillRect(bottomLineRect, tabBarTabLineActiveHovered); } } + + // separator lines between tabs + const QRect leftLineRect(0, 1, 1, height - 2); + const QRect rightLineRect(width - 1, 1, 1, height - 2); + const QColor separatorLineColor = active ? tabBarTabLineActive : tabBarTabLine; + p->fillRect(leftLineRect, separatorLineColor); + p->fillRect(rightLineRect, separatorLineColor); } void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget *w) @@ -386,53 +370,25 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget * } else { r.setHeight(w->height()); } - QRect tabRect = rotateTabPainter(p, tbb->shape, r); - int width = tabRect.width(); - int height = tabRect.height(); - bool active = (tbb->state & QStyle::State_Active); - - // top border lines - QColor borderHighlightTop; - QColor borderTop; - if (active) { - borderTop = QColor(64, 64, 64); - borderHighlightTop = QColor(174, 174, 174); - } else { - borderTop = QColor(135, 135, 135); - borderHighlightTop = QColor(207, 207, 207); - } - p->setPen(borderHighlightTop); - p->drawLine(tabRect.x(), 0, width, 0); - p->setPen(borderTop); - p->drawLine(tabRect.x(), 1, width, 1); - - // center block - QRect centralRect(tabRect.x(), 2, width, height - 2); - if (active) { - QColor mainColor = QColor(120, 120, 120); - p->fillRect(centralRect, mainColor); - } else { - QLinearGradient gradient(centralRect.topLeft(), centralRect.bottomLeft()); - gradient.setColorAt(0, QColor(165, 165, 165)); - gradient.setColorAt(0.5, QColor(164, 164, 164)); - gradient.setColorAt(1, QColor(158, 158, 158)); - p->fillRect(centralRect, gradient); - } - - // bottom border lines - QColor borderHighlightBottom; - QColor borderBottom; - if (active) { - borderHighlightBottom = QColor(153, 153, 153); - borderBottom = QColor(64, 64, 64); - } else { - borderHighlightBottom = QColor(177, 177, 177); - borderBottom = QColor(127, 127, 127); - } - p->setPen(borderHighlightBottom); - p->drawLine(tabRect.x(), height - 2, width, height - 2); - p->setPen(borderBottom); - p->drawLine(tabRect.x(), height - 1, width, height - 1); + const QRect tabRect = rotateTabPainter(p, tbb->shape, r); + const int width = tabRect.width(); + const int height = tabRect.height(); + const bool active = (tbb->state & QStyle::State_Active); + + // fill body + const QRect bodyRect(0, 1, width, height - 1); + const QColor bodyColor = active ? tabBarTabBackgroundActive : tabBarTabBackground; + p->fillRect(bodyRect, bodyColor); + + // top line + const QRect topLineRect(0, 0, width, 1); + const QColor topLineColor = active ? tabBarTabLineActive : tabBarTabLine; + p->fillRect(topLineRect, topLineColor); + + // bottom line + const QRect bottomLineRect(0, height - 1, width, 1); + const QColor bottomLineColor = active ? tabBarTabLineActive : tabBarTabLine; + p->fillRect(bottomLineRect, bottomLineColor); } #endif @@ -661,12 +617,16 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg } if (ct == QStyle::CT_CustomBase && widg) { +#if QT_CONFIG(pushbutton) if (qobject_cast<const QPushButton *>(widg)) ct = QStyle::CT_PushButton; +#endif else if (qobject_cast<const QRadioButton *>(widg)) ct = QStyle::CT_RadioButton; +#if QT_CONFIG(checkbox) else if (qobject_cast<const QCheckBox *>(widg)) ct = QStyle::CT_CheckBox; +#endif #ifndef QT_NO_COMBOBOX else if (qobject_cast<const QComboBox *>(widg)) ct = QStyle::CT_ComboBox; @@ -700,6 +660,7 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg } switch (ct) { +#if QT_CONFIG(pushbutton) case QStyle::CT_PushButton: { const QPushButton *psh = qobject_cast<const QPushButton *>(widg); // If this comparison is false, then the widget was not a push button. @@ -742,6 +703,7 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg // Since there's no default size we return the large size... ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); } +#endif #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam } else if (ct == QStyle::CT_RadioButton) { QRadioButton *rdo = static_cast<QRadioButton *>(widg); @@ -1016,7 +978,7 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius) const { - qreal pixelRatio = p->device()->devicePixelRatioF(); + const qreal pixelRatio = p->device()->devicePixelRatioF(); static const QString keyFormat = QLatin1String("$qt_focusring%1-%2-%3-%4"); const QString &key = keyFormat.arg(hMargin).arg(vMargin).arg(radius).arg(pixelRatio); QPixmap focusRingPixmap; @@ -1027,20 +989,38 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int h focusRingPixmap.fill(Qt::transparent); focusRingPixmap.setDevicePixelRatio(pixelRatio); { + const CGFloat focusRingWidth = radius > 0 ? 3.5 : 6; QMacAutoReleasePool pool; + QMacCGContext ctx(&focusRingPixmap); + CGContextBeginTransparencyLayer(ctx, NULL); + CGContextSetAlpha(ctx, 0.5); // As applied to the stroke color below + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx + flipped:NO]]; + CGRect focusRingRect = CGRectMake(hMargin, vMargin, size, size); NSBezierPath *focusRingPath; - if (radius > 0) - focusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(hMargin, vMargin, size, size) + if (radius > 0) { + const CGFloat roundedRectInset = -1.5; + focusRingPath = [NSBezierPath bezierPathWithRoundedRect:CGRectInset(focusRingRect, roundedRectInset, roundedRectInset) xRadius:radius yRadius:radius]; - else - focusRingPath = [NSBezierPath bezierPathWithRect:NSMakeRect(hMargin, vMargin, size, size)]; - [NSGraphicsContext saveGraphicsState]; - QMacCGContext gc(&focusRingPixmap); - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(CGContextRef)gc - flipped:NO]]; - NSSetFocusRingStyle(NSFocusRingOnly); - [focusRingPath fill]; + } else { + const CGFloat outerClipInset = -focusRingWidth / 2; + NSBezierPath *focusRingClipPath = [NSBezierPath bezierPathWithRect:CGRectInset(focusRingRect, outerClipInset, outerClipInset)]; + const CGFloat innerClipInset = 1; + NSBezierPath *focusRingInnerClipPath = [NSBezierPath bezierPathWithRect:CGRectInset(focusRingRect, innerClipInset, innerClipInset)]; + [focusRingClipPath appendBezierPath:focusRingInnerClipPath.bezierPathByReversingPath]; + [focusRingClipPath setClip]; + focusRingPath = [NSBezierPath bezierPathWithRect:focusRingRect]; + focusRingPath.lineJoinStyle = NSRoundLineJoinStyle; + } + + focusRingPath.lineWidth = focusRingWidth; + [[NSColor keyboardFocusIndicatorColor] setStroke]; + [focusRingPath stroke]; + + CGContextEndTransparencyLayer(ctx); [NSGraphicsContext restoreGraphicsState]; } QPixmapCache::insert(key, focusRingPixmap); @@ -1077,6 +1057,50 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int h QRect(focusRingPixmap.width() - shCornerSize, svCornerSize, shCornerSize, focusRingPixmap.width() - 2 * svCornerSize)); } +#ifndef QT_NO_TABBAR +void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect) const +{ + Q_ASSERT(textRect); + QRect tr = opt->rect; + const bool verticalTabs = opt->shape == QTabBar::RoundedEast + || opt->shape == QTabBar::RoundedWest + || opt->shape == QTabBar::TriangularEast + || opt->shape == QTabBar::TriangularWest; + if (verticalTabs) + tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform + + int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget); + int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget); + const int hpadding = 4; + const int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2; + if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth) + verticalShift = -verticalShift; + tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding); + + // left widget + if (!opt->leftButtonSize.isEmpty()) { + const int buttonSize = verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width(); + tr.setLeft(tr.left() + 4 + buttonSize); + // make text aligned to center + if (opt->rightButtonSize.isEmpty()) + tr.setRight(tr.right() - 4 - buttonSize); + } + // right widget + if (!opt->rightButtonSize.isEmpty()) { + const int buttonSize = verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width(); + tr.setRight(tr.right() - 4 - buttonSize); + // make text aligned to center + if (opt->leftButtonSize.isEmpty()) + tr.setLeft(tr.left() + 4 + buttonSize); + } + + if (!verticalTabs) + tr = proxyStyle->visualRect(opt->direction, opt->rect, tr); + + *textRect = tr; +} +#endif //QT_NO_TABBAR + QAquaWidgetSize QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option, const QWidget *widg, QStyle::ContentsType ct, @@ -1286,6 +1310,7 @@ void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn, } } +#if QT_CONFIG(pushbutton) bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option) { QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style()); @@ -1295,6 +1320,7 @@ bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOpti macStyle->d_func()->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi); return bdi.kind == kThemeBevelButton; } +#endif /** Creates a HIThemeButtonDrawInfo structure that specifies the correct button @@ -1312,8 +1338,6 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem bdi->adornment = kThemeAdornmentFocus; if (combo->activeSubControls & QStyle::SC_ComboBoxArrow) bdi->state = kThemeStatePressed; - else if (tds == kThemeStateInactive && QSysInfo::MacintoshVersion < QSysInfo::MV_10_10) - bdi->state = kThemeStateActive; else bdi->state = tds; @@ -1634,7 +1658,7 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti || slider->tickPosition == QSlider::TicksBothSides; tdi->bounds = qt_hirectForQRect(slider->rect); - if (isScrollbar || QSysInfo::MacintoshVersion < QSysInfo::MV_10_10) { + if (isScrollbar) { tdi->min = slider->minimum; tdi->max = slider->maximum; tdi->value = slider->sliderPosition; @@ -1946,7 +1970,6 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD const bool button = opt->type == QStyleOption::SO_Button; const bool viewItem = opt->type == QStyleOption::SO_ViewItem; const bool pressed = bdi->state == kThemeStatePressed; - const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10; if (button && pressed) { if (bdi->kind == kThemePushButton) { @@ -1985,7 +2008,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height); if (button && pressed) bdi->state = kThemeStateActive; - else if (usingYosemiteOrLater && viewItem) + else if (viewItem) bdi->state = kThemeStateInactive; HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0); } @@ -1993,34 +2016,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD if (!combo && !button && bdi->value == kThemeButtonOff) { pm = activePixmap; - } else if (!usingYosemiteOrLater && (combo || button)) { - QImage image = activePixmap.toImage(); - - for (int y = 0; y < height; ++y) { - QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y)); - - for (int x = 0; x < width; ++x) { - QRgb &pixel = scanLine[x]; - - int darkest = qRed(pixel); - int mid = qGreen(pixel); - int lightest = qBlue(pixel); - - if (darkest > mid) - qSwap(darkest, mid); - if (mid > lightest) - qSwap(mid, lightest); - if (darkest > mid) - qSwap(darkest, mid); - - int gray = (mid + 2 * lightest) / 3; - if (pressed) - gray *= 0.88; - pixel = qRgba(gray, gray, gray, qAlpha(pixel)); - } - } - pm = QPixmap::fromImage(image); - } else if ((usingYosemiteOrLater && combo && !editableCombo) || button) { + } else if ((combo && !editableCombo) || button) { QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi->kind); NSButton *bc = (NSButton *)cocoaControl(cw); [bc highlight:pressed]; @@ -2034,7 +2030,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD rect.adjust(0, 0, -5, 0); drawNSViewInRect(cw, bc, rect, p); return; - } else if (usingYosemiteOrLater && (editableCombo || viewItem)) { + } else if (editableCombo || viewItem) { QImage image = activePixmap.toImage(); for (int y = 0; y < height; ++y) { @@ -2473,6 +2469,26 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW ret = int([NSWindow frameRectForContentRect:NSZeroRect styleMask:NSTitledWindowMask].size.height); break; + case QStyle::PM_TabBarTabHSpace: + switch (d->aquaSizeConstrain(opt, widget)) { + case QAquaSizeLarge: + ret = QCommonStyle::pixelMetric(metric, opt, widget); + break; + case QAquaSizeSmall: + ret = 20; + break; + case QAquaSizeMini: + ret = 16; + break; + case QAquaSizeUnknown: + const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt); + if (tb && tb->documentMode) + ret = 30; + else + ret = QCommonStyle::pixelMetric(metric, opt, widget); + break; + } + break; case PM_TabBarTabVSpace: ret = 4; break; @@ -2481,10 +2497,10 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW ret = 0; break; case PM_TabBarBaseHeight: - ret = 0; + ret = 21; break; case PM_TabBarTabOverlap: - ret = 0; + ret = 1; break; case PM_TabBarBaseOverlap: switch (d->aquaSizeConstrain(opt, widget)) { @@ -2661,20 +2677,6 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW case PM_LayoutHorizontalSpacing: case PM_LayoutVerticalSpacing: return -1; - case QStyle::PM_TabBarTabHSpace: - switch (d->aquaSizeConstrain(opt, widget)) { - case QAquaSizeLarge: - case QAquaSizeUnknown: - ret = QCommonStyle::pixelMetric(metric, opt, widget); - break; - case QAquaSizeSmall: - ret = 20; - break; - case QAquaSizeMini: - ret = 16; - break; - } - break; case PM_MenuHMargin: ret = 0; break; @@ -2942,9 +2944,11 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w case SH_TabBar_ElideMode: ret = Qt::ElideRight; break; +#if QT_CONFIG(dialogbuttonbox) case SH_DialogButtonLayout: ret = QDialogButtonBox::MacLayout; break; +#endif case SH_FormLayoutWrapPolicy: ret = QFormLayout::DontWrapRows; break; @@ -3100,23 +3104,6 @@ QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOpt return icon.pixmap(qt_getWindow(widget), QSize(size, size)); } -void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy) -{ - switch (policy) { - case FocusDefault: - break; - case FocusEnabled: - case FocusDisabled: - w->setAttribute(Qt::WA_MacShowFocusRect, policy == FocusEnabled); - break; - } -} - -QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w) -{ - return w->testAttribute(Qt::WA_MacShowFocusRect) ? FocusEnabled : FocusDisabled; -} - void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy) { QWidget *wadget = const_cast<QWidget *>(widget); @@ -3317,32 +3304,60 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } break; case PE_IndicatorMenuCheckMark: { - const int checkw = 8; - const int checkh = 8; - const int xoff = qMax(0, (opt->rect.width() - checkw) / 2); - const int yoff = qMax(0, (opt->rect.width() - checkh) / 2); - const int x1 = xoff + opt->rect.x(); - const int y1 = yoff + opt->rect.y() + checkw/2; - const int x2 = xoff + opt->rect.x() + checkw/4; - const int y2 = yoff + opt->rect.y() + checkh; - const int x3 = xoff + opt->rect.x() + checkw; - const int y3 = yoff + opt->rect.y(); - - QVector<QLineF> a(2); - a << QLineF(x1, y1, x2, y2); - a << QLineF(x2, y2, x3, y3); - if (opt->palette.currentColorGroup() == QPalette::Active) { - if (opt->state & State_On) - p->setPen(QPen(opt->palette.highlightedText().color(), 3)); - else - p->setPen(QPen(opt->palette.text().color(), 3)); - } else { - p->setPen(QPen(QColor(100, 100, 100), 3)); - } - p->save(); - p->setRenderHint(QPainter::Antialiasing); - p->drawLines(a); - p->restore(); + if (!(opt->state & State_On)) + break; + QColor pc; + if (opt->state & State_Selected) + pc = opt->palette.highlightedText().color(); + else + pc = opt->palette.text().color(); + QCFType<CGColorRef> checkmarkColor = CGColorCreateGenericRGB(static_cast<CGFloat>(pc.redF()), + static_cast<CGFloat>(pc.greenF()), + static_cast<CGFloat>(pc.blueF()), + static_cast<CGFloat>(pc.alphaF())); + // kCTFontUIFontSystem and others give the same result + // as kCTFontUIFontMenuItemMark. However, the latter is + // more reminiscent to HITheme's kThemeMenuItemMarkFont. + // See also the font for small- and mini-sized widgets, + // where we end up using the generic system font type. + const CTFontUIFontType fontType = (opt->state & State_Mini) ? kCTFontUIFontMiniSystem : + (opt->state & State_Small) ? kCTFontUIFontSmallSystem : + kCTFontUIFontMenuItemMark; + // Similarly for the font size, where there is a small difference + // between regular combobox and item view items, and and menu items. + // However, we ignore any difference for small- and mini-sized widgets. + const CGFloat fontSize = fontType == kCTFontUIFontMenuItemMark ? opt->fontMetrics.height() : 0.0; + QCFType<CTFontRef> checkmarkFont = CTFontCreateUIFontForLanguage(fontType, fontSize, NULL); + + CGContextSaveGState(cg); + CGContextSetShouldSmoothFonts(cg, NO); // Same as HITheme and Cocoa menu checkmarks + + // Baseline alignment tweaks for QComboBox and QMenu + const CGFloat vOffset = (opt->state & State_Mini) ? 0.0 : + (opt->state & State_Small) ? 1.0 : + 0.75; + + CGContextTranslateCTM(cg, 0, opt->rect.bottom()); + CGContextScaleCTM(cg, 1, -1); + // Translate back to the original position and add rect origin and offset + CGContextTranslateCTM(cg, opt->rect.x(), vOffset); + + // CTFont has severe difficulties finding the checkmark character among its + // glyphs. Fortunately, CTLine knows its ways inside the Cocoa labyrinth. + static const CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; + static const int numValues = sizeof(keys) / sizeof(keys[0]); + const CFTypeRef values[] = { (CFTypeRef)checkmarkFont, (CFTypeRef)checkmarkColor }; + Q_STATIC_ASSERT((sizeof(values) / sizeof(values[0])) == numValues); + QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, + numValues, NULL, NULL); + // U+2713: CHECK MARK + QCFType<CFAttributedStringRef> checkmarkString = CFAttributedStringCreate(kCFAllocatorDefault, (CFStringRef)@"\u2713", attributes); + QCFType<CTLineRef> line = CTLineCreateWithAttributedString(checkmarkString); + + CTLineDraw((CTLineRef)line, cg); + CGContextFlush(cg); // CTLineDraw's documentation says it doesn't flush + + CGContextRestoreGState(cg); break; } case PE_IndicatorViewItemCheck: case PE_IndicatorRadioButton: @@ -3513,10 +3528,18 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai case PE_FrameStatusBarItem: break; case PE_IndicatorTabClose: { - bool hover = (opt->state & State_MouseOver); - bool selected = (opt->state & State_Selected); - bool active = (opt->state & State_Active); - drawTabCloseButton(p, hover, active, selected); + // Make close button visible only on the hovered tab. + if (QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget())) { + const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar)); + const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex(); + if (hoveredTabIndex != -1 && ((w == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) || + (w == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide)))) { + const bool hover = (opt->state & State_MouseOver); + const bool selected = (opt->state & State_Selected); + const bool pressed = (opt->state & State_Sunken); + drawTabCloseButton(p, hover, selected, pressed); + } + } } break; case PE_PanelStatusBar: { // Fill the status bar with the titlebar gradient. @@ -3581,7 +3604,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QWindow *window = w && w->window() ? w->window()->windowHandle() : QStyleHelper::styleObjectWindow(opt->styleObject); const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window); - const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10; switch (ce) { case CE_HeaderSection: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { @@ -3802,10 +3824,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter // takes precedence over a normal default button if (btn->features & QStyleOptionButton::AutoDefaultButton && opt->state & State_Active && opt->state & State_HasFocus) { - if (usingYosemiteOrLater) - d->autoDefaultButton = opt->styleObject; - else - d->setAutoDefaultButton(opt->styleObject); + d->autoDefaultButton = opt->styleObject; } else if (d->autoDefaultButton == opt->styleObject) { d->setAutoDefaultButton(0); } @@ -3813,8 +3832,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (!d->autoDefaultButton) { if (btn->features & QStyleOptionButton::DefaultButton && opt->state & State_Active) { d->defaultButton = opt->styleObject; - if (!usingYosemiteOrLater && !d->animation(opt->styleObject)) - d->startAnimation(new QStyleAnimation(opt->styleObject)); } else if (d->defaultButton == opt->styleObject) { if (QStyleAnimation *animation = d->animation(opt->styleObject)) { animation->updateTarget(); @@ -3835,42 +3852,18 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter HIThemeButtonDrawInfo bdi; d->initHIThemePushButton(btn, w, tds, &bdi); - if (usingYosemiteOrLater) { - if (!hasMenu) { - // HITheme is not drawing a nice focus frame around buttons. - // We'll do it ourselves further down. - bdi.adornment &= ~kThemeAdornmentFocus; - - // We can't rely on an animation existing to test for the default look. That means a bit - // more logic (notice that the logic is slightly different for the bevel and the label). - if (tds == kThemeStateActive - && (btn->features & QStyleOptionButton::DefaultButton - || (btn->features & QStyleOptionButton::AutoDefaultButton - && d->autoDefaultButton == btn->styleObject))) - bdi.adornment |= kThemeAdornmentDefault; - } - } else { - // the default button animation is paused meanwhile any button - // is pressed or an auto-default button is animated instead - if (QStyleAnimation *defaultAnimation = d->animation(d->defaultButton)) { - if (d->pressedButton || d->autoDefaultButton) { - if (defaultAnimation->state() == QStyleAnimation::Running) { - defaultAnimation->pause(); - defaultAnimation->updateTarget(); - } - } else if (defaultAnimation->state() == QStyleAnimation::Paused) { - defaultAnimation->resume(); - } - } - - if (!d->pressedButton) { - QStyleAnimation* animation = d->animation(opt->styleObject); - if (animation && animation->state() == QStyleAnimation::Running) { - bdi.adornment |= kThemeAdornmentDefault; - bdi.animation.time.start = d->defaultButtonStart; - bdi.animation.time.current = CFAbsoluteTimeGetCurrent(); - } - } + if (!hasMenu) { + // HITheme is not drawing a nice focus frame around buttons. + // We'll do it ourselves further down. + bdi.adornment &= ~kThemeAdornmentFocus; + + // We can't rely on an animation existing to test for the default look. That means a bit + // more logic (notice that the logic is slightly different for the bevel and the label). + if (tds == kThemeStateActive + && (btn->features & QStyleOptionButton::DefaultButton + || (btn->features & QStyleOptionButton::AutoDefaultButton + && d->autoDefaultButton == btn->styleObject))) + bdi.adornment |= kThemeAdornmentDefault; } // Unlike Carbon, we want the button to always be drawn inside its bounds. @@ -3888,7 +3881,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4; } - if (hasMenu && usingYosemiteOrLater && bdi.kind != kThemeBevelButton) { + if (hasMenu && bdi.kind != kThemeBevelButton) { QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind); cw.first = QCocoaPullDownButton; NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(cw); @@ -3902,7 +3895,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter else HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0); - if (usingYosemiteOrLater && btn->state & State_HasFocus) { + if (btn->state & State_HasFocus) { CGRect focusRect = newRect; if (bdi.kind == kThemePushButton) focusRect.size.height += 1; // Another thing HITheme and Cocoa seem to disagree about. @@ -3932,7 +3925,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter d->drawFocusRing(p, focusTargetRect.adjusted(-hMargin, -vMargin, hMargin, vMargin), hMargin, vMargin, radius); } - if (hasMenu && (!usingYosemiteOrLater || bdi.kind == kThemeBevelButton)) { + if (hasMenu && bdi.kind == kThemeBevelButton) { int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w); QRect ir = btn->rect; int arrowXOffset = bdi.kind == kThemePushButton ? 6 : @@ -3973,7 +3966,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter bool hasIcon = !btn.icon.isNull(); bool hasText = !btn.text.isEmpty(); - if (!hasMenu && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10) { + if (!hasMenu) { if (tds == kThemeStatePressed || (tds == kThemeStateActive && ((btn.features & QStyleOptionButton::DefaultButton && !d->autoDefaultButton) @@ -4077,17 +4070,12 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { QStyleOptionComboBox comboCopy = *cb; comboCopy.direction = Qt::LeftToRight; - if (opt->state & QStyle::State_Small) - comboCopy.rect.translate(0, w ? 0 : (QSysInfo::macVersion() >= QSysInfo::MV_10_10 ? 0 : -2)); // Supports Qt Quick Controls - else if (QSysInfo::macVersion() == QSysInfo::MV_10_9) - comboCopy.rect.translate(0, 1); QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w); } break; #ifndef QT_NO_TABBAR case CE_TabBarTabShape: if (const QStyleOptionTab *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) { - if (tabOpt->documentMode) { p->save(); bool isUnified = false; @@ -4097,7 +4085,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y()); } - drawTabShape(p, tabOpt, isUnified); + const int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, opt, w); + drawTabShape(p, tabOpt, isUnified, tabOverlap); + p->restore(); return; } @@ -4143,12 +4133,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter tdi.adornment = kHIThemeTabAdornmentNone; tdi.kind = kHIThemeTabKindNormal; - if (!usingYosemiteOrLater) { - if (!verticalTabs) - tabRect.setY(tabRect.y() - 1); - else - tabRect.setX(tabRect.x() - 1); - } QStyleOptionTab::TabPosition tp = tabOpt->position; QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition; if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) { @@ -4212,15 +4196,13 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QStyleOptionTab myTab = *tab; ThemeTabDirection ttd = getTabDirection(myTab.shape); bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast; - bool selected = (myTab.state & QStyle::State_Selected); // Check to see if we use have the same as the system font // (QComboMenuItem is internal and should never be seen by the // outside world, unless they read the source, in which case, it's // their own fault). bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem"); - bool isSelectedAndNeedsShadow = selected && !usingYosemiteOrLater; - if (isSelectedAndNeedsShadow || verticalTabs || nonDefaultFont || !tab->icon.isNull() + if (verticalTabs || nonDefaultFont || !tab->icon.isNull() || !myTab.leftButtonSize.isEmpty() || !myTab.rightButtonSize.isEmpty()) { int heightOffset = 0; if (verticalTabs) { @@ -4231,23 +4213,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter } myTab.rect.setHeight(myTab.rect.height() + heightOffset); - if (myTab.documentMode || isSelectedAndNeedsShadow) { - p->save(); - rotateTabPainter(p, myTab.shape, myTab.rect); - - QColor shadowColor = QColor(myTab.documentMode ? Qt::white : Qt::black); - shadowColor.setAlpha(75); - QPalette np = tab->palette; - np.setColor(QPalette::WindowText, shadowColor); - - QRect nr = proxy()->subElementRect(SE_TabBarTabText, opt, w); - nr.moveTop(-1); - int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic; - proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled, - tab->text, QPalette::WindowText); - p->restore(); - } - QCommonStyle::drawControl(ce, &myTab, p, w); } else { p->save(); @@ -4427,61 +4392,27 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter p->setPen(mi->palette.buttonText().color()); if (mi->checked) { - // Use the HIThemeTextInfo foo to draw the check mark correctly, if we do it, - // we somehow need to use a special encoding as it doesn't look right with our - // drawText(). - p->save(); - CGContextSetShouldAntialias(cg, true); - CGContextSetShouldSmoothFonts(cg, true); - QColor textColor = p->pen().color(); - CGFloat colorComp[] = { static_cast<CGFloat>(textColor.redF()), static_cast<CGFloat>(textColor.greenF()), - static_cast<CGFloat>(textColor.blueF()), static_cast<CGFloat>(textColor.alphaF()) }; - CGContextSetFillColorSpace(cg, qt_mac_genericColorSpace()); - CGContextSetFillColor(cg, colorComp); - HIThemeTextInfo tti; - tti.version = qt_mac_hitheme_version; - tti.state = tds; - if (active && enabled) - tti.state = kThemeStatePressed; - switch (widgetSize) { - case QAquaSizeUnknown: - case QAquaSizeLarge: - tti.fontID = kThemeMenuItemMarkFont; - break; - case QAquaSizeSmall: - tti.fontID = kThemeSmallSystemFont; - break; - case QAquaSizeMini: - tti.fontID = kThemeMiniSystemFont; - break; - } - tti.horizontalFlushness = kHIThemeTextHorizontalFlushLeft; - tti.verticalFlushness = kHIThemeTextVerticalFlushCenter; - tti.options = kHIThemeTextBoxOptionNone; - tti.truncationPosition = kHIThemeTextTruncationNone; - tti.truncationMaxLines = 1; - QCFString checkmark; -#if 0 - if (mi->checkType == QStyleOptionMenuItem::Exclusive) - checkmark = QString(QChar(kDiamondUnicode)); - else -#endif - checkmark = QString(QChar(kCheckUnicode)); - int mw = checkcol + macItemFrame; - int mh = contentRect.height() - 2 * macItemFrame; - int xp = contentRect.x(); - xp += macItemFrame; - CGFloat outWidth, outHeight, outBaseline; - HIThemeGetTextDimensions(checkmark, 0, &tti, &outWidth, &outHeight, - &outBaseline); + QStyleOption checkmarkOpt; + checkmarkOpt.initFrom(w); + + const int mw = checkcol + macItemFrame; + const int mh = contentRect.height() + macItemFrame; + 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_Enabled, enabled); if (widgetSize == QAquaSizeMini) - outBaseline += 1; - QRect r(xp, contentRect.y(), mw, mh); - r.translate(0, p->fontMetrics().ascent() - int(outBaseline) + 1); - HIRect bounds = qt_hirectForQRect(r); - HIThemeDrawTextBox(checkmark, &bounds, &tti, - cg, kHIThemeOrientationNormal); - p->restore(); + checkmarkOpt.state |= State_Mini; + else if (widgetSize == QAquaSizeSmall) + checkmarkOpt.state |= State_Small; + + // We let drawPrimitive(PE_IndicatorMenuCheckMark) pick the right color + checkmarkOpt.palette.setColor(QPalette::HighlightedText, p->pen().color()); + checkmarkOpt.palette.setColor(QPalette::Text, p->pen().color()); + + proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &checkmarkOpt, p, w); } if (!mi->icon.isNull()) { QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal @@ -4654,7 +4585,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter tdi.value = pb->progress; tdi.attributes = vertical ? 0 : kThemeTrackHorizontal; - if (isIndeterminate || (tdi.value < tdi.max && !usingYosemiteOrLater)) { + if (isIndeterminate) { if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject))) tdi.trackInfo.progress.phase = animation->animationStep(); else if (opt->styleObject) @@ -4736,8 +4667,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter HIThemeSplitterDrawInfo sdi; sdi.version = qt_mac_hitheme_version; sdi.state = tds; - sdi.adornment = qt_mac_is_metal(w) || usingYosemiteOrLater ? - kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone; + sdi.adornment = kHIThemeSplitterAdornmentMetal; HIRect hirect = qt_hirectForQRect(opt->rect); HIThemeDrawPaneSplitter(&hirect, &sdi, cg, kHIThemeOrientationNormal); } else { @@ -5000,6 +4930,73 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, } } break; + case SE_TabBarTabText: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + d->tabLayout(tab, widget, &rect); + } + break; + case SE_TabBarTabLeftButton: + case SE_TabBarTabRightButton: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + bool selected = tab->state & State_Selected; + int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget); + int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget); + int hpadding = 5; + + bool verticalTabs = tab->shape == QTabBar::RoundedEast + || tab->shape == QTabBar::RoundedWest + || tab->shape == QTabBar::TriangularEast + || tab->shape == QTabBar::TriangularWest; + + QRect tr = tab->rect; + if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth) + verticalShift = -verticalShift; + if (verticalTabs) { + qSwap(horizontalShift, verticalShift); + horizontalShift *= -1; + verticalShift *= -1; + } + if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest) + horizontalShift = -horizontalShift; + + tr.adjust(0, 0, horizontalShift, verticalShift); + if (selected) + { + tr.setBottom(tr.bottom() - verticalShift); + tr.setRight(tr.right() - horizontalShift); + } + + QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize; + int w = size.width(); + int h = size.height(); + int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2)); + int midWidth = ((tr.width() - w) / 2); + + bool atTheTop = true; + switch (tab->shape) { + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + atTheTop = (sr == SE_TabBarTabLeftButton); + break; + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + atTheTop = (sr == SE_TabBarTabRightButton); + break; + default: + if (sr == SE_TabBarTabLeftButton) + rect = QRect(tab->rect.x() + hpadding, midHeight, w, h); + else + rect = QRect(tab->rect.right() - w - hpadding, midHeight, w, h); + rect = visualRect(tab->direction, tab->rect, rect); + } + if (verticalTabs) { + if (atTheTop) + rect = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h); + else + rect = QRect(midWidth, tr.y() + hpadding, w, h); + } + } + break; #endif case SE_LineEditContents: rect = QCommonStyle::subElementRect(sr, opt, widget); @@ -5287,7 +5284,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : QStyleHelper::styleObjectWindow(opt->styleObject); const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window); - const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10; switch (cc) { case CC_Slider: case CC_ScrollBar: @@ -5380,7 +5376,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex int oldMin = styleObject->property("_q_stylemin").toInt(); int oldMax = styleObject->property("_q_stylemax").toInt(); QRect oldRect = styleObject->property("_q_stylerect").toRect(); - int oldState = styleObject->property("_q_stylestate").toInt(); + QStyle::State oldState = static_cast<QStyle::State>(styleObject->property("_q_stylestate").value<QStyle::State::Int>()); uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt(); // a scrollbar is transient when the scrollbar itself and @@ -5403,7 +5399,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex styleObject->setProperty("_q_stylemin", slider->minimum); styleObject->setProperty("_q_stylemax", slider->maximum); styleObject->setProperty("_q_stylerect", slider->rect); - styleObject->setProperty("_q_stylestate", static_cast<int>(slider->state)); + styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(slider->state)); styleObject->setProperty("_q_stylecontrols", static_cast<uint>(slider->activeSubControls)); QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject)); @@ -5532,7 +5528,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } else { d->stopAnimation(opt->styleObject); - if (usingYosemiteOrLater && cc == CC_Slider) { + if (cc == CC_Slider) { // Fix min and max positions. (See also getSliderInfo() // for the slider values adjustments.) // HITheme seems to have forgotten how to render @@ -5595,22 +5591,20 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) { HIRect bounds; - if (usingYosemiteOrLater) { - // As part of fixing the min and max positions, - // we need to adjust the tickmarks as well - bounds = tdi.bounds; - if (slider->orientation == Qt::Horizontal) { - tdi.bounds.size.width += 2; - tdi.bounds.origin.x -= 1; - if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) - tdi.bounds.origin.y -= 2; - } else { - tdi.bounds.size.height += 3; - tdi.bounds.origin.y -= 3; - tdi.bounds.origin.y += 1; - if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) // pointing left - tdi.bounds.origin.x -= 2; - } + // As part of fixing the min and max positions, + // we need to adjust the tickmarks as well + bounds = tdi.bounds; + if (slider->orientation == Qt::Horizontal) { + tdi.bounds.size.width += 2; + tdi.bounds.origin.x -= 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) + tdi.bounds.origin.y -= 2; + } else { + tdi.bounds.size.height += 3; + tdi.bounds.origin.y -= 3; + tdi.bounds.origin.y += 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) // pointing left + tdi.bounds.origin.x -= 2; } if (qt_mac_is_metal(widget)) { @@ -5634,10 +5628,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex cg, kHIThemeOrientationNormal); tdi.trackInfo.slider.thumbDir = kThemeThumbUpward; - if (usingYosemiteOrLater) { - if (slider->orientation == Qt::Vertical) - tdi.bounds.origin.x -= 2; - } + // 10.10 and above need a slight shift + if (slider->orientation == Qt::Vertical) + tdi.bounds.origin.x -= 2; HIThemeDrawTrackTickMarks(&tdi, numMarks, cg, kHIThemeOrientationNormal); @@ -5649,11 +5642,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex kHIThemeOrientationNormal); } - if (usingYosemiteOrLater) - tdi.bounds = bounds; + tdi.bounds = bounds; } - if (usingYosemiteOrLater && cc == CC_Slider) { + if (cc == CC_Slider) { // Still as part of fixing the min and max positions, // we also adjust the knob position. We can do this // because it's rendered separately from the track. @@ -5745,11 +5737,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex HIThemeButtonDrawInfo bdi; d->initComboboxBdi(combo, &bdi, widget, tds); HIRect rect = qt_hirectForQRect(combo->rect); - if (combo->editable && usingYosemiteOrLater) + if (combo->editable) rect.origin.y += tds == kThemeStateInactive ? 1 : 2; if (tds != kThemeStateInactive) QMacStylePrivate::drawCombobox(rect, bdi, p); - else if (!widget && combo->editable && usingYosemiteOrLater) { + else if (!widget && combo->editable) { QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind); NSView *cb = d->cocoaControl(cw); QRect r = combo->rect.adjusted(3, 0, 0, 0); @@ -5931,31 +5923,23 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex drawToolbarButtonArrow(tb->rect, tds, cg); } if (tb->state & State_On) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10) { - QWindow *window = 0; - if (widget && widget->window()) - window = widget->window()->windowHandle(); - else if (opt->styleObject) - window = opt->styleObject->property("_q_styleObjectWindow").value<QWindow *>(); - - NSView *view = window ? (NSView *)window->winId() : nil; - bool isKey = false; - if (view) - isKey = [view.window isKeyWindow]; - - QBrush brush(isKey ? QColor(0, 0, 0, 28) - : QColor(0, 0, 0, 21)); - QPainterPath path; - path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4); - p->setRenderHint(QPainter::Antialiasing); - p->fillPath(path, brush); - } else { - static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png")); - p->save(); - p->setRenderHint(QPainter::SmoothPixmapTransform); - QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2); - p->restore(); - } + QWindow *window = 0; + if (widget && widget->window()) + window = widget->window()->windowHandle(); + else if (opt->styleObject) + window = opt->styleObject->property("_q_styleObjectWindow").value<QWindow *>(); + + NSView *view = window ? (NSView *)window->winId() : nil; + bool isKey = false; + if (view) + isKey = [view.window isKeyWindow]; + + QBrush brush(isKey ? QColor(0, 0, 0, 28) + : QColor(0, 0, 0, 21)); + QPainterPath path; + path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4); + p->setRenderHint(QPainter::Antialiasing); + p->fillPath(path, brush); } proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget); } else { @@ -6295,8 +6279,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op switch (sc) { case SC_ComboBoxEditField:{ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi); - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10) - ret.setHeight(ret.height() - 1); + // 10.10 and above need a slight shift + ret.setHeight(ret.height() - 1); break; } case SC_ComboBoxArrow:{ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi); @@ -6620,13 +6604,13 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (vertTabs) sz = sz.transposed(); int defaultTabHeight; - int defaultExtraSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); // Remove spurious gcc warning (AFAIK) + int extraHSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); QFontMetrics fm = opt->fontMetrics; switch (AquaSize) { case QAquaSizeUnknown: case QAquaSizeLarge: if (tab->documentMode) - defaultTabHeight = 23; + defaultTabHeight = 24; else defaultTabHeight = 21; break; @@ -6643,9 +6627,10 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, } else { QSize textSize = fm.size(Qt::TextShowMnemonic, tab->text); sz.rheight() = qMax(defaultTabHeight, textSize.height()); - sz.rwidth() = textSize.width() + defaultExtraSpace; + sz.rwidth() = textSize.width(); setWidth = true; } + sz.rwidth() += extraHSpace; if (vertTabs) sz = sz.transposed(); @@ -6754,7 +6739,7 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_ComboBox: { sz.rwidth() += 50; const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt); - if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_10 || (cb && !cb->editable)) + if (cb && !cb->editable) sz.rheight() += 2; break; } diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h index 3642424a14..7296539356 100644 --- a/src/widgets/styles/qmacstyle_mac_p.h +++ b/src/widgets/styles/qmacstyle_mac_p.h @@ -100,10 +100,6 @@ public: virtual int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0, QStyleHintReturn *shret = 0) const; - enum FocusRectPolicy { FocusEnabled, FocusDisabled, FocusDefault }; - static void setFocusRectPolicy(QWidget *w, FocusRectPolicy policy); - static FocusRectPolicy focusRectPolicy(const QWidget *w); - enum WidgetSizePolicy { SizeSmall, SizeLarge, SizeMini, SizeDefault }; @@ -131,7 +127,9 @@ private: Q_DISABLE_COPY(QMacStyle) Q_DECLARE_PRIVATE(QMacStyle) +#if QT_CONFIG(pushbutton) friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); +#endif }; #endif diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index 601dd643fb..9bbd0995a5 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -53,9 +53,13 @@ #include <private/qstylehelper_p.h> #include <qapplication.h> #include <qbitmap.h> +#if QT_CONFIG(checkbox) #include <qcheckbox.h> +#endif #include <qcombobox.h> +#if QT_CONFIG(dialogbuttonbox) #include <qdialogbuttonbox.h> +#endif #include <qdockwidget.h> #include <qevent.h> #include <qfocusframe.h> @@ -74,7 +78,9 @@ #include <qpixmapcache.h> #include <qpointer.h> #include <qprogressbar.h> +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#endif #include <qradiobutton.h> #include <qrubberband.h> #include <qsizegrip.h> @@ -153,7 +159,9 @@ typedef void (^QCocoaDrawRectBlock)(NSRect, CGContextRef); return sizes[controlSize]; \ } while (0) +#if QT_CONFIG(pushbutton) bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); +#endif class QMacStylePrivate : public QCommonStylePrivate { @@ -220,6 +228,10 @@ public: void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; +#ifndef QT_NO_TABBAR + void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect) const; +#endif + public: mutable QPointer<QObject> pressedButton; mutable QPointer<QObject> defaultButton; diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp index a947f5d079..3aec3cf991 100644 --- a/src/widgets/styles/qpixmapstyle.cpp +++ b/src/widgets/styles/qpixmapstyle.cpp @@ -60,7 +60,9 @@ #include <QAbstractScrollArea> #include <QScrollBar> +#if QT_CONFIG(scroller) #include <qscroller.h> +#endif QT_BEGIN_NAMESPACE @@ -194,7 +196,7 @@ void QPixmapStyle::polish(QWidget *widget) view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); } #endif -#if QT_CONFIG(gestures) +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture); #endif } @@ -235,7 +237,7 @@ void QPixmapStyle::unpolish(QWidget *widget) if (qstrcmp(widget->metaObject()->className(),"QComboBoxPrivateContainer") == 0) widget->removeEventFilter(this); -#if QT_CONFIG(gestures) && QT_CONFIG(scrollarea) +#if QT_CONFIG(gestures) && QT_CONFIG(scrollarea) && QT_CONFIG(scroller) if (QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget)) QScroller::ungrabGesture(scrollArea->viewport()); #endif diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 9be19b2679..275a0550d2 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -58,12 +58,16 @@ #include "private/qabstractscrollarea_p.h" #include <qtooltip.h> #include <qshareddata.h> -#include <qradiobutton.h> #include <qtoolbutton.h> #include <qscrollbar.h> +#if QT_CONFIG(abstractslider) +#include <qabstractslider.h> +#endif #include <qstring.h> #include <qfile.h> +#if QT_CONFIG(checkbox) #include <qcheckbox.h> +#endif #include <qstatusbar.h> #include <qheaderview.h> #include <private/qwindowsstyle_p_p.h> @@ -76,7 +80,9 @@ #include <qdialog.h> #include <private/qwidget_p.h> #include <QAbstractSpinBox> +#if QT_CONFIG(label) #include <QLabel> +#endif #include "qdrawutil.h" #include <limits.h> @@ -1415,11 +1421,13 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q static inline QObject *parentObject(const QObject *obj) { +#if QT_CONFIG(tooltip) if (qobject_cast<const QLabel *>(obj) && qstrcmp(obj->metaObject()->className(), "QTipLabel") == 0) { QObject *p = qvariant_cast<QObject *>(obj->property("_q_stylesheet_parent")); if (p) return p; } +#endif return obj->parent(); } @@ -2421,9 +2429,11 @@ static bool unstylable(const QWidget *w) static quint64 extendedPseudoClass(const QWidget *w) { quint64 pc = w->isWindow() ? quint64(PseudoClass_Window) : 0; +#if QT_CONFIG(abstractslider) if (const QAbstractSlider *slider = qobject_cast<const QAbstractSlider *>(w)) { pc |= ((slider->orientation() == Qt::Vertical) ? PseudoClass_Vertical : PseudoClass_Horizontal); } else +#endif #ifndef QT_NO_COMBOBOX if (const QComboBox *combo = qobject_cast<const QComboBox *>(w)) { if (combo->isEditable()) @@ -2589,7 +2599,7 @@ void QStyleSheetStyle::setPalette(QWidget *w) if (!useStyleSheetPropagationInWidgetStyles || p.resolve() != 0) { QPalette wp = w->palette(); - styleSheetCaches->customPaletteWidgets.insert(w, qMakePair(wp, p.resolve())); + styleSheetCaches->customPaletteWidgets.insert(w, {wp, p.resolve()}); if (useStyleSheetPropagationInWidgetStyles) { p = p.resolve(wp); @@ -2607,21 +2617,16 @@ void QStyleSheetStyle::unsetPalette(QWidget *w) const bool useStyleSheetPropagationInWidgetStyles = QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); - if (styleSheetCaches->customPaletteWidgets.contains(w)) { - QPair<QPalette, uint> p = styleSheetCaches->customPaletteWidgets.value(w); - styleSheetCaches->customPaletteWidgets.remove(w); - - QPalette original = p.first; - - if (useStyleSheetPropagationInWidgetStyles) { - original.resolve(original.resolve() & p.second); + const auto it = styleSheetCaches->customPaletteWidgets.find(w); + if (it != styleSheetCaches->customPaletteWidgets.end()) { + auto customizedPalette = std::move(*it); + styleSheetCaches->customPaletteWidgets.erase(it); - QPalette wp = w->palette(); - wp.resolve(wp.resolve() & ~p.second); - wp.resolve(original); - wp.resolve(wp.resolve() | original.resolve()); - original = wp; - } + QPalette original; + if (useStyleSheetPropagationInWidgetStyles) + original = std::move(customizedPalette).reverted(w->palette()); + else + original = customizedPalette.oldWidgetValue; w->setPalette(original); QWidget *ew = embeddedWidget(w); @@ -2649,19 +2654,11 @@ void QStyleSheetStyle::unsetPalette(QWidget *w) void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const { - if (styleSheetCaches->customFontWidgets.contains(w)) { - QPair<QFont, uint> f = styleSheetCaches->customFontWidgets.value(w); - styleSheetCaches->customFontWidgets.remove(w); - - QFont original = f.first; - original.resolve(original.resolve() & f.second); - - QFont font = w->font(); - font.resolve(font.resolve() & ~f.second); - font.resolve(original); - font.resolve(font.resolve() | original.resolve()); - - w->setFont(font); + const auto it = styleSheetCaches->customFontWidgets.find(w); + if (it != styleSheetCaches->customFontWidgets.end()) { + auto customizedFont = std::move(*it); + styleSheetCaches->customFontWidgets.erase(it); + w->setFont(std::move(customizedFont).reverted(w->font())); } } @@ -4735,10 +4732,12 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const return rule.box()->spacing; break; case PM_CheckBoxLabelSpacing: +#if QT_CONFIG(checkbox) if (qobject_cast<const QCheckBox *>(w)) { if (rule.hasBox() && rule.box()->spacing != -1) return rule.box()->spacing; } +#endif // assume group box subRule = renderRule(w, opt, PseudoElement_GroupBoxTitle); if (subRule.hasBox() && subRule.box()->spacing != -1) @@ -5944,7 +5943,7 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const if (rule.font.resolve()) { QFont wf = w->font(); - styleSheetCaches->customFontWidgets.insert(w, qMakePair(wf, rule.font.resolve())); + styleSheetCaches->customFontWidgets.insert(w, {wf, rule.font.resolve()}); QFont font = rule.font.resolve(wf); font.resolve(wf.resolve() | rule.font.resolve()); diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h index 55dd2df329..2d302305bd 100644 --- a/src/widgets/styles/qstylesheetstyle_p.h +++ b/src/widgets/styles/qstylesheetstyle_p.h @@ -189,12 +189,31 @@ public: QHash<const QObject *, QRenderRules> renderRulesCache; QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets QSet<const QWidget *> autoFillDisabledWidgets; - // widgets whose palettes and fonts we have tampered. stored value pair is - // QPair<old widget value, resolve mask of stylesheet value> - QHash<const QWidget *, QPair<QPalette, uint> > customPaletteWidgets; - QHash<const QWidget *, QPair<QFont, uint> > customFontWidgets; + // widgets with whose palettes and fonts we have tampered: + template <typename T> + struct Tampered { + T oldWidgetValue; + uint resolveMask; + + // only call this function on an rvalue *this (it mangles oldWidgetValue) + T reverted(T current) +#ifdef Q_COMPILER_REF_QUALIFIERS + && +#endif + { + oldWidgetValue.resolve(oldWidgetValue.resolve() & resolveMask); + current.resolve(current.resolve() & ~resolveMask); + current.resolve(oldWidgetValue); + current.resolve(current.resolve() | oldWidgetValue.resolve()); + return current; + } + }; + QHash<const QWidget *, Tampered<QPalette>> customPaletteWidgets; + QHash<const QWidget *, Tampered<QFont>> customFontWidgets; }; - +template <typename T> +class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>> + : QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {}; QT_END_NAMESPACE #endif // QT_NO_STYLE_STYLESHEET diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 7f52d3d2f3..5a53627e95 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -39,6 +39,7 @@ #include "qwindowsvistastyle_p.h" #include "qwindowsvistastyle_p_p.h" +#include <qoperatingsystemversion.h> #include <qscreen.h> #include <qwindow.h> #include <private/qstyleanimation_p.h> @@ -599,6 +600,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt XPThemeData theme(widget, painter, QWindowsXPStylePrivate::EditTheme, EP_EDITBORDER_NOSCROLL, stateId, option->rect); + theme.noContent = true; painter->save(); QRegion clipRegion = option->rect; clipRegion -= option->rect.adjusted(2, 2, -2, -2); @@ -773,6 +775,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt } case PE_Widget: { +#if QT_CONFIG(dialogbuttonbox) const QDialogButtonBox *buttonBox = 0; if (qobject_cast<const QMessageBox *> (widget)) @@ -799,6 +802,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt theme.partId = TDLG_SECONDARYPANEL; d->drawBackground(theme); } +#endif } break; default: @@ -1752,7 +1756,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle theme.stateId = stateId; d->drawBackground(theme); - if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) { const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme); // Draw gripper if there is enough space if (!gripperBounds.isEmpty() && flags & State_Enabled) { @@ -2313,16 +2317,20 @@ void QWindowsVistaStyle::polish(QWidget *widget) } } else if (qobject_cast<QMessageBox *> (widget)) { widget->setAttribute(Qt::WA_StyledBackground); +#if QT_CONFIG(dialogbuttonbox) QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); if (buttonBox) buttonBox->setContentsMargins(0, 9, 0, 0); +#endif } #ifndef QT_NO_INPUTDIALOG else if (qobject_cast<QInputDialog *> (widget)) { widget->setAttribute(Qt::WA_StyledBackground); +#if QT_CONFIG(dialogbuttonbox) QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); if (buttonBox) buttonBox->setContentsMargins(0, 9, 0, 0); +#endif } #endif // QT_NO_INPUTDIALOG else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { @@ -2353,16 +2361,20 @@ void QWindowsVistaStyle::unpolish(QWidget *widget) widget->setAttribute(Qt::WA_Hover, false); else if (qobject_cast<QMessageBox *> (widget)) { widget->setAttribute(Qt::WA_StyledBackground, false); +#if QT_CONFIG(dialogbuttonbox) QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); if (buttonBox) buttonBox->setContentsMargins(0, 0, 0, 0); +#endif } #ifndef QT_NO_INPUTDIALOG else if (qobject_cast<QInputDialog *> (widget)) { widget->setAttribute(Qt::WA_StyledBackground, false); +#if QT_CONFIG(dialogbuttonbox) QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); if (buttonBox) buttonBox->setContentsMargins(0, 0, 0, 0); +#endif } #endif // QT_NO_INPUTDIALOG else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { diff --git a/src/widgets/styles/qwindowsvistastyle_p_p.h b/src/widgets/styles/qwindowsvistastyle_p_p.h index e12203f0a9..db358e6f6c 100644 --- a/src/widgets/styles/qwindowsvistastyle_p_p.h +++ b/src/widgets/styles/qwindowsvistastyle_p_p.h @@ -63,9 +63,10 @@ #include <qapplication.h> #include <qpixmapcache.h> #include <qstyleoption.h> +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#endif #include <qradiobutton.h> -#include <qcheckbox.h> #include <qlineedit.h> #include <qgroupbox.h> #include <qtoolbutton.h> @@ -79,7 +80,9 @@ #include <qtreeview.h> #include <qtextedit.h> #include <qmessagebox.h> +#if QT_CONFIG(dialogbuttonbox) #include <qdialogbuttonbox.h> +#endif #include <qinputdialog.h> #include <qtableview.h> #include <qdatetime.h> diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index f999d823e0..f3c6069f8a 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -65,7 +65,9 @@ #include <qspinbox.h> #include <qlistview.h> #include <qstackedwidget.h> +#if QT_CONFIG(pushbutton) #include <qpushbutton.h> +#endif #include <qtoolbar.h> #include <qlabel.h> #include <qvarlengtharray.h> @@ -397,13 +399,7 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) return topLevelHwnd; } - if (QDesktopWidget *desktop = qApp->desktop()) - if (const HWND desktopHwnd = QApplicationPrivate::getHWNDForWidget(desktop)) - return desktopHwnd; - - Q_ASSERT(false); - - return 0; + return GetDesktopWindow(); } /*! \internal diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 3006f0c9ce..e8f23f08bc 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -1347,11 +1347,12 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) } // default implementation for keys not handled by the widget when popup is open +#if QT_CONFIG(shortcut) if (ke->matches(QKeySequence::Cancel)) { d->popup->hide(); return true; } - +#endif switch (key) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: diff --git a/src/widgets/util/qscroller.h b/src/widgets/util/qscroller.h index 561dcfaefc..ca8d059f50 100644 --- a/src/widgets/util/qscroller.h +++ b/src/widgets/util/qscroller.h @@ -45,6 +45,8 @@ #include <QtCore/QPointF> #include <QtWidgets/QScrollerProperties> +QT_REQUIRE_CONFIG(scroller); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/util/qscrollerproperties.h b/src/widgets/util/qscrollerproperties.h index 4fdc9bd32f..2fc1a5dc18 100644 --- a/src/widgets/util/qscrollerproperties.h +++ b/src/widgets/util/qscrollerproperties.h @@ -45,6 +45,8 @@ #include <QtCore/QMetaType> #include <QtCore/QVariant> +QT_REQUIRE_CONFIG(scroller); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index f7464d50ec..1e0d2ab857 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -46,8 +46,13 @@ #include "qlist.h" #include "qevent.h" #include "qpoint.h" +#if QT_CONFIG(label) #include "qlabel.h" +#include "private/qlabel_p.h" +#endif +#if QT_CONFIG(pushbutton) #include "qpushbutton.h" +#endif #include "qpainterpath.h" #include "qpainter.h" #include "qstyle.h" @@ -55,10 +60,28 @@ #include "qapplication.h" #include "qdesktopwidget.h" #include "qbitmap.h" -#include "private/qlabel_p.h" QT_BEGIN_NAMESPACE +static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon) +{ + QStyle::StandardPixmap stdIcon = QStyle::SP_CustomBase; // silence gcc 4.9.0 about uninited variable + switch (icon) { + case QSystemTrayIcon::Information: + stdIcon = QStyle::SP_MessageBoxInformation; + break; + case QSystemTrayIcon::Warning: + stdIcon = QStyle::SP_MessageBoxWarning; + break; + case QSystemTrayIcon::Critical: + stdIcon = QStyle::SP_MessageBoxCritical; + break; + case QSystemTrayIcon::NoIcon: + return QIcon(); + } + return QApplication::style()->standardIcon(stdIcon); +} + /*! \class QSystemTrayIcon \brief The QSystemTrayIcon class provides an icon for an application in the system tray. @@ -382,11 +405,29 @@ bool QSystemTrayIcon::supportsMessages() \sa show(), supportsMessages() */ void QSystemTrayIcon::showMessage(const QString& title, const QString& msg, - QSystemTrayIcon::MessageIcon icon, int msecs) + QSystemTrayIcon::MessageIcon msgIcon, int msecs) +{ + Q_D(QSystemTrayIcon); + if (d->visible) + d->showMessage_sys(title, msg, messageIcon2qIcon(msgIcon), msgIcon, msecs); +} + +/*! + \fn void QSystemTrayIcon::showMessage(const QString &title, const QString &message, const QIcon &icon, int millisecondsTimeoutHint) + + \overload showMessage() + + Shows a balloon message for the entry with the given \a title, \a message, + and custom icon \a icon for the time specified in \a millisecondsTimeoutHint. + + \since 5.9 +*/ +void QSystemTrayIcon::showMessage(const QString &title, const QString &msg, + const QIcon &icon, int msecs) { Q_D(QSystemTrayIcon); if (d->visible) - d->showMessage_sys(title, msg, icon, msecs); + d->showMessage_sys(title, msg, icon, QSystemTrayIcon::NoIcon, msecs); } void QSystemTrayIconPrivate::_q_emitActivated(QPlatformSystemTrayIcon::ActivationReason reason) @@ -398,9 +439,9 @@ void QSystemTrayIconPrivate::_q_emitActivated(QPlatformSystemTrayIcon::Activatio ////////////////////////////////////////////////////////////////////// static QBalloonTip *theSolitaryBalloonTip = 0; -void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title, - const QString& message, QSystemTrayIcon *trayIcon, - const QPoint& pos, int timeout, bool showArrow) +void QBalloonTip::showBalloon(const QIcon &icon, const QString &title, + const QString &message, QSystemTrayIcon *trayIcon, + const QPoint &pos, int timeout, bool showArrow) { hideBalloon(); if (message.isEmpty() && title.isEmpty()) @@ -434,8 +475,8 @@ bool QBalloonTip::isBalloonVisible() return theSolitaryBalloonTip; } -QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title, - const QString& message, QSystemTrayIcon *ti) +QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title, + const QString &message, QSystemTrayIcon *ti) : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1), @@ -444,6 +485,7 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title setAttribute(Qt::WA_DeleteOnClose); QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close())); +#if QT_CONFIG(label) QLabel *titleLabel = new QLabel; titleLabel->installEventFilter(this); titleLabel->setText(title); @@ -451,17 +493,21 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title f.setBold(true); titleLabel->setFont(f); titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows +#endif const int iconSize = 18; const int closeButtonSize = 15; +#if QT_CONFIG(pushbutton) QPushButton *closeButton = new QPushButton; closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); closeButton->setIconSize(QSize(closeButtonSize, closeButtonSize)); closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); closeButton->setFixedSize(closeButtonSize, closeButtonSize); QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); +#endif +#if QT_CONFIG(label) QLabel *msgLabel = new QLabel; msgLabel->installEventFilter(this); msgLabel->setText(message); @@ -484,27 +530,13 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title // to emulate the weird standard windows behavior. msgLabel->setFixedSize(limit, msgLabel->heightForWidth(limit)); } - - QIcon si; - switch (icon) { - case QSystemTrayIcon::Warning: - si = style()->standardIcon(QStyle::SP_MessageBoxWarning); - break; - case QSystemTrayIcon::Critical: - si = style()->standardIcon(QStyle::SP_MessageBoxCritical); - break; - case QSystemTrayIcon::Information: - si = style()->standardIcon(QStyle::SP_MessageBoxInformation); - break; - case QSystemTrayIcon::NoIcon: - default: - break; - } +#endif QGridLayout *layout = new QGridLayout; - if (!si.isNull()) { +#if QT_CONFIG(label) + if (!icon.isNull()) { QLabel *iconLabel = new QLabel; - iconLabel->setPixmap(si.pixmap(iconSize, iconSize)); + iconLabel->setPixmap(icon.pixmap(iconSize, iconSize)); iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); iconLabel->setMargin(2); layout->addWidget(iconLabel, 0, 0); @@ -512,9 +544,15 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title } else { layout->addWidget(titleLabel, 0, 0, 1, 2); } +#endif +#if QT_CONFIG(pushbutton) layout->addWidget(closeButton, 0, 2); +#endif + +#if QT_CONFIG(label) layout->addWidget(msgLabel, 1, 0, 1, 3); +#endif layout->setSizeConstraint(QLayout::SetFixedSize); layout->setMargin(3); setLayout(layout); @@ -681,54 +719,6 @@ void QSystemTrayIconPrivate::remove_sys_qpa() qpa_sys->cleanup(); } -QRect QSystemTrayIconPrivate::geometry_sys_qpa() const -{ - return qpa_sys->geometry(); -} - -void QSystemTrayIconPrivate::updateIcon_sys_qpa() -{ - qpa_sys->updateIcon(icon); -} - -void QSystemTrayIconPrivate::updateMenu_sys_qpa() -{ -#if QT_CONFIG(menu) - if (menu) { - addPlatformMenu(menu); - qpa_sys->updateMenu(menu->platformMenu()); - } -#endif -} - -void QSystemTrayIconPrivate::updateToolTip_sys_qpa() -{ - qpa_sys->updateToolTip(toolTip); -} - -void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &title, - const QString &message, - QSystemTrayIcon::MessageIcon icon, - int msecs) -{ - QIcon notificationIcon; - switch (icon) { - case QSystemTrayIcon::Information: - notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); - break; - case QSystemTrayIcon::Warning: - notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); - break; - case QSystemTrayIcon::Critical: - notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); - break; - default: - break; - } - qpa_sys->showMessage(title, message, notificationIcon, - static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs); -} - void QSystemTrayIconPrivate::addPlatformMenu(QMenu *menu) const { #if QT_CONFIG(menu) diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h index fb238c92b0..918dd0478e 100644 --- a/src/widgets/util/qsystemtrayicon.h +++ b/src/widgets/util/qsystemtrayicon.h @@ -101,6 +101,7 @@ public Q_SLOTS: void setVisible(bool visible); inline void show() { setVisible(true); } inline void hide() { setVisible(false); } + void showMessage(const QString &title, const QString &msg, const QIcon &icon, int msecs = 10000); void showMessage(const QString &title, const QString &msg, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 10000); diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h index 79e824f4b7..3f5cab40be 100644 --- a/src/widgets/util/qsystemtrayicon_p.h +++ b/src/widgets/util/qsystemtrayicon_p.h @@ -84,7 +84,8 @@ public: void updateToolTip_sys(); void updateMenu_sys(); QRect geometry_sys() const; - void showMessage_sys(const QString &title, const QString &msg, QSystemTrayIcon::MessageIcon icon, int secs); + void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon, + QSystemTrayIcon::MessageIcon msgIcon, int msecs); static bool isSystemTrayAvailable_sys(); static bool supportsMessages_sys(); @@ -101,11 +102,7 @@ public: private: void install_sys_qpa(); void remove_sys_qpa(); - void updateIcon_sys_qpa(); - void updateToolTip_sys_qpa(); - void updateMenu_sys_qpa(); - QRect geometry_sys_qpa() const; - void showMessage_sys_qpa(const QString &title, const QString &msg, QSystemTrayIcon::MessageIcon icon, int secs); + void addPlatformMenu(QMenu *menu) const; }; @@ -113,16 +110,16 @@ class QBalloonTip : public QWidget { Q_OBJECT public: - static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title, - const QString& msg, QSystemTrayIcon *trayIcon, - const QPoint& pos, int timeout, bool showArrow = true); + static void showBalloon(const QIcon &icon, const QString &title, + const QString &msg, QSystemTrayIcon *trayIcon, + const QPoint &pos, int timeout, bool showArrow = true); static void hideBalloon(); static bool isBalloonVisible(); static void updateBalloonPosition(const QPoint& pos); private: - QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title, - const QString& msg, QSystemTrayIcon *trayIcon); + QBalloonTip(const QIcon &icon, const QString &title, + const QString &msg, QSystemTrayIcon *trayIcon); ~QBalloonTip(); void balloon(const QPoint&, int, bool); diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp index 643f17a5fe..c0bf058681 100644 --- a/src/widgets/util/qsystemtrayicon_qpa.cpp +++ b/src/widgets/util/qsystemtrayicon_qpa.cpp @@ -76,7 +76,7 @@ void QSystemTrayIconPrivate::remove_sys() QRect QSystemTrayIconPrivate::geometry_sys() const { if (qpa_sys) - return geometry_sys_qpa(); + return qpa_sys->geometry(); else return QRect(); } @@ -84,19 +84,23 @@ QRect QSystemTrayIconPrivate::geometry_sys() const void QSystemTrayIconPrivate::updateIcon_sys() { if (qpa_sys) - updateIcon_sys_qpa(); + qpa_sys->updateIcon(icon); } void QSystemTrayIconPrivate::updateMenu_sys() { - if (qpa_sys) - updateMenu_sys_qpa(); +#if QT_CONFIG(menu) + if (qpa_sys && menu) { + addPlatformMenu(menu); + qpa_sys->updateMenu(menu->platformMenu()); + } +#endif } void QSystemTrayIconPrivate::updateToolTip_sys() { if (qpa_sys) - updateToolTip_sys_qpa(); + qpa_sys->updateToolTip(toolTip); } bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() @@ -118,10 +122,11 @@ bool QSystemTrayIconPrivate::supportsMessages_sys() } void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, - QSystemTrayIcon::MessageIcon icon, int msecs) + const QIcon &icon, QSystemTrayIcon::MessageIcon msgIcon, int msecs) { if (qpa_sys) - showMessage_sys_qpa(title, message, icon, msecs); + qpa_sys->showMessage(title, message, icon, + static_cast<QPlatformSystemTrayIcon::MessageIcon>(msgIcon), msecs); } QT_END_NAMESPACE diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index 2da24e482b..d110cb8be4 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -81,11 +81,14 @@ struct Q_NOTIFYICONIDENTIFIER { # define NIN_BALLOONTIMEOUT (WM_USER + 4) # define NIN_BALLOONUSERCLICK (WM_USER + 5) # define NIF_SHOWTIP 0x00000080 +# define NIIF_LARGE_ICON 0x00000020 # define NOTIFYICON_VERSION_4 4 #endif #define Q_MSGFLT_ALLOW 1 +Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); + typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation); typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag); typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct); @@ -107,7 +110,7 @@ public: ~QSystemTrayIconSys(); bool trayMessage(DWORD msg); void setIconContents(NOTIFYICONDATA &data); - bool showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs); + bool showMessage(const QString &title, const QString &message, const QIcon &icon, uint uSecs); QRect findIconGeometry(UINT iconId); HICON createIcon(); bool winEvent(MSG *m, long *result); @@ -184,7 +187,7 @@ static inline HWND createTrayIconMessageWindow() QSystemTrayIconSys::QSystemTrayIconSys(HWND hwnd, QSystemTrayIcon *object) : m_hwnd(hwnd), hIcon(0), q(object) - , notifyIconSize(NOTIFYICONDATA_V2_SIZE), version(NOTIFYICON_VERSION) + , notifyIconSize(sizeof(NOTIFYICONDATA)), version(NOTIFYICON_VERSION_4) , ignoreNextMouseRelease(false) { @@ -237,11 +240,7 @@ void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd) qStringToLimitedWCharArray(tip, tnd.szTip, sizeof(tnd.szTip)/sizeof(wchar_t)); } -#ifndef NIIF_LARGE_ICON -# define NIIF_LARGE_ICON 0x00000020 -#endif - -bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs) +bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, const QIcon &icon, uint uSecs) { NOTIFYICONDATA tnd; memset(&tnd, 0, notifyIconSize); @@ -249,23 +248,32 @@ bool QSystemTrayIconSys::showMessage(const QString &title, const QString &messag qStringToLimitedWCharArray(title, tnd.szInfoTitle, 64); tnd.uID = q_uNOTIFYICONID; - switch (type) { - case QSystemTrayIcon::Information: + tnd.dwInfoFlags = NIIF_USER; + + HICON *phIcon = &tnd.hIcon; + QSize size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); + if (version == NOTIFYICON_VERSION_4) { + const QSize largeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); + QSize more = icon.actualSize(largeIcon); + if (more.height() > (largeIcon.height() * 3/4) || more.width() > (largeIcon.width() * 3/4)) { + tnd.dwInfoFlags |= NIIF_LARGE_ICON; + size = largeIcon; + } + phIcon = &tnd.hBalloonIcon; + } + QPixmap pm = icon.pixmap(size); + if (pm.isNull()) { tnd.dwInfoFlags = NIIF_INFO; - break; - case QSystemTrayIcon::Warning: - tnd.dwInfoFlags = NIIF_WARNING; - break; - case QSystemTrayIcon::Critical: - tnd.dwInfoFlags = NIIF_ERROR; - break; - case QSystemTrayIcon::NoIcon: - tnd.dwInfoFlags = hIcon ? NIIF_USER : NIIF_NONE; - break; + } else { + if (pm.size() != size) { + qWarning("QSystemTrayIcon::showMessage: Wrong icon size (%dx%d), please add standard one: %dx%d", + pm.size().width(), pm.size().height(), size.width(), size.height()); + pm = pm.scaled(size, Qt::IgnoreAspectRatio); + } + *phIcon = qt_pixmapToWinHICON(pm); } - if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) - tnd.dwInfoFlags |= NIIF_LARGE_ICON; tnd.cbSize = notifyIconSize; + tnd.uVersion = version; tnd.hWnd = m_hwnd; tnd.uTimeout = uSecs; tnd.uFlags = NIF_INFO | NIF_SHOWTIP; @@ -296,8 +304,6 @@ bool QSystemTrayIconSys::trayMessage(DWORD msg) return success; } -Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); - HICON QSystemTrayIconSys::createIcon() { const HICON oldIcon = hIcon; @@ -509,7 +515,8 @@ QRect QSystemTrayIconSys::findIconGeometry(UINT iconId) void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &messageIn, - QSystemTrayIcon::MessageIcon type, + const QIcon &icon, + QSystemTrayIcon::MessageIcon, int timeOut) { if (!sys || !allowsMessages()) @@ -522,7 +529,7 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &title, if (message.isEmpty() && !title.isEmpty()) message.append(QLatin1Char(' ')); - sys->showMessage(title, message, type, uSecs); + sys->showMessage(title, message, icon, uSecs); } QRect QSystemTrayIconPrivate::geometry_sys() const @@ -557,7 +564,8 @@ void QSystemTrayIconPrivate::updateIcon_sys() void QSystemTrayIconPrivate::updateMenu_sys() { - +#if QT_CONFIG(menu) +#endif } void QSystemTrayIconPrivate::updateToolTip_sys() diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 0bde31fd61..cbd5d9eb80 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -37,7 +37,10 @@ ** ****************************************************************************/ +#include "qtwidgetsglobal.h" +#if QT_CONFIG(label) #include "qlabel.h" +#endif #include "qpainter.h" #include "qpixmap.h" #include "qbitmap.h" @@ -286,7 +289,7 @@ void QSystemTrayIconPrivate::install_sys() QRect QSystemTrayIconPrivate::geometry_sys() const { if (qpa_sys) - return geometry_sys_qpa(); + return qpa_sys->geometry(); if (!sys) return QRect(); return sys->globalGeometry(); @@ -309,7 +312,7 @@ void QSystemTrayIconPrivate::remove_sys() void QSystemTrayIconPrivate::updateIcon_sys() { if (qpa_sys) { - updateIcon_sys_qpa(); + qpa_sys->updateIcon(icon); return; } if (sys) @@ -318,14 +321,18 @@ void QSystemTrayIconPrivate::updateIcon_sys() void QSystemTrayIconPrivate::updateMenu_sys() { - if (qpa_sys) - updateMenu_sys_qpa(); +#if QT_CONFIG(menu) + if (qpa_sys && menu) { + addPlatformMenu(menu); + qpa_sys->updateMenu(menu->platformMenu()); + } +#endif } void QSystemTrayIconPrivate::updateToolTip_sys() { if (qpa_sys) { - updateToolTip_sys_qpa(); + qpa_sys->updateToolTip(toolTip); return; } if (!sys) @@ -359,10 +366,11 @@ bool QSystemTrayIconPrivate::supportsMessages_sys() } void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, - QSystemTrayIcon::MessageIcon icon, int msecs) + const QIcon &icon, QSystemTrayIcon::MessageIcon msgIcon, int msecs) { if (qpa_sys) { - showMessage_sys_qpa(title, message, icon, msecs); + qpa_sys->showMessage(title, message, icon, + static_cast<QPlatformSystemTrayIcon::MessageIcon>(msgIcon), msecs); return; } if (!sys) diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 033d4e9e05..dc0b6855ac 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -145,6 +145,36 @@ QUndoCommand::~QUndoCommand() } /*! + \since 5.9 + + Returns whether the command is obsolete. + + The boolean is used for the automatic removal of commands that are not necessary in the + stack anymore. The isObsolete function is checked in the functions QUndoStack::push(), + QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex(). + + \sa setObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo() +*/ + +bool QUndoCommand::isObsolete() const +{ + return d->obsolete; +} + +/*! + \since 5.9 + + Sets whether the command is obsolete to \a obsolete. + + \sa isObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo() +*/ + +void QUndoCommand::setObsolete(bool obsolete) +{ + d->obsolete = obsolete; +} + +/*! Returns the ID of this command. A command ID is used in command compression. It must be an integer unique to @@ -390,6 +420,28 @@ const QUndoCommand *QUndoCommand::child(int index) const and to update the document's title to reflect that it contains unsaved changes. + \section1 Obsolete Commands + + QUndoStack is able to delete commands from the stack if the command is no + longer needed. One example may be to delete a command when two commands are + merged together in such a way that the merged command has no function. This + can be seen with move commands where the user moves their mouse to one part + of the screen and then moves it to the original position. The merged command + results in a mouse movement of 0. This command can be deleted since it serves + no purpose. Another example is with networking commands that fail due to connection + issues. In this case, the command is to be removed from the stack because the redo() + and undo() functions have no function since there was connection issues. + + A command can be marked obsolete with the QUndoCommand::setObsolete() function. + The QUndoCommand::isObsolete() flag is checked in QUndoStack::push(), + QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex() after calling + QUndoCommand::undo(), QUndoCommand::redo() and QUndoCommand:mergeWith() where + applicable. + + If a command is set obsolete and the clean index is greater than or equal to the + current command index, then the clean index will be reset when the command is + deleted from the stack. + \sa QUndoCommand, QUndoView */ @@ -563,6 +615,11 @@ void QUndoStack::clear() commands by calling QUndoCommand::mergeWith() on the most recently executed command. If QUndoCommand::mergeWith() returns \c true, \a cmd is deleted. + After calling QUndoCommand::redo() and, if applicable, QUndoCommand::mergeWith(), + QUndoCommand::isObsolete() will be called for \a cmd or the merged command. + If QUndoCommand::isObsolete() returns \c true, then \a cmd or the merged command + will be deleted from the stack. + In all other cases \a cmd is simply pushed on the stack. If commands were undone before \a cmd was pushed, the current command and @@ -580,7 +637,8 @@ void QUndoStack::clear() void QUndoStack::push(QUndoCommand *cmd) { Q_D(QUndoStack); - cmd->redo(); + if (!cmd->isObsolete()) + cmd->redo(); bool macro = !d->macro_stack.isEmpty(); @@ -605,13 +663,25 @@ void QUndoStack::push(QUndoCommand *cmd) if (try_merge && cur->mergeWith(cmd)) { delete cmd; - if (!macro) { - emit indexChanged(d->index); - emit canUndoChanged(canUndo()); - emit undoTextChanged(undoText()); - emit canRedoChanged(canRedo()); - emit redoTextChanged(redoText()); + + if (macro) { + if (cur->isObsolete()) + delete d->macro_stack.constLast()->d->child_list.takeLast(); + } else { + if (cur->isObsolete()) { + delete d->command_list.takeLast(); + + d->setIndex(d->index - 1, false); + } else { + emit indexChanged(d->index); + emit canUndoChanged(canUndo()); + emit undoTextChanged(undoText()); + emit canRedoChanged(canRedo()); + emit redoTextChanged(redoText()); + } } + } else if (cmd->isObsolete()) { + delete cmd; // command should be deleted and NOT added to the stack } else { if (macro) { d->macro_stack.constLast()->d->child_list.append(cmd); @@ -712,6 +782,11 @@ int QUndoStack::cleanIndex() const If the stack is empty, or if the bottom command on the stack has already been undone, this function does nothing. + After the command is undone, if QUndoCommand::isObsolete() returns \c true, + then the command will be deleted from the stack. Additionally, if the clean + index is greater than or equal to the current command index, then the clean + index is reset. + \sa redo(), index() */ @@ -727,7 +802,18 @@ void QUndoStack::undo() } int idx = d->index - 1; - d->command_list.at(idx)->undo(); + QUndoCommand *cmd = d->command_list.at(idx); + + if (!cmd->isObsolete()) + cmd->undo(); + + if (cmd->isObsolete()) { // A separate check is done b/c the undo command may set obsolete flag + delete d->command_list.takeAt(idx); + + if (d->clean_index > idx) + resetClean(); + } + d->setIndex(idx, false); } @@ -738,6 +824,11 @@ void QUndoStack::undo() If the stack is empty, or if the top command on the stack has already been redone, this function does nothing. + If QUndoCommand::isObsolete() returns true for the current command, then + the command will be deleted from the stack. Additionally, if the clean + index is greater than or equal to the current command index, then the clean + index is reset. + \sa undo(), index() */ @@ -752,8 +843,20 @@ void QUndoStack::redo() return; } - d->command_list.at(d->index)->redo(); - d->setIndex(d->index + 1, false); + int idx = d->index; + QUndoCommand *cmd = d->command_list.at(idx); + + if (!cmd->isObsolete()) + cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag + + if (cmd->isObsolete()) { + delete d->command_list.takeAt(idx); + + if (d->clean_index > idx) + resetClean(); + } else { + d->setIndex(d->index + 1, false); + } } /*! @@ -805,10 +908,35 @@ void QUndoStack::setIndex(int idx) idx = d->command_list.size(); int i = d->index; - while (i < idx) - d->command_list.at(i++)->redo(); - while (i > idx) - d->command_list.at(--i)->undo(); + while (i < idx) { + QUndoCommand *cmd = d->command_list.at(i); + + if (!cmd->isObsolete()) + cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag + + if (cmd->isObsolete()) { + delete d->command_list.takeAt(i); + + if (d->clean_index > i) + resetClean(); + + idx--; // Subtract from idx because we removed a command + } else { + i++; + } + } + + while (i > idx) { + QUndoCommand *cmd = d->command_list.at(--i); + + cmd->undo(); + if (cmd->isObsolete()) { + delete d->command_list.takeAt(i); + + if (d->clean_index > i) + resetClean(); + } + } d->setIndex(idx, false); } diff --git a/src/widgets/util/qundostack.h b/src/widgets/util/qundostack.h index ca918b0618..2a8f4decb6 100644 --- a/src/widgets/util/qundostack.h +++ b/src/widgets/util/qundostack.h @@ -69,6 +69,9 @@ public: QString actionText() const; void setText(const QString &text); + bool isObsolete() const; + void setObsolete(bool obsolete); + virtual int id() const; virtual bool mergeWith(const QUndoCommand *other); diff --git a/src/widgets/util/qundostack_p.h b/src/widgets/util/qundostack_p.h index 1bfe992426..e92a1fe620 100644 --- a/src/widgets/util/qundostack_p.h +++ b/src/widgets/util/qundostack_p.h @@ -66,11 +66,12 @@ class QUndoGroup; class QUndoCommandPrivate { public: - QUndoCommandPrivate() : id(-1) {} + QUndoCommandPrivate() : id(-1), obsolete(false) {} QList<QUndoCommand*> child_list; QString text; QString actionText; int id; + bool obsolete; }; #ifndef QT_NO_UNDOSTACK diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri index cb19c1fc95..b9b62d9bb0 100644 --- a/src/widgets/util/util.pri +++ b/src/widgets/util/util.pri @@ -6,11 +6,6 @@ HEADERS += \ util/qcompleter.h \ util/qcompleter_p.h \ util/qsystemtrayicon_p.h \ - util/qscroller.h \ - util/qscroller_p.h \ - util/qscrollerproperties.h \ - util/qscrollerproperties_p.h \ - util/qflickgesture_p.h \ util/qundogroup.h \ util/qundostack.h \ util/qundostack_p.h \ @@ -20,13 +15,24 @@ SOURCES += \ util/qsystemtrayicon.cpp \ util/qcolormap.cpp \ util/qcompleter.cpp \ - util/qscroller.cpp \ - util/qscrollerproperties.cpp \ - util/qflickgesture.cpp \ util/qundogroup.cpp \ util/qundostack.cpp \ util/qundoview.cpp +qtConfig(scroller) { + HEADERS += \ + util/qscroller.h \ + util/qscroller_p.h \ + util/qscrollerproperties.h \ + util/qscrollerproperties_p.h \ + util/qflickgesture_p.h + + SOURCES += \ + util/qscroller.cpp \ + util/qscrollerproperties.cpp \ + util/qflickgesture.cpp \ +} + win32:!winrt { SOURCES += util/qsystemtrayicon_win.cpp } else: qtConfig(xcb) { diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 5d3a054922..abdd946c49 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -637,7 +637,6 @@ QWidget *QAbstractScrollArea::viewport() const Returns the size of the viewport as if the scroll bars had no valid scrolling range. */ -// ### still thinking about the name QSize QAbstractScrollArea::maximumViewportSize() const { Q_D(const QAbstractScrollArea); diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index cc6a407bf8..0ea9250695 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -303,9 +303,7 @@ void QAbstractSlider::setOrientation(Qt::Orientation orientation) d->orientation = orientation; if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) { - QSizePolicy sp = sizePolicy(); - sp.transpose(); - setSizePolicy(sp); + setSizePolicy(sizePolicy().transposed()); setAttribute(Qt::WA_WState_OwnSizePolicy, false); } update(); diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h index 86d6830f10..8979685724 100644 --- a/src/widgets/widgets/qabstractslider.h +++ b/src/widgets/widgets/qabstractslider.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qwidget.h> +QT_REQUIRE_CONFIG(abstractslider); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qabstractslider_p.h b/src/widgets/widgets/qabstractslider_p.h index 600616061a..419ce2ba07 100644 --- a/src/widgets/widgets/qabstractslider_p.h +++ b/src/widgets/widgets/qabstractslider_p.h @@ -57,6 +57,8 @@ #include "private/qwidget_p.h" #include "qstyle.h" +QT_REQUIRE_CONFIG(abstractslider); + QT_BEGIN_NAMESPACE class QAbstractSliderPrivate : public QWidgetPrivate diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 8ccad5c35d..7ee53587e6 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -694,6 +694,10 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) this, SLOT(_q_editorTextChanged(QString))); connect(d->edit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(_q_editorCursorPositionChanged(int,int))); + connect(d->edit, SIGNAL(cursorPositionChanged(int,int)), + this, SLOT(updateMicroFocus())); + connect(d->edit->d_func()->control, SIGNAL(updateMicroFocus()), + this, SLOT(updateMicroFocus())); } d->updateEditFieldGeometry(); d->edit->setContextMenuPolicy(Qt::NoContextMenu); @@ -2114,8 +2118,8 @@ int QAbstractSpinBoxPrivate::variantCompare(const QVariant &arg1, const QVariant default: Q_ASSERT_X(0, "QAbstractSpinBoxPrivate::variantCompare", qPrintable(QString::fromLatin1("Internal error 3 (%1 %2)"). - arg(QString::fromLatin1(arg1.typeName())). - arg(QString::fromLatin1(arg2.typeName())))); + arg(QString::fromLatin1(arg1.typeName()), + QString::fromLatin1(arg2.typeName())))); } return -2; } diff --git a/src/widgets/widgets/qbuttongroup_p.h b/src/widgets/widgets/qbuttongroup_p.h index b94dd170b4..93f3f4e0ec 100644 --- a/src/widgets/widgets/qbuttongroup_p.h +++ b/src/widgets/widgets/qbuttongroup_p.h @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index b0ded70c4a..f81377a85c 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -765,13 +765,15 @@ bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e) if (m_widget) { if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) { QKeyEvent* ke = (QKeyEvent*)e; - if ((ke->text().length() > 0 && ke->text()[0].isPrint()) || m_dateFrame) { + if ((ke->text().length() > 0 && ke->text().at(0).isPrint()) || m_dateFrame) { if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Select) { applyDate(); emit editingFinished(); removeDateLabel(); +#if QT_CONFIG(shortcut) } else if (ke->matches(QKeySequence::Cancel)) { removeDateLabel(); +#endif } else if (e->type() == QEvent::KeyPress) { createDateLabel(); m_dateValidator->handleKeyEvent(ke); @@ -3107,12 +3109,14 @@ void QCalendarWidget::resizeEvent(QResizeEvent * event) */ void QCalendarWidget::keyPressEvent(QKeyEvent * event) { +#if QT_CONFIG(shortcut) Q_D(QCalendarWidget); if (d->yearEdit->isVisible()&& event->matches(QKeySequence::Cancel)) { d->yearEdit->setValue(yearShown()); d->_q_yearEditingFinished(); return; } +#endif QWidget::keyPressEvent(event); } diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h index 22f26b6667..8543c4c86f 100644 --- a/src/widgets/widgets/qcheckbox.h +++ b/src/widgets/widgets/qcheckbox.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractbutton.h> +QT_REQUIRE_CONFIG(checkbox); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 4519265fb8..b18066c174 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -65,6 +65,7 @@ #include <private/qcombobox_p.h> #include <private/qabstractitemmodel_p.h> #include <private/qabstractscrollarea_p.h> +#include <private/qlineedit_p.h> #include <qdebug.h> #if 0 /* Used to be included in Qt4 for Q_WS_MAC */ && !defined(QT_NO_EFFECTS) && QT_CONFIG(style_mac) #include <private/qcore_mac_p.h> @@ -681,10 +682,12 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) combo->hidePopup(); return true; default: +#if QT_CONFIG(shortcut) if (keyEvent->matches(QKeySequence::Cancel)) { combo->hidePopup(); return true; } +#endif break; } break; @@ -1790,6 +1793,7 @@ void QComboBox::setLineEdit(QLineEdit *edit) connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString))); connect(d->lineEdit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateMicroFocus())); connect(d->lineEdit, SIGNAL(selectionChanged()), this, SLOT(updateMicroFocus())); + connect(d->lineEdit->d_func()->control, SIGNAL(updateMicroFocus()), this, SLOT(updateMicroFocus())); d->lineEdit->setFrame(false); d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu); d->updateFocusPolicy(); diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h index 4f81651ce4..d8215a256e 100644 --- a/src/widgets/widgets/qcommandlinkbutton.h +++ b/src/widgets/widgets/qcommandlinkbutton.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qpushbutton.h> +QT_REQUIRE_CONFIG(commandlinkbutton); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index c5eab55a53..cebfb9316a 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2662,11 +2662,13 @@ void QCalendarPopup::mouseReleaseEvent(QMouseEvent*) bool QCalendarPopup::event(QEvent *event) { +#if QT_CONFIG(shortcut) if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); if (keyEvent->matches(QKeySequence::Cancel)) dateChanged = false; } +#endif return QWidget::event(event); } diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h index 5c9f4e0f9d..b54b0e7cf0 100644 --- a/src/widgets/widgets/qdatetimeedit.h +++ b/src/widgets/widgets/qdatetimeedit.h @@ -58,7 +58,6 @@ class Q_WIDGETS_EXPORT QDateTimeEdit : public QAbstractSpinBox { Q_OBJECT - Q_FLAGS(Sections) Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged USER true) Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged) Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged) @@ -92,6 +91,7 @@ public: Q_ENUM(Section) Q_DECLARE_FLAGS(Sections, Section) + Q_FLAG(Sections) explicit QDateTimeEdit(QWidget *parent = Q_NULLPTR); explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = Q_NULLPTR); diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index 730aa0f0b2..5302d6d9a7 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -57,7 +57,6 @@ #include "QtWidgets/qspinbox.h" #include "QtWidgets/qtoolbutton.h" #include "QtWidgets/qmenu.h" -#include "QtWidgets/qlabel.h" #include "QtWidgets/qdatetimeedit.h" #include "private/qabstractspinbox_p.h" #include "private/qdatetimeparser_p.h" diff --git a/src/widgets/widgets/qdial.h b/src/widgets/widgets/qdial.h index 3629ebf8f6..472b14fcdb 100644 --- a/src/widgets/widgets/qdial.h +++ b/src/widgets/widgets/qdial.h @@ -42,13 +42,14 @@ #define QDIAL_H #include <QtWidgets/qtwidgetsglobal.h> + +#if QT_CONFIG(dial) + #include <QtWidgets/qabstractslider.h> QT_BEGIN_NAMESPACE -#ifndef QT_NO_DIAL - class QDialPrivate; class QStyleOptionSlider; @@ -98,8 +99,8 @@ private: Q_DISABLE_COPY(QDial) }; -#endif // QT_NO_DIAL - QT_END_NAMESPACE +#endif // QT_CONFIG(dial) + #endif // QDIAL_H diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 984669f29a..a3e55114bb 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -410,14 +410,9 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); else addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), doLayout); - -#if 0 // Used to be included in Qt4 for Q_WS_MAC - // Since mnemonics is off by default on Mac, we add a Cmd-D - // shortcut here to e.g. make the "Don't Save" button work nativly: - if (sbutton == QDialogButtonBox::Discard) - button->setShortcut(QKeySequence(QLatin1String("Ctrl+D"))); +#if QT_CONFIG(shortcut) + button->setShortcut(QGuiApplicationPrivate::platformTheme()->standardButtonShortcut(sbutton)); #endif - return button; } diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h index 699547c32f..af9e705234 100644 --- a/src/widgets/widgets/qdialogbuttonbox.h +++ b/src/widgets/widgets/qdialogbuttonbox.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qwidget.h> +QT_REQUIRE_CONFIG(dialogbuttonbox); + QT_BEGIN_NAMESPACE @@ -53,7 +55,6 @@ class QDialogButtonBoxPrivate; class Q_WIDGETS_EXPORT QDialogButtonBox : public QWidget { Q_OBJECT - Q_FLAGS(StandardButtons) Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons) Q_PROPERTY(bool centerButtons READ centerButtons WRITE setCenterButtons) @@ -104,6 +105,7 @@ public: }; Q_DECLARE_FLAGS(StandardButtons, StandardButton) + Q_FLAG(StandardButtons) enum ButtonLayout { // keep this in sync with QMessageBox::ButtonLayout and QPlatformDialogHelper::ButtonLayout diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 8d9280ebb5..37ea7dadbc 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2605,12 +2605,16 @@ bool QDockAreaLayout::insertGap(const QList<int> &path, QLayoutItem *dockWidgetI QLayoutItem *QDockAreaLayout::plug(const QList<int> &path) { +#if QT_CONFIG(tabbar) Q_ASSERT(!path.isEmpty()); const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); QLayoutItem *item = docks[index].plug(path.mid(1)); docks[index].reparentWidgets(mainWindow); return item; +#else + return nullptr; +#endif } QLayoutItem *QDockAreaLayout::unplug(const QList<int> &path) diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index f51e3c7988..307a261a43 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -930,7 +930,9 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) } if (state->dragging && !state->nca) { - QPoint pos = event->globalPos() - state->pressPos; + QMargins windowMargins = q->window()->windowHandle()->frameMargins(); + QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top()); + QPoint pos = event->globalPos() - state->pressPos - windowMarginOffset; QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); if (floatingTab && !q->isFloating()) diff --git a/src/widgets/widgets/qdockwidget.h b/src/widgets/widgets/qdockwidget.h index 7b3f8d0ddb..80df009007 100644 --- a/src/widgets/widgets/qdockwidget.h +++ b/src/widgets/widgets/qdockwidget.h @@ -57,7 +57,6 @@ class Q_WIDGETS_EXPORT QDockWidget : public QWidget { Q_OBJECT - Q_FLAGS(DockWidgetFeatures) Q_PROPERTY(bool floating READ isFloating WRITE setFloating) Q_PROPERTY(DockWidgetFeatures features READ features WRITE setFeatures NOTIFY featuresChanged) Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas @@ -86,6 +85,7 @@ public: Reserved = 0xff }; Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature) + Q_FLAG(DockWidgetFeatures) void setFeatures(DockWidgetFeatures features); DockWidgetFeatures features() const; diff --git a/src/widgets/widgets/qfontcombobox.h b/src/widgets/widgets/qfontcombobox.h index c409d33fef..983d5224dd 100644 --- a/src/widgets/widgets/qfontcombobox.h +++ b/src/widgets/widgets/qfontcombobox.h @@ -54,7 +54,6 @@ class QFontComboBoxPrivate; class Q_WIDGETS_EXPORT QFontComboBox : public QComboBox { Q_OBJECT - Q_FLAGS(FontFilters) Q_PROPERTY(QFontDatabase::WritingSystem writingSystem READ writingSystem WRITE setWritingSystem) Q_PROPERTY(FontFilters fontFilters READ fontFilters WRITE setFontFilters) Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged) @@ -74,6 +73,7 @@ public: ProportionalFonts = 0x8 }; Q_DECLARE_FLAGS(FontFilters, FontFilter) + Q_FLAG(FontFilters) void setFontFilters(FontFilters filters); FontFilters fontFilters() const; diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp index a9b32ae065..fda68879d1 100644 --- a/src/widgets/widgets/qgroupbox.cpp +++ b/src/widgets/widgets/qgroupbox.cpp @@ -44,7 +44,9 @@ #include "qdrawutil.h" #include "qevent.h" #include "qlayout.h" +#if QT_CONFIG(radiobutton) #include "qradiobutton.h" +#endif #include "qstyle.h" #include "qstyleoption.h" #include "qstylepainter.h" @@ -430,11 +432,13 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason) QWidget * w = q; while ((w = w->nextInFocusChain()) != q) { if (q->isAncestorOf(w) && (w->focusPolicy() & Qt::TabFocus) == Qt::TabFocus && w->isVisibleTo(q)) { +#if QT_CONFIG(radiobutton) if (!best && qobject_cast<QRadioButton*>(w) && ((QRadioButton*)w)->isChecked()) // we prefer a checked radio button or a widget that // already has focus, if there is one best = w; else +#endif if (!candidate) // but we'll accept anything that takes focus candidate = w; diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index 1f76937a63..3978e34d14 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qframe.h> +QT_REQUIRE_CONFIG(label); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index e5e832ab98..0a35bae200 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -437,6 +437,7 @@ bool QLineEdit::hasFrame() const \since 5.2 */ +#if QT_CONFIG(action) /*! \overload @@ -466,7 +467,7 @@ QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position) addAction(result, position); return result; } - +#endif // QT_CONFIG(action) /*! \property QLineEdit::clearButtonEnabled \brief Whether the line edit displays a clear button when it is not empty. @@ -483,6 +484,7 @@ static const char clearButtonActionNameC[] = "_q_qlineeditclearaction"; void QLineEdit::setClearButtonEnabled(bool enable) { +#if QT_CONFIG(action) Q_D(QLineEdit); if (enable == isClearButtonEnabled()) return; @@ -497,11 +499,16 @@ void QLineEdit::setClearButtonEnabled(bool enable) d->removeAction(clearAction); delete clearAction; } +#endif // QT_CONFIG(action) } bool QLineEdit::isClearButtonEnabled() const { +#if QT_CONFIG(action) return findChild<QAction *>(QLatin1String(clearButtonActionNameC)); +#else + return false; +#endif } void QLineEdit::setFrame(bool enable) @@ -737,10 +744,10 @@ void QLineEdit::setCursorPosition(int pos) d->control->setCursorPosition(pos); } +// ### What should this do if the point is outside of contentsRect? Currently returns 0. /*! Returns the cursor position under the point \a pos. */ -// ### What should this do if the point is outside of contentsRect? Currently returns 0. int QLineEdit::cursorPositionAt(const QPoint &pos) { Q_D(QLineEdit); @@ -1432,8 +1439,10 @@ bool QLineEdit::event(QEvent * e) || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this)) d->setCursorVisible(true); } +#if QT_CONFIG(action) } else if (e->type() == QEvent::ActionRemoved) { d->removeAction(static_cast<QActionEvent *>(e)->action()); +#endif } else if (e->type() == QEvent::Resize) { d->positionSideWidgets(); } diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index 1bdcfaf848..4d32b11f06 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -174,9 +174,11 @@ public: void getTextMargins(int *left, int *top, int *right, int *bottom) const; QMargins textMargins() const; +#if QT_CONFIG(action) using QWidget::addAction; void addAction(QAction *action, ActionPosition position); QAction *addAction(const QIcon &icon, ActionPosition position); +#endif public Q_SLOTS: void setText(const QString &); @@ -239,6 +241,7 @@ public: private: friend class QAbstractSpinBox; friend class QAccessibleLineEdit; + friend class QComboBox; #ifdef QT_KEYPAD_NAVIGATION friend class QDateTimeEdit; #endif diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 9947d63279..1d81d1fcb5 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -196,6 +196,9 @@ void QLineEditPrivate::init(const QString& txt) QObject::connect(control, SIGNAL(textChanged(QString)), q, SLOT(updateMicroFocus())); + QObject::connect(control, SIGNAL(updateMicroFocus()), + q, SLOT(updateMicroFocus())); + // for now, going completely overboard with updates. QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(update())); @@ -445,12 +448,14 @@ QIcon QLineEditPrivate::clearButtonIcon() const void QLineEditPrivate::setClearButtonEnabled(bool enabled) { +#if QT_CONFIG(action) for (const SideWidgetEntry &e : trailingSideWidgets) { if (e.flags & SideWidgetClearButton) { e.action->setEnabled(enabled); break; } } +#endif } void QLineEditPrivate::positionSideWidgets() @@ -464,33 +469,37 @@ void QLineEditPrivate::positionSideWidgets() QSize(p.widgetWidth, p.widgetHeight)); for (const SideWidgetEntry &e : leftSideWidgetList()) { e.widget->setGeometry(widgetGeometry); +#if QT_CONFIG(action) if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); +#endif } widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin); for (const SideWidgetEntry &e : rightSideWidgetList()) { e.widget->setGeometry(widgetGeometry); +#if QT_CONFIG(action) if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() - delta); +#endif } } } -QLineEditPrivate::PositionIndexPair QLineEditPrivate::findSideWidget(const QAction *a) const +QLineEditPrivate::SideWidgetLocation QLineEditPrivate::findSideWidget(const QAction *a) const { int i = 0; for (const auto &e : leadingSideWidgets) { if (a == e.action) - return PositionIndexPair(QLineEdit::LeadingPosition, i); + return {QLineEdit::LeadingPosition, i}; ++i; } i = 0; for (const auto &e : trailingSideWidgets) { if (a == e.action) - return PositionIndexPair(QLineEdit::TrailingPosition, i); + return {QLineEdit::TrailingPosition, i}; ++i; } - return PositionIndexPair(QLineEdit::LeadingPosition, -1); + return {QLineEdit::LeadingPosition, -1}; } QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition position, int flags) @@ -505,10 +514,12 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE QWidget *w = 0; // Store flags about QWidgetAction here since removeAction() may be called from ~QAction, // in which a qobject_cast<> no longer works. +#if QT_CONFIG(action) if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(newAction)) { if ((w = widgetAction->requestWidget(q))) flags |= SideWidgetCreatedByWidgetAction; } +#endif if (!w) { #if QT_CONFIG(toolbutton) QLineEditIconButton *toolButton = new QLineEditIconButton(q); @@ -523,11 +534,10 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE #endif } // If there is a 'before' action, it takes preference - PositionIndexPair positionIndex = before ? findSideWidget(before) : PositionIndexPair(position, -1); - SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets; - if (positionIndex.second < 0) - positionIndex.second = int(list.size()); - list.insert(list.begin() + positionIndex.second, SideWidgetEntry(w, newAction, flags)); + const auto location = before ? findSideWidget(before) : SideWidgetLocation{position, -1}; + SideWidgetEntryList &list = location.position == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets; + list.insert(location.isValid() ? list.begin() + location.index : list.end(), + SideWidgetEntry(w, newAction, flags)); positionSideWidgets(); w->show(); return w; @@ -535,13 +545,14 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE void QLineEditPrivate::removeAction(QAction *action) { +#if QT_CONFIG(action) Q_Q(QLineEdit); - const PositionIndexPair positionIndex = findSideWidget(action); - if (positionIndex.second == -1) + const auto location = findSideWidget(action); + if (!location.isValid()) return; - SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets; - SideWidgetEntry entry = list[positionIndex.second]; - list.erase(list.begin() + positionIndex.second); + SideWidgetEntryList &list = location.position == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets; + SideWidgetEntry entry = list[location.index]; + list.erase(list.begin() + location.index); if (entry.flags & SideWidgetCreatedByWidgetAction) static_cast<QWidgetAction *>(entry.action)->releaseWidget(entry.widget); else @@ -550,6 +561,7 @@ void QLineEditPrivate::removeAction(QAction *action) if (!hasSideWidgets()) // Last widget, remove connection QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); q->update(); +#endif // QT_CONFIG(action) } static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e) diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index a903c003e6..2d695f8411 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -235,15 +235,22 @@ public: int effectiveRightTextMargin() const; private: - typedef QPair<QLineEdit::ActionPosition, int> PositionIndexPair; + struct SideWidgetLocation { + QLineEdit::ActionPosition position; + int index; - PositionIndexPair findSideWidget(const QAction *a) const; + bool isValid() const { return index >= 0; } + }; + friend class QTypeInfo<SideWidgetLocation>; + + SideWidgetLocation findSideWidget(const QAction *a) const; SideWidgetEntryList leadingSideWidgets; SideWidgetEntryList trailingSideWidgets; int lastTextSize; }; Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetLocation, Q_PRIMITIVE_TYPE); #endif // QT_NO_LINEEDIT diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm index 8e565ecfe0..610df2125b 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm @@ -44,6 +44,7 @@ #include <QtGui/QWindow> #include <qpa/qplatformnativeinterface.h> #include <private/qwidget_p.h> +#include <private/qwindow_p.h> /*! \class QMacCocoaViewContainer @@ -117,7 +118,9 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate() QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent) : QWidget(*new QMacCocoaViewContainerPrivate, parent, 0) { + // Ensures that we have a QWindow, even if we're not a top level widget setAttribute(Qt::WA_NativeWindow); + setCocoaView(view); } @@ -149,23 +152,19 @@ void QMacCocoaViewContainer::setCocoaView(NSView *view) [view retain]; d->nsview = view; - QWindow *window = windowHandle(); + // Get rid of QWindow completely, and re-create a new vanilla one, which + // we will then re-configure to be a foreign window. + destroy(); + create(); - // Note that we only set the flag on the QWindow, and not the QWidget. - // These two are not in sync, so from a QWidget standpoint the widget - // is not a Window, and hence will be shown when the parent widget is - // shown, like all QWidget children. - window->setFlags(Qt::ForeignWindow); - window->setProperty("_q_foreignWinId", view ? WId(view) : QVariant()); - - // Destroying the platform window implies hiding the window, and we - // also lose the geometry information that the platform window kept, - // and fall back to the stale QWindow geometry, so we update the two - // based on the widget visibility and geometry, which is up to date. + // Can't use QWindow::fromWinId() here due to QWidget controlling its + // QWindow, and can't use QWidget::createWindowContainer() due to the + // QMacCocoaViewContainer class being public API instead of a factory + // function. + QWindow *window = windowHandle(); window->destroy(); - window->setVisible(isVisible()); - window->setGeometry(geometry()); - window->create(); + qt_window_private(window)->create(false, WId(view)); + Q_ASSERT(window->handle()); [oldView release]; } diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h index 9bd7eb1cd8..bab1176d8a 100644 --- a/src/widgets/widgets/qmainwindow.h +++ b/src/widgets/widgets/qmainwindow.h @@ -60,7 +60,6 @@ class Q_WIDGETS_EXPORT QMainWindow : public QWidget { Q_OBJECT - Q_FLAGS(DockOptions) Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle) #ifndef QT_NO_DOCKWIDGET @@ -89,6 +88,7 @@ public: }; Q_ENUM(DockOption) Q_DECLARE_FLAGS(DockOptions, DockOption) + Q_FLAG(DockOptions) explicit QMainWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QMainWindow(); diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index a627c86871..a8cdca1719 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1863,7 +1863,7 @@ void QMdiSubWindowPrivate::removeButtonsFromMenuBar() topLevelWindow->removeEventFilter(q); if (baseWidget && !drawTitleBarWhenMaximized()) topLevelWindow->setWindowModified(false); - originalTitle = QString::null; + originalTitle.clear(); } #endif // QT_NO_MENUBAR @@ -2769,7 +2769,7 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event) #ifndef QT_NO_MENUBAR } else if (maximizedButtonsWidget() && d->controlContainer->menuBar() && d->controlContainer->menuBar() ->cornerWidget(Qt::TopRightCorner) == maximizedButtonsWidget()) { - d->originalTitle = QString::null; + d->originalTitle.clear(); if (d->baseWidget && d->baseWidget->windowTitle() == windowTitle()) d->updateWindowTitle(true); else diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 5d218ac1ba..e9a5db1112 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -98,8 +98,8 @@ public: #else // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template<class Obj, typename Func1> - inline typename QtPrivate::QEnableIf<!std::is_same<const char*, Func1>::value - && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + inline typename std::enable_if<!std::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type addAction(const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) { QAction *result = addAction(text); @@ -126,8 +126,8 @@ public: } // addAction(QIcon, QString): Connect to a QObject slot / functor or function pointer (with context) template<class Obj, typename Func1> - inline typename QtPrivate::QEnableIf<!std::is_same<const char*, Func1>::value - && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + inline typename std::enable_if<!std::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) { QAction *result = addAction(actionIcon, text); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 2588f41468..77ed7a4f78 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1119,7 +1119,7 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) int clashCount = 0; QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0; { - QChar c = e->text()[0].toUpper(); + const QChar c = e->text().at(0).toUpper(); for(int i = 0; i < d->actions.size(); ++i) { if (d->actionRects.at(i).isNull()) continue; @@ -1192,10 +1192,6 @@ QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action) QPlatformMenu *platformMenu = action->menu()->platformMenu(); if (!platformMenu && platformMenuBar) { platformMenu = platformMenuBar->createMenu(); - // QPlatformMenuBar::createMenu() was introduced in Qt 5.7. Not all third party - // platform themes are using it, so fallback to QPlatformTheme::createPlatformMenu(). - if (!platformMenu) - platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); if (platformMenu) action->menu()->setPlatformMenu(platformMenu); } @@ -1494,6 +1490,7 @@ bool QMenuBar::eventFilter(QObject *object, QEvent *event) case QEvent::FocusIn: case QEvent::FocusOut: case QEvent::ActivationChange: + case QEvent::Shortcut: d->altPressed = false; qApp->removeEventFilter(this); break; diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 64f19047b6..2b228cdb2c 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -508,9 +508,7 @@ void QProgressBar::setOrientation(Qt::Orientation orientation) return; d->orientation = orientation; if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) { - QSizePolicy sp = sizePolicy(); - sp.transpose(); - setSizePolicy(sp); + setSizePolicy(sizePolicy().transposed()); setAttribute(Qt::WA_WState_OwnSizePolicy, false); } d->resetLayoutItemMargins(); diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index 3b1440edb6..20758679f0 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -55,7 +55,9 @@ #include "qtoolbar.h" #include "qdebug.h" #include "qlayoutitem.h" +#if QT_CONFIG(dialogbuttonbox) #include "qdialogbuttonbox.h" +#endif #if 0 // Used to be included in Qt4 for Q_WS_MAC #include "private/qmacstyle_mac_p.h" #include "private/qmacstyle_mac_p_p.h" @@ -400,8 +402,7 @@ QSize QPushButton::sizeHint() const initStyleOption(&opt); // calculate contents size... -#ifndef QT_NO_ICON - +#if !defined(QT_NO_ICON) && QT_CONFIG(dialogbuttonbox) bool showButtonBoxIcons = qobject_cast<QDialogButtonBox*>(parentWidget()) && style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons); @@ -607,19 +608,21 @@ QPoint QPushButtonPrivate::adjustedMenuPosition() QPoint globalPos = q->mapToGlobal(rect.topLeft()); int x = globalPos.x(); int y = globalPos.y(); + const QRect availableGeometry = QApplication::desktop()->availableGeometry(q); if (horizontal) { - if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->availableGeometry(q).height()) { + if (globalPos.y() + rect.height() + menuSize.height() <= availableGeometry.bottom()) { y += rect.height(); - } else { + } else if (globalPos.y() - menuSize.height() >= availableGeometry.y()) { y -= menuSize.height(); } if (q->layoutDirection() == Qt::RightToLeft) x += rect.width() - menuSize.width(); } else { - if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->availableGeometry(q).width()) + if (globalPos.x() + rect.width() + menu->sizeHint().width() <= availableGeometry.right()) { x += rect.width(); - else + } else if (globalPos.x() - menuSize.width() >= availableGeometry.x()) { x -= menuSize.width(); + } } return QPoint(x,y); @@ -676,7 +679,7 @@ bool QPushButton::event(QEvent *e) } #if 0 // Used to be included in Qt4 for Q_WS_MAC -/*! \reimp */ +/* \reimp */ bool QPushButton::hitButton(const QPoint &pos) const { QStyleOptionButton opt; diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h index b0d1ccacdb..ea9baa8ccb 100644 --- a/src/widgets/widgets/qpushbutton.h +++ b/src/widgets/widgets/qpushbutton.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractbutton.h> +QT_REQUIRE_CONFIG(pushbutton); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qpushbutton_p.h b/src/widgets/widgets/qpushbutton_p.h index ee41c345c8..198091503a 100644 --- a/src/widgets/widgets/qpushbutton_p.h +++ b/src/widgets/widgets/qpushbutton_p.h @@ -43,6 +43,8 @@ #include <QtWidgets/private/qtwidgetsglobal_p.h> #include "private/qabstractbutton_p.h" +QT_REQUIRE_CONFIG(pushbutton); + // // W A R N I N G // ------------- diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h index 2dcb0d0fdf..137ae01380 100644 --- a/src/widgets/widgets/qradiobutton.h +++ b/src/widgets/widgets/qradiobutton.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractbutton.h> +QT_REQUIRE_CONFIG(radiobutton); + QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h index 2b8a110c99..b99ad219eb 100644 --- a/src/widgets/widgets/qscrollbar.h +++ b/src/widgets/widgets/qscrollbar.h @@ -42,12 +42,12 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qwidget.h> -#include <QtWidgets/qabstractslider.h> -QT_BEGIN_NAMESPACE +#if QT_CONFIG(scrollbar) +#include <QtWidgets/qabstractslider.h> -#ifndef QT_NO_SCROLLBAR +QT_BEGIN_NAMESPACE class QScrollBarPrivate; class QStyleOptionSlider; @@ -94,8 +94,8 @@ private: #endif }; -#endif // QT_NO_SCROLLBAR - QT_END_NAMESPACE +#endif // QT_CONFIG(scrollbar) + #endif // QSCROLLBAR_H diff --git a/src/widgets/widgets/qslider.h b/src/widgets/widgets/qslider.h index 33b90ece06..001863c18d 100644 --- a/src/widgets/widgets/qslider.h +++ b/src/widgets/widgets/qslider.h @@ -41,13 +41,14 @@ #define QSLIDER_H #include <QtWidgets/qtwidgetsglobal.h> + +#if QT_CONFIG(slider) + #include <QtWidgets/qabstractslider.h> QT_BEGIN_NAMESPACE -#ifndef QT_NO_SLIDER - class QSliderPrivate; class QStyleOptionSlider; class Q_WIDGETS_EXPORT QSlider : public QAbstractSlider @@ -99,8 +100,8 @@ private: Q_DECLARE_PRIVATE(QSlider) }; -#endif // QT_NO_SLIDER - QT_END_NAMESPACE +#endif // QT_CONFIG(slider) + #endif // QSLIDER_H diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 910904e96e..e6332293e4 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -241,21 +241,24 @@ void QSplitterHandle::resizeEvent(QResizeEvent *event) { Q_D(const QSplitterHandle); - // When splitters are only 1 or 0 pixel large we increase the - // actual grab area to five pixels + // Ensure the actual grab area is at least 4 or 5 pixels + const int handleMargin = (5 - d->s->handleWidth()) / 2; // Note that QSplitter uses contentsRect for layouting // and ensures that handles are drawn on top of widgets // We simply use the contents margins for draggin and only // paint the mask area - bool useTinyMode = (d->s->handleWidth() <= 1); + const bool useTinyMode = handleMargin > 0; setAttribute(Qt::WA_MouseNoMask, useTinyMode); if (useTinyMode) { if (orientation() == Qt::Horizontal) - setContentsMargins(2, 0, 2, 0); + setContentsMargins(handleMargin, 0, handleMargin, 0); else - setContentsMargins(0, 2, 0, 2); + setContentsMargins(0, handleMargin, 0, handleMargin); setMask(QRegion(contentsRect())); + } else { + setContentsMargins(0, 0, 0, 0); + clearMask(); } QWidget::resizeEvent(event); @@ -731,6 +734,12 @@ void QSplitterPrivate::setSizes_helper(const QList<int> &sizes, bool clampNegati doResize(); } +bool QSplitterPrivate::shouldShowWidget(const QWidget *w) const +{ + Q_Q(const QSplitter); + return q->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide)); +} + void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool allowCollapse) { Q_Q(QSplitter); @@ -827,8 +836,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show { Q_Q(QSplitter); QBoolBlocker b(blockChildAdd); - bool needShow = show && q->isVisible() && - !(widget->isHidden() && widget->testAttribute(Qt::WA_WState_ExplicitShowHide)); + const bool needShow = show && shouldShowWidget(widget); if (widget->parentWidget() != q) widget->setParent(q); if (needShow) @@ -1000,9 +1008,7 @@ void QSplitter::setOrientation(Qt::Orientation orientation) return; if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) { - QSizePolicy sp = sizePolicy(); - sp.transpose(); - setSizePolicy(sp); + setSizePolicy(sizePolicy().transposed()); setAttribute(Qt::WA_WState_OwnSizePolicy, false); } @@ -1125,6 +1131,66 @@ void QSplitter::insertWidget(int index, QWidget *widget) } /*! + \since 5.9 + + Replaces the widget in the splitter's layout at the given \a index by \a widget. + + Returns the widget that has just been replaced if \a index is valid and \a widget + is not already a child of the splitter. Otherwise, it returns null and no replacement + or addition is made. + + The geometry of the newly inserted widget will be the same as the widget it replaces. + Its visible and collapsed states are also inherited. + + \note The splitter takes ownership of \a widget and sets the parent of the + replaced widget to null. + + \sa insertWidget(), indexOf() +*/ +QWidget *QSplitter::replaceWidget(int index, QWidget *widget) +{ + Q_D(QSplitter); + if (!widget) { + qWarning("QSplitter::replaceWidget: Widget can't be null"); + return nullptr; + } + + if (index < 0 || index >= d->list.count()) { + qWarning("QSplitter::replaceWidget: Index %d out of range", index); + return nullptr; + } + + QSplitterLayoutStruct *s = d->list.at(index); + QWidget *current = s->widget; + if (current == widget) { + qWarning("QSplitter::replaceWidget: Trying to replace a widget with itself"); + return nullptr; + } + + if (widget->parentWidget() == this) { + qWarning("QSplitter::replaceWidget: Trying to replace a widget with one of its siblings"); + return nullptr; + } + + QBoolBlocker b(d->blockChildAdd); + + const QRect geom = current->geometry(); + const bool shouldShow = d->shouldShowWidget(current); + + s->widget = widget; + current->setParent(nullptr); + widget->setParent(this); + + // The splitter layout struct's geometry is already set and + // should not change. Only set the geometry on the new widget + widget->setGeometry(geom); + widget->lower(); + widget->setVisible(shouldShow); + + return current; +} + +/*! \fn int QSplitter::indexOf(QWidget *widget) const Returns the index in the splitter's layout of the specified \a widget. This @@ -1232,7 +1298,7 @@ void QSplitter::childEvent(QChildEvent *c) if (c->added() && !d->blockChildAdd && !d->findWidget(w)) { d->insertWidget_helper(d->list.count(), w, false); } else if (c->polished() && !d->blockChildAdd) { - if (isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide))) + if (d->shouldShowWidget(w)) w->show(); } else if (c->type() == QEvent::ChildRemoved) { for (int i = 0; i < d->list.size(); ++i) { diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h index 9cfde9fed3..e9ef3c3f2d 100644 --- a/src/widgets/widgets/qsplitter.h +++ b/src/widgets/widgets/qsplitter.h @@ -71,6 +71,7 @@ public: void addWidget(QWidget *widget); void insertWidget(int index, QWidget *widget); + QWidget *replaceWidget(int index, QWidget *widget); void setOrientation(Qt::Orientation); Qt::Orientation orientation() const; diff --git a/src/widgets/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h index 4422d9a8a4..07b43e56b8 100644 --- a/src/widgets/widgets/qsplitter_p.h +++ b/src/widgets/widgets/qsplitter_p.h @@ -125,6 +125,7 @@ public: int findWidgetJustBeforeOrJustAfter(int index, int delta, int &collapsibleSize) const; void updateHandles(); void setSizes_helper(const QList<int> &sizes, bool clampNegativeSize = false); + bool shouldShowWidget(const QWidget *w) const; }; diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 35d9498413..eeece1a42a 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -177,8 +177,7 @@ void QTabBarPrivate::initBasicStyleOption(QStyleOptionTab *option, int tabIndex) if (tab.textColor.isValid()) option->palette.setColor(q->foregroundRole(), tab.textColor); #ifdef Q_OS_MACOS - else if (isCurrent && !documentMode - && (QSysInfo::MacintoshVersion < QSysInfo::MV_10_10 || q->isActiveWindow())) { + else if (isCurrent && !documentMode && q->isActiveWindow()) { option->palette.setColor(QPalette::WindowText, Qt::white); } #endif @@ -520,12 +519,14 @@ void QTabBarPrivate::layoutTabs() maxExtent = maxWidth; } + if (!expanding) { + // Mirror our front item. + tabChain[tabChainIndex].init(); + tabChain[tabChainIndex].expansive = (tabAlignment != Qt::AlignRight) + && (tabAlignment != Qt::AlignJustify); + tabChain[tabChainIndex].empty = true; + } Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure. - // Mirror our front item. - tabChain[tabChainIndex].init(); - tabChain[tabChainIndex].expansive = (tabAlignment != Qt::AlignRight) - && (tabAlignment != Qt::AlignJustify); - tabChain[tabChainIndex].empty = true; // Do the calculation qGeomCalc(tabChain, 0, tabChain.count(), 0, qMax(available, last), 0); @@ -665,6 +666,15 @@ QRect QTabBarPrivate::normalizedScrollRect(int index) } } +int QTabBarPrivate::hoveredTabIndex() const +{ + if (dragInProgress) + return currentIndex; + if (hoverIndex >= 0) + return hoverIndex; + return -1; +} + void QTabBarPrivate::makeVisible(int index) { Q_Q(QTabBar); @@ -1054,6 +1064,17 @@ void QTabBar::removeTab(int index) } d->refresh(); d->autoHideTabs(); + if (!d->hoverRect.isEmpty()) { + for (int i = 0; i < d->tabList.count(); ++i) { + const QRect area = tabRect(i); + if (area.contains(mapFromGlobal(QCursor::pos()))) { + d->hoverIndex = i; + d->hoverRect = area; + break; + } + } + update(d->hoverRect); + } tabRemoved(index); } } @@ -1578,20 +1599,28 @@ bool QTabBar::event(QEvent *event) QHoverEvent *he = static_cast<QHoverEvent *>(event); if (!d->hoverRect.contains(he->pos())) { QRect oldHoverRect = d->hoverRect; + bool cursorOverTabs = false; for (int i = 0; i < d->tabList.count(); ++i) { QRect area = tabRect(i); if (area.contains(he->pos())) { + d->hoverIndex = i; d->hoverRect = area; + cursorOverTabs = true; break; } } + if (!cursorOverTabs) { + d->hoverIndex = -1; + d->hoverRect = QRect(); + } if (he->oldPos() != QPoint(-1, -1)) update(oldHoverRect); update(d->hoverRect); } return true; - } else if (event->type() == QEvent::HoverLeave ) { + } else if (event->type() == QEvent::HoverLeave) { QRect oldHoverRect = d->hoverRect; + d->hoverIndex = -1; d->hoverRect = QRect(); update(oldHoverRect); return true; @@ -1757,7 +1786,10 @@ void QTabBar::paintEvent(QPaintEvent *) p.drawControl(QStyle::CE_TabBarTab, tab); else { int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this); - d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0)); + if (verticalTabs(d->shape)) + d->movingTab->setGeometry(tab.rect.adjusted(0, -taboverlap, 0, taboverlap)); + else + d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0)); } } @@ -2036,7 +2068,10 @@ void QTabBarPrivate::setupMovableTab() int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q); QRect grabRect = q->tabRect(pressedIndex); - grabRect.adjust(-taboverlap, 0, taboverlap, 0); + if (verticalTabs(shape)) + grabRect.adjust(0, -taboverlap, 0, taboverlap); + else + grabRect.adjust(-taboverlap, 0, taboverlap, 0); QPixmap grabImage(grabRect.size() * q->devicePixelRatioF()); grabImage.setDevicePixelRatio(q->devicePixelRatioF()); @@ -2046,7 +2081,11 @@ void QTabBarPrivate::setupMovableTab() QStyleOptionTab tab; q->initStyleOption(&tab, pressedIndex); - tab.rect.moveTopLeft(QPoint(taboverlap, 0)); + tab.position = QStyleOptionTab::OnlyOneTab; + if (verticalTabs(shape)) + tab.rect.moveTopLeft(QPoint(0, taboverlap)); + else + tab.rect.moveTopLeft(QPoint(taboverlap, 0)); p.drawControl(QStyle::CE_TabBarTab, tab); p.end(); @@ -2426,7 +2465,7 @@ void QTabBar::setMovable(bool movable) This property is used as a hint for styles to draw the tabs in a different way then they would normally look in a tab widget. On \macos this will - look similar to the tabs in Safari or Leopard's Terminal.app. + look similar to the tabs in Safari or Sierra's Terminal.app. \sa QTabWidget::documentMode */ diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index e8d5503fdf..7c653a95e9 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -87,7 +87,7 @@ class QTabBarPrivate : public QWidgetPrivate public: QTabBarPrivate() :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), - drawBase(true), scrollOffset(0), elideModeSetByUser(false), useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false), + drawBase(true), scrollOffset(0), hoverIndex(-1), elideModeSetByUser(false), useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), autoHide(false), changeCurrentOnDrag(false), switchTabCurrentIndex(-1), switchTabTimerId(0), movingTab(0) @@ -192,6 +192,7 @@ public: void moveTab(int index, int offset); void moveTabFinished(int index); QRect hoverRect; + int hoverIndex; void refresh(); void layoutTabs(); @@ -202,6 +203,7 @@ public: void setupMovableTab(); void autoHideTabs(); QRect normalizedScrollRect(int index = -1); + int hoveredTabIndex() const; void initBasicStyleOption(QStyleOptionTab *option, int tabIndex) const; diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 5dce76056c..be870133ee 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -209,7 +209,6 @@ public: bool dirty; QTabWidget::TabPosition pos; QTabWidget::TabShape shape; - int alignment; QWidget *leftCornerWidget; QWidget *rightCornerWidget; }; @@ -732,7 +731,7 @@ QTabBar* QTabWidget::tabBar() const return d->tabs; } -/*! +/* Ensures that the selected tab's page is visible and appropriately sized. */ diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h index 3b523e3ed0..b0e19193a9 100644 --- a/src/widgets/widgets/qtextedit.h +++ b/src/widgets/widgets/qtextedit.h @@ -64,7 +64,6 @@ class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea { Q_OBJECT Q_DECLARE_PRIVATE(QTextEdit) - Q_FLAGS(AutoFormatting) Q_PROPERTY(AutoFormatting autoFormatting READ autoFormatting WRITE setAutoFormatting) Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus) Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle) @@ -100,6 +99,7 @@ public: }; Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag) + Q_FLAG(AutoFormatting) explicit QTextEdit(QWidget *parent = Q_NULLPTR); explicit QTextEdit(const QString &text, QWidget *parent = Q_NULLPTR); diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index 0ea4d4afeb..e0f2d9b073 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -116,8 +116,8 @@ public: #else // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template<class Obj, typename Func1> - inline typename QtPrivate::QEnableIf<!std::is_same<const char*, Func1>::value - && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + inline typename std::enable_if<!std::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type addAction(const QString &text, const Obj *object, Func1 slot) { QAction *result = addAction(text); @@ -134,8 +134,8 @@ public: } // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template<class Obj, typename Func1> - inline typename QtPrivate::QEnableIf<!std::is_same<const char*, Func1>::value - && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + inline typename std::enable_if<!std::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::type addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot) { QAction *result = addAction(actionIcon, text); diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri index abba3e0472..f67640e40f 100644 --- a/src/widgets/widgets/widgets.pri +++ b/src/widgets/widgets/widgets.pri @@ -5,19 +5,14 @@ HEADERS += \ widgets/qbuttongroup_p.h \ widgets/qabstractbutton.h \ widgets/qabstractbutton_p.h \ - widgets/qabstractslider.h \ - widgets/qabstractslider_p.h \ widgets/qabstractspinbox.h \ widgets/qabstractspinbox_p.h \ widgets/qcalendarwidget.h \ - widgets/qcheckbox.h \ widgets/qcombobox.h \ widgets/qcombobox_p.h \ - widgets/qcommandlinkbutton.h \ widgets/qdatetimeedit.h \ widgets/qdatetimeedit_p.h \ widgets/qdial.h \ - widgets/qdialogbuttonbox.h \ widgets/qdockwidget.h \ widgets/qdockwidget_p.h \ widgets/qdockarealayout_p.h \ @@ -27,8 +22,6 @@ HEADERS += \ widgets/qgroupbox.h \ widgets/qkeysequenceedit.h \ widgets/qkeysequenceedit_p.h \ - widgets/qlabel.h \ - widgets/qlabel_p.h \ widgets/qlcdnumber.h \ widgets/qlineedit.h \ widgets/qlineedit_p.h \ @@ -43,9 +36,6 @@ HEADERS += \ widgets/qmenubar.h \ widgets/qmenubar_p.h \ widgets/qprogressbar.h \ - widgets/qpushbutton.h \ - widgets/qpushbutton_p.h \ - widgets/qradiobutton.h \ widgets/qrubberband.h \ widgets/qscrollbar.h \ widgets/qscrollbar_p.h \ @@ -87,15 +77,11 @@ HEADERS += \ SOURCES += \ widgets/qbuttongroup.cpp \ widgets/qabstractbutton.cpp \ - widgets/qabstractslider.cpp \ widgets/qabstractspinbox.cpp \ widgets/qcalendarwidget.cpp \ - widgets/qcheckbox.cpp \ widgets/qcombobox.cpp \ - widgets/qcommandlinkbutton.cpp \ widgets/qdatetimeedit.cpp \ widgets/qdial.cpp \ - widgets/qdialogbuttonbox.cpp \ widgets/qdockwidget.cpp \ widgets/qdockarealayout.cpp \ widgets/qeffects.cpp \ @@ -103,7 +89,6 @@ SOURCES += \ widgets/qframe.cpp \ widgets/qgroupbox.cpp \ widgets/qkeysequenceedit.cpp \ - widgets/qlabel.cpp \ widgets/qlcdnumber.cpp \ widgets/qlineedit_p.cpp \ widgets/qlineedit.cpp \ @@ -114,8 +99,6 @@ SOURCES += \ widgets/qmenu.cpp \ widgets/qmenubar.cpp \ widgets/qprogressbar.cpp \ - widgets/qpushbutton.cpp \ - widgets/qradiobutton.cpp \ widgets/qrubberband.cpp \ widgets/qscrollbar.cpp \ widgets/qsizegrip.cpp \ @@ -145,6 +128,66 @@ SOURCES += \ widgets/qtoolbararealayout.cpp \ widgets/qplaintextedit.cpp +qtConfig(abstractslider) { + HEADERS += \ + widgets/qabstractslider.h \ + widgets/qabstractslider_p.h + + SOURCES += \ + widgets/qabstractslider.cpp +} + +qtConfig(checkbox) { + HEADERS += \ + widgets/qcheckbox.h + + SOURCES += \ + widgets/qcheckbox.cpp +} + +qtConfig(commandlinkbutton) { + HEADERS += \ + widgets/qcommandlinkbutton.h + + SOURCES += \ + widgets/qcommandlinkbutton.cpp +} + +qtConfig(label) { + HEADERS += \ + widgets/qlabel.h \ + widgets/qlabel_p.h + + SOURCES += \ + widgets/qlabel.cpp +} + + +qtConfig(pushbutton) { + HEADERS += \ + widgets/qpushbutton.h \ + widgets/qpushbutton_p.h + + SOURCES += \ + widgets/qpushbutton.cpp +} + +qtConfig(radiobutton) { + HEADERS += \ + widgets/qradiobutton.h + + SOURCES += \ + widgets/qradiobutton.cpp +} + +qtConfig(dialogbuttonbox) { + HEADERS += \ + widgets/qdialogbuttonbox.h + + SOURCES += \ + widgets/qdialogbuttonbox.cpp +} + macx { HEADERS += \ widgets/qmacnativewidget_mac.h \ |