summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-10-05 12:38:45 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2017-10-05 12:38:45 +0000
commit7bbb9a8ce81653b1665c9c942cc707ce98f611c5 (patch)
tree2bbfb13413d95feb6b2e65f3673f750f0bd32ce7 /src/widgets
parent8e70241dccaf5a9e5c79c8d6da5665b881c5914d (diff)
parentbc5f45052fd8f9a5481a37a6a4d55c7f6cbf037d (diff)
Merge "Merge remote-tracking branch 'origin/5.9' into 5.10" into refs/staging/5.10
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/configure.json2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp18
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp37
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp6
-rw-r--r--src/widgets/util/qcompleter_p.h3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp13
-rw-r--r--src/widgets/widgets/qcombobox.cpp38
-rw-r--r--src/widgets/widgets/qmenubar.cpp3
-rw-r--r--src/widgets/widgets/qtabwidget.cpp83
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp17
11 files changed, 147 insertions, 75 deletions
diff --git a/src/widgets/configure.json b/src/widgets/configure.json
index 4c596c09a5..b3a5227d26 100644
--- a/src/widgets/configure.json
+++ b/src/widgets/configure.json
@@ -129,7 +129,7 @@
"label": "QDateTimeEdit",
"purpose": "Supports editing dates and times.",
"section": "Widgets",
- "condition": "features.calendarwidget && features.datestring && features.textdate",
+ "condition": "features.calendarwidget && features.datestring && features.textdate && features.datetimeparser",
"output": [ "publicFeature", "feature" ]
},
"stackedwidget": {
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index fe27be8522..15e6b0eb99 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -2230,7 +2230,7 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
QAbstractScrollArea::focusInEvent(event);
const QItemSelectionModel* model = selectionModel();
- const bool currentIndexValid = currentIndex().isValid();
+ bool currentIndexValid = currentIndex().isValid();
if (model
&& !d->currentIndexSet
@@ -2238,19 +2238,16 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
bool autoScroll = d->autoScroll;
d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
- if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason)
+ if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) {
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ currentIndexValid = true;
+ }
d->autoScroll = autoScroll;
}
- if (model && currentIndexValid) {
- if (currentIndex().flags() != Qt::ItemIsEditable)
- setAttribute(Qt::WA_InputMethodEnabled, false);
- else
- setAttribute(Qt::WA_InputMethodEnabled);
- }
-
- if (!currentIndexValid)
+ if (model && currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, (currentIndex().flags() & Qt::ItemIsEditable));
+ else if (!currentIndexValid)
setAttribute(Qt::WA_InputMethodEnabled, false);
d->viewport->update();
@@ -3665,6 +3662,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
d->shouldScrollToCurrentOnShow = d->autoScroll;
}
}
+ setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable)));
}
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index fca36c7472..5bf66d68e3 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -244,6 +244,36 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state;
}
+static bool logIgnoredEvent(QEvent::Type t)
+{
+ bool result = false;
+ switch (t) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchCancel:
+ case QEvent::TouchEnd:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove:
+ result = true;
+ break;
+ default:
+ break;
+
+ }
+ return result;
+}
+
bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts,
QEvent *event)
@@ -289,10 +319,13 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: not gesture: " << state << event;
notGestures << state;
} else if (recognizerState == QGestureRecognizer::Ignore) {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
+ if (logIgnoredEvent(event->type()))
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
} else {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
+ if (logIgnoredEvent(event->type())) {
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
<< "ignored the event: " << state << event;
+ }
}
if (resultHint & QGestureRecognizer::ConsumeEventHint) {
qCDebug(lcGestureManager) << "QGestureManager: we were asked to consume the event: "
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index a7258d8f7e..3369548f18 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -5888,7 +5888,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset -= effectRect.topLeft();
- const qreal dpr = context->painter->device()->devicePixelRatio();
+ const qreal dpr = context->painter->device()->devicePixelRatioF();
QPixmap pixmap(effectRect.size() * dpr);
pixmap.setDevicePixelRatio(dpr);
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index d2ad7a466e..d388327687 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -89,7 +89,7 @@ public:
void updateUsesNativeWidgets()
{
- if (usesNativeWidgets || window->parent() == 0)
+ if (window->parent() == 0)
return;
Q_Q(QWindowContainer);
if (q->internalWinId()) {
@@ -97,6 +97,7 @@ public:
usesNativeWidgets = true;
return;
}
+ bool nativeWidgetSet = false;
QWidget *p = q->parentWidget();
while (p) {
if (false
@@ -108,11 +109,12 @@ public:
#endif
) {
q->winId();
- usesNativeWidgets = true;
+ nativeWidgetSet = true;
break;
}
p = p->parentWidget();
}
+ usesNativeWidgets = nativeWidgetSet;
}
void markParentChain() {
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
index 179e116d51..e76dcdc8bc 100644
--- a/src/widgets/util/qcompleter_p.h
+++ b/src/widgets/util/qcompleter_p.h
@@ -101,6 +101,9 @@ public:
void _q_autoResizePopup();
void _q_fileSystemModelDirectoryLoaded(const QString &path);
void setCurrentIndex(QModelIndex, bool = true);
+
+ static QCompleterPrivate *get(QCompleter *o) { return o->d_func(); }
+ static const QCompleterPrivate *get(const QCompleter *o) { return o->d_func(); }
};
class QIndexMapper
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index c72c060f9a..3427579d1f 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -39,7 +39,9 @@
#include <qplatformdefs.h>
#include <private/qabstractspinbox_p.h>
+#if QT_CONFIG(datetimeparser)
#include <private/qdatetimeparser_p.h>
+#endif
#include <private/qlineedit_p.h>
#include <qabstractspinbox.h>
@@ -47,9 +49,6 @@
#include <qstylehints.h>
#include <qclipboard.h>
#include <qdatetime.h>
-#if QT_CONFIG(datetimeedit)
-#include <qdatetimeedit.h>
-#endif
#include <qevent.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
@@ -1962,12 +1961,15 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
break;
}
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
QDateTime a2 = arg2.toDateTime();
QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2));
a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time())));
ret = QVariant(a1);
+ break;
}
+#endif // datetimeparser
default: break;
}
return ret;
@@ -2022,6 +2024,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
break;
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
int daysInt = (int)days;
@@ -2031,6 +2034,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(msecs));
break;
}
+#endif // datetimeparser
default: ret = arg1; break;
}
@@ -2053,11 +2057,14 @@ double operator/(const QVariant &arg1, const QVariant &arg2)
a1 = arg1.toDouble();
a2 = arg2.toDouble();
break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime:
a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
a1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000);
a2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000);
+ break;
+#endif // datetimeparser
default: break;
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index cd2e20694e..1338a496e6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -72,6 +72,7 @@
#include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h>
#include <private/qlineedit_p.h>
+#include <private/qcompleter_p.h>
#include <qdebug.h>
#if QT_CONFIG(effects)
# include <private/qeffects_p.h>
@@ -1227,8 +1228,27 @@ Qt::MatchFlags QComboBoxPrivate::matchFlags() const
void QComboBoxPrivate::_q_editingFinished()
{
Q_Q(QComboBox);
- if (lineEdit && !lineEdit->text().isEmpty() && itemText(currentIndex) != lineEdit->text()) {
- const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (!lineEdit)
+ return;
+ const auto leText = lineEdit->text();
+ if (!leText.isEmpty() && itemText(currentIndex) != leText) {
+#if QT_CONFIG(completer)
+ const auto *leCompleter = lineEdit->completer();
+ const auto *popup = leCompleter ? QCompleterPrivate::get(leCompleter)->popup : nullptr;
+ if (popup && popup->isVisible()) {
+ // QLineEdit::editingFinished() will be emitted before the code flow returns
+ // to QCompleter::eventFilter(), where QCompleter::activated() may be emitted.
+ // We know that the completer popup will still be visible at this point, and
+ // that any selection should be valid.
+ const QItemSelectionModel *selModel = popup->selectionModel();
+ const QModelIndex curIndex = popup->currentIndex();
+ const bool completerIsActive = selModel && selModel->selectedIndexes().contains(curIndex);
+
+ if (completerIsActive)
+ return;
+ }
+#endif
+ const int index = q_func()->findText(leText, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -3163,13 +3183,13 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
Q_D(QComboBox);
#if QT_CONFIG(completer)
- if (d->lineEdit
- && d->lineEdit->completer()
- && d->lineEdit->completer()->popup()
- && d->lineEdit->completer()->popup()->isVisible()) {
- // provide same autocompletion support as line edit
- d->lineEdit->event(e);
- return;
+ if (const auto *cmpltr = completer()) {
+ const auto *popup = QCompleterPrivate::get(cmpltr)->popup;
+ if (popup && popup->isVisible()) {
+ // provide same autocompletion support as line edit
+ d->lineEdit->event(e);
+ return;
+ }
}
#endif
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index aa8e6a1c6a..cc6f39c439 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -289,7 +289,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b)
keyboardState = b;
if(b) {
QWidget *fw = QApplication::focusWidget();
- if (fw != q)
+ if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
keyboardFocusWidget = fw;
focusFirstAction();
q->setFocus(Qt::MenuBarFocusReason);
@@ -1707,6 +1707,7 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
}
}
+ keyboardFocusWidget = QApplication::focusWidget();
setCurrentAction(act, true, true);
if (act && !act->menu()) {
activateAction(act, QAction::Trigger);
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index fd783da49a..60a924510a 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -196,6 +196,8 @@ public:
void _q_tabMoved(int from, int to);
void init();
+ void initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const;
+
QTabBar *tabs;
QStackedWidget *stack;
QRect panelRect;
@@ -258,6 +260,43 @@ bool QTabWidget::hasHeightForWidth() const
return has;
}
+/*!
+ \internal
+
+ Initialize only time inexpensive parts of the style option
+ for QTabWidget::setUpLayout()'s non-visible code path.
+*/
+void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const
+{
+ Q_Q(const QTabWidget);
+ option->initFrom(q);
+
+ if (q->documentMode())
+ option->lineWidth = 0;
+ else
+ option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
+
+ switch (pos) {
+ case QTabWidget::North:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
+ : QTabBar::TriangularNorth;
+ break;
+ case QTabWidget::South:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
+ : QTabBar::TriangularSouth;
+ break;
+ case QTabWidget::West:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedWest
+ : QTabBar::TriangularWest;
+ break;
+ case QTabWidget::East:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedEast
+ : QTabBar::TriangularEast;
+ break;
+ }
+
+ option->tabBarRect = q->tabBar()->geometry();
+}
/*!
Initialize \a option with the values from this QTabWidget. This method is useful
@@ -272,12 +311,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
return;
Q_D(const QTabWidget);
- option->initFrom(this);
-
- if (documentMode())
- option->lineWidth = 0;
- else
- option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
+ d->initBasicStyleOption(option);
int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this);
QSize t(0, d->stack->frameWidth());
@@ -308,31 +342,10 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
option->leftCornerWidgetSize = QSize(0, 0);
}
- switch (d->pos) {
- case QTabWidget::North:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
- : QTabBar::TriangularNorth;
- break;
- case QTabWidget::South:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
- : QTabBar::TriangularSouth;
- break;
- case QTabWidget::West:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedWest
- : QTabBar::TriangularWest;
- break;
- case QTabWidget::East:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedEast
- : QTabBar::TriangularEast;
- break;
- }
-
option->tabBarSize = t;
- QRect tbRect = tabBar()->geometry();
QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
- option->tabBarRect = tbRect;
- selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
+ selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + option->tabBarRect.topLeft());
option->selectedTabRect = selectedTabRect;
}
@@ -764,17 +777,19 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty)
return; // nothing to do
- QStyleOptionTabWidgetFrame option;
- initStyleOption(&option);
-
- // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
- d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
-
if (!isVisible()) {
+ // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
+ QStyleOptionTabWidgetFrame basicOption;
+ d->initBasicStyleOption(&basicOption);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &basicOption);
d->dirty = true;
return; // we'll do it later
}
+ QStyleOptionTabWidgetFrame option;
+ initStyleOption(&option);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
+
QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 1b7a41d547..4f4a6f70b5 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -44,6 +44,7 @@
#endif
#include "qclipboard.h"
#include <private/qguiapplication_p.h>
+#include <private/qcompleter_p.h>
#include <qpa/qplatformtheme.h>
#include <qstylehints.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -1484,7 +1485,8 @@ void QWidgetLineControl::complete(int key)
} else {
#ifndef QT_KEYPAD_NAVIGATION
if (text.isEmpty()) {
- m_completer->popup()->hide();
+ if (auto *popup = QCompleterPrivate::get(m_completer)->popup)
+ popup->hide();
return;
}
#endif
@@ -1630,25 +1632,16 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
#if QT_CONFIG(completer)
if (m_completer) {
QCompleter::CompletionMode completionMode = m_completer->completionMode();
+ auto *popup = QCompleterPrivate::get(m_completer)->popup;
if ((completionMode == QCompleter::PopupCompletion
|| completionMode == QCompleter::UnfilteredPopupCompletion)
- && m_completer->popup()
- && m_completer->popup()->isVisible()) {
+ && popup && popup->isVisible()) {
// The following keys are forwarded by the completer to the widget
// Ignoring the events lets the completer provide suitable default behavior
switch (event->key()) {
case Qt::Key_Escape:
event->ignore();
return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- m_completer->popup()->hide(); // just hide. will end up propagating to parent
default:
break; // normal key processing
}