mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
bc837163f5
commit
e6be14bf10
2 changed files with 23 additions and 0 deletions
|
@ -80,6 +80,7 @@ struct CurrSelected{
|
||||||
int currRow;
|
int currRow;
|
||||||
QString activeText;
|
QString activeText;
|
||||||
QAbstractItemModel *model;
|
QAbstractItemModel *model;
|
||||||
|
bool ignoreSelection;
|
||||||
} currCombo;
|
} currCombo;
|
||||||
|
|
||||||
QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
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->setAutoCompletion(true);
|
||||||
comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive);
|
comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive);
|
||||||
comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion);
|
comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion);
|
||||||
|
comboDelegate->view()->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||||
comboDelegate->lineEdit()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this)));
|
comboDelegate->lineEdit()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this)));
|
||||||
comboDelegate->view()->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(highlighted(QString)), this, SLOT(testActivation(QString)));
|
||||||
|
connect(comboDelegate, SIGNAL(activated(QString)), this, SLOT(fakeActivation()));
|
||||||
currCombo.comboEditor = comboDelegate;
|
currCombo.comboEditor = comboDelegate;
|
||||||
currCombo.currRow = index.row();
|
currCombo.currRow = index.row();
|
||||||
currCombo.model = const_cast<QAbstractItemModel*>(index.model());
|
currCombo.model = const_cast<QAbstractItemModel*>(index.model());
|
||||||
|
@ -105,6 +108,23 @@ void ComboBoxDelegate::testActivation(const QString& s)
|
||||||
setModelData(currCombo.comboEditor, currCombo.model, QModelIndex());
|
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)
|
bool ComboBoxDelegate::eventFilter(QObject* object, QEvent* event)
|
||||||
{
|
{
|
||||||
// Reacts on Key_UP and Key_DOWN to show the QComboBox - list of choices.
|
// 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
|
if (object == currCombo.comboEditor){ // the 'LineEdit' part
|
||||||
QKeyEvent *ev = static_cast<QKeyEvent*>(event);
|
QKeyEvent *ev = static_cast<QKeyEvent*>(event);
|
||||||
if(ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down){
|
if(ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down){
|
||||||
|
currCombo.ignoreSelection = true;
|
||||||
currCombo.comboEditor->showPopup();
|
currCombo.comboEditor->showPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
virtual bool eventFilter(QObject* object, QEvent* event);
|
virtual bool eventFilter(QObject* object, QEvent* event);
|
||||||
public slots:
|
public slots:
|
||||||
void testActivation(const QString& s);
|
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;
|
virtual void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) = 0;
|
||||||
protected:
|
protected:
|
||||||
QAbstractItemModel *model;
|
QAbstractItemModel *model;
|
||||||
|
|
Loading…
Add table
Reference in a new issue