Improve editing of hotkeys (#4628)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Mm2PL 2023-05-27 14:04:30 +00:00 committed by GitHub
parent fb02d59b48
commit c7b22939d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 412 additions and 125 deletions

View file

@ -4,6 +4,7 @@
- Minor: Add an icon showing when streamer mode is enabled (#4410) - Minor: Add an icon showing when streamer mode is enabled (#4410)
- Minor: Added `/shoutout <username>` commands to shoutout specified user. (#4638) - Minor: Added `/shoutout <username>` commands to shoutout specified user. (#4638)
- Minor: Improved editing hotkeys. (#4628)
- Dev: Added command to set Qt's logging filter/rules at runtime (`/c2-set-logging-rules`). (#4637) - Dev: Added command to set Qt's logging filter/rules at runtime (`/c2-set-logging-rules`). (#4637)
- Dev: Added the ability to see & load custom themes from the Themes directory. No stable promises are made of this feature, changes might be made that breaks custom themes without notice. (#4570) - Dev: Added the ability to see & load custom themes from the Themes directory. No stable promises are made of this feature, changes might be made that breaks custom themes without notice. (#4570)
- Dev: Added test cases for emote and tab completion. (#4644) - Dev: Added test cases for emote and tab completion. (#4644)

View file

@ -5,6 +5,20 @@
#include <QString> #include <QString>
#include <map> #include <map>
#include <vector>
inline const std::vector<std::pair<QString, std::vector<QString>>>
HOTKEY_ARG_ON_OFF_TOGGLE = {
{"Toggle", {}},
{"Set to on", {"on"}},
{"Set to off", {"off"}},
};
inline const std::vector<std::pair<QString, std::vector<QString>>>
HOTKEY_ARG_WITH_OR_WITHOUT_SELECTION = {
{"No", {"withoutSelection"}},
{"Yes", {"withSelection"}},
};
namespace chatterino { namespace chatterino {
@ -13,6 +27,9 @@ struct ActionDefinition {
// displayName is the value that would be shown to a user when they edit or create a hotkey for an action // displayName is the value that would be shown to a user when they edit or create a hotkey for an action
QString displayName; QString displayName;
// argumentDescription is a description of the arguments in a format of
// "<required arg: description of possible values> [optional arg: possible
// values]"
QString argumentDescription = ""; QString argumentDescription = "";
// minCountArguments is the minimum amount of arguments the action accepts // minCountArguments is the minimum amount of arguments the action accepts
@ -21,6 +38,20 @@ struct ActionDefinition {
// maxCountArguments is the maximum amount of arguments the action accepts // maxCountArguments is the maximum amount of arguments the action accepts
uint8_t maxCountArguments = minCountArguments; uint8_t maxCountArguments = minCountArguments;
// possibleArguments is empty or contains all possible argument values,
// it is an ordered mapping from option name (what the user sees) to
// arguments (what the action code will see).
// As std::map<K, V> does not guarantee order this is a std::vector<...>
std::vector<std::pair<QString, std::vector<QString>>> possibleArguments =
{};
// When possibleArguments are present this should be a string like
// "Direction:" which will be shown before the values from
// possibleArguments in the UI. Otherwise, it should be empty.
QString argumentsPrompt = "";
// A more detailed description of what argumentsPrompt means
QString argumentsPromptHover = "";
}; };
using ActionDefinitionMap = std::map<QString, ActionDefinition>; using ActionDefinitionMap = std::map<QString, ActionDefinition>;
@ -39,9 +70,15 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
}}, }},
{"scrollPage", {"scrollPage",
ActionDefinition{ ActionDefinition{
"Scroll", .displayName = "Scroll",
"<up or down>", .argumentDescription = "<direction: up or down>",
1, .minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments{
{"Up", {"up"}},
{"Down", {"down"}},
},
.argumentsPrompt = "Direction:",
}}, }},
{"search", ActionDefinition{"Focus search box"}}, {"search", ActionDefinition{"Focus search box"}},
{"execModeratorAction", {"execModeratorAction",
@ -57,9 +94,19 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"delete", ActionDefinition{"Close"}}, {"delete", ActionDefinition{"Close"}},
{"focus", {"focus",
ActionDefinition{ ActionDefinition{
"Focus neighbouring split", .displayName = "Focus neighbouring split",
"<up, down, left, or right>", .argumentDescription = "<direction: up, down, left or right>",
1, .minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments{
{"Up", {"up"}},
{"Down", {"down"}},
{"Left", {"left"}},
{"Right", {"right"}},
},
.argumentsPrompt = "Direction:",
.argumentsPromptHover =
"Which direction to look for a split to focus?",
}}, }},
{"openInBrowser", ActionDefinition{"Open channel in browser"}}, {"openInBrowser", ActionDefinition{"Open channel in browser"}},
{"openInCustomPlayer", {"openInCustomPlayer",
@ -71,10 +118,18 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"reconnect", ActionDefinition{"Reconnect to chat"}}, {"reconnect", ActionDefinition{"Reconnect to chat"}},
{"reloadEmotes", {"reloadEmotes",
ActionDefinition{ ActionDefinition{
"Reload emotes", .displayName = "Reload emotes",
"[channel or subscriber]", .argumentDescription =
0, "[type: channel or subscriber; default: all emotes]",
1, .minCountArguments = 0,
.maxCountArguments = 1,
.possibleArguments{
{"All emotes", {}},
{"Channel emotes only", {"channel"}},
{"Subscriber emotes only", {"subscriber"}},
},
.argumentsPrompt = "Emote type:",
.argumentsPromptHover = "Which emotes should Chatterino reload",
}}, }},
{"runCommand", {"runCommand",
ActionDefinition{ ActionDefinition{
@ -84,25 +139,41 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
}}, }},
{"scrollPage", {"scrollPage",
ActionDefinition{ ActionDefinition{
"Scroll", .displayName = "Scroll",
"<up or down>", .argumentDescription = "<up or down>",
1, .minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments{
{"Up", {"up"}},
{"Down", {"down"}},
},
.argumentsPrompt = "Direction:",
.argumentsPromptHover =
"Which direction do you want to see more messages",
}}, }},
{"scrollToBottom", ActionDefinition{"Scroll to the bottom"}}, {"scrollToBottom", ActionDefinition{"Scroll to the bottom"}},
{"scrollToTop", ActionDefinition{"Scroll to the top"}}, {"scrollToTop", ActionDefinition{"Scroll to the top"}},
{"setChannelNotification", {"setChannelNotification",
ActionDefinition{ ActionDefinition{
"Set channel live notification", .displayName = "Set channel live notification",
"[on or off. default: toggle]", .argumentDescription = "[on or off. default: toggle]",
0, .minCountArguments = 0,
1, .maxCountArguments = 1,
.possibleArguments = HOTKEY_ARG_ON_OFF_TOGGLE,
.argumentsPrompt = "New value:",
.argumentsPromptHover = "Should the channel live notification be "
"enabled, disabled or toggled",
}}, }},
{"setModerationMode", {"setModerationMode",
ActionDefinition{ ActionDefinition{
"Set moderation mode", .displayName = "Set moderation mode",
"[on or off. default: toggle]", .argumentDescription = "[on or off. default: toggle]",
0, .minCountArguments = 0,
1, .maxCountArguments = 1,
.possibleArguments = HOTKEY_ARG_ON_OFF_TOGGLE,
.argumentsPrompt = "New value:",
.argumentsPromptHover =
"Should the moderation mode be enabled, disabled or toggled",
}}, }},
{"showSearch", ActionDefinition{"Search current channel"}}, {"showSearch", ActionDefinition{"Search current channel"}},
{"showGlobalSearch", ActionDefinition{"Search all channels"}}, {"showGlobalSearch", ActionDefinition{"Search all channels"}},
@ -114,21 +185,38 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"clear", ActionDefinition{"Clear message"}}, {"clear", ActionDefinition{"Clear message"}},
{"copy", {"copy",
ActionDefinition{ ActionDefinition{
"Copy", .displayName = "Copy",
"<source of text: split, splitInput or auto>", .argumentDescription =
1, "<source of text: auto, split or splitInput>",
.minCountArguments = 1,
.possibleArguments{
{"Automatic", {"auto"}},
{"Split", {"split"}},
{"Split Input", {"splitInput"}},
},
.argumentsPrompt = "Source of text:",
}}, }},
{"cursorToStart", {"cursorToStart",
ActionDefinition{ ActionDefinition{
"To start of message", .displayName = "To start of message",
"<withSelection or withoutSelection>", .argumentDescription =
1, "<selection mode: withSelection or withoutSelection>",
.minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments = HOTKEY_ARG_WITH_OR_WITHOUT_SELECTION,
.argumentsPrompt = "Select text from cursor to start:",
// XXX: write a hover for this that doesn't suck
}}, }},
{"cursorToEnd", {"cursorToEnd",
ActionDefinition{ ActionDefinition{
"To end of message", .displayName = "To end of message",
"<withSelection or withoutSelection>", .argumentDescription =
1, "<selection mode: withSelection or withoutSelection>",
.minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments = HOTKEY_ARG_WITH_OR_WITHOUT_SELECTION,
.argumentsPrompt = "Select text from cursor to end:",
// XXX: write a hover for this that doesn't suck
}}, }},
{"nextMessage", ActionDefinition{"Choose next sent message"}}, {"nextMessage", ActionDefinition{"Choose next sent message"}},
{"openEmotesPopup", ActionDefinition{"Open emotes list"}}, {"openEmotesPopup", ActionDefinition{"Open emotes list"}},
@ -140,10 +228,16 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"selectWord", ActionDefinition{"Select word"}}, {"selectWord", ActionDefinition{"Select word"}},
{"sendMessage", {"sendMessage",
ActionDefinition{ ActionDefinition{
"Send message", .displayName = "Send message",
"[keepInput to not clear the text after sending]", .argumentDescription =
0, "[keepInput to not clear the text after sending]",
1, .minCountArguments = 0,
.maxCountArguments = 1,
.possibleArguments{
{"Default behavior", {}},
{"Keep message in input after sending it", {"keepInput"}},
},
.argumentsPrompt = "Behavior:",
}}, }},
{"undo", ActionDefinition{"Undo"}}, {"undo", ActionDefinition{"Undo"}},
@ -163,7 +257,7 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"moveTab", {"moveTab",
ActionDefinition{ ActionDefinition{
"Move tab", "Move tab",
"<next, previous, or new index of tab>", "<where to move the tab: next, previous, or new index of tab>",
1, 1,
}}, }},
{"newSplit", ActionDefinition{"Create a new split"}}, {"newSplit", ActionDefinition{"Create a new split"}},
@ -172,40 +266,73 @@ inline const std::map<HotkeyCategory, ActionDefinitionMap> actionNames{
{"openTab", {"openTab",
ActionDefinition{ ActionDefinition{
"Select tab", "Select tab",
"<last, next, previous, or index of tab to select>", "<which tab to select: last, next, previous, or index>",
1, 1,
}}, }},
{"openQuickSwitcher", ActionDefinition{"Open the quick switcher"}}, {"openQuickSwitcher", ActionDefinition{"Open the quick switcher"}},
{"popup", {"popup",
ActionDefinition{ ActionDefinition{
"New popup", .displayName = "New popup",
"<split or window>", .argumentDescription = "<split or window>",
1, .minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments{
{"Focused Split", {"split"}},
{"Entire Tab", {"window"}},
},
.argumentsPrompt = "Include:",
.argumentsPromptHover =
"What should be included in the new popup",
}}, }},
{"quit", ActionDefinition{"Quit Chatterino"}}, {"quit", ActionDefinition{"Quit Chatterino"}},
{"removeTab", ActionDefinition{"Remove current tab"}}, {"removeTab", ActionDefinition{"Remove current tab"}},
{"reopenSplit", ActionDefinition{"Reopen closed split"}}, {"reopenSplit", ActionDefinition{"Reopen closed split"}},
{"setStreamerMode", {"setStreamerMode",
ActionDefinition{ ActionDefinition{
"Set streamer mode", .displayName = "Set streamer mode",
"[on, off, toggle, or auto. default: toggle]", .argumentDescription =
0, "[on, off, toggle, or auto. default: toggle]",
1, .minCountArguments = 0,
.maxCountArguments = 1,
.possibleArguments =
{
{"Toggle on/off", {}},
{"Set to on", {"on"}},
{"Set to off", {"off"}},
{"Set to automatic", {"auto"}},
},
.argumentsPrompt = "New value:",
.argumentsPromptHover =
"Should streamer mode be enabled, disabled, toggled (on/off) "
"or set to auto",
}}, }},
{"toggleLocalR9K", ActionDefinition{"Toggle local R9K"}}, {"toggleLocalR9K", ActionDefinition{"Toggle local R9K"}},
{"zoom", {"zoom",
ActionDefinition{ ActionDefinition{
"Zoom in/out", .displayName = "Zoom in/out",
"<in, out, or reset>", .argumentDescription = "Argument:",
1, .minCountArguments = 1,
.maxCountArguments = 1,
.possibleArguments =
{
{"Zoom in", {"in"}},
{"Zoom out", {"out"}},
{"Reset zoom", {"reset"}},
},
.argumentsPrompt = "Option:",
}}, }},
{"setTabVisibility", {"setTabVisibility",
ActionDefinition{ ActionDefinition{
"Set tab visibility", .displayName = "Set tab visibility",
"[on, off, or toggle. default: toggle]", .argumentDescription = "[on, off, or toggle. default: toggle]",
0, .minCountArguments = 0,
1, .maxCountArguments = 1,
}}}}, .possibleArguments = HOTKEY_ARG_ON_OFF_TOGGLE,
.argumentsPrompt = "New value:",
.argumentsPromptHover =
"Should the tabs be enabled, disabled or toggled.",
}},
}},
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -1,5 +1,9 @@
#include "controllers/hotkeys/HotkeyHelpers.hpp" #include "controllers/hotkeys/HotkeyHelpers.hpp"
#include "controllers/hotkeys/ActionNames.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include <boost/optional/optional.hpp>
#include <QStringList> #include <QStringList>
namespace chatterino { namespace chatterino {
@ -27,4 +31,20 @@ std::vector<QString> parseHotkeyArguments(QString argumentString)
return arguments; return arguments;
} }
boost::optional<ActionDefinition> findHotkeyActionDefinition(
HotkeyCategory category, const QString &action)
{
auto allActions = actionNames.find(category);
if (allActions != actionNames.end())
{
const auto &actionsMap = allActions->second;
auto definition = actionsMap.find(action);
if (definition != actionsMap.end())
{
return {definition->second};
}
}
return {};
}
} // namespace chatterino } // namespace chatterino

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include "controllers/hotkeys/ActionNames.hpp"
#include <boost/optional/optional.hpp>
#include <QString> #include <QString>
#include <vector> #include <vector>
@ -7,5 +10,7 @@
namespace chatterino { namespace chatterino {
std::vector<QString> parseHotkeyArguments(QString argumentString); std::vector<QString> parseHotkeyArguments(QString argumentString);
boost::optional<ActionDefinition> findHotkeyActionDefinition(
HotkeyCategory category, const QString &action);
} // namespace chatterino } // namespace chatterino

View file

@ -17,6 +17,14 @@ EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr<Hotkey> hotkey,
, data_(hotkey) , data_(hotkey)
{ {
this->ui_->setupUi(this); this->ui_->setupUi(this);
this->setStyleSheet(R"(QToolTip {
padding: 2px;
background-color: #333333;
border: 1px solid #545454;
color: white;
})");
this->ui_->easyArgsPicker->setVisible(false);
this->ui_->easyArgsLabel->setVisible(false);
// dynamically add category names to the category picker // dynamically add category names to the category picker
for (const auto &[_, hotkeyCategory] : getApp()->hotkeys->categories()) for (const auto &[_, hotkeyCategory] : getApp()->hotkeys->categories())
{ {
@ -28,34 +36,7 @@ EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr<Hotkey> hotkey,
if (hotkey) if (hotkey)
{ {
if (!hotkey->validAction()) this->setFromHotkey(hotkey);
{
this->showEditError("Invalid action, make sure you select the "
"correct action before saving.");
}
// editing a hotkey
// update pickers/input boxes to values from Hotkey object
this->ui_->categoryPicker->setCurrentIndex(size_t(hotkey->category()));
this->ui_->keyComboEdit->setKeySequence(
QKeySequence::fromString(hotkey->keySequence().toString()));
this->ui_->nameEdit->setText(hotkey->name());
// update arguments
QString argsText;
bool first = true;
for (const auto &arg : hotkey->arguments())
{
if (!first)
{
argsText += '\n';
}
argsText += arg;
first = false;
}
this->ui_->argumentsEdit->setPlainText(argsText);
} }
else else
{ {
@ -66,6 +47,96 @@ EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr<Hotkey> hotkey,
this->ui_->argumentsEdit->setPlainText(""); this->ui_->argumentsEdit->setPlainText("");
} }
} }
void EditHotkeyDialog::setFromHotkey(std::shared_ptr<Hotkey> hotkey)
{
if (!hotkey->validAction())
{
this->showEditError("Invalid action, make sure you select the "
"correct action before saving.");
}
// editing a hotkey
// update pickers/input boxes to values from Hotkey object
this->ui_->categoryPicker->setCurrentIndex(size_t(hotkey->category()));
this->ui_->keyComboEdit->setKeySequence(
QKeySequence::fromString(hotkey->keySequence().toString()));
this->ui_->nameEdit->setText(hotkey->name());
auto def = findHotkeyActionDefinition(hotkey->category(), hotkey->action());
if (def.has_value() && !def->possibleArguments.empty())
{
qCDebug(chatterinoHotkeys) << "Enabled easy picker and arg edit "
"because we have arguments from hotkey";
this->ui_->easyArgsLabel->setVisible(true);
this->ui_->easyArgsPicker->setVisible(true);
this->ui_->argumentsEdit->setVisible(false);
this->ui_->argumentsLabel->setVisible(false);
this->ui_->argumentsDescription->setVisible(false);
this->ui_->easyArgsPicker->clear();
this->ui_->easyArgsLabel->setText(def->argumentsPrompt);
this->ui_->easyArgsLabel->setToolTip(def->argumentsPromptHover);
int matchIdx = -1;
for (int i = 0; i < def->possibleArguments.size(); i++)
{
const auto &[displayText, argData] = def->possibleArguments.at(i);
this->ui_->easyArgsPicker->addItem(displayText);
// check if matches
if (argData.size() != hotkey->arguments().size())
{
continue;
}
bool matches = true;
for (int j = 0; j < argData.size(); j++)
{
if (argData.at(j) != hotkey->arguments().at(j))
{
matches = false;
break;
}
}
if (matches)
{
matchIdx = i;
}
}
if (matchIdx != -1)
{
this->ui_->easyArgsPicker->setCurrentIndex(matchIdx);
return;
}
qCDebug(chatterinoHotkeys)
<< "Did not match hotkey arguments for " << hotkey->toString()
<< "using text edit instead of easy picker";
this->showEditError("Arguments do not match what's expected. The "
"argument picker is not available.");
this->ui_->easyArgsLabel->setVisible(false);
this->ui_->easyArgsPicker->setVisible(false);
this->ui_->argumentsEdit->setVisible(true);
this->ui_->argumentsLabel->setVisible(true);
this->ui_->argumentsDescription->setVisible(true);
}
// update arguments
QString argsText;
bool first = true;
for (const auto &arg : hotkey->arguments())
{
if (!first)
{
argsText += '\n';
}
argsText += arg;
first = false;
}
this->ui_->argumentsEdit->setPlainText(argsText);
}
EditHotkeyDialog::~EditHotkeyDialog() EditHotkeyDialog::~EditHotkeyDialog()
{ {
@ -151,6 +222,14 @@ void EditHotkeyDialog::afterEdit()
action = actionTemp.toString(); action = actionTemp.toString();
} }
auto def = findHotkeyActionDefinition(*category, action);
if (def.has_value() && this->ui_->easyArgsPicker->isVisible())
{
arguments =
def->possibleArguments.at(this->ui_->easyArgsPicker->currentIndex())
.second;
}
auto hotkey = std::make_shared<Hotkey>( auto hotkey = std::make_shared<Hotkey>(
*category, this->ui_->keyComboEdit->keySequence(), action, arguments, *category, this->ui_->keyComboEdit->keySequence(), action, arguments,
nameText); nameText);
@ -263,44 +342,69 @@ void EditHotkeyDialog::updateArgumentsInput()
} }
const ActionDefinition &def = definition->second; const ActionDefinition &def = definition->second;
if (def.maxCountArguments != 0) if (def.maxCountArguments == 0)
{
QString text =
"Arguments wrapped in <> are required.\nArguments wrapped in "
"[] "
"are optional.\nArguments are separated by a newline.";
if (!def.argumentDescription.isEmpty())
{
this->ui_->argumentsDescription->setVisible(true);
this->ui_->argumentsDescription->setText(
def.argumentDescription);
}
else
{
this->ui_->argumentsDescription->setVisible(false);
}
text = QString("Arguments wrapped in <> are required.");
if (def.maxCountArguments != def.minCountArguments)
{
text += QString("\nArguments wrapped in [] are optional.");
}
text += "\nArguments are separated by a newline.";
this->ui_->argumentsEdit->setEnabled(true);
this->ui_->argumentsEdit->setPlaceholderText(text);
this->ui_->argumentsLabel->setVisible(true);
this->ui_->argumentsDescription->setVisible(true);
this->ui_->argumentsEdit->setVisible(true);
}
else
{ {
qCDebug(chatterinoHotkeys) << "Disabled easy picker and arg edit "
"because we don't have any arguments";
this->ui_->argumentsLabel->setVisible(false); this->ui_->argumentsLabel->setVisible(false);
this->ui_->argumentsDescription->setVisible(false); this->ui_->argumentsDescription->setVisible(false);
this->ui_->argumentsEdit->setVisible(false); this->ui_->argumentsEdit->setVisible(false);
this->ui_->easyArgsLabel->setVisible(false);
this->ui_->easyArgsPicker->setVisible(false);
return;
} }
if (!def.argumentDescription.isEmpty())
{
this->ui_->argumentsDescription->setVisible(true);
this->ui_->argumentsDescription->setText(def.argumentDescription);
}
else
{
this->ui_->argumentsDescription->setVisible(false);
}
QString text = "Arguments wrapped in <> are required.";
if (def.maxCountArguments != def.minCountArguments)
{
text += QString("\nArguments wrapped in [] are optional.");
}
text += "\nArguments are separated by a newline.";
this->ui_->argumentsEdit->setEnabled(true);
this->ui_->argumentsEdit->setPlaceholderText(text);
this->ui_->argumentsLabel->setVisible(true);
this->ui_->argumentsDescription->setVisible(true);
this->ui_->argumentsEdit->setVisible(true);
// update easy picker
if (def.possibleArguments.empty())
{
qCDebug(chatterinoHotkeys)
<< "Disabled easy picker because we have possible arguments";
this->ui_->easyArgsPicker->setVisible(false);
this->ui_->easyArgsLabel->setVisible(false);
return;
}
qCDebug(chatterinoHotkeys)
<< "Enabled easy picker because we have possible arguments";
this->ui_->easyArgsPicker->setVisible(true);
this->ui_->easyArgsLabel->setVisible(true);
this->ui_->argumentsLabel->setVisible(false);
this->ui_->argumentsEdit->setVisible(false);
this->ui_->argumentsDescription->setVisible(false);
this->ui_->easyArgsPicker->clear();
for (const auto &[displayText, _] : def.possibleArguments)
{
this->ui_->easyArgsPicker->addItem(displayText);
}
this->ui_->easyArgsPicker->setCurrentIndex(0);
this->ui_->easyArgsLabel->setText(def.argumentsPrompt);
this->ui_->easyArgsLabel->setToolTip(def.argumentsPromptHover);
} }
} }

