diff options
author | Liang Qi <liang.qi@qt.io> | 2019-01-26 08:35:40 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-01-26 08:35:40 +0100 |
commit | 980567b3a32b2e2f00c86f2d627cd82b5230dd0f (patch) | |
tree | bc8cc4005b2e07cbc5cad8ba30f8c9fa4f236c3d /src/widgets | |
parent | e81acde7d0cf5fb44a3fb2cf0bf7aaa2c65f807e (diff) | |
parent | 730cbad8824bcfcb7ab60371a6563cfb6dd5658d (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
src/android/templates/AndroidManifest.xml
tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
Change-Id: I4c9679e3a8ebba118fbf4772301ff8fde60455b9
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 2 | ||||
-rw-r--r-- | src/widgets/doc/qtwidgets.qdocconf | 3 | ||||
-rw-r--r-- | src/widgets/itemviews/qlistview.cpp | 9 | ||||
-rw-r--r-- | src/widgets/kernel/qtestsupport_widgets.cpp | 17 | ||||
-rw-r--r-- | src/widgets/kernel/qtooltip.cpp | 24 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 22 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 7 | ||||
-rw-r--r-- | src/widgets/styles/qcommonstyle.cpp | 36 | ||||
-rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 11 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit.cpp | 1 |
11 files changed, 81 insertions, 55 deletions
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ce918b8a74..ac1952a642 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1890,7 +1890,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>" "<p>Qt is The Qt Company Ltd product developed as an open source " "project. See <a href=\"http://%3/\">%3</a> for more information.</p>" - ).arg(QStringLiteral("2018"), + ).arg(QStringLiteral("2019"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 4700ee29bf..5d7262fca1 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -40,6 +40,9 @@ exampledirs += ../../../examples/widgets \ excludedirs += snippets +# Included in qttestlib.qdocconf instead +excludefiles += ../kernel/qtestsupport_widgets.cpp + imagedirs += images \ ../../../doc/src/images \ ../../../examples/widgets/doc/images \ diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index fdac332367..143b243091 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -982,18 +982,9 @@ void QListView::paintEvent(QPaintEvent *e) ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing() : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing(); - const int rowCount = d->commonListView->rowCount(); QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd(); for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { Q_ASSERT((*it).isValid()); - if (rowCount == 1) - option.viewItemPosition = QStyleOptionViewItem::OnlyOne; - else if ((*it).row() == 0) - option.viewItemPosition = QStyleOptionViewItem::Beginning; - else if ((*it).row() == rowCount - 1) - option.viewItemPosition = QStyleOptionViewItem::End; - else - option.viewItemPosition = QStyleOptionViewItem::Middle; option.rect = visualRect(*it); if (flow() == TopToBottom) diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp index b227e6ff5d..0056bebdc6 100644 --- a/src/widgets/kernel/qtestsupport_widgets.cpp +++ b/src/widgets/kernel/qtestsupport_widgets.cpp @@ -46,15 +46,14 @@ QT_BEGIN_NAMESPACE -/*! \fn bool qWaitForWindowActive(QWidget *widget, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a widget's window is active. Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false. - \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow() + \sa qWaitForWindowExposed(), QWidget::isActiveWindow() */ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout) { @@ -63,8 +62,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid return false; } -/*! \fn bool qWaitForWindowExposed(QWidget *widget, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a widget's window is exposed. @@ -80,7 +78,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS: The viewport widget gets the expose event, not the parent widget. - \sa QTest::qWaitForWindowActive() + \sa qWaitForWindowActive() */ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout) { @@ -89,11 +87,12 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi return false; } -/*! \fn bool qWaitForWindowShown(QWidget *widget, int timeout) - \relates QTest +/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout) \since 5.0 \deprecated + Use qWaitForWindowExposed() instead. + Waits for \a timeout milliseconds or until the \a widget's window is exposed. Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false. @@ -107,7 +106,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi QTest::qWaitForWindowShown(&widget); \endcode - \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed() + \sa qWaitForWindowActive(), qWaitForWindowExposed() */ QT_END_NAMESPACE diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 9d8b0062f5..cf0f3f153b 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -216,7 +216,6 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint } #endif - setWordWrap(true); setText(text); updateSize(pos); restartExpireTimer(msecDisplayTime); @@ -235,20 +234,17 @@ void QTipLabel::updateSize(const QPoint &pos) // Make it look good with the default ToolTip font on Mac, which has a small descent. if (fm.descent() == 2 && fm.ascent() >= 11) ++extra.rheight(); + setWordWrap(Qt::mightBeRichText(text())); QSize sh = sizeHint(); - if (wordWrap()) { - // ### When the above WinRT code is fixed, windowhandle should be used to find the screen. - QScreen *screen = QGuiApplication::screenAt(pos); - if (!screen) - screen = QGuiApplication::primaryScreen(); - if (screen) { - const qreal screenWidth = screen->geometry().width(); - if (sh.width() > screenWidth) { - // Try to use widely accepted 75chars max length or 80% of the screen width else. - // See https://en.wikipedia.org/wiki/Line_length - sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenWidth * .8))); - sh.setHeight(heightForWidth(sh.width())); - } + // ### When the above WinRT code is fixed, windowhandle should be used to find the screen. + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + if (screen) { + const qreal screenWidth = screen->geometry().width(); + if (!wordWrap() && sh.width() > screenWidth) { + setWordWrap(true); + sh = sizeHint(); } } resize(sh + extra); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6616cb6de3..c0430bec23 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -247,6 +247,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_TOOLTIP , toolTipDuration(-1) #endif + , directFontResolveMask(0) , inheritedFontResolveMask(0) , inheritedPaletteResolveMask(0) , leftmargin(0) @@ -4519,7 +4520,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role) the "color", "background-color", "selection-color", "selection-background-color" and "alternate-background-color". - \sa QApplication::palette(), QWidget::font(), \l {Qt Style Sheets} + \sa QApplication::palette(), QWidget::font(), {Qt Style Sheets} */ const QPalette &QWidget::palette() const { @@ -4757,6 +4758,18 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const /*! \internal + Returns a font suitable for inheritance, where only locally set attributes are considered resolved. +*/ +QFont QWidgetPrivate::localFont() const +{ + QFont localfont = data.fnt; + localfont.resolve(directFontResolveMask); + return localfont; +} + +/*! + \internal + Determine which font is implicitly imposed on this widget by its ancestors and QApplication::font, resolve this against its own font (attributes from the implicit font are copied over). Then propagate this font to this @@ -4765,7 +4778,7 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const void QWidgetPrivate::resolveFont() { QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask); - QFont resolvedFont = data.fnt.resolve(naturalFont); + QFont resolvedFont = localFont().resolve(naturalFont); setFont_helper(resolvedFont); } @@ -4804,6 +4817,11 @@ void QWidgetPrivate::updateFont(const QFont &font) inheritedFontResolveMask = 0; } uint newMask = data.fnt.resolve() | inheritedFontResolveMask; + // Set the font as also having resolved inherited traits, so the result of reading QWidget::font() + // isn't all weak information, but save the original mask to be able to let new changes on the + // parent widget font propagate correctly. + directFontResolveMask = data.fnt.resolve(); + data.fnt.resolve(newMask); for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast<QWidget*>(children.at(i)); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 7c757a43f2..ab5dc6bfba 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -383,10 +383,11 @@ public: void updateFont(const QFont &); inline void setFont_helper(const QFont &font) { - if (data.fnt.resolve() == font.resolve() && data.fnt == font) + if (directFontResolveMask == font.resolve() && data.fnt == font) return; updateFont(font); } + QFont localFont() const; void resolveFont(); QFont naturalWidgetFont(uint inheritedMask) const; @@ -730,6 +731,7 @@ public: #endif // Other variables. + uint directFontResolveMask; uint inheritedFontResolveMask; uint inheritedPaletteResolveMask; short leftmargin; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 279c6c0282..991a05fa02 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -899,10 +899,10 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event) const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); - translated.setDropAction(event->dropAction()); - translated.setAccepted(event->isAccepted()); if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove + translated.setDropAction(event->dropAction()); + translated.setAccepted(event->isAccepted()); QGuiApplication::forwardEvent(m_dragTarget, &translated, event); } else { if (m_dragTarget) { // Send DragLeave to previous @@ -912,6 +912,9 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event) } // Send DragEnter to new widget. handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget); + // Handling 'DragEnter' should suffice for the application. + translated.setDropAction(event->dropAction()); + translated.setAccepted(event->isAccepted()); // The drag enter event is always immediately followed by a drag move event, // see QDragEnterEvent documentation. QGuiApplication::forwardEvent(m_dragTarget, &translated, event); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 49543061cc..2bfc1acc26 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -946,17 +946,20 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt const QRectF boundingRect = textLayout.boundingRect(); const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, boundingRect.size().toSize(), textRect); - const QPointF position = layoutRect.topLeft(); - const int lineCount = textLayout.lineCount(); + QPointF paintPosition = QPointF(textRect.x(), layoutRect.top()); + QString newText; qreal height = 0; + const int lineCount = textLayout.lineCount(); for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); height += line.height(); // above visible rect - if (height + layoutRect.top() <= textRect.top()) + if (height + layoutRect.top() <= textRect.top()) { + paintPosition.ry() += line.height(); continue; + } const int start = line.textStart(); const int length = line.textLength(); @@ -971,26 +974,33 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt elideLastVisibleLine = true; } + QString text = textLayout.text().mid(start, length); if (drawElided || elideLastVisibleLine) { - QString text = textLayout.text().mid(start, length); - if (elideLastVisibleLine) + if (elideLastVisibleLine) { + if (text.endsWith(QChar::LineSeparator)) + text.chop(1); text += QChar(0x2026); + } const QStackTextEngine engine(text, option->font); - const QString elidedText = engine.elidedText(option->textElideMode, textRect.width()); - const QPointF pos(position.x() + line.x(), - position.y() + line.y() + line.ascent()); - p->save(); - p->setFont(option->font); - p->drawText(pos, elidedText); - p->restore(); + newText += engine.elidedText(option->textElideMode, textRect.width()); + // sometimes drawElided is true but no eliding is done so the text ends + // with QChar::LineSeparator - don't add another one. This happened with + // arabic text in the testcase for QTBUG-72805 + if (i < lineCount - 1 && + !newText.endsWith(QChar::LineSeparator)) + newText += QChar::LineSeparator; } else { - line.draw(p, position); + newText += text; } // below visible text, can stop if (height + layoutRect.top() >= textRect.bottom()) break; } + + textLayout.setText(newText); + viewItemTextLayout(textLayout, textRect.width()); + textLayout.draw(p, paintPosition); } /*! \internal diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index e261055c3c..e73d019408 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2645,7 +2645,7 @@ void QStyleSheetStyle::setPalette(QWidget *w) QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w)); if (i == 0) { if (!w->property("_q_styleSheetWidgetFont").isValid()) { - saveWidgetFont(w, w->font()); + saveWidgetFont(w, w->d_func()->localFont()); } updateStyleSheetFont(w); if (ew != w) @@ -6033,7 +6033,7 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const unsetStyleSheetFont(w); if (rule.font.resolve()) { - QFont wf = w->font(); + QFont wf = w->d_func()->localFont(); styleSheetCaches->customFontWidgets.insert(w, {wf, rule.font.resolve()}); QFont font = rule.font.resolve(wf); @@ -6041,7 +6041,9 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const w->setFont(font); } } else { - QFont font = rule.font.resolve(w->font()); + QFont wf = w->d_func()->localFont(); + QFont font = rule.font.resolve(wf); + font.resolve(wf.resolve() | rule.font.resolve()); if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation)) && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) { @@ -6049,10 +6051,11 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const font = font.resolve(static_cast<QWidget *>(w->parent())->font()); } - if (w->data->fnt == font) + if (wf.resolve() == font.resolve() && wf == font) return; w->data->fnt = font; + w->d_func()->directFontResolveMask = font.resolve(); QEvent e(QEvent::FontChange); QApplication::sendEvent(w, &e); diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 2ae2e16c89..4301a3a2e7 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1681,6 +1681,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) /*! \fn void QLineEdit::inputRejected() + \since 5.12 This signal is emitted when the user presses a key that is not considered to be acceptable input. For example, if a key press |