summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tomaz Canabrava <tcanabrava@kde.org>2013-09-25 16:37:24 -0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-09-25 12:48:24 -0700
commite6be14bf104e608f80c9ef1539ea5c51b92793f9 (patch)
tree25800967baf290d7546dd7789a5576d540787d90
parentbc837163f505a8d9722a0cea5d71ce998b79d7d4 (diff)
downloadsubsurface-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.cpp21
-rw-r--r--qt-ui/modeldelegates.h2
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;