summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/widgets/qcombobox.cpp19
-rw-r--r--src/widgets/widgets/qcombobox_p.h4
-rw-r--r--tests/manual/widgets/itemviews/delegate/example.cpp41
3 files changed, 56 insertions, 8 deletions
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index bdd06da7fc..90310308c3 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -407,7 +407,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *)
}
QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent)
- : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0)
+ : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0), maybeIgnoreMouseButtonRelease(false)
{
// we need the combobox and itemview
Q_ASSERT(parent);
@@ -667,10 +667,15 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
}
}
break;
+ case QEvent::MouseButtonPress:
+ maybeIgnoreMouseButtonRelease = false;
+ break;
case QEvent::MouseButtonRelease: {
+ bool ignoreEvent = maybeIgnoreMouseButtonRelease && popupTimer.elapsed() < QApplication::doubleClickInterval();
+
QMouseEvent *m = static_cast<QMouseEvent *>(e);
if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()
- && !blockMouseReleaseTimer.isActive()
+ && !blockMouseReleaseTimer.isActive() && !ignoreEvent
&& (view->currentIndex().flags() & Qt::ItemIsEnabled)
&& (view->currentIndex().flags() & Qt::ItemIsSelectable)) {
combo->hidePopup();
@@ -2562,6 +2567,7 @@ void QComboBox::showPopup()
container->setUpdatesEnabled(false);
#endif
+ bool startTimer = !container->isVisible();
container->raise();
container->show();
container->updateScrollers();
@@ -2581,6 +2587,10 @@ void QComboBox::showPopup()
if (QApplication::keypadNavigationEnabled())
view()->setEditFocus(true);
#endif
+ if (startTimer) {
+ container->popupTimer.start();
+ container->maybeIgnoreMouseButtonRelease = true;
+ }
}
/*!
@@ -2876,6 +2886,11 @@ void QComboBox::mousePressEvent(QMouseEvent *e)
}
#endif
showPopup();
+ // The code below ensures that regular mousepress and pick item still works
+ // If it was not called the viewContainer would ignore event since it didn't have
+ // a mousePressEvent first.
+ if (d->viewContainer())
+ d->viewContainer()->maybeIgnoreMouseButtonRelease = false;
} else {
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && d->lineEdit) {
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 07ba9b0925..1ad2aa455a 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -254,6 +254,10 @@ private:
QAbstractItemView *view;
QComboBoxPrivateScroller *top;
QComboBoxPrivateScroller *bottom;
+ bool maybeIgnoreMouseButtonRelease;
+ QElapsedTimer popupTimer;
+
+ friend class QComboBox;
};
class QComboMenuDelegate : public QAbstractItemDelegate
diff --git a/tests/manual/widgets/itemviews/delegate/example.cpp b/tests/manual/widgets/itemviews/delegate/example.cpp
index c65f49f266..dcebf437b1 100644
--- a/tests/manual/widgets/itemviews/delegate/example.cpp
+++ b/tests/manual/widgets/itemviews/delegate/example.cpp
@@ -45,6 +45,7 @@
#include <QStandardItemModel>
#include <QItemDelegate>
#include <QDebug>
+#include <QComboBox>
class ExampleEditor : public QLineEdit
{
@@ -56,13 +57,26 @@ public:
class ExampleDelegate : public QItemDelegate
{
public:
- ExampleDelegate():QItemDelegate() { m_editor = new ExampleEditor(0); }
+ ExampleDelegate() : QItemDelegate()
+ {
+ m_editor = new ExampleEditor(0);
+ m_combobox = new QComboBox(0);
+ m_combobox->addItem(QString::fromUtf8("item1"));
+ m_combobox->addItem(QString::fromUtf8("item2"));
+ }
protected:
- QWidget* createEditor(QWidget *p, const QStyleOptionViewItem &o, const QModelIndex &) const
+ QWidget* createEditor(QWidget *p, const QStyleOptionViewItem &o, const QModelIndex &i) const
{
- m_editor->setParent(p);
- m_editor->setGeometry(o.rect);
- return m_editor;
+ // doubleclick rownumber 3 (last row) to see the difference.
+ if (i.row() == 3) {
+ m_combobox->setParent(p);
+ m_combobox->setGeometry(o.rect);
+ return m_combobox;
+ } else {
+ m_editor->setParent(p);
+ m_editor->setGeometry(o.rect);
+ return m_editor;
+ }
}
void destroyEditor(QWidget *editor, const QModelIndex &) const
{
@@ -71,10 +85,25 @@ protected:
}
// Avoid setting data - and therefore show that the editor keeps its state.
- void setEditorData(QWidget*, const QModelIndex &) const { }
+ void setEditorData(QWidget* w, const QModelIndex &) const
+ {
+ QComboBox *combobox = qobject_cast<QComboBox*>(w);
+ if (combobox) {
+ qDebug() << "Try to show popup at once";
+ // Now we could try to make a call to
+ // QCoreApplication::processEvents();
+ // But it does not matter. The fix:
+ // https://codereview.qt-project.org/40608
+ // is blocking QComboBox from reacting to this doubleclick edit event
+ // and we need to do that since the mouseReleaseEvent has not yet happened,
+ // and therefore cannot be processed.
+ combobox->showPopup();
+ }
+ }
~ExampleDelegate() { delete m_editor; }
mutable ExampleEditor *m_editor;
+ mutable QComboBox *m_combobox;
};
int main(int argc, char *argv[])