summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-01-04 07:31:22 +0100
committerLiang Qi <liang.qi@qt.io>2019-01-04 07:33:14 +0100
commit03039979b5a643f9def38a73e19835bb69384202 (patch)
treee8a9184d5963128f013247ac64ec768d1cbf6911 /src/widgets
parent9682d217e21a2e88b6de799d79b843bbe0039df1 (diff)
parent4dc2bc323c985bdceb27f096dd6c8e7af657bb6b (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Also blacklist tst_QRawFont::unsupportedWritingSystem() and tst_QGlyphRun::mixedScripts() on windows for now. Conflicts: qmake/generators/makefile.cpp src/corelib/itemmodels/qstringlistmodel.cpp src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp tests/auto/gui/text/qglyphrun/BLACKLIST tests/auto/gui/text/qrawfont/BLACKLIST Task-number: QTBUG-72836 Change-Id: I10fea1493f0ae1a5708e1e48d0a4d7d6b76258b9
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qdialog.cpp57
-rw-r--r--src/widgets/dialogs/qdialog_p.h5
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp3
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp42
-rw-r--r--src/widgets/itemviews/qtableview.cpp103
-rw-r--r--src/widgets/itemviews/qtableview_p.h20
-rw-r--r--src/widgets/kernel/qtooltip.cpp9
-rw-r--r--src/widgets/kernel/qwidget.cpp21
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.cpp2
-rw-r--r--src/widgets/widgets/qmenu.cpp20
-rw-r--r--src/widgets/widgets/qmenu_p.h1
13 files changed, 214 insertions, 74 deletions
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index cadd7ef031..5e64503f27 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -145,10 +145,48 @@ bool QDialogPrivate::canBeNativeDialog() const
return false;
}
-QWindow *QDialogPrivate::parentWindow() const
+/*!
+ \internal
+
+ Properly hides dialog and sets the \p resultCode
+ */
+void QDialogPrivate::hide(int resultCode)
{
- if (const QWidget *parent = q_func()->nativeParentWidget())
+ Q_Q(QDialog);
+
+ q->setResult(resultCode);
+ q->hide();
+
+ close_helper(QWidgetPrivate::CloseNoEvent);
+ resetModalitySetByOpen();
+}
+
+/*!
+ \internal
+
+ Emits finished() signal with \p resultCode. If the \p dialogCode
+ is equal to 0 emits rejected(), if the \p dialogCode is equal to
+ 1 emits accepted().
+ */
+void QDialogPrivate::finalize(int resultCode, int dialogCode)
+{
+ Q_Q(QDialog);
+
+ if (dialogCode == QDialog::Accepted)
+ emit q->accepted();
+ else if (dialogCode == QDialog::Rejected)
+ emit q->rejected();
+
+ emit q->finished(resultCode);
+}
+
+QWindow *QDialogPrivate::transientParentWindow() const
+{
+ Q_Q(const QDialog);
+ if (const QWidget *parent = q->nativeParentWidget())
return parent->windowHandle();
+ else if (q->windowHandle())
+ return q->windowHandle()->transientParent();
return 0;
}
@@ -158,7 +196,7 @@ bool QDialogPrivate::setNativeDialogVisible(bool visible)
if (visible) {
Q_Q(QDialog);
helperPrepareShow(helper);
- nativeDialogInUse = helper->show(q->windowFlags(), q->windowModality(), parentWindow());
+ nativeDialogInUse = helper->show(q->windowFlags(), q->windowModality(), transientParentWindow());
} else if (nativeDialogInUse) {
helper->hide();
}
@@ -590,17 +628,8 @@ int QDialog::exec()
void QDialog::done(int r)
{
Q_D(QDialog);
- setResult(r);
- hide();
-
- d->close_helper(QWidgetPrivate::CloseNoEvent);
- d->resetModalitySetByOpen();
-
- emit finished(r);
- if (r == Accepted)
- emit accepted();
- else if (r == Rejected)
- emit rejected();
+ d->hide(r);
+ d->finalize(r, r);
}
/*!
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
index 99fff08e65..92634f6793 100644
--- a/src/widgets/dialogs/qdialog_p.h
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -87,7 +87,7 @@ public:
{}
~QDialogPrivate();
- QWindow *parentWindow() const;
+ QWindow *transientParentWindow() const;
bool setNativeDialogVisible(bool visible);
QVariant styleHint(QPlatformDialogHelper::StyleHint hint) const;
void deletePlatformHelper();
@@ -122,6 +122,9 @@ public:
QPlatformDialogHelper *platformHelper() const;
virtual bool canBeNativeDialog() const;
+ void hide(int resultCode);
+ void finalize(int resultCode, int dialogCode);
+
private:
virtual void initHelper(QPlatformDialogHelper *) {}
virtual void helperPrepareShow(QPlatformDialogHelper *) {}
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 8b3549c3f5..d29f74e93d 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -2032,8 +2032,7 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
: QRegularExpression::CaseInsensitiveOption;
for (const auto &nameFilter : nameFilters) {
- const QString wildcard = QRegularExpression::wildcardToRegularExpression(nameFilter);
- QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard), options);
+ QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(nameFilter), options);
QRegularExpressionMatch match = rx.match(node->fileName);
if (match.hasMatch())
return true;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index ffbbe82856..ce918b8a74 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -209,6 +209,7 @@ public:
void setupLayout();
void _q_buttonClicked(QAbstractButton *);
void _q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
+ void setClickedButton(QAbstractButton *button);
QAbstractButton *findButton(int button0, int button1, int button2, int flags);
void addOldButtons(int button0, int button1, int button2);
@@ -216,6 +217,8 @@ public:
QAbstractButton *abstractButtonForId(int id) const;
int execReturnCode(QAbstractButton *button);
+ int dialogCodeForButton(QAbstractButton *button) const;
+
void detectEscapeButton();
void updateSize();
int layoutMinimumWidth();
@@ -466,6 +469,27 @@ int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
return ret;
}
+/*!
+ \internal
+
+ Returns 0 for RejectedRole and NoRole, 1 for AcceptedRole and YesRole, -1 otherwise
+ */
+int QMessageBoxPrivate::dialogCodeForButton(QAbstractButton *button) const
+{
+ Q_Q(const QMessageBox);
+
+ switch (q->buttonRole(button)) {
+ case QMessageBox::AcceptRole:
+ case QMessageBox::YesRole:
+ return QDialog::Accepted;
+ case QMessageBox::RejectRole:
+ case QMessageBox::NoRole:
+ return QDialog::Rejected;
+ default:
+ return -1;
+ }
+}
+
void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
{
Q_Q(QMessageBox);
@@ -477,20 +501,30 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
} else
#endif
{
- clickedButton = button;
- q->done(execReturnCode(button)); // does not trigger closeEvent
- emit q->buttonClicked(button);
+ setClickedButton(button);
if (receiverToDisconnectOnClose) {
QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose,
memberToDisconnectOnClose);
- receiverToDisconnectOnClose = 0;
+ receiverToDisconnectOnClose = nullptr;
}
signalToDisconnectOnClose.clear();
memberToDisconnectOnClose.clear();
}
}
+void QMessageBoxPrivate::setClickedButton(QAbstractButton *button)
+{
+ Q_Q(QMessageBox);
+
+ clickedButton = button;
+ emit q->buttonClicked(clickedButton);
+
+ auto resultCode = execReturnCode(button);
+ hide(resultCode);
+ finalize(resultCode, dialogCodeForButton(button));
+}
+
void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
{
Q_Q(QMessageBox);
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index dac8174a2a..fce6b75079 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -766,6 +766,66 @@ bool QTableViewPrivate::spanContainsSection(const QHeaderView *header, int logic
/*!
\internal
+ Searches for the next cell which is available for e.g. keyboard navigation
+ The search is done by row
+*/
+int QTableViewPrivate::nextActiveVisualRow(int rowToStart, int column, int limit,
+ SearchDirection searchDirection) const
+{
+ const int lc = logicalColumn(column);
+ int visualRow = rowToStart;
+ const auto isCellActive = [this](int vr, int lc)
+ {
+ const int lr = logicalRow(vr);
+ return !isRowHidden(lr) && isCellEnabled(lr, lc);
+ };
+ switch (searchDirection) {
+ case SearchDirection::Increasing:
+ if (visualRow < limit) {
+ while (!isCellActive(visualRow, lc)) {
+ if (++visualRow == limit)
+ return rowToStart;
+ }
+ }
+ break;
+ case SearchDirection::Decreasing:
+ while (visualRow > limit && !isCellActive(visualRow, lc))
+ --visualRow;
+ break;
+ }
+ return visualRow;
+}
+
+/*!
+ \internal
+ Searches for the next cell which is available for e.g. keyboard navigation
+ The search is done by column
+*/
+int QTableViewPrivate::nextActiveVisualColumn(int row, int columnToStart, int limit,
+ SearchDirection searchDirection) const
+{
+ const int lr = logicalRow(row);
+ int visualColumn = columnToStart;
+ const auto isCellActive = [this](int lr, int vc)
+ {
+ const int lc = logicalColumn(vc);
+ return !isColumnHidden(lc) && isCellEnabled(lr, lc);
+ };
+ switch (searchDirection) {
+ case SearchDirection::Increasing:
+ while (visualColumn < limit && !isCellActive(lr, visualColumn))
+ ++visualColumn;
+ break;
+ case SearchDirection::Decreasing:
+ while (visualColumn > limit && !isCellActive(lr, visualColumn))
+ --visualColumn;
+ break;
+ }
+ return visualColumn;
+}
+
+/*!
+ \internal
Returns the visual rect for the given \a span.
*/
QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const
@@ -1807,35 +1867,34 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
break;
}
case MoveHome:
- visualColumn = 0;
- while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
- ++visualColumn;
- if (modifiers & Qt::ControlModifier) {
- visualRow = 0;
- while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
- ++visualRow;
- }
+ visualColumn = d->nextActiveVisualColumn(visualRow, 0, right,
+ QTableViewPrivate::SearchDirection::Increasing);
+ if (modifiers & Qt::ControlModifier)
+ visualRow = d->nextActiveVisualRow(0, visualColumn, bottom,
+ QTableViewPrivate::SearchDirection::Increasing);
break;
case MoveEnd:
- visualColumn = right;
+ visualColumn = d->nextActiveVisualColumn(visualRow, right, -1,
+ QTableViewPrivate::SearchDirection::Decreasing);
if (modifiers & Qt::ControlModifier)
- visualRow = bottom;
+ visualRow = d->nextActiveVisualRow(bottom, current.column(), -1,
+ QTableViewPrivate::SearchDirection::Decreasing);
break;
case MovePageUp: {
- int newRow = rowAt(visualRect(current).bottom() - d->viewport->height());
- if (newRow == -1) {
- int visualRow = 0;
- while (visualRow < bottom && isRowHidden(d->logicalRow(visualRow)))
- ++visualRow;
- newRow = d->logicalRow(visualRow);
- }
- return d->model->index(newRow, current.column(), d->root);
+ int newLogicalRow = rowAt(visualRect(current).bottom() - d->viewport->height());
+ int visualRow = (newLogicalRow == -1 ? 0 : d->visualRow(newLogicalRow));
+ visualRow = d->nextActiveVisualRow(visualRow, current.column(), bottom,
+ QTableViewPrivate::SearchDirection::Increasing);
+ newLogicalRow = d->logicalRow(visualRow);
+ return d->model->index(newLogicalRow, current.column(), d->root);
}
case MovePageDown: {
- int newRow = rowAt(visualRect(current).top() + d->viewport->height());
- if (newRow == -1)
- newRow = d->logicalRow(bottom);
- return d->model->index(newRow, current.column(), d->root);
+ int newLogicalRow = rowAt(visualRect(current).top() + d->viewport->height());
+ int visualRow = (newLogicalRow == -1 ? bottom : d->visualRow(newLogicalRow));
+ visualRow = d->nextActiveVisualRow(visualRow, current.column(), -1,
+ QTableViewPrivate::SearchDirection::Decreasing);
+ newLogicalRow = d->logicalRow(visualRow);
+ return d->model->index(newLogicalRow, current.column(), d->root);
}}
d->visualCursor = QPoint(visualColumn, visualRow);
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 520fd9a3af..d55462c28b 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -234,16 +234,16 @@ public:
inline bool isCellEnabled(int row, int column) const {
return isIndexEnabled(model->index(row, column, root));
}
- inline bool isVisualRowHiddenOrDisabled(int row, int column) const {
- int r = logicalRow(row);
- int c = logicalColumn(column);
- return isRowHidden(r) || !isCellEnabled(r, c);
- }
- inline bool isVisualColumnHiddenOrDisabled(int row, int column) const {
- int r = logicalRow(row);
- int c = logicalColumn(column);
- return isColumnHidden(c) || !isCellEnabled(r, c);
- }
+
+ enum class SearchDirection
+ {
+ Increasing,
+ Decreasing
+ };
+ int nextActiveVisualRow(int rowToStart, int column, int limit,
+ SearchDirection searchDirection) const;
+ int nextActiveVisualColumn(int row, int columnToStart, int limit,
+ SearchDirection searchDirection) const;
QRect visualSpanRect(const QSpanCollection::Span &span) const;
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 2e6575c163..9d8b0062f5 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -41,6 +41,7 @@
#endif
#include <QtWidgets/private/qtwidgetsglobal_p.h>
+#include <QtWidgets/private/qlabel_p.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
@@ -127,6 +128,7 @@ public:
~QTipLabel();
static QTipLabel *instance;
+ void adjustTooltipScreen(const QPoint &pos);
void updateSize(const QPoint &pos);
bool eventFilter(QObject *, QEvent *) override;
@@ -222,6 +224,12 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint
void QTipLabel::updateSize(const QPoint &pos)
{
+#ifndef Q_OS_WINRT
+ // ### The code below does not always work well on WinRT
+ // (e.g COIN fails an auto test - tst_QToolTip::qtbug64550_stylesheet - QTBUG-72652)
+ d_func()->setScreenForPoint(pos);
+#endif
+ // Ensure that we get correct sizeHints by placing this window on the right screen.
QFontMetrics fm(font());
QSize extra(1, 0);
// Make it look good with the default ToolTip font on Mac, which has a small descent.
@@ -229,6 +237,7 @@ void QTipLabel::updateSize(const QPoint &pos)
++extra.rheight();
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();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index ccfd3534cd..396a3bcf07 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -2574,6 +2574,27 @@ void QWidgetPrivate::createWinId()
}
}
+/*!
+\internal
+Ensures that the widget is set on the screen point is on. This is handy getting a correct
+size hint before a resize in e.g QMenu and QToolTip
+*/
+
+void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
+{
+ Q_Q(QWidget);
+ if (!q->isWindow())
+ return;
+ // Find the screen for pos and make the widget undertand it is on that screen.
+ const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
+ QScreen *actualScreen = QGuiApplication::screenAt(pos);
+ if (actualScreen && currentScreen != actualScreen) {
+ if (!windowHandle()) // Try to create a window handle if not created.
+ createWinId();
+ if (windowHandle())
+ windowHandle()->setScreen(actualScreen);
+ }
+}
/*!
\internal
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 1f995278f4..7c757a43f2 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -355,6 +355,8 @@ public:
void createRecursively();
void createWinId();
+ void setScreenForPoint(const QPoint &pos);
+
void createTLExtra();
void createExtra();
void deleteExtra();
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index b146cb1183..d1767679f7 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -1679,7 +1679,8 @@ 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());
+ const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle,
+ tr.width(), 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/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 8006be8c27..ac4fb7fbd1 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1998,7 +1998,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
This enum value has been introduced in Qt 5.10.
\value SH_SpinBox_ButtonsInsideFrame
- Determnines if the spin box buttons are inside the line edit frame.
+ Determines if the spin box buttons are inside the line edit frame.
This enum value has been introduced in Qt 5.11.
\value SH_SpinBox_StepModifier
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index bf1102434c..5927331305 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -896,23 +896,6 @@ void QMenuPrivate::_q_overrideMenuActionDestroyed()
menuAction=defaultMenuAction;
}
-void QMenuPrivate::adjustMenuScreen(const QPoint &p)
-{
- Q_Q(QMenu);
- // The windowHandle must point to the screen where the menu will be shown.
- // The (item) size calculations depend on the menu screen,
- // so a wrong screen would often cause wrong sizes (on high DPI)
- const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : nullptr;
- QScreen *actualScreen = QGuiApplication::screenAt(p);
- if (actualScreen && currentScreen != actualScreen) {
- if (!q->windowHandle()) // Try to create a window handle if not created.
- createWinId();
- if (q->windowHandle())
- q->windowHandle()->setScreen(actualScreen);
- itemsDirty = true;
- }
-}
-
void QMenuPrivate::updateLayoutDirection()
{
Q_Q(QMenu);
@@ -2347,7 +2330,8 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->motions = 0;
d->doChildEffects = true;
d->updateLayoutDirection();
- d->adjustMenuScreen(p);
+ // Ensure that we get correct sizeHints by placing this window on the right screen.
+ d->setScreenForPoint(p);
const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) {
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index c39dd33b08..3e1aa2f738 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -456,7 +456,6 @@ public:
bool hasMouseMoved(const QPoint &globalPos);
- void adjustMenuScreen(const QPoint &p);
void updateLayoutDirection();
QPointer<QPlatformMenu> platformMenu;