Merge pull request #343 from BigBahss/script-editing
Add completion suggestions for global event scripts
This commit is contained in:
commit
d1be0d5a58
6 changed files with 95 additions and 8 deletions
|
@ -60,6 +60,9 @@ public:
|
||||||
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
|
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
|
||||||
static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
|
static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
|
||||||
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
|
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
|
||||||
|
static QStringList getGlobalScriptLabels(const QString &filePath);
|
||||||
|
static QStringList getGlobalRawScriptLabels(QString text);
|
||||||
|
static QStringList getGlobalPoryScriptLabels(QString text);
|
||||||
static QString removeStringLiterals(QString text);
|
static QString removeStringLiterals(QString text);
|
||||||
static QString removeLineComments(QString text, const QString &commentSymbol);
|
static QString removeLineComments(QString text, const QString &commentSymbol);
|
||||||
static QString removeLineComments(QString text, const QStringList &commentSymbols);
|
static QString removeLineComments(QString text, const QStringList &commentSymbols);
|
||||||
|
@ -74,6 +77,12 @@ private:
|
||||||
QList<Token> generatePostfix(const QList<Token> &tokens);
|
QList<Token> generatePostfix(const QList<Token> &tokens);
|
||||||
int evaluatePostfix(const QList<Token> &postfix);
|
int evaluatePostfix(const QList<Token> &postfix);
|
||||||
void error(const QString &message, const QString &expression);
|
void error(const QString &message, const QString &expression);
|
||||||
|
|
||||||
|
static const QRegularExpression re_incScriptLabel;
|
||||||
|
static const QRegularExpression re_globalIncScriptLabel;
|
||||||
|
static const QRegularExpression re_poryScriptLabel;
|
||||||
|
static const QRegularExpression re_globalPoryScriptLabel;
|
||||||
|
static const QRegularExpression re_poryRawSection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PARSEUTIL_H
|
#endif // PARSEUTIL_H
|
||||||
|
|
|
@ -62,6 +62,7 @@ public:
|
||||||
QStringList secretBaseIds;
|
QStringList secretBaseIds;
|
||||||
QStringList bgEventFacingDirections;
|
QStringList bgEventFacingDirections;
|
||||||
QStringList trainerTypes;
|
QStringList trainerTypes;
|
||||||
|
QStringList globalScriptLabels;
|
||||||
QMap<QString, int> metatileBehaviorMap;
|
QMap<QString, int> metatileBehaviorMap;
|
||||||
QMap<int, QString> metatileBehaviorMapInverse;
|
QMap<int, QString> metatileBehaviorMapInverse;
|
||||||
QMap<QString, QString> facingDirections;
|
QMap<QString, QString> facingDirections;
|
||||||
|
@ -168,6 +169,7 @@ public:
|
||||||
bool readMetatileBehaviors();
|
bool readMetatileBehaviors();
|
||||||
bool readHealLocations();
|
bool readHealLocations();
|
||||||
bool readMiscellaneousConstants();
|
bool readMiscellaneousConstants();
|
||||||
|
bool readEventScriptLabels();
|
||||||
|
|
||||||
void loadEventPixmaps(QList<Event*> objects);
|
void loadEventPixmaps(QList<Event*> objects);
|
||||||
QMap<QString, int> getEventObjGfxConstants();
|
QMap<QString, int> getEventObjGfxConstants();
|
||||||
|
@ -178,6 +180,7 @@ public:
|
||||||
QString getScriptDefaultString(bool usePoryScript, QString mapName) const;
|
QString getScriptDefaultString(bool usePoryScript, QString mapName) const;
|
||||||
QString getMapScriptsFilePath(const QString &mapName) const;
|
QString getMapScriptsFilePath(const QString &mapName) const;
|
||||||
QStringList getEventScriptsFilePaths() const;
|
QStringList getEventScriptsFilePaths() const;
|
||||||
|
QCompleter *getEventScriptLabelCompleter(QStringList additionalScriptLabels);
|
||||||
|
|
||||||
bool loadMapBorder(Map *map);
|
bool loadMapBorder(Map *map);
|
||||||
|
|
||||||
|
@ -220,6 +223,9 @@ private:
|
||||||
static int default_map_size;
|
static int default_map_size;
|
||||||
static int max_object_events;
|
static int max_object_events;
|
||||||
|
|
||||||
|
QStringListModel eventScriptLabelModel;
|
||||||
|
QCompleter eventScriptLabelCompleter;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void reloadProject();
|
void reloadProject();
|
||||||
void uncheckMonitorFilesAction();
|
void uncheckMonitorFilesAction();
|
||||||
|
|
|
@ -427,8 +427,8 @@ QStringList Map::eventScriptLabels(const QString &event_group_type) const {
|
||||||
scriptLabels << event->get("script_label");
|
scriptLabels << event->get("script_label");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scriptLabels.removeAll("");
|
||||||
scriptLabels.removeDuplicates();
|
scriptLabels.removeDuplicates();
|
||||||
scriptLabels.removeAll(QString());
|
|
||||||
if (scriptLabels.contains("0x0"))
|
if (scriptLabels.contains("0x0"))
|
||||||
scriptLabels.move(scriptLabels.indexOf("0x0"), scriptLabels.count() - 1);
|
scriptLabels.move(scriptLabels.indexOf("0x0"), scriptLabels.count() - 1);
|
||||||
if (scriptLabels.contains("NULL"))
|
if (scriptLabels.contains("NULL"))
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
|
|
||||||
|
const QRegularExpression ParseUtil::re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
|
||||||
|
const QRegularExpression ParseUtil::re_globalIncScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*)::");
|
||||||
|
const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
||||||
|
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
||||||
|
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
|
||||||
|
|
||||||
void ParseUtil::set_root(const QString &dir) {
|
void ParseUtil::set_root(const QString &dir) {
|
||||||
this->root = dir;
|
this->root = dir;
|
||||||
|
@ -425,7 +430,6 @@ int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel)
|
||||||
text = removeStringLiterals(text);
|
text = removeStringLiterals(text);
|
||||||
text = removeLineComments(text, "@");
|
text = removeLineComments(text, "@");
|
||||||
|
|
||||||
static const QRegularExpression re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
|
|
||||||
QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text);
|
QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
const QRegularExpressionMatch match = it.next();
|
const QRegularExpressionMatch match = it.next();
|
||||||
|
@ -440,7 +444,6 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
|
||||||
text = removeStringLiterals(text);
|
text = removeStringLiterals(text);
|
||||||
text = removeLineComments(text, {"//", "#"});
|
text = removeLineComments(text, {"//", "#"});
|
||||||
|
|
||||||
static const QRegularExpression re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
|
||||||
QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text);
|
QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
const QRegularExpressionMatch match = it.next();
|
const QRegularExpressionMatch match = it.next();
|
||||||
|
@ -448,7 +451,6 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
|
||||||
return text.left(match.capturedStart("label")).count('\n') + 1;
|
return text.left(match.capturedStart("label")).count('\n') + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QRegularExpression re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
|
|
||||||
QRegularExpressionMatchIterator raw_it = re_poryRawSection.globalMatch(text);
|
QRegularExpressionMatchIterator raw_it = re_poryRawSection.globalMatch(text);
|
||||||
while (raw_it.hasNext()) {
|
while (raw_it.hasNext()) {
|
||||||
const QRegularExpressionMatch match = raw_it.next();
|
const QRegularExpressionMatch match = raw_it.next();
|
||||||
|
@ -460,6 +462,47 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList ParseUtil::getGlobalScriptLabels(const QString &filePath) {
|
||||||
|
if (filePath.endsWith(".inc") || filePath.endsWith(".s"))
|
||||||
|
return getGlobalRawScriptLabels(readTextFile(filePath));
|
||||||
|
else if (filePath.endsWith(".pory"))
|
||||||
|
return getGlobalPoryScriptLabels(readTextFile(filePath));
|
||||||
|
else
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ParseUtil::getGlobalRawScriptLabels(QString text) {
|
||||||
|
removeStringLiterals(text);
|
||||||
|
removeLineComments(text, "@");
|
||||||
|
|
||||||
|
QStringList rawScriptLabels;
|
||||||
|
|
||||||
|
QRegularExpressionMatchIterator it = re_globalIncScriptLabel.globalMatch(text);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
const QRegularExpressionMatch match = it.next();
|
||||||
|
rawScriptLabels << match.captured("label");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawScriptLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ParseUtil::getGlobalPoryScriptLabels(QString text) {
|
||||||
|
removeStringLiterals(text);
|
||||||
|
removeLineComments(text, {"//", "#"});
|
||||||
|
|
||||||
|
QStringList poryScriptLabels;
|
||||||
|
|
||||||
|
QRegularExpressionMatchIterator it = re_globalPoryScriptLabel.globalMatch(text);
|
||||||
|
while (it.hasNext())
|
||||||
|
poryScriptLabels << it.next().captured("label");
|
||||||
|
|
||||||
|
QRegularExpressionMatchIterator raw_it = re_poryRawSection.globalMatch(text);
|
||||||
|
while (raw_it.hasNext())
|
||||||
|
poryScriptLabels << getGlobalRawScriptLabels(raw_it.next().captured("raw_script"));
|
||||||
|
|
||||||
|
return poryScriptLabels;
|
||||||
|
}
|
||||||
|
|
||||||
QString ParseUtil::removeStringLiterals(QString text) {
|
QString ParseUtil::removeStringLiterals(QString text) {
|
||||||
static const QRegularExpression re_string("\".*\"");
|
static const QRegularExpression re_string("\".*\"");
|
||||||
return text.remove(re_string);
|
return text.remove(re_string);
|
||||||
|
@ -477,12 +520,15 @@ QString ParseUtil::removeLineComments(QString text, const QStringList &commentSy
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
QStringList ParseUtil::splitShellCommand(QStringView command) {
|
QStringList ParseUtil::splitShellCommand(QStringView command) {
|
||||||
return QProcess::splitCommand(command);
|
return QProcess::splitCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// The source for QProcess::splitCommand() as of Qt 5.15.2
|
// The source for QProcess::splitCommand() as of Qt 5.15.2
|
||||||
QStringList ParseUtil::splitShellCommand(QStringView command) {
|
QStringList ParseUtil::splitShellCommand(QStringView command) {
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
@ -522,4 +568,5 @@ QStringList ParseUtil::splitShellCommand(QStringView command) {
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -877,7 +877,8 @@ bool MainWindow::loadDataStructures() {
|
||||||
&& project->readHealLocations()
|
&& project->readHealLocations()
|
||||||
&& project->readMiscellaneousConstants()
|
&& project->readMiscellaneousConstants()
|
||||||
&& project->readSpeciesIconPaths()
|
&& project->readSpeciesIconPaths()
|
||||||
&& project->readWildMonData();
|
&& project->readWildMonData()
|
||||||
|
&& project->readEventScriptLabels();
|
||||||
|
|
||||||
return success && loadProjectCombos();
|
return success && loadProjectCombos();
|
||||||
}
|
}
|
||||||
|
@ -1913,7 +1914,9 @@ void MainWindow::updateSelectedObjects() {
|
||||||
"normal movement behavior actions.");
|
"normal movement behavior actions.");
|
||||||
combo->setMinimumContentsLength(4);
|
combo->setMinimumContentsLength(4);
|
||||||
} else if (key == "script_label") {
|
} else if (key == "script_label") {
|
||||||
combo->addItems(editor->map->eventScriptLabels());
|
const auto localScriptLabels = editor->map->eventScriptLabels();
|
||||||
|
combo->addItems(localScriptLabels);
|
||||||
|
combo->setCompleter(editor->project->getEventScriptLabelCompleter(localScriptLabels));
|
||||||
combo->setToolTip("The script which is executed with this event.");
|
combo->setToolTip("The script which is executed with this event.");
|
||||||
} else if (key == "trainer_type") {
|
} else if (key == "trainer_type") {
|
||||||
combo->addItems(editor->project->trainerTypes);
|
combo->addItems(editor->project->trainerTypes);
|
||||||
|
|
|
@ -36,7 +36,10 @@ int Project::max_map_data_size = 10240; // 0x2800
|
||||||
int Project::default_map_size = 20;
|
int Project::default_map_size = 20;
|
||||||
int Project::max_object_events = 64;
|
int Project::max_object_events = 64;
|
||||||
|
|
||||||
Project::Project(QWidget *parent) : QObject(parent)
|
Project::Project(QWidget *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
eventScriptLabelModel(this),
|
||||||
|
eventScriptLabelCompleter(this)
|
||||||
{
|
{
|
||||||
initSignals();
|
initSignals();
|
||||||
}
|
}
|
||||||
|
@ -2311,6 +2314,18 @@ bool Project::readMiscellaneousConstants() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Project::readEventScriptLabels() {
|
||||||
|
for (const auto &filePath : getEventScriptsFilePaths())
|
||||||
|
globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath);
|
||||||
|
|
||||||
|
eventScriptLabelModel.setStringList(globalScriptLabels);
|
||||||
|
eventScriptLabelCompleter.setModel(&eventScriptLabelModel);
|
||||||
|
eventScriptLabelCompleter.setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
eventScriptLabelCompleter.setFilterMode(Qt::MatchContains);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QString Project::fixPalettePath(QString path) {
|
QString Project::fixPalettePath(QString path) {
|
||||||
path = path.replace(QRegExp("\\.gbapal$"), ".pal");
|
path = path.replace(QRegExp("\\.gbapal$"), ".pal");
|
||||||
return path;
|
return path;
|
||||||
|
@ -2374,6 +2389,13 @@ QStringList Project::getEventScriptsFilePaths() const {
|
||||||
return filePaths;
|
return filePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLabels) {
|
||||||
|
additionalScriptLabels << globalScriptLabels;
|
||||||
|
additionalScriptLabels.removeDuplicates();
|
||||||
|
eventScriptLabelModel.setStringList(additionalScriptLabels);
|
||||||
|
return &eventScriptLabelCompleter;
|
||||||
|
}
|
||||||
|
|
||||||
void Project::loadEventPixmaps(QList<Event*> objects) {
|
void Project::loadEventPixmaps(QList<Event*> objects) {
|
||||||
bool needs_update = false;
|
bool needs_update = false;
|
||||||
for (Event *object : objects) {
|
for (Event *object : objects) {
|
||||||
|
|
Loading…
Reference in a new issue