summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-02-08 09:28:00 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2019-02-08 12:31:02 +0100
commitfbfacd33be482fa3cf0aa5cffaf7006d538a2f92 (patch)
tree92da72786b3740e37004623612c4fc1c9640d30f /src/widgets
parentc1f4286a5cbc1794fe7be5bdbbd6a0bf29ef84d4 (diff)
parent74e04d6ace7aa949db97ae2e46c38a4dc0d4d36a (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: src/android/templates/AndroidManifest.xml src/network/ssl/qsslsocket_mac.cpp src/widgets/styles/qstylesheetstyle.cpp tests/auto/corelib/kernel/qtimer/BLACKLIST tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp tests/auto/testlib/selftests/expected_blacklisted.lightxml tests/auto/testlib/selftests/expected_blacklisted.tap tests/auto/testlib/selftests/expected_blacklisted.teamcity tests/auto/testlib/selftests/expected_blacklisted.txt tests/auto/testlib/selftests/expected_blacklisted.xml tests/auto/testlib/selftests/expected_blacklisted.xunitxml tests/auto/testlib/selftests/expected_float.tap tests/auto/testlib/selftests/expected_float.teamcity tests/auto/testlib/selftests/expected_float.txt tests/auto/testlib/selftests/expected_float.xunitxml Done-With: Christian Ehrlicher <ch.ehrlicher@gmx.de> Done-With: Edward Welbourne <edward.welbourne@qt.io> Done-With: Timur Pocheptsov <timur.pocheptsov@qt.io> Change-Id: If93cc432a56ae3ac1b6533d0028e4dc497415a52
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp2
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp17
-rw-r--r--src/widgets/dialogs/qwizard.cpp2
-rw-r--r--src/widgets/itemviews/qlistview.cpp34
-rw-r--r--src/widgets/kernel/qwidget.cpp3
-rw-r--r--src/widgets/styles/qcommonstyle.cpp164
-rw-r--r--src/widgets/styles/qcommonstyle_p.h10
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp36
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp7
9 files changed, 184 insertions, 91 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 92ab846a41..722aa3e278 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1887,7 +1887,7 @@ bool QColorDialogPrivate::canBeNativeDialog() const
}
static const Qt::WindowFlags DefaultWindowFlags =
- Qt::Dialog | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint
+ Qt::Dialog | Qt::WindowTitleHint
| Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
/*!
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 5a7d6edddf..3cfe8367e0 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -168,6 +168,18 @@ private:
}
};
+class QInputDialogListView : public QListView
+{
+public:
+ QInputDialogListView(QWidget *parent = 0) : QListView(parent) {}
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
+ {
+ if (query == Qt::ImEnabled)
+ return false;
+ return QListView::inputMethodQuery(query);
+ }
+};
+
class QInputDialogPrivate : public QDialogPrivate
{
Q_DECLARE_PUBLIC(QInputDialog)
@@ -201,7 +213,7 @@ public:
mutable QSpinBox *intSpinBox;
mutable QDoubleSpinBox *doubleSpinBox;
mutable QComboBox *comboBox;
- mutable QListView *listView;
+ mutable QInputDialogListView *listView;
mutable QWidget *inputWidget;
mutable QVBoxLayout *mainLayout;
QInputDialog::InputDialogOptions opts;
@@ -298,8 +310,7 @@ void QInputDialogPrivate::ensureListView()
Q_Q(QInputDialog);
if (!listView) {
ensureComboBox();
-
- listView = new QListView(q);
+ listView = new QInputDialogListView(q);
listView->hide();
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
listView->setSelectionMode(QAbstractItemView::SingleSelection);
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 9345a4b583..5eae70baf2 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -456,7 +456,7 @@ public:
QSize minimumSizeHint() const override {
if (pixmap() && !pixmap()->isNull())
- return pixmap()->size();
+ return pixmap()->size() / pixmap()->devicePixelRatio();
return QFrame::minimumSizeHint();
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 143b243091..e7b2aaec29 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1100,19 +1100,45 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
Q_D(QListView);
Q_UNUSED(modifiers);
- QModelIndex current = currentIndex();
- if (!current.isValid()) {
+ auto findAvailableRowBackward = [d](int row) {
+ while (row >= 0 && d->isHiddenOrDisabled(row))
+ --row;
+ return row;
+ };
+
+ auto findAvailableRowForward = [d](int row) {
int rowCount = d->model->rowCount(d->root);
if (!rowCount)
- return QModelIndex();
- int row = 0;
+ return -1;
while (row < rowCount && d->isHiddenOrDisabled(row))
++row;
if (row >= rowCount)
+ return -1;
+ return row;
+ };
+
+ QModelIndex current = currentIndex();
+ if (!current.isValid()) {
+ int row = findAvailableRowForward(0);
+ if (row == -1)
return QModelIndex();
return d->model->index(row, d->column, d->root);
}
+ if ((d->flow == LeftToRight && cursorAction == MoveLeft) ||
+ (d->flow == TopToBottom && (cursorAction == MoveUp || cursorAction == MovePrevious))) {
+ const int row = findAvailableRowBackward(current.row() - 1);
+ if (row == -1)
+ return current;
+ return d->model->index(row, d->column, d->root);
+ } else if ((d->flow == LeftToRight && cursorAction == MoveRight) ||
+ (d->flow == TopToBottom && (cursorAction == MoveDown || cursorAction == MoveNext))) {
+ const int row = findAvailableRowForward(current.row() + 1);
+ if (row == -1)
+ return current;
+ return d->model->index(row, d->column, d->root);
+ }
+
const QRect initialRect = rectForIndex(current);
QRect rect = initialRect;
if (rect.isEmpty()) {
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 87cc150530..b4ae994375 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -4513,8 +4513,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role)
style, depend on third party APIs to render the content of widgets,
and these styles typically do not follow the palette. Because of this,
assigning roles to a widget's palette is not guaranteed to change the
- appearance of the widget. Instead, you may choose to apply a \l
- styleSheet.
+ appearance of the widget. Instead, you may choose to apply a \l {styleSheet}.
\warning Do not use this function in conjunction with \l{Qt Style Sheets}.
When using style sheets, the palette of a widget can be customized using
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 1980dc47a9..01c400c5da 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -846,8 +846,6 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
}
#endif // QT_CONFIG(toolbutton)
-#if QT_CONFIG(itemviews)
-
static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
{
qreal height = 0;
@@ -866,6 +864,80 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
return QSizeF(widthUsed, height);
}
+QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTextOption &textOption,
+ const QFont &font, const QRect &textRect, const Qt::Alignment valign,
+ Qt::TextElideMode textElideMode, int flags,
+ bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const
+{
+ QTextLayout textLayout(text, font);
+ textLayout.setTextOption(textOption);
+
+ viewItemTextLayout(textLayout, textRect.width());
+
+ const QRectF boundingRect = textLayout.boundingRect();
+ // don't care about LTR/RTL here, only need the height
+ const QRect layoutRect = QStyle::alignedRect(Qt::LayoutDirectionAuto, valign,
+ boundingRect.size().toSize(), textRect);
+
+ if (paintStartPosition)
+ *paintStartPosition = QPointF(textRect.x(), layoutRect.top());
+
+ QString ret;
+ 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 (paintStartPosition)
+ paintStartPosition->ry() += line.height();
+ continue;
+ }
+
+ const int start = line.textStart();
+ const int length = line.textLength();
+ const bool drawElided = line.naturalTextWidth() > textRect.width();
+ bool elideLastVisibleLine = false;
+ if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) {
+ const QTextLine nextLine = textLayout.lineAt(i + 1);
+ const int nextHeight = height + nextLine.height() / 2;
+ // elide when less than the next half line is visible
+ if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
+ elideLastVisibleLine = true;
+ }
+
+ QString text = textLayout.text().mid(start, length);
+ if (drawElided || elideLastVisibleLine) {
+ if (elideLastVisibleLine) {
+ if (text.endsWith(QChar::LineSeparator))
+ text.chop(1);
+ text += QChar(0x2026);
+ }
+ const QStackTextEngine engine(text, font);
+ ret += engine.elidedText(textElideMode, textRect.width(), flags);
+
+ // no newline for the last line (last visible or real)
+ // 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 &&
+ !ret.endsWith(QChar::LineSeparator))
+ ret += QChar::LineSeparator;
+ } else {
+ ret += text;
+ }
+
+ // below visible text, can stop
+ if (height + layoutRect.top() >= textRect.bottom())
+ break;
+ }
+ return ret;
+}
+
+#if QT_CONFIG(itemviews)
+
QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const
{
const QWidget *widget = option->widget;
@@ -938,67 +1010,15 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
textOption.setTextDirection(option->direction);
textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
- QTextLayout textLayout(option->text, option->font);
- textLayout.setTextOption(textOption);
-
- viewItemTextLayout(textLayout, textRect.width());
-
- const QRectF boundingRect = textLayout.boundingRect();
- const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
- boundingRect.size().toSize(), textRect);
- 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()) {
- paintPosition.ry() += line.height();
- continue;
- }
-
- const int start = line.textStart();
- const int length = line.textLength();
-
- const bool drawElided = line.naturalTextWidth() > textRect.width();
- bool elideLastVisibleLine = false;
- if (!drawElided && i + 1 < lineCount) {
- const QTextLine nextLine = textLayout.lineAt(i + 1);
- const int nextHeight = height + nextLine.height() / 2;
- // elide when less than the next half line is visible
- if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
- elideLastVisibleLine = true;
- }
-
- QString text = textLayout.text().mid(start, length);
- if (drawElided || elideLastVisibleLine) {
- if (elideLastVisibleLine) {
- if (text.endsWith(QChar::LineSeparator))
- text.chop(1);
- text += QChar(0x2026);
- }
- const QStackTextEngine engine(text, option->font);
- 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 {
- newText += text;
- }
- // below visible text, can stop
- if (height + layoutRect.top() >= textRect.bottom())
- break;
- }
+ QPointF paintPosition;
+ const QString newText = calculateElidedText(option->text, textOption,
+ option->font, textRect, option->displayAlignment,
+ option->textElideMode, 0,
+ true, &paintPosition);
- textLayout.setText(newText);
+ QTextLayout textLayout(newText, option->font);
+ textLayout.setTextOption(textOption);
viewItemTextLayout(textLayout, textRect.width());
textLayout.draw(p, paintPosition);
}
@@ -1140,6 +1160,25 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect
}
#endif // QT_CONFIG(itemviews)
+#if QT_CONFIG(toolbutton)
+QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option,
+ const QRect &textRect, int flags) const
+{
+ if (option->fontMetrics.horizontalAdvance(option->text) <= textRect.width())
+ return option->text;
+
+ QString text = option->text;
+ text.replace('\n', QChar::LineSeparator);
+ QTextOption textOption;
+ textOption.setWrapMode(QTextOption::ManualWrap);
+ textOption.setTextDirection(option->direction);
+
+ return calculateElidedText(text, textOption,
+ option->font, textRect, Qt::AlignTop,
+ Qt::ElideMiddle, flags,
+ false, nullptr);
+}
+#endif // QT_CONFIG(toolbutton)
#if QT_CONFIG(tabbar)
/*! \internal
@@ -1689,8 +1728,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
alignment |= Qt::AlignLeft | Qt::AlignVCenter;
}
tr.translate(shiftX, shiftY);
- const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle,
- tr.width(), alignment);
+ const QString text = d->toolButtonElideText(toolbutton, tr, alignment);
proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
toolbutton->state & State_Enabled, text,
QPalette::ButtonText);
diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h
index b347c8563a..296f89ce5f 100644
--- a/src/widgets/styles/qcommonstyle_p.h
+++ b/src/widgets/styles/qcommonstyle_p.h
@@ -62,6 +62,7 @@ QT_BEGIN_NAMESPACE
//
class QStringList;
+class QTextOption;
// Private class
class Q_WIDGETS_EXPORT QCommonStylePrivate : public QStylePrivate
@@ -85,6 +86,10 @@ public:
#endif
}
+ QString calculateElidedText(const QString &text, const QTextOption &textOption,
+ const QFont &font, const QRect &textRect, const Qt::Alignment valign,
+ Qt::TextElideMode textElideMode, int flags,
+ bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const;
#if QT_CONFIG(itemviews)
void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const;
void viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect,
@@ -110,6 +115,11 @@ public:
&& option.viewItemPosition == cachedOption->viewItemPosition);
}
#endif
+#if QT_CONFIG(toolbutton)
+ QString toolButtonElideText(const QStyleOptionToolButton *toolbutton,
+ const QRect &textRect, int flags) const;
+#endif
+
mutable QIcon tabBarcloseButtonIcon;
#if QT_CONFIG(tabbar)
void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index e73d019408..b058d4c557 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3708,21 +3708,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
QStyleOptionMenuItem newMi = mi;
newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- checkableOffset = newMi.rect.width();
+ // align with icons if there are some
+ checkableOffset = std::max(m->maxIconWidth, newMi.rect.width());
if (subSubRule.hasDrawable() || checked)
drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
}
- int iconOffset = 0;
if (!mi.icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis)
mode = QIcon::Active;
- QPixmap pixmap;
- if (checked)
- pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
- else
- pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ const QPixmap pixmap(mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, checked ? QIcon::On : QIcon::Off));
const int pixw = pixmap.width() / pixmap.devicePixelRatio();
const int pixh = pixmap.height() / pixmap.devicePixelRatio();
QRenderRule iconRule = renderRule(w, opt, PseudoElement_MenuIcon);
@@ -3741,15 +3737,20 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(iconRect.center());
p->drawPixmap(pmr.topLeft(), pixmap);
- iconOffset = iconRule.geo->width;
}
+ int textOffset = 0;
+ // padding overrules it all
+ if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) {
+ textOffset = checkableOffset;
+ if (!m->icon.isNull() || !checkable)
+ textOffset += m->maxIconWidth;
+ }
QRect textRect = subRule.contentsRect(opt->rect);
- if (opt->direction == Qt::LeftToRight)
- textRect.setLeft(textRect.left() + checkableOffset + iconOffset);
- else
- textRect.setRight(textRect.right() - checkableOffset - iconOffset);
+ textRect.setLeft(textRect.left() + textOffset);
textRect.setWidth(textRect.width() - mi.tabWidth);
+ const QRect vTextRect = visualRect(opt->direction, m->rect, textRect);
+
QStringRef s(&mi.text);
p->setPen(mi.palette.buttonText().color());
if (!s.isEmpty()) {
@@ -3763,7 +3764,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
p->drawText(vShortcutRect, text_flags, s.mid(t + 1).toString());
s = s.left(t);
}
- p->drawText(textRect, text_flags, s.left(t).toString());
+ p->drawText(vTextRect, text_flags, s.left(t).toString());
}
if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
@@ -5088,10 +5089,11 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
if (mi->text.contains(QLatin1Char('\t')))
sz.rwidth() += 12; //as in QCommonStyle
bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable;
+ int checkableWidth = 0;
if (checkable) {
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- sz.rwidth() += checkmarkRect.width();
+ checkableWidth = std::max(mi->maxIconWidth, checkmarkRect.width());
}
if (!mi->icon.isNull()) {
QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize));
@@ -5102,6 +5104,12 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
const QRect r = fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, mi->text);
sz = sz.expandedTo(r.size());
}
+ // padding overrules it all
+ if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) {
+ sz.rwidth() += checkableWidth;
+ if (!mi->icon.isNull() || !checkable)
+ sz.rwidth() += mi->maxIconWidth;
+ }
return subRule.boxSize(subRule.adjustSize(sz));
}
}
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 0b79a990a9..363422ac74 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -312,10 +312,11 @@ void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int c
QTextBlock block = changeStartBlock;
do {
block.clearLayout();
- const int lineCount = block.isVisible() ? 1 : 0;
- if (block.lineCount() != lineCount) {
+ if (block.isVisible()
+ ? (block.lineCount() == 0)
+ : (block.lineCount() > 0)) {
blockVisibilityChanged = true;
- block.setLineCount(lineCount);
+ block.setLineCount(block.isVisible() ? 1 : 0);
}
if (block == changeEndBlock)
break;