manage conflicting hotkeys in QComboBox, QLineEdit, QSpinBox

This commit is contained in:
Garux
2022-12-20 23:41:16 +06:00
parent 88a03b07be
commit 2ed868d254
8 changed files with 145 additions and 25 deletions

41
libs/gtkutil/combobox.h Normal file
View File

@@ -0,0 +1,41 @@
/*
Copyright (C) 2001-2006, William Joseph.
All Rights Reserved.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <QComboBox>
#include <QKeyEvent>
/// @brief Subclassed QComboBox not comsuming Enter key (why does it do it? works as expected for editable ComboBox)
/// purpose is to have working confirmation by Enter in dialogs
/// fixme unsolved crude problem here is triggering arrows, page, home, end global shortcuts when pressed in popup; even if modal dialog 😱
class ComboBox : public QComboBox
{
protected:
void keyPressEvent( QKeyEvent *event ) override {
if( event->key() == Qt::Key_Enter
|| event->key() == Qt::Key_Return ){
event->ignore();
return;
}
QComboBox::keyPressEvent( event );
}
};

54
libs/gtkutil/lineedit.h Normal file
View File

@@ -0,0 +1,54 @@
/*
Copyright (C) 2001-2006, William Joseph.
All Rights Reserved.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <QLineEdit>
#include <QKeyEvent>
#include <QCompleter>
#include <QAbstractItemView>
/// @brief Subclassed QLineEdit not comsuming undo/redo shortcuts
/// it's more useful to have working undo of editor
/// Qt should better not eat these shortcuts when QLineEdit's undo is disabled, but it does
class LineEdit : public QLineEdit
{
protected:
bool event( QEvent *event ) override {
if( event->type() == QEvent::ShortcutOverride ){
QKeyEvent *keyEvent = static_cast<QKeyEvent *>( event );
if( keyEvent == QKeySequence::StandardKey::Undo
|| keyEvent == QKeySequence::StandardKey::Redo )
return false;
// fix QCompleter leaking shortcuts
if( completer() != nullptr && completer()->popup() != nullptr && completer()->popup()->isVisible() )
if( keyEvent->key() == Qt::Key_Return
|| keyEvent->key() == Qt::Key_Enter
|| keyEvent->key() == Qt::Key_Escape
|| keyEvent->key() == Qt::Key_Up
|| keyEvent->key() == Qt::Key_Down
|| keyEvent->key() == Qt::Key_PageUp
|| keyEvent->key() == Qt::Key_PageDown )
event->accept();
}
return QLineEdit::event( event );
}
};

View File

@@ -21,22 +21,20 @@
#pragma once
#include <QLineEdit>
#include <QKeyEvent>
#include "lineedit.h"
#include "spinbox.h"
#include <QTimer>
#include "generic/callback.h"
#include "spinbox.h"
class NonModalEntry : public QLineEdit
class NonModalEntry : public LineEdit
{
bool m_editing{};
Callback m_apply;
Callback m_cancel;
public:
NonModalEntry( const Callback& apply, const Callback& cancel ) : QLineEdit(), m_apply( apply ), m_cancel( cancel ){
NonModalEntry( const Callback& apply, const Callback& cancel ) : LineEdit(), m_apply( apply ), m_cancel( cancel ){
QObject::connect( this, &QLineEdit::textEdited, [this](){ m_editing = true; } );
QObject::connect( this, &QLineEdit::editingFinished, [this](){ // on enter or focus out
if( m_editing ){
@@ -53,11 +51,12 @@ protected:
if( keyEvent->key() == Qt::Key_Escape ){
m_editing = false;
m_cancel();
clearFocus();
event->accept();
// defer clearFocus(); as immediately done after certain actions = cursor visible + not handling key input
QTimer::singleShot( 0, [this](){ clearFocus(); } );
}
}
return QLineEdit::event( event );
return LineEdit::event( event );
}
void focusInEvent( QFocusEvent *event ) override {
if( event->reason() == Qt::FocusReason::MouseFocusReason )

View File

@@ -45,14 +45,23 @@ public:
}
protected:
bool event( QEvent *event ) override {
/* QAbstractSpinBox has no well defined ShortcutOverride routine, unlike underlying QLineEdit
thus box' portion of key events ends up firing application's shortcuts (e.g. up, down, pgUp, pgDown)
let's lock entire input on the box except a few keys, handled by parent window */
if( event->type() == QEvent::ShortcutOverride ){
QKeyEvent *keyEvent = static_cast<QKeyEvent *>( event );
if( keyEvent->key() != Qt::Key_Return
&& keyEvent->key() != Qt::Key_Enter
&& keyEvent->key() != Qt::Key_Escape )
// don't pass undo/redo to be eaten by underlying lineedit
// it's more useful to have working undo of editor
if( keyEvent == QKeySequence::StandardKey::Undo
|| keyEvent == QKeySequence::StandardKey::Redo )
return false;
/* QAbstractSpinBox has no well defined ShortcutOverride routine, unlike underlying QLineEdit
thus box' portion of key events ends up firing application's shortcuts (e.g. up, down, pgUp, pgDown)
let's implement it kinda */
if( keyEvent->key() == Qt::Key_PageUp
|| keyEvent->key() == Qt::Key_PageDown
|| keyEvent->key() == Qt::Key_Up
|| keyEvent->key() == Qt::Key_Down
|| keyEvent->key() == Qt::Key_End
|| keyEvent->key() == Qt::Key_Home
|| keyEvent == QKeySequence::StandardKey::SelectAll )
event->accept();
}
return SpinT::event( event );