Skip to content

Commit 4df2da6

Browse files
Merge pull request #754 from GriffinRichards/autocomplete-settings
Add setting to autocomplete with common scripts but not all scripts
2 parents a2bb2ef + ef86103 commit 4df2da6

File tree

11 files changed

+161
-72
lines changed

11 files changed

+161
-72
lines changed

forms/preferenceeditor.ui

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
<item row="3" column="0">
105105
<spacer name="verticalSpacer_5">
106106
<property name="orientation">
107-
<enum>Qt::Vertical</enum>
107+
<enum>Qt::Orientation::Vertical</enum>
108108
</property>
109109
<property name="sizeHint" stdset="0">
110110
<size>
@@ -159,7 +159,7 @@
159159
<item row="0" column="3">
160160
<spacer name="horizontalSpacer">
161161
<property name="orientation">
162-
<enum>Qt::Horizontal</enum>
162+
<enum>Qt::Orientation::Horizontal</enum>
163163
</property>
164164
<property name="sizeHint" stdset="0">
165165
<size>
@@ -209,7 +209,7 @@
209209
<item>
210210
<spacer name="verticalSpacer_4">
211211
<property name="orientation">
212-
<enum>Qt::Vertical</enum>
212+
<enum>Qt::Orientation::Vertical</enum>
213213
</property>
214214
<property name="sizeHint" stdset="0">
215215
<size>
@@ -253,13 +253,42 @@
253253
</widget>
254254
</item>
255255
<item>
256-
<widget class="QCheckBox" name="checkBox_AutocompleteAllScripts">
257-
<property name="toolTip">
258-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
259-
</property>
260-
<property name="text">
261-
<string>Autocomplete Script labels using all possible scripts</string>
256+
<widget class="QGroupBox" name="groupBox_ScriptAutocomplete">
257+
<property name="title">
258+
<string>Script label autocomplete</string>
262259
</property>
260+
<layout class="QVBoxLayout" name="verticalLayout_7">
261+
<item>
262+
<widget class="QRadioButton" name="radioButton_AutocompleteAllScripts">
263+
<property name="toolTip">
264+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
265+
</property>
266+
<property name="text">
267+
<string>All possible scripts</string>
268+
</property>
269+
</widget>
270+
</item>
271+
<item>
272+
<widget class="QRadioButton" name="radioButton_AutocompleteCommonScripts">
273+
<property name="toolTip">
274+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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 &lt;span style=&quot; font-family:'SFMono-Regular','Menlo','Monaco','Consolas','Liberation Mono','Courier New','Courier','monospace'; font-size:11px; color:#e74c3c; background-color:#ffffff;&quot;&gt;data_scripts_folders &lt;/span&gt;folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
275+
</property>
276+
<property name="text">
277+
<string>Current map, and global script files</string>
278+
</property>
279+
</widget>
280+
</item>
281+
<item>
282+
<widget class="QRadioButton" name="radioButton_AutocompleteMapScripts">
283+
<property name="toolTip">
284+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
285+
</property>
286+
<property name="text">
287+
<string>Current map only</string>
288+
</property>
289+
</widget>
290+
</item>
291+
</layout>
263292
</widget>
264293
</item>
265294
<item>
@@ -294,7 +323,7 @@
294323
<item>
295324
<spacer name="verticalSpacer_3">
296325
<property name="orientation">
297-
<enum>Qt::Vertical</enum>
326+
<enum>Qt::Orientation::Vertical</enum>
298327
</property>
299328
<property name="sizeHint" stdset="0">
300329
<size>
@@ -323,7 +352,7 @@
323352
<item>
324353
<widget class="QScrollArea" name="scrollArea_TextEditor">
325354
<property name="frameShape">
326-
<enum>QFrame::NoFrame</enum>
355+
<enum>QFrame::Shape::NoFrame</enum>
327356
</property>
328357
<property name="widgetResizable">
329358
<bool>true</bool>
@@ -333,21 +362,21 @@
333362
<rect>
334363
<x>0</x>
335364
<y>0</y>
336-
<width>476</width>
337-
<height>343</height>
365+
<width>495</width>
366+
<height>376</height>
338367
</rect>
339368
</property>
340369
<layout class="QGridLayout" name="gridLayout_2">
341370
<property name="sizeConstraint">
342-
<enum>QLayout::SetMinimumSize</enum>
371+
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
343372
</property>
344373
<item row="6" column="0" colspan="2">
345374
<widget class="QLabel" name="label_TextEditorGotoLineHelp">
346375
<property name="text">
347376
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When this command is set a button will appear next to the &lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Script&lt;/span&gt; combo-box in the &lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Events&lt;/span&gt; tab which executes this command.&lt;span style=&quot; font-weight:600;&quot;&gt; %F&lt;/span&gt; will be substituted with the file path of the script and &lt;span style=&quot; font-weight:600;&quot;&gt;%L&lt;/span&gt; will be substituted with the line number of the script in that file. &lt;span style=&quot; font-weight:600;&quot;&gt;%F &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;must&lt;/span&gt; be given if &lt;span style=&quot; font-weight:600;&quot;&gt;%L&lt;/span&gt; is given. If &lt;span style=&quot; font-weight:600;&quot;&gt;%F&lt;/span&gt; is &lt;span style=&quot; font-style:italic;&quot;&gt;not&lt;/span&gt; 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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
348377
</property>
349378
<property name="alignment">
350-
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
379+
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
351380
</property>
352381
<property name="wordWrap">
353382
<bool>true</bool>
@@ -380,7 +409,7 @@
380409
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This is the command that is executed when clicking &lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Open Project in Text Editor&lt;/span&gt; in the &lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Tools&lt;/span&gt; menu. &lt;span style=&quot; font-weight:600;&quot;&gt;%D&lt;/span&gt; will be substituted with the project's root directory. If &lt;span style=&quot; font-weight:600;&quot;&gt;%D&lt;/span&gt; is &lt;span style=&quot; font-style:italic;&quot;&gt;not&lt;/span&gt; specified then the project directory will be added to the end of the command.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
381410
</property>
382411
<property name="alignment">
383-
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
412+
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
384413
</property>
385414
<property name="wordWrap">
386415
<bool>true</bool>
@@ -410,10 +439,10 @@
410439
<item row="2" column="0" colspan="2">
411440
<spacer name="verticalSpacer_2">
412441
<property name="orientation">
413-
<enum>Qt::Vertical</enum>
442+
<enum>Qt::Orientation::Vertical</enum>
414443
</property>
415444
<property name="sizeType">
416-
<enum>QSizePolicy::Fixed</enum>
445+
<enum>QSizePolicy::Policy::Fixed</enum>
417446
</property>
418447
<property name="sizeHint" stdset="0">
419448
<size>
@@ -426,7 +455,7 @@
426455
<item row="7" column="0" colspan="2">
427456
<spacer name="verticalSpacer">
428457
<property name="orientation">
429-
<enum>Qt::Vertical</enum>
458+
<enum>Qt::Orientation::Vertical</enum>
430459
</property>
431460
<property name="sizeHint" stdset="0">
432461
<size>
@@ -447,7 +476,7 @@
447476
<item>
448477
<widget class="QDialogButtonBox" name="buttonBox">
449478
<property name="standardButtons">
450-
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
479+
<set>QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
451480
</property>
452481
</widget>
453482
</item>

