Fix shortcut conflict when one is a default (#1989)
* Fix config checking on startup Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Handle conflicts when one shortcut is a default Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix bugs Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Refactor slot in ShortcutsWidget for consistency Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Update shortcut table on config file change Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix bounded int bug in config Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Revert changes manually Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Reimplement ConfigHandler::shortcut and setShortcut Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Handle Return/Numpad-Enter equivalently Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Re-enable user-configured Imgur upload shortcut Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Document copyAndCloseAfterUpload config option Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com>
This commit is contained in:
@@ -66,6 +66,9 @@
|
||||
;; Copy path to image after save (bool)
|
||||
;copyPathAfterSave=false
|
||||
;
|
||||
;; On successful upload, close the dialog and copy URL to clipboard.
|
||||
;copyAndCloseAfterUpload=true
|
||||
;
|
||||
;; Anti-aliasing image when zoom the pinned image (bool)
|
||||
;antialiasingPinZoom=true
|
||||
;
|
||||
|
||||
@@ -187,7 +187,7 @@ void ConfigWindow::initErrorIndicator(QWidget* tab, QWidget* widget)
|
||||
|
||||
qApp->processEvents();
|
||||
QPoint center = dialog.geometry().center();
|
||||
QRect dialogRect(0, 0, 400, 400);
|
||||
QRect dialogRect(0, 0, 600, 400);
|
||||
dialogRect.moveCenter(center);
|
||||
dialog.setGeometry(dialogRect);
|
||||
|
||||
|
||||
@@ -38,16 +38,14 @@ ShortcutsWidget::ShortcutsWidget(QWidget* parent)
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
|
||||
initShortcuts();
|
||||
initInfoTable();
|
||||
connect(ConfigHandler::getInstance(),
|
||||
&ConfigHandler::fileChanged,
|
||||
this,
|
||||
&ShortcutsWidget::populateInfoTable);
|
||||
show();
|
||||
}
|
||||
|
||||
const QList<QStringList>& ShortcutsWidget::shortcuts()
|
||||
{
|
||||
return m_shortcuts;
|
||||
}
|
||||
|
||||
void ShortcutsWidget::initInfoTable()
|
||||
{
|
||||
m_table = new QTableWidget(this);
|
||||
@@ -56,7 +54,6 @@ void ShortcutsWidget::initInfoTable()
|
||||
m_layout->addWidget(m_table);
|
||||
|
||||
m_table->setColumnCount(2);
|
||||
m_table->setRowCount(m_shortcuts.size());
|
||||
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
m_table->setFocusPolicy(Qt::NoFocus);
|
||||
m_table->verticalHeader()->hide();
|
||||
@@ -66,21 +63,35 @@ void ShortcutsWidget::initInfoTable()
|
||||
names << tr("Description") << tr("Key");
|
||||
m_table->setHorizontalHeaderLabels(names);
|
||||
connect(m_table,
|
||||
SIGNAL(cellClicked(int, int)),
|
||||
&QTableWidget::cellClicked,
|
||||
this,
|
||||
SLOT(slotShortcutCellClicked(int, int)));
|
||||
&ShortcutsWidget::onShortcutCellClicked);
|
||||
|
||||
// populate with dynamic data
|
||||
populateInfoTable();
|
||||
|
||||
// adjust size
|
||||
m_table->horizontalHeader()->setMinimumSectionSize(200);
|
||||
m_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
m_table->horizontalHeader()->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
m_table->resizeColumnsToContents();
|
||||
m_table->resizeRowsToContents();
|
||||
}
|
||||
|
||||
void ShortcutsWidget::populateInfoTable()
|
||||
{
|
||||
loadShortcuts();
|
||||
m_table->setRowCount(m_shortcuts.size());
|
||||
|
||||
// add content
|
||||
for (int i = 0; i < shortcuts().size(); ++i) {
|
||||
for (int i = 0; i < m_shortcuts.size(); ++i) {
|
||||
const auto current_shortcut = m_shortcuts.at(i);
|
||||
const auto identifier = current_shortcut.at(0);
|
||||
const auto description = current_shortcut.at(1);
|
||||
const auto default_key_sequence = current_shortcut.at(2);
|
||||
const auto key_sequence = current_shortcut.at(2);
|
||||
m_table->setItem(i, 0, new QTableWidgetItem(description));
|
||||
|
||||
const auto key_sequence = identifier.isEmpty()
|
||||
? default_key_sequence
|
||||
: m_config.shortcut(identifier);
|
||||
#if defined(Q_OS_MACOS)
|
||||
QTableWidgetItem* item =
|
||||
new QTableWidgetItem(nativeOSHotKeyText(key_sequence));
|
||||
@@ -106,17 +117,9 @@ void ShortcutsWidget::initInfoTable()
|
||||
item->setFlags(item->flags() ^ Qt::ItemIsEditable);
|
||||
}
|
||||
}
|
||||
|
||||
// adjust size
|
||||
m_table->resizeColumnsToContents();
|
||||
m_table->resizeRowsToContents();
|
||||
m_table->horizontalHeader()->setMinimumSectionSize(200);
|
||||
m_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
m_table->horizontalHeader()->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
}
|
||||
|
||||
void ShortcutsWidget::slotShortcutCellClicked(int row, int col)
|
||||
void ShortcutsWidget::onShortcutCellClicked(int row, int col)
|
||||
{
|
||||
if (col == 1) {
|
||||
// Ignore non-changable shortcuts
|
||||
@@ -140,38 +143,27 @@ void ShortcutsWidget::slotShortcutCellClicked(int row, int col)
|
||||
shortcutValue = QKeySequence("");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_config.setShortcut(shortcutName, shortcutValue.toString())) {
|
||||
#if defined(Q_OS_MACOS)
|
||||
QTableWidgetItem* item = new QTableWidgetItem(
|
||||
nativeOSHotKeyText(shortcutValue.toString()));
|
||||
#else
|
||||
QTableWidgetItem* item =
|
||||
new QTableWidgetItem(shortcutValue.toString());
|
||||
#endif
|
||||
item->setTextAlignment(Qt::AlignCenter);
|
||||
item->setFlags(item->flags() ^ Qt::ItemIsEditable);
|
||||
m_table->setItem(row, col, item);
|
||||
populateInfoTable();
|
||||
}
|
||||
}
|
||||
delete setShortcutDialog;
|
||||
}
|
||||
}
|
||||
|
||||
void ShortcutsWidget::initShortcuts()
|
||||
void ShortcutsWidget::loadShortcuts()
|
||||
{
|
||||
m_shortcuts.clear();
|
||||
auto buttonTypes = CaptureToolButton::getIterableButtonTypes();
|
||||
|
||||
// get shortcuts names from capture buttons
|
||||
for (const CaptureTool::Type& t : buttonTypes) {
|
||||
CaptureTool* tool = ToolFactory().CreateTool(t);
|
||||
QString shortcutName = QVariant::fromValue(t).toString();
|
||||
if (t != CaptureTool::TYPE_IMAGEUPLOADER) {
|
||||
appendShortcut(shortcutName, tool->description());
|
||||
if (shortcutName == "TYPE_COPY")
|
||||
m_shortcuts << (QStringList() << "" << tool->description()
|
||||
<< "Left Double-click");
|
||||
}
|
||||
appendShortcut(shortcutName, tool->description());
|
||||
if (shortcutName == "TYPE_COPY")
|
||||
m_shortcuts << (QStringList() << "" << tool->description()
|
||||
<< "Left Double-click");
|
||||
delete tool;
|
||||
}
|
||||
|
||||
@@ -219,10 +211,11 @@ void ShortcutsWidget::initShortcuts()
|
||||
void ShortcutsWidget::appendShortcut(const QString& shortcutName,
|
||||
const QString& description)
|
||||
{
|
||||
QString shortcut = ConfigHandler().shortcut(shortcutName);
|
||||
m_shortcuts << (QStringList()
|
||||
<< shortcutName
|
||||
<< QObject::tr(description.toStdString().c_str())
|
||||
<< ConfigHandler().shortcut(shortcutName));
|
||||
<< shortcut.replace("Return", "Enter"));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
|
||||
@@ -18,7 +18,6 @@ class ShortcutsWidget : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ShortcutsWidget(QWidget* parent = nullptr);
|
||||
const QList<QStringList>& shortcuts();
|
||||
|
||||
private:
|
||||
void initInfoTable();
|
||||
@@ -28,7 +27,8 @@ private:
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void slotShortcutCellClicked(int, int);
|
||||
void populateInfoTable();
|
||||
void onShortcutCellClicked(int, int);
|
||||
|
||||
private:
|
||||
#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
QVBoxLayout* m_layout;
|
||||
QList<QStringList> m_shortcuts;
|
||||
|
||||
void initShortcuts();
|
||||
void loadShortcuts();
|
||||
void appendShortcut(const QString& shortcutName,
|
||||
const QString& description);
|
||||
};
|
||||
|
||||
@@ -131,7 +131,7 @@ static QMap<QString, QSharedPointer<KeySequence>> recognizedShortcuts = {
|
||||
SHORTCUT("TYPE_SAVE" , "Ctrl+S" ),
|
||||
SHORTCUT("TYPE_ACCEPT" , "Return" ),
|
||||
SHORTCUT("TYPE_EXIT" , "Ctrl+Q" ),
|
||||
SHORTCUT("TYPE_IMAGEUPLOADER" , "Ctrl+U" ),
|
||||
SHORTCUT("TYPE_IMAGEUPLOADER" , ),
|
||||
#if !defined(Q_OS_MACOS)
|
||||
SHORTCUT("TYPE_OPEN_APP" , "Ctrl+O" ),
|
||||
#endif
|
||||
@@ -161,6 +161,7 @@ static QMap<QString, QSharedPointer<KeySequence>> recognizedShortcuts = {
|
||||
SHORTCUT("TYPE_SIZEDECREASE" , ),
|
||||
SHORTCUT("TYPE_CIRCLECOUNT" , ),
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
// CLASS CONFIGHANDLER
|
||||
@@ -171,12 +172,14 @@ ConfigHandler::ConfigHandler(bool skipInitialErrorCheck)
|
||||
qApp->organizationName(),
|
||||
qApp->applicationName())
|
||||
{
|
||||
|
||||
if (m_configWatcher == nullptr) {
|
||||
if (!skipInitialErrorCheck) {
|
||||
// check for error on initial call
|
||||
checkAndHandleError();
|
||||
}
|
||||
static bool wasEverChecked = false;
|
||||
static bool firstInitialization = true;
|
||||
if (!skipInitialErrorCheck && !wasEverChecked) {
|
||||
// check for error on initial call
|
||||
checkAndHandleError();
|
||||
wasEverChecked = true;
|
||||
}
|
||||
if (firstInitialization) {
|
||||
// check for error every time the file changes
|
||||
m_configWatcher.reset(new QFileSystemWatcher());
|
||||
ensureFileWatched();
|
||||
@@ -201,6 +204,7 @@ ConfigHandler::ConfigHandler(bool skipInitialErrorCheck)
|
||||
}
|
||||
});
|
||||
}
|
||||
firstInitialization = false;
|
||||
}
|
||||
|
||||
/// Serves as an object to which slots can be connected.
|
||||
@@ -363,59 +367,79 @@ QString ConfigHandler::configFilePath() const
|
||||
|
||||
// GENERIC GETTERS AND SETTERS
|
||||
|
||||
bool ConfigHandler::setShortcut(const QString& shortcutName,
|
||||
const QString& shortutValue)
|
||||
bool ConfigHandler::setShortcut(const QString& actionName,
|
||||
const QString& shortcut)
|
||||
{
|
||||
bool error = false;
|
||||
m_settings.beginGroup("Shortcuts");
|
||||
|
||||
QVector<QKeySequence> reservedShortcuts;
|
||||
|
||||
qDebug() << actionName;
|
||||
static QVector<QKeySequence> reservedShortcuts = {
|
||||
#if defined(Q_OS_MACOS)
|
||||
reservedShortcuts << QKeySequence(Qt::CTRL + Qt::Key_Backspace)
|
||||
<< QKeySequence(Qt::Key_Escape);
|
||||
Qt::CTRL + Qt::Key_Backspace,
|
||||
Qt::Key_Escape,
|
||||
#else
|
||||
reservedShortcuts << QKeySequence(Qt::Key_Backspace)
|
||||
<< QKeySequence(Qt::Key_Escape);
|
||||
Qt::Key_Backspace,
|
||||
Qt::Key_Escape,
|
||||
#endif
|
||||
};
|
||||
|
||||
if (shortutValue.isEmpty()) {
|
||||
setValue(shortcutName, "");
|
||||
} else if (reservedShortcuts.contains(QKeySequence(shortutValue))) {
|
||||
if (hasError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool error = false;
|
||||
|
||||
m_settings.beginGroup("Shortcuts");
|
||||
if (shortcut.isEmpty()) {
|
||||
setValue(actionName, "");
|
||||
} else if (reservedShortcuts.contains(QKeySequence(shortcut))) {
|
||||
// do not allow to set reserved shortcuts
|
||||
error = true;
|
||||
} else {
|
||||
error = false;
|
||||
// Make no difference for Return and Enter keys
|
||||
QString shortcutItem = shortutValue;
|
||||
if (shortcutItem == "Enter") {
|
||||
shortcutItem = QKeySequence(Qt::Key_Return).toString();
|
||||
}
|
||||
|
||||
// do not allow to set overlapped shortcuts
|
||||
foreach (auto currentShortcutName, m_settings.allKeys()) {
|
||||
if (value(currentShortcutName) == shortcutItem) {
|
||||
setValue(shortcutName, "");
|
||||
QString newShortcut = KeySequence().value(shortcut).toString();
|
||||
for (auto& otherAction : m_settings.allKeys()) {
|
||||
if (actionName == otherAction) {
|
||||
continue;
|
||||
}
|
||||
QString existingShortcut =
|
||||
KeySequence().value(m_settings.value(otherAction)).toString();
|
||||
if (newShortcut == existingShortcut) {
|
||||
error = true;
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
setValue(shortcutName, shortcutItem);
|
||||
}
|
||||
m_settings.setValue(actionName, KeySequence().value(shortcut));
|
||||
}
|
||||
done:
|
||||
m_settings.endGroup();
|
||||
return !error;
|
||||
}
|
||||
|
||||
QString ConfigHandler::shortcut(const QString& shortcutName)
|
||||
QString ConfigHandler::shortcut(const QString& actionName)
|
||||
{
|
||||
return value(QStringLiteral("Shortcuts/") + shortcutName).toString();
|
||||
QString setting = "Shortcuts/" + actionName;
|
||||
QString shortcut = value(setting).toString();
|
||||
if (!m_settings.contains(setting)) {
|
||||
// The action uses a shortcut that is a flameshot default
|
||||
// (not set explicitly by user)
|
||||
m_settings.beginGroup("Shortcuts");
|
||||
for (auto& otherAction : m_settings.allKeys()) {
|
||||
if (m_settings.value(otherAction) == shortcut) {
|
||||
// We found an explicit shortcut - it will take precedence
|
||||
m_settings.endGroup();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
m_settings.endGroup();
|
||||
}
|
||||
return shortcut;
|
||||
}
|
||||
|
||||
void ConfigHandler::setValue(const QString& key, const QVariant& value)
|
||||
{
|
||||
assertKeyRecognized(key);
|
||||
if (!hasError()) {
|
||||
// don't let the file watcher initiate another error check
|
||||
m_skipNextErrorCheck = true;
|
||||
auto val = valueHandler(key)->representation(value);
|
||||
m_settings.setValue(key, val);
|
||||
@@ -444,14 +468,14 @@ QVariant ConfigHandler::value(const QString& key) const
|
||||
return handler->value(val);
|
||||
}
|
||||
|
||||
const QSet<QString>& ConfigHandler::recognizedGeneralOptions() const
|
||||
QSet<QString>& ConfigHandler::recognizedGeneralOptions()
|
||||
{
|
||||
static QSet<QString> options =
|
||||
QSet<QString>::fromList(::recognizedGeneralOptions.keys());
|
||||
return options;
|
||||
}
|
||||
|
||||
const QSet<QString>& ConfigHandler::recognizedShortcutNames() const
|
||||
QSet<QString>& ConfigHandler::recognizedShortcutNames()
|
||||
{
|
||||
static QSet<QString> names =
|
||||
QSet<QString>::fromList(recognizedShortcuts.keys());
|
||||
@@ -515,8 +539,12 @@ bool ConfigHandler::checkUnrecognizedSettings(QTextStream* log) const
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if there are multiple shortcuts with the same key binding.
|
||||
* @brief Check if there are multiple actions with the same shortcut.
|
||||
* @return Whether the config passes this check.
|
||||
*
|
||||
* @note It is not considered a conflict if action A uses shortcut S because it
|
||||
* is the flameshot default (not because the user explicitly configured it), and
|
||||
* action B uses the same shortcut.
|
||||
*/
|
||||
bool ConfigHandler::checkShortcutConflicts(QTextStream* log) const
|
||||
{
|
||||
@@ -529,12 +557,18 @@ bool ConfigHandler::checkShortcutConflicts(QTextStream* log) const
|
||||
// values stored in variables are useful when running debugger
|
||||
QString value1 = m_settings.value(*key1).toString(),
|
||||
value2 = m_settings.value(*key2).toString();
|
||||
if (!value1.isEmpty() && value1 == value2) {
|
||||
// The check will pass if:
|
||||
// - one shortcut is empty (the action doesn't use a shortcut)
|
||||
// - or one of the settings is not found in m_settings, i.e.
|
||||
// user wants to use flameshot's default shortcut for the action
|
||||
// - or the shortcuts for both actions are different
|
||||
if (!(value1.isEmpty() || !m_settings.contains(*key1) ||
|
||||
!m_settings.contains(*key2) || value1 != value2)) {
|
||||
ok = false;
|
||||
if (log == nullptr) {
|
||||
break;
|
||||
} else if (!reportedInLog.contains(*key1) &&
|
||||
!reportedInLog.contains(*key2)) {
|
||||
} else if (!reportedInLog.contains(*key1) && // No duplicate
|
||||
!reportedInLog.contains(*key2)) { // log entries
|
||||
reportedInLog.append(*key1);
|
||||
reportedInLog.append(*key2);
|
||||
*log << QStringLiteral("Shortcut conflict: '%1' and '%2' "
|
||||
@@ -559,8 +593,10 @@ bool ConfigHandler::checkSemantics(QTextStream* log) const
|
||||
QStringList allKeys = m_settings.allKeys();
|
||||
bool ok = true;
|
||||
for (const QString& key : allKeys) {
|
||||
// Test if the key is recognized
|
||||
if (!recognizedGeneralOptions().contains(key) &&
|
||||
!recognizedShortcutNames().contains(baseName(key))) {
|
||||
(!isShortcut(key) ||
|
||||
!recognizedShortcutNames().contains(baseName(key)))) {
|
||||
continue;
|
||||
}
|
||||
QVariant val = m_settings.value(key);
|
||||
@@ -670,10 +706,8 @@ QSharedPointer<ValueHandler> ConfigHandler::valueHandler(
|
||||
{
|
||||
QSharedPointer<ValueHandler> handler;
|
||||
if (isShortcut(key)) {
|
||||
QString _key = key;
|
||||
_key.replace("Shortcuts/", "");
|
||||
handler = recognizedShortcuts.value(
|
||||
_key, QSharedPointer<KeySequence>(new KeySequence()));
|
||||
baseName(key), QSharedPointer<KeySequence>(new KeySequence()));
|
||||
} else { // General group
|
||||
handler = ::recognizedGeneralOptions.value(key);
|
||||
}
|
||||
@@ -720,4 +754,5 @@ QString ConfigHandler::baseName(QString key) const
|
||||
bool ConfigHandler::m_hasError = false;
|
||||
bool ConfigHandler::m_errorCheckPending = false;
|
||||
bool ConfigHandler::m_skipNextErrorCheck = false;
|
||||
|
||||
QSharedPointer<QFileSystemWatcher> ConfigHandler::m_configWatcher;
|
||||
|
||||
@@ -111,14 +111,14 @@ public:
|
||||
QString configFilePath() const;
|
||||
|
||||
// GENERIC GETTERS AND SETTERS
|
||||
bool setShortcut(const QString&, const QString&);
|
||||
QString shortcut(const QString&);
|
||||
bool setShortcut(const QString& actionName, const QString& shortcut);
|
||||
QString shortcut(const QString& actionName);
|
||||
void setValue(const QString& key, const QVariant& value);
|
||||
QVariant value(const QString& key) const;
|
||||
|
||||
// INFO
|
||||
const QSet<QString>& recognizedGeneralOptions() const;
|
||||
const QSet<QString>& recognizedShortcutNames() const;
|
||||
static QSet<QString>& recognizedGeneralOptions();
|
||||
static QSet<QString>& recognizedShortcutNames();
|
||||
QSet<QString> keysFromGroup(const QString& group) const;
|
||||
|
||||
// ERROR HANDLING
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "confighandler.h"
|
||||
#include <QColor>
|
||||
#include <QFileInfo>
|
||||
#include <QKeySequence>
|
||||
#include <QStandardPaths>
|
||||
#include <QVariant>
|
||||
|
||||
@@ -151,7 +152,7 @@ bool BoundedInt::check(const QVariant& val)
|
||||
QString str = val.toString();
|
||||
bool conversionOk;
|
||||
int num = str.toInt(&conversionOk);
|
||||
return conversionOk && (m_max < m_min || num <= m_max);
|
||||
return conversionOk && m_min <= num && num <= m_max;
|
||||
}
|
||||
|
||||
QVariant BoundedInt::fallback()
|
||||
@@ -214,6 +215,24 @@ QString KeySequence::expected()
|
||||
return QStringLiteral("keyboard shortcut");
|
||||
}
|
||||
|
||||
QVariant KeySequence::representation(const QVariant& val)
|
||||
{
|
||||
QString str(val.toString());
|
||||
if (QKeySequence(str) == QKeySequence(Qt::Key_Return)) {
|
||||
return QStringLiteral("Enter");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
QVariant KeySequence::process(const QVariant& val)
|
||||
{
|
||||
QString str(val.toString());
|
||||
if (str == "Enter") {
|
||||
return QKeySequence(Qt::Key_Return).toString();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// EXISTING DIR
|
||||
|
||||
bool ExistingDir::check(const QVariant& val)
|
||||
|
||||
@@ -153,9 +153,12 @@ public:
|
||||
bool check(const QVariant& val) override;
|
||||
QVariant fallback() override;
|
||||
QString expected() override;
|
||||
QVariant representation(const QVariant& val) override;
|
||||
|
||||
private:
|
||||
QKeySequence m_fallback;
|
||||
|
||||
QVariant process(const QVariant& val) override;
|
||||
};
|
||||
|
||||
class ExistingDir : public ValueHandler
|
||||
|
||||
@@ -290,7 +290,6 @@ void CaptureWidget::initButtons()
|
||||
|
||||
switch (t) {
|
||||
case CaptureTool::TYPE_UNDO:
|
||||
case CaptureTool::TYPE_IMAGEUPLOADER:
|
||||
case CaptureTool::TYPE_REDO:
|
||||
// nothing to do, just skip non-dynamic buttons with existing
|
||||
// hard coded slots
|
||||
@@ -300,12 +299,12 @@ void CaptureWidget::initButtons()
|
||||
QString shortcut =
|
||||
ConfigHandler().shortcut(QVariant::fromValue(t).toString());
|
||||
if (!shortcut.isNull()) {
|
||||
QShortcut* key =
|
||||
new QShortcut(QKeySequence(shortcut), this);
|
||||
CaptureWidget* captureWidget = this;
|
||||
connect(key, &QShortcut::activated, this, [=]() {
|
||||
captureWidget->setState(b);
|
||||
});
|
||||
auto shortcuts = newShortcut(shortcut, this, nullptr);
|
||||
for (auto* shortcut : shortcuts) {
|
||||
connect(shortcut, &QShortcut::activated, this, [=]() {
|
||||
setState(b);
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1269,57 +1268,57 @@ void CaptureWidget::removeToolObject(int index)
|
||||
|
||||
void CaptureWidget::initShortcuts()
|
||||
{
|
||||
new QShortcut(
|
||||
newShortcut(
|
||||
QKeySequence(ConfigHandler().shortcut("TYPE_UNDO")), this, SLOT(undo()));
|
||||
|
||||
new QShortcut(
|
||||
newShortcut(
|
||||
QKeySequence(ConfigHandler().shortcut("TYPE_REDO")), this, SLOT(redo()));
|
||||
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_TOGGLE_PANEL")),
|
||||
this,
|
||||
SLOT(togglePanel()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_TOGGLE_PANEL")),
|
||||
this,
|
||||
SLOT(togglePanel()));
|
||||
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_LEFT")),
|
||||
m_selection,
|
||||
SLOT(resizeLeft()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_RIGHT")),
|
||||
m_selection,
|
||||
SLOT(resizeRight()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_UP")),
|
||||
m_selection,
|
||||
SLOT(resizeUp()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")),
|
||||
m_selection,
|
||||
SLOT(resizeDown()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_LEFT")),
|
||||
m_selection,
|
||||
SLOT(resizeLeft()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_RIGHT")),
|
||||
m_selection,
|
||||
SLOT(resizeRight()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_UP")),
|
||||
m_selection,
|
||||
SLOT(resizeUp()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")),
|
||||
m_selection,
|
||||
SLOT(resizeDown()));
|
||||
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")),
|
||||
m_selection,
|
||||
SLOT(moveLeft()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_RIGHT")),
|
||||
m_selection,
|
||||
SLOT(moveRight()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_UP")),
|
||||
m_selection,
|
||||
SLOT(moveUp()));
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_DOWN")),
|
||||
m_selection,
|
||||
SLOT(moveDown()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")),
|
||||
m_selection,
|
||||
SLOT(moveLeft()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_RIGHT")),
|
||||
m_selection,
|
||||
SLOT(moveRight()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_UP")),
|
||||
m_selection,
|
||||
SLOT(moveUp()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_DOWN")),
|
||||
m_selection,
|
||||
SLOT(moveDown()));
|
||||
|
||||
new QShortcut(
|
||||
newShortcut(
|
||||
QKeySequence(ConfigHandler().shortcut("TYPE_DELETE_CURRENT_TOOL")),
|
||||
this,
|
||||
SLOT(deleteCurrentTool()));
|
||||
|
||||
new QShortcut(
|
||||
newShortcut(
|
||||
QKeySequence(ConfigHandler().shortcut("TYPE_COMMIT_CURRENT_TOOL")),
|
||||
this,
|
||||
SLOT(commitCurrentTool()));
|
||||
|
||||
new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SELECT_ALL")),
|
||||
this,
|
||||
SLOT(selectAll()));
|
||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SELECT_ALL")),
|
||||
this,
|
||||
SLOT(selectAll()));
|
||||
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(deleteToolWidgetOrClose()));
|
||||
newShortcut(Qt::Key_Escape, this, SLOT(deleteToolWidgetOrClose()));
|
||||
}
|
||||
|
||||
void CaptureWidget::deleteCurrentTool()
|
||||
@@ -1507,6 +1506,26 @@ void CaptureWidget::makeChild(QWidget* w)
|
||||
w->installEventFilter(m_eventFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wrapper around `new QShortcut`, properly handling Enter/Return.
|
||||
*/
|
||||
QList<QShortcut*> CaptureWidget::newShortcut(const QKeySequence& key,
|
||||
QWidget* parent,
|
||||
const char* slot)
|
||||
{
|
||||
QList<QShortcut*> shortcuts;
|
||||
QString strKey = key.toString();
|
||||
if (strKey.contains("Enter") || strKey.contains("Return")) {
|
||||
strKey.replace("Enter", "Return");
|
||||
shortcuts << new QShortcut(strKey, parent, slot);
|
||||
strKey.replace("Return", "Enter");
|
||||
shortcuts << new QShortcut(strKey, parent, slot);
|
||||
} else {
|
||||
shortcuts << new QShortcut(key, parent, slot);
|
||||
}
|
||||
return shortcuts;
|
||||
}
|
||||
|
||||
void CaptureWidget::togglePanel()
|
||||
{
|
||||
m_panel->toggle();
|
||||
|
||||
@@ -26,6 +26,7 @@ class QLabel;
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
class QMouseEvent;
|
||||
class QShortcut;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class ColorPicker;
|
||||
@@ -116,6 +117,10 @@ private:
|
||||
void pushToolToStack();
|
||||
void makeChild(QWidget* w);
|
||||
|
||||
QList<QShortcut*> newShortcut(const QKeySequence& key,
|
||||
QWidget* parent,
|
||||
const char* slot);
|
||||
|
||||
void setToolSize(int size);
|
||||
|
||||
QRect extendedSelection() const;
|
||||
|
||||
Reference in New Issue
Block a user