From 06b22e0c2e792d9f87268ad4318ecdaac8d386cf Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Jul 2025 16:14:31 -0400 Subject: [PATCH 1/4] Add direct link to manual under Help --- CHANGELOG.md | 3 +++ forms/mainwindow.ui | 6 ++++++ include/mainwindow.h | 1 + src/mainwindow.cpp | 5 +++++ 4 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34a9b266..bec4738a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project somewhat adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The MAJOR version number is bumped when there are **"Breaking Changes"** in the pret projects. For more on this, see [the manual page on breaking changes](https://huderlem.github.io/porymap/manual/breaking-changes.html). ## [Unreleased] +### Added +- A link to Porymap's manual is now available under `Help`. + ### Changed - The scroll position of the map view now remains the same between the Connections tab and the Map/Events tabs. - The Move tool now behaves more like a traditional pan tool (with no momentum). diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 996dff3b..30520979 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -2926,6 +2926,7 @@ Help + @@ -3267,6 +3268,11 @@ Alt+Right + + + Open Manual + + diff --git a/include/mainwindow.h b/include/mainwindow.h index 3b3003aa..c28e78f3 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -286,6 +286,7 @@ private slots: void on_spinBox_SelectedCollision_valueChanged(int collision); void on_actionRegion_Map_Editor_triggered(); void on_actionPreferences_triggered(); + void on_actionOpen_Manual_triggered(); void on_actionCheck_for_Updates_triggered(); void togglePreferenceSpecificUi(); void on_actionProject_Settings_triggered(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 238d9706..7a316459 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2905,6 +2905,11 @@ void MainWindow::on_actionOpen_Config_Folder_triggered() { QDesktopServices::openUrl(QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))); } +void MainWindow::on_actionOpen_Manual_triggered() { + static const QUrl url("https://huderlem.github.io/porymap/"); + QDesktopServices::openUrl(url); +} + void MainWindow::on_actionPreferences_triggered() { if (!preferenceEditor) { preferenceEditor = new PreferenceEditor(this); From a2bb2efa3e4bad05cdb2d3c035616c0d0d6aeaf9 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Jul 2025 22:24:01 -0400 Subject: [PATCH 2/4] Fix UIntSpinBox disallowing intermediate inputs outside of range --- src/ui/uintspinbox.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ui/uintspinbox.cpp b/src/ui/uintspinbox.cpp index 53f6df78..095d754e 100644 --- a/src/ui/uintspinbox.cpp +++ b/src/ui/uintspinbox.cpp @@ -113,11 +113,16 @@ void UIntSpinBox::onEditFinished() { // Valid input newValue = this->valueFromText(input); } else if (state == QValidator::Intermediate) { - // User has deleted all the number text. - // If they did this by selecting all text and then hitting delete - // make sure to put the cursor back in front of the prefix. - newValue = m_minimum; - this->lineEdit()->setCursorPosition(m_prefix.length()); + if (input == m_prefix) { + // User has deleted all the number text. + // If they did this by selecting all text and then hitting delete + // make sure to put the cursor back in front of the prefix. + newValue = m_minimum; + this->lineEdit()->setCursorPosition(m_prefix.length()); + } else { + // Other intermediate inputs (values outside of acceptable range) should be ignored. + return; + } } if (newValue != m_value) { m_value = newValue; @@ -160,10 +165,14 @@ QValidator::State UIntSpinBox::validate(QString &input, int &pos) const { bool ok; uint32_t num = copy.toUInt(&ok, m_displayIntegerBase); - if (!ok || num < m_minimum || num > m_maximum) + if (!ok) return QValidator::Invalid; input += copy.toUpper(); + + if (num < m_minimum || num > m_maximum) + return QValidator::Intermediate; + return QValidator::Acceptable; } From ef86103f78c4b318a435e327ac3937c5383cc295 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Jul 2025 14:16:31 -0400 Subject: [PATCH 3/4] Add setting to autocomplete with common scripts but not all scripts --- forms/preferenceeditor.ui | 69 +++++++++++++++++++++++---------- include/config.h | 10 ++++- include/core/map.h | 2 +- include/editor.h | 3 +- include/project.h | 6 ++- include/ui/preferenceeditor.h | 3 +- src/config.cpp | 9 ++++- src/editor.cpp | 34 ++++++++++------- src/project.cpp | 72 +++++++++++++++++++++++------------ src/ui/eventframes.cpp | 4 +- src/ui/preferenceeditor.cpp | 25 +++++++++--- 11 files changed, 163 insertions(+), 74 deletions(-) diff --git a/forms/preferenceeditor.ui b/forms/preferenceeditor.ui index d3ec7cea..63017212 100644 --- a/forms/preferenceeditor.ui +++ b/forms/preferenceeditor.ui @@ -104,7 +104,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -159,7 +159,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -209,7 +209,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -253,13 +253,42 @@ - - - <html><head/><body><p>If checked, the list of suggestions when typing in an Event's Script field will include all global script labels in the project. Enabling this setting will make Porymap's startup slower.</p></body></html> - - - Autocomplete Script labels using all possible scripts + + + Script label autocomplete + + + + + <html><head/><body><p>If checked, the list of suggestions when typing in an Event's Script field will include all global script labels in the project. This is the slowest option for Porymap's project opening.</p></body></html> + + + All possible scripts + + + + + + + <html><head/><body><p>If checked, the list of suggestions when typing in an Event's Script field will include script labels from the current map's scripts file, scripts in-use by the map's other events, and all script files in the <span style=" font-family:'SFMono-Regular','Menlo','Monaco','Consolas','Liberation Mono','Courier New','Courier','monospace'; font-size:11px; color:#e74c3c; background-color:#ffffff;">data_scripts_folders </span>folder.</p></body></html> + + + Current map, and global script files + + + + + + + <html><head/><body><p>If checked, the list of suggestions when typing in an Event's Script field will only include script labels from the current map's scripts file and scripts in-use by the map's other events. This is the fastest option for Porymap's project opening.</p></body></html> + + + Current map only + + + + @@ -294,7 +323,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -323,7 +352,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true @@ -333,13 +362,13 @@ 0 0 - 476 - 343 + 495 + 376 - QLayout::SetMinimumSize + QLayout::SizeConstraint::SetMinimumSize @@ -347,7 +376,7 @@ <html><head/><body><p>When this command is set a button will appear next to the <span style=" font-weight:600; font-style:italic;">Script</span> combo-box in the <span style=" font-weight:600; font-style:italic;">Events</span> tab which executes this command.<span style=" font-weight:600;"> %F</span> will be substituted with the file path of the script and <span style=" font-weight:600;">%L</span> will be substituted with the line number of the script in that file. <span style=" font-weight:600;">%F </span><span style=" font-style:italic;">must</span> be given if <span style=" font-weight:600;">%L</span> is given. If <span style=" font-weight:600;">%F</span> is <span style=" font-style:italic;">not</span> given then the script's file path will be added to the end of the command. If the script can't be found then the current map's scripts file is opened.</p></body></html> - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop true @@ -380,7 +409,7 @@ <html><head/><body><p>This is the command that is executed when clicking <span style=" font-weight:600; font-style:italic;">Open Project in Text Editor</span> in the <span style=" font-weight:600; font-style:italic;">Tools</span> menu. <span style=" font-weight:600;">%D</span> will be substituted with the project's root directory. If <span style=" font-weight:600;">%D</span> is <span style=" font-style:italic;">not</span> specified then the project directory will be added to the end of the command.</p></body></html> - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop true @@ -410,10 +439,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -426,7 +455,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -447,7 +476,7 @@ - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/include/config.h b/include/config.h index 234fa76d..6e9bbfca 100644 --- a/include/config.h +++ b/include/config.h @@ -27,6 +27,12 @@ extern const QVersionNumber porymapVersion; #define CONFIG_BACKWARDS_COMPATABILITY +enum ScriptAutocompleteMode { + MapOnly, + MapAndCommon, + All, +}; + class KeyValueConfigBase { public: @@ -101,7 +107,7 @@ public: this->textEditorGotoLine = ""; this->paletteEditorBitDepth = 24; this->projectSettingsTab = 0; - this->loadAllEventScripts = false; + this->scriptAutocompleteMode = ScriptAutocompleteMode::MapOnly; this->warpBehaviorWarningDisabled = false; this->eventDeleteWarningDisabled = false; this->eventOverlayEnabled = false; @@ -168,7 +174,7 @@ public: QString textEditorGotoLine; int paletteEditorBitDepth; int projectSettingsTab; - bool loadAllEventScripts; + ScriptAutocompleteMode scriptAutocompleteMode; bool warpBehaviorWarningDisabled; bool eventDeleteWarningDisabled; bool eventOverlayEnabled; diff --git a/include/core/map.h b/include/core/map.h index d5e28075..1d460cf1 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -149,7 +149,7 @@ signals: void modified(); void scriptsModified(); void mapDimensionsChanged(const QSize &size); - void openScriptRequested(QString label); + void openScriptRequested(const QString &label); void connectionAdded(MapConnection*); void connectionRemoved(MapConnection*); void layoutChanged(); diff --git a/include/editor.h b/include/editor.h index 414356d1..9de1bc94 100644 --- a/include/editor.h +++ b/include/editor.h @@ -209,7 +209,8 @@ public: public slots: void openMapScripts() const; - void openScript(const QString &scriptLabel) const; + bool openScript(const QString &scriptLabel) const; + bool openScriptInFile(const QString &scriptLabel, const QString &filepath) const; void openProjectInTextEditor() const; void maskNonVisibleConnectionTiles(); void onBorderMetatilesChanged(); diff --git a/include/project.h b/include/project.h index ca7d9bbe..45df8143 100644 --- a/include/project.h +++ b/include/project.h @@ -215,7 +215,11 @@ public: static QString getScriptFileExtension(bool usePoryScript); QString getScriptDefaultString(bool usePoryScript, QString mapName) const; - QStringList getEventScriptsFilepaths() const; + + QStringList getAllEventScriptsFilepaths() const; + QStringList getMapScriptsFilepaths() const; + QStringList getCommonEventScriptsFilepaths() const; + QStringList findScriptsFiles(const QString &searchDir, const QStringList &fileNames = {"*"}) const; void insertGlobalScriptLabels(QStringList &scriptLabels) const; QString getDefaultPrimaryTilesetLabel() const; diff --git a/include/ui/preferenceeditor.h b/include/ui/preferenceeditor.h index 74181c37..24b6253f 100644 --- a/include/ui/preferenceeditor.h +++ b/include/ui/preferenceeditor.h @@ -2,6 +2,7 @@ #define PREFERENCES_H #include +#include "config.h" class NoScrollComboBox; class QAbstractButton; @@ -23,7 +24,7 @@ public: signals: void preferencesSaved(); void themeChanged(const QString &theme); - void scriptSettingsChanged(bool on); + void scriptSettingsChanged(ScriptAutocompleteMode mode); void reloadProjectRequested(); private: diff --git a/src/config.cpp b/src/config.cpp index 4f5188bd..666ec12c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -428,8 +428,13 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { } } else if (key == "project_settings_tab") { this->projectSettingsTab = getConfigInteger(key, value, 0); +#ifdef CONFIG_BACKWARDS_COMPATABILITY + // Old setting replaced by script_autocomplete_mode } else if (key == "load_all_event_scripts") { - this->loadAllEventScripts = getConfigBool(key, value); + this->scriptAutocompleteMode = getConfigBool(key, value) ? ScriptAutocompleteMode::All : ScriptAutocompleteMode::MapOnly; +#endif + } else if (key == "script_autocomplete_mode") { + this->scriptAutocompleteMode = static_cast(getConfigInteger(key, value, ScriptAutocompleteMode::MapOnly, ScriptAutocompleteMode::All)); } else if (key == "warp_behavior_warning_disabled") { this->warpBehaviorWarningDisabled = getConfigBool(key, value); } else if (key == "event_delete_warning_disabled") { @@ -551,7 +556,7 @@ QMap PorymapConfig::getKeyValueMap() { map.insert("text_editor_goto_line", this->textEditorGotoLine); map.insert("palette_editor_bit_depth", QString::number(this->paletteEditorBitDepth)); map.insert("project_settings_tab", QString::number(this->projectSettingsTab)); - map.insert("load_all_event_scripts", QString::number(this->loadAllEventScripts)); + map.insert("script_autocomplete_mode", QString::number(this->scriptAutocompleteMode)); map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled)); map.insert("event_delete_warning_disabled", QString::number(this->eventDeleteWarningDisabled)); map.insert("event_overlay_enabled", QString::number(this->eventOverlayEnabled)); diff --git a/src/editor.cpp b/src/editor.cpp index 5ad15a84..a0635d38 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -2355,21 +2355,29 @@ void Editor::openMapScripts() const { openInTextEditor(map->getScriptsFilepath()); } -void Editor::openScript(const QString &scriptLabel) const { +bool Editor::openScript(const QString &scriptLabel) const { // Find the location of scriptLabel. - QStringList scriptPaths(map->getScriptsFilepath()); - scriptPaths << project->getEventScriptsFilepaths(); - int lineNum = 0; - QString scriptPath = scriptPaths.first(); - for (const auto &path : scriptPaths) { - lineNum = ParseUtil::getScriptLineNumber(path, scriptLabel); - if (lineNum != 0) { - scriptPath = path; - break; - } - } + // First, try the current map's scripts file. + if (openScriptInFile(scriptLabel, map->getScriptsFilepath())) + return true; - openInTextEditor(scriptPath, lineNum); + // Script is not in the current map's scripts file. + // Search all possible script files. + const QStringList paths = project->getAllEventScriptsFilepaths(); + for (const auto &path : paths) { + if (openScriptInFile(scriptLabel, path)) + return true; + } + return false; +} + +bool Editor::openScriptInFile(const QString &scriptLabel, const QString &filepath) const { + int lineNum = ParseUtil::getScriptLineNumber(filepath, scriptLabel); + if (lineNum == 0) + return false; + + openInTextEditor(filepath, lineNum); + return true; } void Editor::openMapJson(const QString &mapName) const { diff --git a/src/project.cpp b/src/project.cpp index 75b32474..7188b5ef 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -2970,13 +2970,19 @@ bool Project::readGlobalConstants() { bool Project::readEventScriptLabels() { this->globalScriptLabels.clear(); - if (porymapConfig.loadAllEventScripts) { - for (const auto &filePath : getEventScriptsFilepaths()) - this->globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath); - - this->globalScriptLabels.sort(Qt::CaseInsensitive); - this->globalScriptLabels.removeDuplicates(); + QStringList paths; + if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::All) { + paths = getAllEventScriptsFilepaths(); + } else if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::MapAndCommon) { + paths = getCommonEventScriptsFilepaths(); } + + for (const auto &path : paths) { + this->globalScriptLabels << ParseUtil::getGlobalScriptLabels(path); + } + this->globalScriptLabels.sort(Qt::CaseInsensitive); + this->globalScriptLabels.removeDuplicates(); + emit eventScriptLabelsRead(); return true; } @@ -3012,30 +3018,46 @@ QString Project::getScriptDefaultString(bool usePoryScript, QString mapName) con return QString("%1_MapScripts::\n\t.byte 0\n").arg(mapName); } -QStringList Project::getEventScriptsFilepaths() const { - QStringList filePaths(QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts))); - const QString scriptsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_scripts_folders)); - const QString mapsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_map_folders)); +QStringList Project::getAllEventScriptsFilepaths() const { + return getMapScriptsFilepaths() + getCommonEventScriptsFilepaths(); +} - if (projectConfig.usePoryScript) { - QDirIterator it_pory_shared(scriptsDir, {"*.pory"}, QDir::Files); - while (it_pory_shared.hasNext()) - filePaths << it_pory_shared.next(); +// Get the paths for all "scripts.inc" / "scripts.pory" files in the data/maps/*/ folders. +QStringList Project::getMapScriptsFilepaths() const { + return findScriptsFiles(projectConfig.getFilePath(ProjectFilePath::data_map_folders), {"scripts"}); +} - QDirIterator it_pory_maps(mapsDir, {"scripts.pory"}, QDir::Files, QDirIterator::Subdirectories); - while (it_pory_maps.hasNext()) - filePaths << it_pory_maps.next(); +// Get the paths for all "*.inc" / "*.pory" files in the data/scripts/ folder, + data/event_scripts.s. +QStringList Project::getCommonEventScriptsFilepaths() const { + QStringList paths = { QDir::cleanPath(this->root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts)) }; + return paths + findScriptsFiles(projectConfig.getFilePath(ProjectFilePath::data_scripts_folders)); +} + +QStringList Project::findScriptsFiles(const QString &searchDir, const QStringList &fileNames) const { + QStringList paths; + + QString dir = searchDir; + if (!dir.startsWith(this->root)) { + dir = QDir::cleanPath(this->root + "/" + dir); } - QDirIterator it_inc_shared(scriptsDir, {"*.inc"}, QDir::Files); - while (it_inc_shared.hasNext()) - filePaths << it_inc_shared.next(); + QStringList filters; + for (const auto &s : fileNames) { + filters.append(s + getScriptFileExtension(false)); + if (projectConfig.usePoryScript) { + filters.append(s + getScriptFileExtension(true)); + } + } - QDirIterator it_inc_maps(mapsDir, {"scripts.inc"}, QDir::Files, QDirIterator::Subdirectories); - while (it_inc_maps.hasNext()) - filePaths << it_inc_maps.next(); - - return filePaths; + // TODO: Filter out .inc files that are generated by a .pory file. + // They won't cause problems for the user, but it'll create extra parsing work later. + if (!filters.isEmpty()) { + QDirIterator it(dir, filters, QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); + while (it.hasNext()) { + paths.append(it.next()); + } + } + return paths; } void Project::loadEventPixmap(Event *event, bool forceLoad) { diff --git a/src/ui/eventframes.cpp b/src/ui/eventframes.cpp index 6457e564..a1af9e97 100644 --- a/src/ui/eventframes.cpp +++ b/src/ui/eventframes.cpp @@ -201,8 +201,8 @@ void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * proj QStringList scripts = map->getScriptLabels(this->event->getEventGroup()); populateDropdown(combo, scripts); - // Depending on the settings, the autocomplete may also contain all global scripts. - if (project && porymapConfig.loadAllEventScripts) { + // Depending on the settings, the autocomplete may also contain scripts from outside the map. + if (project && porymapConfig.scriptAutocompleteMode != ScriptAutocompleteMode::MapOnly) { project->insertGlobalScriptLabels(scripts); } diff --git a/src/ui/preferenceeditor.cpp b/src/ui/preferenceeditor.cpp index 4f4b0929..5765ba01 100644 --- a/src/ui/preferenceeditor.cpp +++ b/src/ui/preferenceeditor.cpp @@ -1,6 +1,5 @@ #include "preferenceeditor.h" #include "ui_preferenceeditor.h" -#include "config.h" #include "noscrollcombobox.h" #include "message.h" @@ -76,7 +75,14 @@ void PreferenceEditor::updateFields() { ui->checkBox_OpenRecentProject->setChecked(porymapConfig.reopenOnLaunch); ui->checkBox_CheckForUpdates->setChecked(porymapConfig.checkForUpdates); ui->checkBox_DisableEventWarning->setChecked(porymapConfig.eventDeleteWarningDisabled); - ui->checkBox_AutocompleteAllScripts->setChecked(porymapConfig.loadAllEventScripts); + + if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::MapOnly) { + ui->radioButton_AutocompleteMapScripts->setChecked(true); + } else if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::MapAndCommon) { + ui->radioButton_AutocompleteCommonScripts->setChecked(true); + } else if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::All) { + ui->radioButton_AutocompleteAllScripts->setChecked(true); + } auto logTypeEnd = porymapConfig.statusBarLogTypes.end(); ui->checkBox_StatusErrors->setChecked(porymapConfig.statusBarLogTypes.find(LogType::LOG_ERROR) != logTypeEnd); @@ -95,11 +101,18 @@ void PreferenceEditor::saveFields() { porymapConfig.theme = themeSelector->currentText(); changedTheme = true; } - bool loadAllEventScripts = ui->checkBox_AutocompleteAllScripts->isChecked(); - if (loadAllEventScripts != porymapConfig.loadAllEventScripts) { - porymapConfig.loadAllEventScripts = loadAllEventScripts; - emit scriptSettingsChanged(loadAllEventScripts); + + auto scriptAutocompleteMode = ScriptAutocompleteMode::MapOnly; + if (ui->radioButton_AutocompleteCommonScripts->isChecked()) { + scriptAutocompleteMode = ScriptAutocompleteMode::MapAndCommon; + } else if (ui->radioButton_AutocompleteAllScripts->isChecked()) { + scriptAutocompleteMode = ScriptAutocompleteMode::All; } + if (scriptAutocompleteMode != porymapConfig.scriptAutocompleteMode) { + porymapConfig.scriptAutocompleteMode = scriptAutocompleteMode; + emit scriptSettingsChanged(scriptAutocompleteMode); + } + porymapConfig.eventSelectionShapeMode = ui->radioButton_OnSprite->isChecked() ? QGraphicsPixmapItem::MaskShape : QGraphicsPixmapItem::BoundingRectShape; porymapConfig.textEditorOpenFolder = ui->lineEdit_TextEditorOpenFolder->text(); porymapConfig.textEditorGotoLine = ui->lineEdit_TextEditorGotoLine->text(); From 4ea92dd9b9ea5ebf6cc490f239a6e3f9da8741c4 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 17 Jul 2025 11:32:25 -0400 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bec4738a..2cfad804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp ## [Unreleased] ### Added +- Add an option under `Preferences` to include common scripts in the autocomplete for Script labels. - A link to Porymap's manual is now available under `Help`. ### Changed