diff options
author | Tomaz Canabrava <tcanabrava@kde.org> | 2013-09-25 16:37:24 -0300 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-09-25 12:48:24 -0700 |
commit | e6be14bf104e608f80c9ef1539ea5c51b92793f9 (patch) | |
tree | 25800967baf290d7546dd7789a5576d540787d90 | |
parent | bc837163f505a8d9722a0cea5d71ce998b79d7d4 (diff) | |
download | subsurface-e6be14bf104e608f80c9ef1539ea5c51b92793f9.tar.gz |
Make the Qt ComboBox behave in a Better Way
So, the ComboBox is a beast, and when used on a Delegate
it's very hard to get things right, wich is a pitty, because
I overly like qt. So:
1 - Combobox needs to show the popup when user press ↓ and ↑ keys
2 - Combobox needs to select when user press enter, not twice.
3 - Combobox neesds to select when user selects from the mouse, not
pressing enter after.
4 - Combobox needs to not mess with stuff when moving around.
Everything that I listed there works on a non-delegate combobox,
but for some reason, a delegate missed those, so I reimplemented
all. not nice, but now we have a code that will work, I hope.
*fingers crossed*
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
-rw-r--r-- | qt-ui/modeldelegates.cpp | 21 | ||||
-rw-r--r-- | qt-ui/modeldelegates.h | 2 |
2 files changed, 23 insertions, 0 deletions
diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp index 13201e436..ab91f1673 100644 --- a/qt-ui/modeldelegates.cpp +++ b/qt-ui/modeldelegates.cpp @@ -80,6 +80,7 @@ struct CurrSelected{ int currRow; QString activeText; QAbstractItemModel *model; + bool ignoreSelection; } currCombo; QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const @@ -90,9 +91,11 @@ QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewI comboDelegate->setAutoCompletion(true); comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion); + comboDelegate->view()->setEditTriggers(QAbstractItemView::AllEditTriggers); comboDelegate->lineEdit()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this))); comboDelegate->view()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this))); connect(comboDelegate, SIGNAL(highlighted(QString)), this, SLOT(testActivation(QString))); + connect(comboDelegate, SIGNAL(activated(QString)), this, SLOT(fakeActivation())); currCombo.comboEditor = comboDelegate; currCombo.currRow = index.row(); currCombo.model = const_cast<QAbstractItemModel*>(index.model()); @@ -105,6 +108,23 @@ void ComboBoxDelegate::testActivation(const QString& s) setModelData(currCombo.comboEditor, currCombo.model, QModelIndex()); } +// HACK, send a fake event so Qt thinks we hit 'enter' on the line edit. +void ComboBoxDelegate::fakeActivation(){ + /* this test is needed because as soon as I show the selector, + * the first item gots selected, this sending an activated signal, + * calling this fakeActivation code and setting as the current, + * thig that we don't want. so, let's just set the ignoreSelection + * to false and be happy, because the next activation ( by click + * or keypress) is real. + */ + if(currCombo.ignoreSelection){ + currCombo.ignoreSelection = false; + return; + } + QKeyEvent ev(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); + QStyledItemDelegate::eventFilter(currCombo.comboEditor, &ev); +} + bool ComboBoxDelegate::eventFilter(QObject* object, QEvent* event) { // Reacts on Key_UP and Key_DOWN to show the QComboBox - list of choices. @@ -112,6 +132,7 @@ bool ComboBoxDelegate::eventFilter(QObject* object, QEvent* event) if (object == currCombo.comboEditor){ // the 'LineEdit' part QKeyEvent *ev = static_cast<QKeyEvent*>(event); if(ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down){ + currCombo.ignoreSelection = true; currCombo.comboEditor->showPopup(); } } diff --git a/qt-ui/modeldelegates.h b/qt-ui/modeldelegates.h index 29d4f3717..92826ba41 100644 --- a/qt-ui/modeldelegates.h +++ b/qt-ui/modeldelegates.h @@ -24,6 +24,8 @@ public: virtual bool eventFilter(QObject* object, QEvent* event); public slots: void testActivation(const QString& s); + //HACK: try to get rid of this in the future. + void fakeActivation(); virtual void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) = 0; protected: QAbstractItemModel *model; |