include/config.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ extern const QVersionNumber porymapVersion;
2727

2828
#define CONFIG_BACKWARDS_COMPATABILITY
2929

30+
enum ScriptAutocompleteMode {
31+
MapOnly,
32+
MapAndCommon,
33+
All,
34+
};
35+
3036
class KeyValueConfigBase
3137
{
3238
public:
@@ -101,7 +107,7 @@ class PorymapConfig: public KeyValueConfigBase
101107
this->textEditorGotoLine = "";
102108
this->paletteEditorBitDepth = 24;
103109
this->projectSettingsTab = 0;
104-
this->loadAllEventScripts = false;
110+
this->scriptAutocompleteMode = ScriptAutocompleteMode::MapOnly;
105111
this->warpBehaviorWarningDisabled = false;
106112
this->eventDeleteWarningDisabled = false;
107113
this->eventOverlayEnabled = false;
@@ -168,7 +174,7 @@ class PorymapConfig: public KeyValueConfigBase
168174
QString textEditorGotoLine;
169175
int paletteEditorBitDepth;
170176
int projectSettingsTab;
171-
bool loadAllEventScripts;
177+
ScriptAutocompleteMode scriptAutocompleteMode;
172178
bool warpBehaviorWarningDisabled;
173179
bool eventDeleteWarningDisabled;
174180
bool eventOverlayEnabled;

include/core/map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class Map : public QObject
149149
void modified();
150150
void scriptsModified();
151151
void mapDimensionsChanged(const QSize &size);
152-
void openScriptRequested(QString label);
152+
void openScriptRequested(const QString &label);
153153
void connectionAdded(MapConnection*);
154154
void connectionRemoved(MapConnection*);
155155
void layoutChanged();

include/editor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ class Editor : public QObject
209209

210210
public slots:
211211
void openMapScripts() const;
212-
void openScript(const QString &scriptLabel) const;
212+
bool openScript(const QString &scriptLabel) const;
213+
bool openScriptInFile(const QString &scriptLabel, const QString &filepath) const;
213214
void openProjectInTextEditor() const;
214215
void maskNonVisibleConnectionTiles();
215216
void onBorderMetatilesChanged();

include/project.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ class Project : public QObject
215215

216216
static QString getScriptFileExtension(bool usePoryScript);
217217
QString getScriptDefaultString(bool usePoryScript, QString mapName) const;
218-
QStringList getEventScriptsFilepaths() const;
218+
219+
QStringList getAllEventScriptsFilepaths() const;
220+
QStringList getMapScriptsFilepaths() const;
221+
QStringList getCommonEventScriptsFilepaths() const;
222+
QStringList findScriptsFiles(const QString &searchDir, const QStringList &fileNames = {"*"}) const;
219223
void insertGlobalScriptLabels(QStringList &scriptLabels) const;
220224

221225
QString getDefaultPrimaryTilesetLabel() const;

include/ui/preferenceeditor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define PREFERENCES_H
33

44
#include <QMainWindow>
5+
#include "config.h"
56

67
class NoScrollComboBox;
78
class QAbstractButton;
@@ -23,7 +24,7 @@ class PreferenceEditor : public QMainWindow
2324
signals:
2425
void preferencesSaved();
2526
void themeChanged(const QString &theme);
26-
void scriptSettingsChanged(bool on);
27+
void scriptSettingsChanged(ScriptAutocompleteMode mode);
2728
void reloadProjectRequested();
2829

2930
private:

src/config.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,13 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
428428
}
429429
} else if (key == "project_settings_tab") {
430430
this->projectSettingsTab = getConfigInteger(key, value, 0);
431+
#ifdef CONFIG_BACKWARDS_COMPATABILITY
432+
// Old setting replaced by script_autocomplete_mode
431433
} else if (key == "load_all_event_scripts") {
432-
this->loadAllEventScripts = getConfigBool(key, value);
434+
this->scriptAutocompleteMode = getConfigBool(key, value) ? ScriptAutocompleteMode::All : ScriptAutocompleteMode::MapOnly;
435+
#endif
436+
} else if (key == "script_autocomplete_mode") {
437+
this->scriptAutocompleteMode = static_cast<ScriptAutocompleteMode>(getConfigInteger(key, value, ScriptAutocompleteMode::MapOnly, ScriptAutocompleteMode::All));
433438
} else if (key == "warp_behavior_warning_disabled") {
434439
this->warpBehaviorWarningDisabled = getConfigBool(key, value);
435440
} else if (key == "event_delete_warning_disabled") {
@@ -551,7 +556,7 @@ QMap<QString, QString> PorymapConfig::getKeyValueMap() {
551556
map.insert("text_editor_goto_line", this->textEditorGotoLine);
552557
map.insert("palette_editor_bit_depth", QString::number(this->paletteEditorBitDepth));
553558
map.insert("project_settings_tab", QString::number(this->projectSettingsTab));
554-
map.insert("load_all_event_scripts", QString::number(this->loadAllEventScripts));
559+
map.insert("script_autocomplete_mode", QString::number(this->scriptAutocompleteMode));
555560
map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled));
556561
map.insert("event_delete_warning_disabled", QString::number(this->eventDeleteWarningDisabled));
557562
map.insert("event_overlay_enabled", QString::number(this->eventOverlayEnabled));

