Add option to turn custom scripts on/off

This commit is contained in:
GriffinR 2023-09-05 17:02:35 -04:00
parent d6d27ae8b3
commit 40e8824eca
7 changed files with 127 additions and 67 deletions

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>129</width>
<height>30</height>
<height>34</height>
</rect>
</property>
<property name="sizePolicy">
@ -23,6 +23,20 @@
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QToolButton" name="b_Choose">
<property name="toolTip">
<string>Choose a new filepath for this script</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/folder.ico</normaloff>:/icons/folder.ico</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_filepath">
<property name="minimumSize">
@ -37,16 +51,9 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="b_Choose">
<property name="toolTip">
<string>Choose a new filepath for this script</string>
</property>
<widget class="QCheckBox" name="checkBox_Enable">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/folder.ico</normaloff>:/icons/folder.ico</iconset>
<string/>
</property>
</widget>
</item>

View file

@ -348,8 +348,11 @@ public:
bool getEncounterJsonActive();
void setProjectDir(QString projectDir);
QString getProjectDir();
void setCustomScripts(QStringList scripts);
QStringList getCustomScripts();
void setCustomScripts(QStringList scripts, QList<bool> enabled);
QStringList getCustomScriptPaths();
QList<bool> getCustomScriptsEnabled();
void parseCustomScripts(QString input);
QString outputCustomScripts();
protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override;
@ -363,7 +366,7 @@ private:
QString projectDir;
QString recentMap;
bool useEncounterJson;
QStringList customScripts;
QMap<QString, bool> customScripts;
QStringList readKeys;
};

View file

@ -31,16 +31,17 @@ private:
QString importDir;
const QString baseDir;
void displayScript(const QString &filepath);
void displayScript(const QString &filepath, bool enabled);
QString chooseScript(QString dir);
void removeScript(QListWidgetItem * item);
void replaceScript(QListWidgetItem * item);
void openScript(QListWidgetItem * item);
QString getScriptFilepath(QListWidgetItem * item, bool absolutePath = true) const;
void setScriptFilepath(QListWidgetItem * item, QString filepath) const;
bool getScriptEnabled(QListWidgetItem * item) const;
QString getListItemFilepath(QListWidgetItem * item) const;
void setListItemFilepath(QListWidgetItem * item, QString filepath) const;
void markEdited();
int prompt(const QString &text, QMessageBox::StandardButton defaultButton);
void save();
void closeEvent(QCloseEvent*);

View file