View file

@ -49,6 +49,7 @@ protected slots:
private: private:
void showEditError(QString errorText); void showEditError(QString errorText);
void setFromHotkey(std::shared_ptr<Hotkey> hotkey);
Ui::EditHotkeyDialog *ui_; Ui::EditHotkeyDialog *ui_;
std::shared_ptr<Hotkey> data_; std::shared_ptr<Hotkey> data_;

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>400</width>
<height>300</height> <height>400</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -42,6 +42,9 @@ see this message :)</string>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="nameLabel"> <widget class="QLabel" name="nameLabel">
<property name="toolTip">
<string>Set a name for the hotkey so you will be able to identify it later</string>
</property>
<property name="text"> <property name="text">
<string>Name:</string> <string>Name:</string>
</property> </property>
@ -76,6 +79,9 @@ see this message :)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QComboBox" name="categoryPicker"/>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="actionLabel"> <widget class="QLabel" name="actionLabel">
<property name="text"> <property name="text">
@ -95,6 +101,9 @@ see this message :)</string>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="keyComboLabel"> <widget class="QLabel" name="keyComboLabel">
<property name="toolTip">
<string>Pressing this keybinding will invoke the hotkey</string>
</property>
<property name="text"> <property name="text">
<string>Keybinding:</string> <string>Keybinding:</string>
</property> </property>
@ -107,6 +116,16 @@ see this message :)</string>
<widget class="QKeySequenceEdit" name="keyComboEdit"/> <widget class="QKeySequenceEdit" name="keyComboEdit"/>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QLabel" name="easyArgsLabel">
<property name="toolTip">
<string>You are not supposed to see this, please report this!</string>
</property>
<property name="text">
<string>Argument:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="argumentsLabel"> <widget class="QLabel" name="argumentsLabel">
<property name="text"> <property name="text">
<string>Arguments:</string> <string>Arguments:</string>
@ -116,7 +135,7 @@ see this message :)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QLabel" name="argumentsDescription"> <widget class="QLabel" name="argumentsDescription">
<property name="text"> <property name="text">
<string>You should never see this message :)</string> <string>You should never see this message :)</string>
@ -126,7 +145,7 @@ see this message :)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="6" column="1">
<widget class="QPlainTextEdit" name="argumentsEdit"> <widget class="QPlainTextEdit" name="argumentsEdit">
<property name="plainText"> <property name="plainText">
<string/> <string/>
@ -136,8 +155,18 @@ see this message :)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="4" column="1">
<widget class="QComboBox" name="categoryPicker"/> <widget class="QComboBox" name="easyArgsPicker">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentText">
<string/>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -169,8 +198,8 @@ see this message :)</string>
<slot>afterEdit()</slot> <slot>afterEdit()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>257</x> <x>263</x>
<y>290</y> <y>352</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
@ -185,8 +214,8 @@ see this message :)</string>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>325</x> <x>331</x>
<y>290</y> <y>352</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>
@ -201,8 +230,8 @@ see this message :)</string>
<slot>updatePossibleActions()</slot> <slot>updatePossibleActions()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>246</x> <x>172</x>
<y>85</y> <y>118</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>75</x> <x>75</x>
@ -217,8 +246,8 @@ see this message :)</string>
<slot>updateArgumentsInput()</slot> <slot>updateArgumentsInput()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>148</x> <x>172</x>
<y>119</y> <y>156</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>74</x> <x>74</x>