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

View file

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

View file

@ -31,16 +31,17 @@ private:
QString importDir; QString importDir;
const QString baseDir; const QString baseDir;
void displayScript(const QString &filepath); void displayScript(const QString &filepath, bool enabled);
QString chooseScript(QString dir); QString chooseScript(QString dir);
void removeScript(QListWidgetItem * item); void removeScript(QListWidgetItem * item);
void replaceScript(QListWidgetItem * item); void replaceScript(QListWidgetItem * item);
void openScript(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 markEdited();
void setListItemFilepath(QListWidgetItem * item, QString filepath) const;
int prompt(const QString &text, QMessageBox::StandardButton defaultButton); int prompt(const QString &text, QMessageBox::StandardButton defaultButton);
void save(); void save();
void closeEvent(QCloseEvent*); void closeEvent(QCloseEvent*);

View file

@ -646,14 +646,7 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "use_encounter_json") { } else if (key == "use_encounter_json") {
userConfig.useEncounterJson = getConfigBool(key, value); userConfig.useEncounterJson = getConfigBool(key, value);
} else if (key == "custom_scripts") { } else if (key == "custom_scripts") {
userConfig.customScripts.clear(); userConfig.parseCustomScripts(value);
QList<QString> paths = value.split(",", Qt::SkipEmptyParts);
paths.removeDuplicates();
for (QString script : paths) {
if (!script.isEmpty()) {
userConfig.customScripts.append(script);
}
}
#endif #endif
} else if (key.startsWith("path/")) { } else if (key.startsWith("path/")) {
auto k = reverseDefaultPaths(key.mid(5)); auto k = reverseDefaultPaths(key.mid(5));
@ -1076,14 +1069,7 @@ void UserConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "use_encounter_json") { } else if (key == "use_encounter_json") {
this->useEncounterJson = getConfigBool(key, value); this->useEncounterJson = getConfigBool(key, value);
} else if (key == "custom_scripts") { } else if (key == "custom_scripts") {
this->customScripts.clear(); this->parseCustomScripts(value);
QList<QString> paths = value.split(",", Qt::SkipEmptyParts);
paths.removeDuplicates();
for (QString script : paths) {
if (!script.isEmpty()) {
this->customScripts.append(script);
}
}
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); 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; QMap<QString, QString> map;
map.insert("recent_map", this->recentMap); map.insert("recent_map", this->recentMap);
map.insert("use_encounter_json", QString::number(this->useEncounterJson)); map.insert("use_encounter_json", QString::number(this->useEncounterJson));
map.insert("custom_scripts", this->customScripts.join(",")); map.insert("custom_scripts", this->outputCustomScripts());
return map; return map;
} }
@ -1133,13 +1119,51 @@ bool UserConfig::getEncounterJsonActive() {
return this->useEncounterJson; return this->useEncounterJson;
} }
void UserConfig::setCustomScripts(QStringList scripts) { // Read input from the config to get the script paths and whether each is enabled or disbled.
this->customScripts = scripts; // 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(); this->save();
} }
QStringList UserConfig::getCustomScripts() { QStringList UserConfig::getCustomScriptPaths() {
return this->customScripts; return this->customScripts.keys();
}
QList<bool> UserConfig::getCustomScriptsEnabled() {
return this->customScripts.values();
} }
ShortcutsConfig shortcutsConfig; ShortcutsConfig shortcutsConfig;

View file

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

View file

@ -36,8 +36,11 @@ Scripting::Scripting(MainWindow *mainWindow) {
this->mainWindow = mainWindow; this->mainWindow = mainWindow;
this->engine = new QJSEngine(mainWindow); this->engine = new QJSEngine(mainWindow);
this->engine->installExtensions(QJSEngine::ConsoleExtension); this->engine->installExtensions(QJSEngine::ConsoleExtension);
for (QString script : userConfig.getCustomScripts()) { const QStringList paths = userConfig.getCustomScriptPaths();
this->filepaths.append(script); 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->loadModules(this->filepaths);
this->scriptUtility = new ScriptUtility(mainWindow); this->scriptUtility = new ScriptUtility(mainWindow);

View file

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