@ -646,14 +646,7 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "use_encounter_json") {
userConfig.useEncounterJson = getConfigBool(key, value);
} else if (key == "custom_scripts") {
userConfig.customScripts.clear();
QList<QString> paths = value.split(",", Qt::SkipEmptyParts);
paths.removeDuplicates();
for (QString script : paths) {
if (!script.isEmpty()) {
userConfig.customScripts.append(script);
}
}
userConfig.parseCustomScripts(value);
#endif
} else if (key.startsWith("path/")) {
auto k = reverseDefaultPaths(key.mid(5));
@ -1076,14 +1069,7 @@ void UserConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "use_encounter_json") {
this->useEncounterJson = getConfigBool(key, value);
} else if (key == "custom_scripts") {
this->customScripts.clear();
QList<QString> paths = value.split(",", Qt::SkipEmptyParts);
paths.removeDuplicates();
for (QString script : paths) {
if (!script.isEmpty()) {
this->customScripts.append(script);
}
}
this->parseCustomScripts(value);
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
@ -1097,7 +1083,7 @@ QMap<QString, QString> UserConfig::getKeyValueMap() {
QMap<QString, QString> map;
map.insert("recent_map", this->recentMap);
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
map.insert("custom_scripts", this->customScripts.join(","));
map.insert("custom_scripts", this->outputCustomScripts());
return map;
}
@ -1133,13 +1119,51 @@ bool UserConfig::getEncounterJsonActive() {
return this->useEncounterJson;
}
void UserConfig::setCustomScripts(QStringList scripts) {
this->customScripts = scripts;
// Read input from the config to get the script paths and whether each is enabled or disbled.
// The format is a comma-separated list of paths. Each path can be followed (before the comma)
// by a :0 or :1 to indicate whether it should be disabled or enabled, respectively. If neither
// follow, it's assumed the script should be enabled.
void UserConfig::parseCustomScripts(QString input) {
this->customScripts.clear();
QList<QString> paths = input.split(",", Qt::SkipEmptyParts);
for (QString path : paths) {
// Read and remove suffix
bool enabled = !path.endsWith(":0");
if (!enabled || path.endsWith(":1"))
path.chop(2);
if (!path.isEmpty()) {
// If a path is repeated only its last instance will be considered.
this->customScripts.insert(path, enabled);
}
}
}
// Inverse of UserConfig::parseCustomScripts
QString UserConfig::outputCustomScripts() {
QStringList list;
QMapIterator<QString, bool> i(this->customScripts);
while (i.hasNext()) {
i.next();
list.append(QString("%1:%2").arg(i.key()).arg(i.value() ? "1" : "0"));
}
return list.join(",");
}
void UserConfig::setCustomScripts(QStringList scripts, QList<bool> enabled) {
this->customScripts.clear();
size_t size = qMin(scripts.length(), enabled.length());
for (size_t i = 0; i < size; i++)
this->customScripts.insert(scripts.at(i), enabled.at(i));
this->save();
}
QStringList UserConfig::getCustomScripts() {
return this->customScripts;
QStringList UserConfig::getCustomScriptPaths() {
return this->customScripts.keys();
}
QList<bool> UserConfig::getCustomScriptsEnabled() {
return this->customScripts.values();
}
ShortcutsConfig shortcutsConfig;

View file

@ -184,7 +184,7 @@ bool ScriptUtility::getSmartPathsEnabled() {
}
QList<QString> ScriptUtility::getCustomScripts() {
return userConfig.getCustomScripts();
return userConfig.getCustomScriptPaths();
}
QList<int> ScriptUtility::getMetatileLayerOrder() {

View file

@ -36,8 +36,11 @@ Scripting::Scripting(MainWindow *mainWindow) {
this->mainWindow = mainWindow;
this->engine = new QJSEngine(mainWindow);
this->engine->installExtensions(QJSEngine::ConsoleExtension);
for (QString script : userConfig.getCustomScripts()) {
this->filepaths.append(script);
const QStringList paths = userConfig.getCustomScriptPaths();
const QList<bool> enabled = userConfig.getCustomScriptsEnabled();
for (int i = 0; i < paths.length(); i++) {
if (enabled.at(i))
this->filepaths.append(paths.at(i));
}
this->loadModules(this->filepaths);
this->scriptUtility = new ScriptUtility(mainWindow);

View file

@ -8,8 +8,6 @@
#include <QDir>
#include <QFileDialog>
// TODO: System for turning scripts on or off
//
// TODO: Better URL colors on dark themes
// TODO: Save window state
@ -23,8 +21,10 @@ CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) :
// This property seems to be reset if we don't set it programmatically
ui->list->setDragDropMode(QAbstractItemView::NoDragDrop);
for (auto path : userConfig.getCustomScripts())
this->displayScript(path);
const QStringList paths = userConfig.getCustomScriptPaths();
const QList<bool> enabled = userConfig.getCustomScriptsEnabled();
for (int i = 0; i < paths.length(); i++)
this->displayScript(paths.at(i), enabled.at(i));
this->importDir = userConfig.getProjectDir();
@ -90,36 +90,44 @@ void CustomScriptsEditor::applyUserShortcuts() {
shortcut->setKeys(shortcutsConfig.userShortcuts(shortcut));
}
void CustomScriptsEditor::displayScript(const QString &filepath) {
void CustomScriptsEditor::displayScript(const QString &filepath, bool enabled) {
auto item = new QListWidgetItem();
auto buttons = new CustomScriptsListItem();
auto widget = new CustomScriptsListItem();
buttons->ui->lineEdit_filepath->setText(filepath);
item->setSizeHint(buttons->sizeHint());
widget->ui->checkBox_Enable->setChecked(enabled);
widget->ui->lineEdit_filepath->setText(filepath);
item->setSizeHint(widget->sizeHint());
connect(buttons->ui->b_Choose, &QAbstractButton::clicked, [this, item](bool) { this->replaceScript(item); });
connect(buttons->ui->b_Edit, &QAbstractButton::clicked, [this, item](bool) { this->openScript(item); });
connect(buttons->ui->b_Delete, &QAbstractButton::clicked, [this, item](bool) { this->removeScript(item); });
connect(buttons->ui->lineEdit_filepath, &QLineEdit::textEdited, [this](const QString&) { this->hasUnsavedChanges = true; });
connect(widget->ui->b_Choose, &QAbstractButton::clicked, [this, item](bool) { this->replaceScript(item); });
connect(widget->ui->b_Edit, &QAbstractButton::clicked, [this, item](bool) { this->openScript(item); });
connect(widget->ui->b_Delete, &QAbstractButton::clicked, [this, item](bool) { this->removeScript(item); });
connect(widget->ui->checkBox_Enable, &QCheckBox::stateChanged, this, &CustomScriptsEditor::markEdited);
connect(widget->ui->lineEdit_filepath, &QLineEdit::textEdited, this, &CustomScriptsEditor::markEdited);
// Per the Qt manual, for performance reasons QListWidget::setItemWidget shouldn't be used with non-static items.
// There's an assumption here that users won't have enough scripts for that to be a problem.
ui->list->addItem(item);
ui->list->setItemWidget(item, buttons);
ui->list->setItemWidget(item, widget);
}
QString CustomScriptsEditor::getListItemFilepath(QListWidgetItem * item) const {
void CustomScriptsEditor::markEdited() {
this->hasUnsavedChanges = true;
}
QString CustomScriptsEditor::getScriptFilepath(QListWidgetItem * item, bool absolutePath) const {
auto widget = dynamic_cast<CustomScriptsListItem *>(ui->list->itemWidget(item));
if (!widget) return QString();
QString path = widget->ui->lineEdit_filepath->text();
QFileInfo fileInfo(path);
if (fileInfo.isRelative())
path.prepend(this->baseDir);
if (absolutePath) {
QFileInfo fileInfo(path);
if (fileInfo.isRelative())
path.prepend(this->baseDir);
}
return path;
}
void CustomScriptsEditor::setListItemFilepath(QListWidgetItem * item, QString filepath) const {
void CustomScriptsEditor::setScriptFilepath(QListWidgetItem * item, QString filepath) const {
auto widget = dynamic_cast<CustomScriptsListItem *>(ui->list->itemWidget(item));
if (!widget) return;
@ -128,6 +136,11 @@ void CustomScriptsEditor::setListItemFilepath(QListWidgetItem * item, QString fi
widget->ui->lineEdit_filepath->setText(filepath);
}
bool CustomScriptsEditor::getScriptEnabled(QListWidgetItem * item) const {
auto widget = dynamic_cast<CustomScriptsListItem *>(ui->list->itemWidget(item));
return widget && widget->ui->checkBox_Enable->isChecked();
}
QString CustomScriptsEditor::chooseScript(QString dir) {
return QFileDialog::getOpenFileName(this, "Choose Custom Script File", dir, "JavaScript Files (*.js)");
}
@ -139,13 +152,13 @@ void CustomScriptsEditor::addNewScript() {
this->importDir = filepath;
if (filepath.startsWith(this->baseDir))
filepath.remove(0, this->baseDir.length());
this->displayScript(filepath);
this->hasUnsavedChanges = true;
this->displayScript(filepath, true);
this->markEdited();
}
void CustomScriptsEditor::removeScript(QListWidgetItem * item) {
ui->list->takeItem(ui->list->row(item));
this->hasUnsavedChanges = true;
this->markEdited();
}
void CustomScriptsEditor::removeSelectedScripts() {
@ -157,15 +170,15 @@ void CustomScriptsEditor::removeSelectedScripts() {
}
void CustomScriptsEditor::replaceScript(QListWidgetItem * item) {
const QString filepath = this->chooseScript(this->getListItemFilepath(item));
const QString filepath = this->chooseScript(this->getScriptFilepath(item));
if (filepath.isEmpty())
return;
this->setListItemFilepath(item, filepath);
this->hasUnsavedChanges = true;
this->setScriptFilepath(item, filepath);
this->markEdited();
}
void CustomScriptsEditor::openScript(QListWidgetItem * item) {
const QString path = this->getListItemFilepath(item);
const QString path = this->getScriptFilepath(item);
QFileInfo fileInfo(path);
if (!fileInfo.exists() || !fileInfo.isFile()){
QMessageBox::warning(this, "", QString("Failed to open script '%1'").arg(path));
@ -191,7 +204,16 @@ void CustomScriptsEditor::reloadScripts() {
void CustomScriptsEditor::save() {
if (!this->hasUnsavedChanges)
return;
// TODO: Set new paths in config
QStringList paths;
QList<bool> enabledStates;
for (int i = 0; i < ui->list->count(); i++) {
auto item = ui->list->item(i);
paths.append(this->getScriptFilepath(item, false));
enabledStates.append(this->getScriptEnabled(item));
}
userConfig.setCustomScripts(paths, enabledStates);
this->hasUnsavedChanges = false;
this->reloadScripts();
}