Merge #13791: gui: Reject dialogs if key escape is pressed

7bf22bf0c2 gui: Reject options dialog when key escape is pressed (João Barbosa)
4a43306a4f gui: Reject edit address dialog when key escape is pressed (João Barbosa)
f7a553177d gui: Add GUIUtil::ItemDelegate with keyEscapePressed signal (João Barbosa)

Pull request description:

  Currently `EditAddressDialog` and `OptionsDialog` don't close when the escape key is pressed. The `QDataWidgetMapper` instances prevents closing the dialogs because the escape key is used to reset the widgets values. More details and workarounds in https://stackoverflow.com/a/51487847 and http://qtramblings.blogspot.com/2010/10/qdatawidgetmapper-annoyances.html.

  The adopted solution is different from the above references. It turns out that `QDataWidgetMapper::setItemDelegate` sets the event filter for all mapped widgets. So in this PR the mapper's delegate are changed to a custom `GUIUtil::ItemDelegate` that offers the signal `keyEscapePressed`, which is connected to the `QDialog::reject` slot.

  Note that the installed event filter lets all events pass, so the current behaviour isn't changed, meaning that widgets values are reset in addition to closing the dialog.

Tree-SHA512: 9c961d488480b4ccc3880a11a8f1824b65f77570ee8918c7302c62775a1a73e52ae988a31a55ffff87b4170ddbecf833c2f09b66095c00eb6854a4d43f030f1f
This commit is contained in:
Wladimir J. van der Laan 2018-08-02 12:45:15 +02:00
commit 2c14c1fa2f
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
4 changed files with 32 additions and 0 deletions

View file

@ -39,6 +39,10 @@ EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
mapper = new QDataWidgetMapper(this); mapper = new QDataWidgetMapper(this);
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
GUIUtil::ItemDelegate* delegate = new GUIUtil::ItemDelegate(mapper);
connect(delegate, &GUIUtil::ItemDelegate::keyEscapePressed, this, &EditAddressDialog::reject);
mapper->setItemDelegate(delegate);
} }
EditAddressDialog::~EditAddressDialog() EditAddressDialog::~EditAddressDialog()

View file

@ -49,6 +49,7 @@
#include <QDoubleValidator> #include <QDoubleValidator>
#include <QFileDialog> #include <QFileDialog>
#include <QFont> #include <QFont>
#include <QKeyEvent>
#include <QLineEdit> #include <QLineEdit>
#include <QSettings> #include <QSettings>
#include <QTextDocument> // for Qt::mightBeRichText #include <QTextDocument> // for Qt::mightBeRichText
@ -927,4 +928,14 @@ void ClickableProgressBar::mouseReleaseEvent(QMouseEvent *event)
Q_EMIT clicked(event->pos()); Q_EMIT clicked(event->pos());
} }
bool ItemDelegate::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
Q_EMIT keyEscapePressed();
}
}
return QItemDelegate::eventFilter(object, event);
}
} // namespace GUIUtil } // namespace GUIUtil

View file

@ -10,6 +10,7 @@
#include <QEvent> #include <QEvent>
#include <QHeaderView> #include <QHeaderView>
#include <QItemDelegate>
#include <QMessageBox> #include <QMessageBox>
#include <QObject> #include <QObject>
#include <QProgressBar> #include <QProgressBar>
@ -232,6 +233,18 @@ namespace GUIUtil
typedef ClickableProgressBar ProgressBar; typedef ClickableProgressBar ProgressBar;
class ItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
ItemDelegate(QObject* parent) : QItemDelegate(parent) {}
Q_SIGNALS:
void keyEscapePressed();
private:
bool eventFilter(QObject *object, QEvent *event);
};
} // namespace GUIUtil } // namespace GUIUtil
#endif // BITCOIN_QT_GUIUTIL_H #endif // BITCOIN_QT_GUIUTIL_H

View file

@ -115,6 +115,10 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical); mapper->setOrientation(Qt::Vertical);
GUIUtil::ItemDelegate* delegate = new GUIUtil::ItemDelegate(mapper);
connect(delegate, &GUIUtil::ItemDelegate::keyEscapePressed, this, &OptionsDialog::reject);
mapper->setItemDelegate(delegate);
/* setup/change UI elements when proxy IPs are invalid/valid */ /* setup/change UI elements when proxy IPs are invalid/valid */
ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent)); ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent)); ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));