src/editor.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,21 +2355,29 @@ void Editor::openMapScripts() const {
23552355
openInTextEditor(map->getScriptsFilepath());
23562356
}
23572357

2358-
void Editor::openScript(const QString &scriptLabel) const {
2358+
bool Editor::openScript(const QString &scriptLabel) const {
23592359
// Find the location of scriptLabel.
2360-
QStringList scriptPaths(map->getScriptsFilepath());
2361-
scriptPaths << project->getEventScriptsFilepaths();
2362-
int lineNum = 0;
2363-
QString scriptPath = scriptPaths.first();
2364-
for (const auto &path : scriptPaths) {
2365-
lineNum = ParseUtil::getScriptLineNumber(path, scriptLabel);
2366-
if (lineNum != 0) {
2367-
scriptPath = path;
2368-
break;
2369-
}
2360+
// First, try the current map's scripts file.
2361+
if (openScriptInFile(scriptLabel, map->getScriptsFilepath()))
2362+
return true;
2363+
2364+
// Script is not in the current map's scripts file.
2365+
// Search all possible script files.
2366+
const QStringList paths = project->getAllEventScriptsFilepaths();
2367+
for (const auto &path : paths) {
2368+
if (openScriptInFile(scriptLabel, path))
2369+
return true;
23702370
}
2371+
return false;
2372+
}
2373+
2374+
bool Editor::openScriptInFile(const QString &scriptLabel, const QString &filepath) const {
2375+
int lineNum = ParseUtil::getScriptLineNumber(filepath, scriptLabel);
2376+
if (lineNum == 0)
2377+
return false;
23712378

2372-
openInTextEditor(scriptPath, lineNum);
2379+
openInTextEditor(filepath, lineNum);
2380+
return true;
23732381
}
23742382

23752383
void Editor::openMapJson(const QString &mapName) const {

src/project.cpp

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,13 +2970,19 @@ bool Project::readGlobalConstants() {
29702970
bool Project::readEventScriptLabels() {
29712971
this->globalScriptLabels.clear();
29722972

2973-
if (porymapConfig.loadAllEventScripts) {
2974-
for (const auto &filePath : getEventScriptsFilepaths())
2975-
this->globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath);
2973+
QStringList paths;
2974+
if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::All) {
2975+
paths = getAllEventScriptsFilepaths();
2976+
} else if (porymapConfig.scriptAutocompleteMode == ScriptAutocompleteMode::MapAndCommon) {
2977+
paths = getCommonEventScriptsFilepaths();
2978+
}
29762979

2977-
this->globalScriptLabels.sort(Qt::CaseInsensitive);
2978-
this->globalScriptLabels.removeDuplicates();
2980+
for (const auto &path : paths) {
2981+
this->globalScriptLabels << ParseUtil::getGlobalScriptLabels(path);
29792982
}
2983+
this->globalScriptLabels.sort(Qt::CaseInsensitive);
2984+
this->globalScriptLabels.removeDuplicates();
2985+
29802986
emit eventScriptLabelsRead();
29812987
return true;
29822988
}
@@ -3012,30 +3018,46 @@ QString Project::getScriptDefaultString(bool usePoryScript, QString mapName) con
30123018
return QString("%1_MapScripts::\n\t.byte 0\n").arg(mapName);
30133019
}
30143020

3015-
QStringList Project::getEventScriptsFilepaths() const {
3016-
QStringList filePaths(QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts)));
3017-
const QString scriptsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_scripts_folders));
3018-
const QString mapsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_map_folders));
3021+
QStringList Project::getAllEventScriptsFilepaths() const {
3022+
return getMapScriptsFilepaths() + getCommonEventScriptsFilepaths();
3023+
}
30193024

