Customize buttons on MessageBox and confirm before recycling (#2376)

* Add confirmation prompt before moving groups to the recycling bin

Spawn a yes/no QMessage box when "Delete Group" is selected on a group
that is not already in the recycle bin (note: the prompt for deletion
from the recycle bin was already implemented).  This follows the same
pattern and language as entry deletion.

Fixes #2125

* Make prompts for destructive operations use action words on buttons

Replace yes/no, yes/cancel (and other such buttons on prompts that cause
data to be destroyed) use language that indicates the action that it is
going to take. This makes destructive/unsafe and/or irreversible operations
more clear to the user.

Address feedback on PR #2376

* Refactor MessageBox class to allow for custom buttons

Replaces arguments and return values of type QMessageBox::StandardButton(s)
with MessageBox::Button(s), which reimplements the entire set of
QMessageBox::StandardButton and allows for custom KeePassXC buttons,
such as "Skip". Modifies all calls to MessageBox functions to use
MessageBox::Button(s).

Addresses feedback on #2376

* Remove MessageBox::addButton in favor of map lookup

Replaced the switch statement mechanism in MessageBox::addButton with
a map lookup to address CodeFactor Complex Method issue. This has a
side-effect of a small performance/cleanliness increase, as an
extra QPushButton is no longer created/destroyed (to obtain it's label
text) everytime a MessageBox button based on QMessageBox::StandardButton
is created; now the text is obtained once, at application start up.
This commit is contained in:
Kyle Kneitinger 2018-12-19 20:14:11 -08:00 committed by Jonathan White
parent 8ac9d0a131
commit 4d4c839afa
15 changed files with 400 additions and 232 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,35 +20,91 @@
#define KEEPASSX_MESSAGEBOX_H
#include <QMessageBox>
#include <QPushButton>
#include <QMap>
class MessageBox
{
public:
static QMessageBox::StandardButton critical(QWidget* parent,
const QString& title,
const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static QMessageBox::StandardButton information(QWidget* parent,
const QString& title,
const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static QMessageBox::StandardButton question(QWidget* parent,
const QString& title,
const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static QMessageBox::StandardButton warning(QWidget* parent,
const QString& title,
const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
enum Button : uint64_t {
// Reimplementation of Qt StandardButtons
NoButton = 0,
Ok = 1 << 1,
Open = 1 << 2,
Save = 1 << 3,
Cancel = 1 << 4,
Close = 1 << 5,
Discard = 1 << 6,
Apply = 1 << 7,
Reset = 1 << 8,
RestoreDefaults = 1 << 9,
Help = 1 << 10,
SaveAll = 1 << 11,
Yes = 1 << 12,
YesToAll = 1 << 13,
No = 1 << 14,
NoToAll = 1 << 15,
Abort = 1 << 16,
Retry = 1 << 17,
Ignore = 1 << 18,
static void setNextAnswer(QMessageBox::StandardButton button);
// KeePassXC Buttons
Overwrite = 1 << 19,
Delete = 1 << 20,
Move = 1 << 21,
Empty = 1 << 22,
Remove = 1 << 23,
Skip = 1 << 24,
Disable = 1 << 25,
Merge = 1 << 26,
// Internal loop markers. Update Last when new KeePassXC button is added
First = Ok,
Last = Merge,
};
typedef uint64_t Buttons;
static void initializeButtonDefs();
static void setNextAnswer(Button button);
static Button critical(QWidget* parent,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
Button defaultButton = MessageBox::NoButton);
static Button information(QWidget* parent,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
Button defaultButton = MessageBox::NoButton);
static Button question(QWidget* parent,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
Button defaultButton = MessageBox::NoButton);
static Button warning(QWidget* parent,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
Button defaultButton = MessageBox::NoButton);
private:
static QMessageBox::StandardButton m_nextAnswer;
static Button m_nextAnswer;
static QMap<QAbstractButton*, Button> m_addedButtonLookup;
static QMap<Button, std::pair<QString, QMessageBox::ButtonRole>> m_buttonDefs;
static Button messageBox(QWidget* parent,
QMessageBox::Icon icon,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
Button defaultButton = MessageBox::NoButton);
static QString stdButtonText(QMessageBox::StandardButton button);
};
#endif // KEEPASSX_MESSAGEBOX_H