3020-
if (projectConfig.usePoryScript) {
3021-
QDirIterator it_pory_shared(scriptsDir, {"*.pory"}, QDir::Files);
3022-
while (it_pory_shared.hasNext())
3023-
filePaths << it_pory_shared.next();
3025+
// Get the paths for all "scripts.inc" / "scripts.pory" files in the data/maps/*/ folders.
3026+
QStringList Project::getMapScriptsFilepaths() const {
3027+
return findScriptsFiles(projectConfig.getFilePath(ProjectFilePath::data_map_folders), {"scripts"});
3028+
}
30243029

3025-
QDirIterator it_pory_maps(mapsDir, {"scripts.pory"}, QDir::Files, QDirIterator::Subdirectories);
3026-
while (it_pory_maps.hasNext())
3027-
filePaths << it_pory_maps.next();
3028-
}
3030+
// Get the paths for all "*.inc" / "*.pory" files in the data/scripts/ folder, + data/event_scripts.s.
3031+
QStringList Project::getCommonEventScriptsFilepaths() const {
3032+
QStringList paths = { QDir::cleanPath(this->root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts)) };
3033+
return paths + findScriptsFiles(projectConfig.getFilePath(ProjectFilePath::data_scripts_folders));
3034+
}
30293035

3030-
QDirIterator it_inc_shared(scriptsDir, {"*.inc"}, QDir::Files);
3031-
while (it_inc_shared.hasNext())
3032-
filePaths << it_inc_shared.next();
3036+
QStringList Project::findScriptsFiles(const QString &searchDir, const QStringList &fileNames) const {
3037+
QStringList paths;
30333038

3034-
QDirIterator it_inc_maps(mapsDir, {"scripts.inc"}, QDir::Files, QDirIterator::Subdirectories);
3035-
while (it_inc_maps.hasNext())
3036-
filePaths << it_inc_maps.next();
3039+
QString dir = searchDir;
3040+
if (!dir.startsWith(this->root)) {
3041+
dir = QDir::cleanPath(this->root + "/" + dir);
3042+
}
3043+
3044+
QStringList filters;
3045+
for (const auto &s : fileNames) {
3046+
filters.append(s + getScriptFileExtension(false));
3047+
if (projectConfig.usePoryScript) {
3048+
filters.append(s + getScriptFileExtension(true));
3049+
}
3050+
}
30373051

3038-
return filePaths;
3052+
// TODO: Filter out .inc files that are generated by a .pory file.
3053+
// They won't cause problems for the user, but it'll create extra parsing work later.
3054+
if (!filters.isEmpty()) {
3055+
QDirIterator it(dir, filters, QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
3056+
while (it.hasNext()) {
3057+
paths.append(it.next());
3058+
}
3059+
}
3060+
return paths;
30393061
}
30403062

30413063
void Project::loadEventPixmap(Event *event, bool forceLoad) {

0 commit comments

Comments
 (0)