remove refs to old functions

This commit is contained in:
garak 2024-09-24 12:45:32 -04:00
commit b622bec2be
26 changed files with 236 additions and 182 deletions

2
.gitignore vendored
View file

@ -8,9 +8,11 @@ porymap.app*
porymap
porymap.cfg
porymap.log
build/
# Qt generated files
ui_*.h
moc_*.h
moc_*.cpp
qrc_*.cpp
.qtc_clangd

View file

@ -12,6 +12,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- Add a `Close Project` option
- Add charts to the `Wild Pokémon` tab that show species and level distributions.
- An alert will be displayed when attempting to open a seemingly invalid project.
- Add support for defining project values with `enum` where `#define` was expected.
### Changed
- Edits to map connections now have Undo/Redo and can be viewed in exported timelapses.
@ -43,6 +44,8 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- Fix map connections rendering incorrectly if their dimensions were smaller than the border draw distance.
- Fix the map list filter retaining text between project open/close.
- Fix the map list mishandling value gaps when sorting by Area.
- Fix a freeze on startup if project values are defined with mismatched parentheses.
- Fix stitched map images sometimes rendering garbage
## [5.4.1] - 2024-03-21
### Fixed

View file

@ -39,3 +39,14 @@ qmake
make
./porymap
```
## Arch Linux
You need to install Qt. You can check the version of your Qt packages with `qtdiag` or `qmake --version`.
```bash
sudo pacman -S qt6-declarative qt6-charts
qmake
make
./porymap
```

View file

@ -187,6 +187,7 @@ public:
static QString eventGroupToString(Event::Group group);
static QString eventTypeToString(Event::Type type);
static Event::Type eventTypeFromString(QString type);
static void clearIcons();
static void setIcons();
// protected attributes

View file

@ -54,9 +54,9 @@ public:
QString readCIncbin(const QString &text, const QString &label);
QMap<QString, QString> readCIncbinMulti(const QString &filepath);
QStringList readCIncbinArray(const QString &filename, const QString &label);
QMap<QString, int> readCDefinesByPrefix(const QString &filename, QStringList prefixes);
QMap<QString, int> readCDefinesByName(const QString &filename, QStringList names);
QStringList readCDefineNames(const QString&, const QStringList&);
QMap<QString, int> readCDefinesByRegex(const QString &filename, const QStringList &regexList);
QMap<QString, int> readCDefinesByName(const QString &filename, const QStringList &names);
QStringList readCDefineNames(const QString &filename, const QStringList &regexList);
QMap<QString, QHash<QString, QString>> readCStructs(const QString &, const QString & = "", const QHash<int, QString> = { });
QList<QStringList> getLabelMacros(const QList<QStringList>&, const QString&);
QStringList getLabelValues(const QList<QStringList>&, const QString&);
@ -97,8 +97,15 @@ private:
void recordErrors(const QStringList &errors);
void logRecordedErrors();
QString createErrorMessage(const QString &message, const QString &expression);
QString readCDefinesFile(const QString &filename);
QMap<QString, int> readCDefines(const QString &filename, const QStringList &searchText, bool fullMatch);
struct ParsedDefines {
QMap<QString,QString> expressions; // Map of all define names encountered to their expressions
QStringList filteredNames; // List of define names that matched the search text, in the order that they were encountered
};
ParsedDefines readCDefines(const QString &filename, const QStringList &filterList, bool useRegex);
QMap<QString, int> evaluateCDefines(const QString &filename, const QStringList &filterList, bool useRegex);
bool defineNameMatchesFilter(const QString &name, const QStringList &filterList) const;
bool defineNameMatchesFilter(const QString &name, const QList<QRegularExpression> &filterList) const;
static const QRegularExpression re_incScriptLabel;
static const QRegularExpression re_globalIncScriptLabel;

View file

@ -93,7 +93,8 @@ public:
void clearMapCache();
void clearTilesetCache();
void clearLayoutsTable();
void clearMapLayouts();
void clearEventGraphics();
struct DataQualifiers
{

View file

@ -17,7 +17,7 @@ class UpdatePromoter : public QDialog
public:
explicit UpdatePromoter(QWidget *parent, NetworkAccessManager *manager);
~UpdatePromoter() {};
~UpdatePromoter();
void checkForUpdates();
void updatePreferences();

View file

@ -208,7 +208,6 @@ void KeyValueConfigBase::load() {
}
QTextStream in(&file);
QList<QString> configLines;
static const QRegularExpression re("^(?<key>[^=]+)=(?<value>.*)$");
while (!in.atEnd()) {
QString line = in.readLine().trimmed();
@ -1063,7 +1062,6 @@ QMap<QString, QString> UserConfig::getKeyValueMap() {
}
void UserConfig::init() {
QString dirName = QDir(this->projectDir).dirName().toLower();
this->useEncounterJson = true;
this->customScripts.clear();
}

View file

@ -146,10 +146,13 @@ void Event::loadPixmap(Project *) {
this->pixmap = pixmap ? *pixmap : QPixmap();
}
void Event::setIcons() {
void Event::clearIcons() {
qDeleteAll(icons);
icons.clear();
}
void Event::setIcons() {
clearIcons();
const int w = 16;
const int h = 16;
static const QPixmap defaultIcons = QPixmap(":/images/Entities_16x16.png");

View file

@ -15,6 +15,22 @@ const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|l
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
static const QMap<QString, int> globalDefineValues = {
{"FALSE", 0},
{"TRUE", 1},
{"SCHAR_MIN", SCHAR_MIN},
{"SCHAR_MAX", SCHAR_MAX},
{"CHAR_MIN", CHAR_MIN},
{"CHAR_MAX", CHAR_MAX},
{"UCHAR_MAX", UCHAR_MAX},
{"SHRT_MIN", SHRT_MIN},
{"SHRT_MAX", SHRT_MAX},
{"USHRT_MAX", USHRT_MAX},
{"INT_MIN", INT_MIN},
{"INT_MAX", INT_MAX},
{"UINT_MAX", UINT_MAX},
};
using OrderedJson = poryjson::Json;
ParseUtil::ParseUtil() { }
@ -33,10 +49,10 @@ void ParseUtil::recordErrors(const QStringList &errors) {
}
void ParseUtil::logRecordedErrors() {
QStringList errors = this->errorMap.value(this->curDefine);
const QStringList errors = this->errorMap.value(this->curDefine);
if (errors.isEmpty()) return;
QString message = QString("Failed to parse '%1':").arg(this->curDefine);
for (const auto error : errors)
for (const auto &error : errors)
message.append(QString("\n%1").arg(error));
logError(message);
}
@ -225,10 +241,11 @@ QList<Token> ParseUtil::generatePostfix(const QList<Token> &tokens) {
}
while (!operatorStack.isEmpty()) {
if (operatorStack.top().value == "(" || operatorStack.top().value == ")") {
Token token = operatorStack.pop();
if (token.value == "(" || token.value == ")") {
recordError("Mismatched parentheses detected in expression!");
} else {
output.append(operatorStack.pop());
output.append(token);
}
}
@ -353,12 +370,24 @@ QStringList ParseUtil::readCIncbinArray(const QString &filename, const QString &
return paths;
}
QString ParseUtil::readCDefinesFile(const QString &filename)
{
bool ParseUtil::defineNameMatchesFilter(const QString &name, const QStringList &filterList) const {
return filterList.contains(name);
}
bool ParseUtil::defineNameMatchesFilter(const QString &name, const QList<QRegularExpression> &filterList) const {
for (auto filter : filterList) {
if (filter.match(name).hasMatch())
return true;
}
return false;
}
ParseUtil::ParsedDefines ParseUtil::readCDefines(const QString &filename, const QStringList &filterList, bool useRegex) {
ParsedDefines result;
this->file = filename;
if (this->file.isEmpty()) {
return QString();
return result;
}
QString filepath = this->root + "/" + this->file;
@ -366,98 +395,113 @@ QString ParseUtil::readCDefinesFile(const QString &filename)
if (this->text.isNull()) {
logError(QString("Failed to read C defines file: '%1'").arg(filepath));
return QString();
return result;
}
static const QRegularExpression re_extraChars("(//.*)|(\\/+\\*+[^*]*\\*+\\/+)");
this->text.replace(re_extraChars, "");
static const QRegularExpression re_extraSpaces("(\\\\\\s+)");
this->text.replace(re_extraSpaces, "");
return this->text;
if (this->text.isEmpty())
return result;
// If necessary, construct regular expressions from filter list
QList<QRegularExpression> filterList_Regex;
if (useRegex) {
for (auto filter : filterList) {
filterList_Regex.append(QRegularExpression(filter));
}
}
// Create lambda function to match the define name to the filter, depending on the filter type
auto matchesFilter = [this, &filterList, &filterList_Regex, useRegex](const QString &name) {
if (useRegex)
return defineNameMatchesFilter(name, filterList_Regex);
return defineNameMatchesFilter(name, filterList);
};
// Capture either the name and value of a #define, or everything between the braces of 'enum { }'
static const QRegularExpression re("#define\\s+(?<defineName>\\w+)[\\s\\n][^\\S\\n]*(?<defineValue>.+)?"
"|\\benum\\b[^{]*{(?<enumBody>[^}]*)}");
QRegularExpressionMatchIterator iter = re.globalMatch(this->text);
while (iter.hasNext()) {
QRegularExpressionMatch match = iter.next();
const QString enumBody = match.captured("enumBody");
if (!enumBody.isNull()) {
// Encountered an enum, extract the elements of the enum and give each an appropriate expression
int baseNum = 0;
QString baseExpression = "0";
// Note: We lazily consider an enum's expression to be any characters after the assignment up until the first comma or EOL.
// This would be a problem for e.g. NAME = MACRO(a, b), but we're currently unable to parse function-like macros anyway.
// If this changes then the regex below needs to be updated.
static const QRegularExpression re_enumElement("\\b(?<name>\\w+)\\b\\s*=?\\s*(?<expression>[^,]*)");
QRegularExpressionMatchIterator elementIter = re_enumElement.globalMatch(enumBody);
while (elementIter.hasNext()) {
QRegularExpressionMatch elementMatch = elementIter.next();
const QString name = elementMatch.captured("name");
QString expression = elementMatch.captured("expression");
if (expression.isEmpty()) {
// enum values may use tokens that we don't know how to evaluate yet.
// For now we define each element to be 1 + the previous element's expression.
expression = QString("((%1)+%2)").arg(baseExpression).arg(baseNum++);
} else {
// This element was explicitly assigned an expression with '=', reset the bases for any subsequent elements.
baseExpression = expression;
baseNum = 1;
}
result.expressions.insert(name, expression);
if (matchesFilter(name))
result.filteredNames.append(name);
}
} else {
// Encountered a #define
const QString name = match.captured("defineName");
result.expressions.insert(name, match.captured("defineValue"));
if (matchesFilter(name))
result.filteredNames.append(name);
}
}
return result;
}
// Read all the define names and their expressions in the specified file, then evaluate the ones matching the search text (and any they depend on).
// If 'fullMatch' is true, 'searchText' is a list of exact define names to evaluate and return.
// If 'fullMatch' is false, 'searchText' is a list of prefixes or regexes for define names to evaluate and return.
QMap<QString, int> ParseUtil::readCDefines(const QString &filename, const QStringList &searchText, bool fullMatch)
{
QMap<QString, int> filteredValues;
this->text = this->readCDefinesFile(filename);
if (this->text.isEmpty()) {
return filteredValues;
}
// Extract all the define names and expressions
QMap<QString, QString> allExpressions;
QMap<QString, QString> filteredExpressions;
static const QRegularExpression re("#define\\s+(?<defineName>\\w+)[^\\S\\n]+(?<defineValue>.+)");
QRegularExpressionMatchIterator iter = re.globalMatch(this->text);
while (iter.hasNext()) {
QRegularExpressionMatch match = iter.next();
const QString name = match.captured("defineName");
const QString expression = match.captured("defineValue");
// If name matches the search text record it for evaluation.
for (auto s : searchText) {
if ((fullMatch && name == s) || (!fullMatch && (name.startsWith(s) || QRegularExpression(s).match(name).hasMatch()))) {
filteredExpressions.insert(name, expression);
break;
}
}
allExpressions.insert(name, expression);
}
QMap<QString, int> allValues;
allValues.insert("FALSE", 0);
allValues.insert("TRUE", 1);
QMap<QString, int> ParseUtil::evaluateCDefines(const QString &filename, const QStringList &filterList, bool useRegex) {
ParsedDefines defines = readCDefines(filename, filterList, useRegex);
// Evaluate defines
QMap<QString, int> filteredValues;
QMap<QString, int> allValues = globalDefineValues;
this->errorMap.clear();
while (!filteredExpressions.isEmpty()) {
const QString name = filteredExpressions.firstKey();
const QString expression = filteredExpressions.take(name);
while (!defines.filteredNames.isEmpty()) {
const QString name = defines.filteredNames.takeFirst();
const QString expression = defines.expressions.take(name);
if (expression == " ") continue;
this->curDefine = name;
filteredValues.insert(name, evaluateDefine(name, expression, &allValues, &allExpressions));
filteredValues.insert(name, evaluateDefine(name, expression, &allValues, &defines.expressions));
logRecordedErrors(); // Only log errors for defines that Porymap is looking for
}
return filteredValues;
}
// Find and evaluate an unknown list of defines with a known name prefix.
QMap<QString, int> ParseUtil::readCDefinesByPrefix(const QString &filename, QStringList prefixes) {
prefixes.removeDuplicates();
return this->readCDefines(filename, prefixes, false);
return filteredValues;
}
// Find and evaluate a specific set of defines with known names.
QMap<QString, int> ParseUtil::readCDefinesByName(const QString &filename, QStringList names) {
names.removeDuplicates();
return this->readCDefines(filename, names, true);
QMap<QString, int> ParseUtil::readCDefinesByName(const QString &filename, const QStringList &names) {
return evaluateCDefines(filename, names, false);
}
// Similar to readCDefines, but for cases where we only need to show a list of define names.
// We can skip reading/evaluating any expressions (and by extension skip reporting any errors from this process).
QStringList ParseUtil::readCDefineNames(const QString &filename, const QStringList &prefixes) {
QStringList filteredNames;
this->text = this->readCDefinesFile(filename);
if (this->text.isEmpty()) {
return filteredNames;
// Find and evaluate an unknown list of defines with a known name pattern.
QMap<QString, int> ParseUtil::readCDefinesByRegex(const QString &filename, const QStringList &regexList) {
return evaluateCDefines(filename, regexList, true);
}
static const QRegularExpression re("#define\\s+(?<defineName>\\w+)[^\\S\\n]+");
QRegularExpressionMatchIterator iter = re.globalMatch(this->text);
while (iter.hasNext()) {
QRegularExpressionMatch match = iter.next();
QString name = match.captured("defineName");
for (QString prefix : prefixes) {
if (name.startsWith(prefix) || QRegularExpression(prefix).match(name).hasMatch()) {
filteredNames.append(name);
}
}
}
return filteredNames;
// Find an unknown list of defines with a known name pattern.
// Similar to readCDefinesByRegex, but for cases where we only need to show a list of define names.
// We can skip evaluating any expressions (and by extension skip reporting any errors from this process).
QStringList ParseUtil::readCDefineNames(const QString &filename, const QStringList &regexList) {
return readCDefines(filename, regexList, true).filteredNames;
}
QStringList ParseUtil::readCArray(const QString &filename, const QString &label) {

View file

@ -1561,7 +1561,7 @@ bool Editor::displayMap() {
bool Editor::displayLayout() {
if (!scene) {
scene = new QGraphicsScene;
MapSceneEventFilter *filter = new MapSceneEventFilter();
MapSceneEventFilter *filter = new MapSceneEventFilter(scene);
scene->installEventFilter(filter);
connect(filter, &MapSceneEventFilter::wheelZoom, this, &Editor::onWheelZoom);
scene->installEventFilter(this->map_ruler);

View file

@ -33,7 +33,6 @@ static const int max_depth = 200;
using std::map;
using std::make_shared;
using std::initializer_list;
using std::move;
/* Helper for representing null - just a do-nothing struct, plus comparison
* operators so the helpers in JsonValue work. We can't use nullptr_t because
@ -164,7 +163,7 @@ protected:
// Constructors
explicit Value(const T &value) : m_value(value) {}
explicit Value(T &&value) : m_value(move(value)) {}
explicit Value(T &&value) : m_value(std::move(value)) {}
// Get type tag
Json::Type type() const override {
@ -211,7 +210,7 @@ class JsonString final : public Value<Json::STRING, QString> {
const QString &string_value() const override { return m_value; }
public:
explicit JsonString(const QString &value) : Value(value) {}
explicit JsonString(QString &&value) : Value(move(value)) {}
explicit JsonString(QString &&value) : Value(std::move(value)) {}
};
class JsonArray final : public Value<Json::ARRAY, Json::array> {
@ -219,7 +218,7 @@ class JsonArray final : public Value<Json::ARRAY, Json::array> {
const Json & operator[](int i) const override;
public:
explicit JsonArray(const Json::array &value) : Value(value) {}
explicit JsonArray(Json::array &&value) : Value(move(value)) {}
explicit JsonArray(Json::array &&value) : Value(std::move(value)) {}
};
class JsonObject final : public Value<Json::OBJECT, Json::object> {
@ -227,7 +226,7 @@ class JsonObject final : public Value<Json::OBJECT, Json::object> {
const Json & operator[](const QString &key) const override;
public:
explicit JsonObject(const Json::object &value) : Value(value) {}
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
explicit JsonObject(Json::object &&value) : Value(std::move(value)) {}
};
class JsonNull final : public Value<Json::NUL, NullStruct> {
@ -269,12 +268,12 @@ Json::Json(double value) : m_ptr(make_shared<JsonDouble>(value)) {
Json::Json(int value) : m_ptr(make_shared<JsonInt>(value)) {}
Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {}
Json::Json(const QString &value) : m_ptr(make_shared<JsonString>(value)) {}
Json::Json(QString &&value) : m_ptr(make_shared<JsonString>(move(value))) {}
Json::Json(QString &&value) : m_ptr(make_shared<JsonString>(std::move(value))) {}
Json::Json(const char * value) : m_ptr(make_shared<JsonString>(value)) {}
Json::Json(const Json::array &values) : m_ptr(make_shared<JsonArray>(values)) {}
Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(move(values))) {}
Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(std::move(values))) {}
Json::Json(const Json::object &values) : m_ptr(make_shared<JsonObject>(values)) {}
Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(move(values))) {}
Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(std::move(values))) {}
/* * * * * * * * * * * * * * * * * * * *
* Accessors
@ -399,7 +398,7 @@ struct JsonParser final {
* Mark this parse as failed.
*/
Json fail(QString &&msg) {
return fail(move(msg), Json());
return fail(std::move(msg), Json());
}
template <typename T>

View file

@ -1337,6 +1337,8 @@ void MainWindow::clearProjectUI() {
delete this->layoutListProxyModel;
this->layoutListProxyModel = nullptr;
}
Event::clearIcons();
}
void MainWindow::scrollTreeView(QString itemName) {
@ -2149,7 +2151,6 @@ void MainWindow::paste() {
else if (!clipboardText.isEmpty()) {
// we only can paste json text
// so, check if clipboard text is valid json
QString parseError;
QJsonDocument pasteJsonDoc = QJsonDocument::fromJson(clipboardText.toUtf8());
// test empty
@ -2457,7 +2458,6 @@ void MainWindow::updateObjects() {
}
void MainWindow::updateSelectedObjects() {
QList<DraggablePixmapItem *> all_events = editor->getObjects();
QList<DraggablePixmapItem *> events;
if (editor->selected_events && editor->selected_events->length()) {

View file

@ -42,9 +42,10 @@ Project::Project(QObject *parent) :
Project::~Project()
{
clearLayoutsTable();
clearMapCache();
clearTilesetCache();
clearMapLayouts();
clearEventGraphics();
}
void Project::initSignals() {
@ -171,17 +172,6 @@ void Project::clearTilesetCache() {
tilesetCache.clear();
}
void Project::clearLayoutsTable() {
// clearMapLayouts
// QMap<QString, Layout*> mapLayouts;
// QMap<QString, Layout*> mapLayoutsMaster;
for (Layout *layout : mapLayouts.values()) {
if (layout)
delete layout;
}
mapLayouts.clear();
}
Map* Project::loadMap(QString map_name) {
if (map_name == DYNAMIC_MAP_NAME)
return nullptr;
@ -373,6 +363,7 @@ bool Project::loadMapData(Map* map) {
heal->setRespawnNPC(loc.respawnNPC);
}
map->events[Event::Group::Heal].append(heal);
map->ownedEvents.append(heal);
}
}
@ -542,10 +533,15 @@ bool Project::loadMapLayout(Map* map) {
}
}
bool Project::readMapLayouts() {
void Project::clearMapLayouts() {
qDeleteAll(mapLayouts);
mapLayouts.clear();
mapLayoutsTable.clear();
layoutIdsToNames.clear();
}
bool Project::readMapLayouts() {
clearMapLayouts();
QString layoutsFilepath = projectConfig.getFilePath(ProjectFilePath::json_layouts);
QString fullFilepath = QString("%1/%2").arg(root).arg(layoutsFilepath);
@ -571,7 +567,7 @@ bool Project::readMapLayouts() {
.arg(layoutsLabel));
}
QList<QString> requiredFields = QList<QString>{
static const QList<QString> requiredFields = QList<QString>{
"id",
"name",
"width",
@ -1683,8 +1679,8 @@ bool Project::readTilesetMetatileLabels() {
QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels);
fileWatcher.addPath(root + "/" + metatileLabelsFilename);
const QStringList prefixes = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix))};
QMap<QString, int> defines = parser.readCDefinesByPrefix(metatileLabelsFilename, prefixes);
const QStringList regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix))};
QMap<QString, int> defines = parser.readCDefinesByRegex(metatileLabelsFilename, regexList);
for (QString label : defines.keys()) {
uint32_t metatileId = static_cast<uint32_t>(defines[label]);
@ -2059,8 +2055,6 @@ void Project::appendTilesetLabel(QString label, QString isSecondaryStr) {
}
bool Project::readTilesetLabels() {
QStringList primaryTilesets;
QStringList secondaryTilesets;
this->primaryTilesetLabels.clear();
this->secondaryTilesetLabels.clear();
this->tilesetLabelsOrdered.clear();
@ -2089,9 +2083,9 @@ bool Project::readTilesetLabels() {
} else {
this->usingAsmTilesets = false;
const auto structs = parser.readCStructs(filename, "", Tileset::getHeaderMemberMap(this->usingAsmTilesets));
QStringList labels = structs.keys();
const QStringList labels = structs.keys();
// TODO: This is alphabetical, AdvanceMap import wants the vanilla order in tilesetLabelsOrdered
for (const auto tilesetLabel : labels){
for (const auto &tilesetLabel : labels){
appendTilesetLabel(tilesetLabel, structs[tilesetLabel].value("isSecondary"));
}
}
@ -2288,10 +2282,10 @@ bool Project::readRegionMapSections() {
this->mapSectionNameToValue.clear();
this->mapSectionValueToName.clear();
const QStringList prefixes = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))};
const QStringList regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))};
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections);
fileWatcher.addPath(root + "/" + filename);
this->mapSectionNameToValue = parser.readCDefinesByPrefix(filename, prefixes);
this->mapSectionNameToValue = parser.readCDefinesByRegex(filename, regexList);
if (this->mapSectionNameToValue.isEmpty()) {
logError(QString("Failed to read region map sections from %1.").arg(filename));
return false;
@ -2343,13 +2337,13 @@ int Project::appendMapsec(QString name) {
// Read the constants to preserve any "unused" heal locations when writing the file later
bool Project::readHealLocationConstants() {
this->healLocationNameToValue.clear();
const QStringList prefixes = {
const QStringList regexList = {
QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_heal_locations_prefix)),
QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_spawn_prefix))
};
QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_heal_locations);
fileWatcher.addPath(root + "/" + constantsFilename);
this->healLocationNameToValue = parser.readCDefinesByPrefix(constantsFilename, prefixes);
this->healLocationNameToValue = parser.readCDefinesByRegex(constantsFilename, regexList);
// No need to check if empty, not finding any heal location constants is ok
return true;
}
@ -2405,7 +2399,7 @@ bool Project::readHealLocations() {
// Pattern for an x, y number pair
const QString coordPattern = "\\s*(?<x>[0-9A-Fa-fx]+),\\s*(?<y>[0-9A-Fa-fx]+)";
for (const auto idName : constants) {
for (const auto &idName : constants) {
// Create regex pattern for e.g. "SPAWN_PALLET_TOWN - 1] = "
const QString initializerPattern = QString("%1\\s*-\\s*1\\s*\\]\\s*=\\s*").arg(idName);
@ -2448,40 +2442,40 @@ bool Project::readHealLocations() {
}
bool Project::readItemNames() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_items)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_items)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items);
fileWatcher.addPath(root + "/" + filename);
itemNames = parser.readCDefineNames(filename, prefixes);
itemNames = parser.readCDefineNames(filename, regexList);
if (itemNames.isEmpty())
logWarn(QString("Failed to read item constants from %1").arg(filename));
return true;
}
bool Project::readFlagNames() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_flags)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_flags)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_flags);
fileWatcher.addPath(root + "/" + filename);
flagNames = parser.readCDefineNames(filename, prefixes);
flagNames = parser.readCDefineNames(filename, regexList);
if (flagNames.isEmpty())
logWarn(QString("Failed to read flag constants from %1").arg(filename));
return true;
}
bool Project::readVarNames() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_vars)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_vars)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars);
fileWatcher.addPath(root + "/" + filename);
varNames = parser.readCDefineNames(filename, prefixes);
varNames = parser.readCDefineNames(filename, regexList);
if (varNames.isEmpty())
logWarn(QString("Failed to read var constants from %1").arg(filename));
return true;
}
bool Project::readMovementTypes() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_movement_types)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_movement_types)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement);
fileWatcher.addPath(root + "/" + filename);
movementTypes = parser.readCDefineNames(filename, prefixes);
movementTypes = parser.readCDefineNames(filename, regexList);
if (movementTypes.isEmpty())
logWarn(QString("Failed to read movement type constants from %1").arg(filename));
return true;
@ -2497,30 +2491,30 @@ bool Project::readInitialFacingDirections() {
}
bool Project::readMapTypes() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_map_types)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_map_types)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types);
fileWatcher.addPath(root + "/" + filename);
mapTypes = parser.readCDefineNames(filename, prefixes);
mapTypes = parser.readCDefineNames(filename, regexList);
if (mapTypes.isEmpty())
logWarn(QString("Failed to read map type constants from %1").arg(filename));
return true;
}
bool Project::readMapBattleScenes() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_battle_scenes)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_battle_scenes)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types);
fileWatcher.addPath(root + "/" + filename);
mapBattleScenes = parser.readCDefineNames(filename, prefixes);
mapBattleScenes = parser.readCDefineNames(filename, regexList);
if (mapBattleScenes.isEmpty())
logWarn(QString("Failed to read map battle scene constants from %1").arg(filename));
return true;
}
bool Project::readWeatherNames() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_weather)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_weather)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather);
fileWatcher.addPath(root + "/" + filename);
weatherNames = parser.readCDefineNames(filename, prefixes);
weatherNames = parser.readCDefineNames(filename, regexList);
if (weatherNames.isEmpty())
logWarn(QString("Failed to read weather constants from %1").arg(filename));
return true;
@ -2530,10 +2524,10 @@ bool Project::readCoordEventWeatherNames() {
if (!projectConfig.eventWeatherTriggerEnabled)
return true;
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_coord_event_weather)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_coord_event_weather)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather);
fileWatcher.addPath(root + "/" + filename);
coordEventWeatherNames = parser.readCDefineNames(filename, prefixes);
coordEventWeatherNames = parser.readCDefineNames(filename, regexList);
if (coordEventWeatherNames.isEmpty())
logWarn(QString("Failed to read coord event weather constants from %1").arg(filename));
return true;
@ -2543,30 +2537,30 @@ bool Project::readSecretBaseIds() {
if (!projectConfig.eventSecretBaseEnabled)
return true;
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_secret_bases)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_secret_bases)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases);
fileWatcher.addPath(root + "/" + filename);
secretBaseIds = parser.readCDefineNames(filename, prefixes);
secretBaseIds = parser.readCDefineNames(filename, regexList);
if (secretBaseIds.isEmpty())
logWarn(QString("Failed to read secret base id constants from '%1'").arg(filename));
return true;
}
bool Project::readBgEventFacingDirections() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_sign_facing_directions)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_sign_facing_directions)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg);
fileWatcher.addPath(root + "/" + filename);
bgEventFacingDirections = parser.readCDefineNames(filename, prefixes);
bgEventFacingDirections = parser.readCDefineNames(filename, regexList);
if (bgEventFacingDirections.isEmpty())
logWarn(QString("Failed to read bg event facing direction constants from %1").arg(filename));
return true;
}
bool Project::readTrainerTypes() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_trainer_types)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_trainer_types)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types);
fileWatcher.addPath(root + "/" + filename);
trainerTypes = parser.readCDefineNames(filename, prefixes);
trainerTypes = parser.readCDefineNames(filename, regexList);
if (trainerTypes.isEmpty())
logWarn(QString("Failed to read trainer type constants from %1").arg(filename));
return true;
@ -2576,10 +2570,10 @@ bool Project::readMetatileBehaviors() {
this->metatileBehaviorMap.clear();
this->metatileBehaviorMapInverse.clear();
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)};
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors);
fileWatcher.addPath(root + "/" + filename);
QMap<QString, int> defines = parser.readCDefinesByPrefix(filename, prefixes);
QMap<QString, int> defines = parser.readCDefinesByRegex(filename, regexList);
if (defines.isEmpty()) {
// Not having any metatile behavior names is ok (their values will be displayed instead).
// If the user's metatiles can have nonzero values then warn them, as they likely want names.
@ -2598,10 +2592,10 @@ bool Project::readMetatileBehaviors() {
}
bool Project::readSongNames() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_music)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_music)};
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs);
fileWatcher.addPath(root + "/" + filename);
this->songNames = parser.readCDefineNames(filename, prefixes);
this->songNames = parser.readCDefineNames(filename, regexList);
if (this->songNames.isEmpty())
logWarn(QString("Failed to read song names from %1.").arg(filename));
@ -2613,10 +2607,10 @@ bool Project::readSongNames() {
}
bool Project::readObjEventGfxConstants() {
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_obj_event_gfx)};
const QStringList regexList = {projectConfig.getIdentifier(ProjectIdentifier::regex_obj_event_gfx)};
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_events);
fileWatcher.addPath(root + "/" + filename);
this->gfxDefines = parser.readCDefinesByPrefix(filename, prefixes);
this->gfxDefines = parser.readCDefinesByRegex(filename, regexList);
if (this->gfxDefines.isEmpty())
logWarn(QString("Failed to read object event graphics constants from %1.").arg(filename));
return true;
@ -2719,7 +2713,14 @@ void Project::setEventPixmap(Event *event, bool forceLoad) {
event->loadPixmap(this);
}
void Project::clearEventGraphics() {
qDeleteAll(eventGraphicsMap);
eventGraphicsMap.clear();
}
bool Project::readEventGraphics() {
clearEventGraphics();
fileWatcher.addPaths(QStringList() << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers)
<< root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info)
<< root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables)
@ -2729,8 +2730,6 @@ bool Project::readEventGraphics() {
const QString pointersName = projectConfig.getIdentifier(ProjectIdentifier::symbol_obj_event_gfx_pointers);
QMap<QString, QString> pointerHash = parser.readNamedIndexCArray(pointersFilepath, pointersName);
qDeleteAll(eventGraphicsMap);
eventGraphicsMap.clear();
QStringList gfxNames = gfxDefines.keys();
// The positions of each of the required members for the gfx info struct.
@ -2749,14 +2748,13 @@ bool Project::readEventGraphics() {
QMap<QString, QString> graphicIncbins = parser.readCIncbinMulti(projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx));
for (QString gfxName : gfxNames) {
EventGraphics * eventGraphics = new EventGraphics;
QString info_label = pointerHash[gfxName].replace("&", "");
if (!gfxInfos.contains(info_label))
continue;
const auto gfxInfoAttributes = gfxInfos[info_label];
auto eventGraphics = new EventGraphics;
eventGraphics->inanimate = ParseUtil::gameStringToBool(gfxInfoAttributes.value("inanimate"));
QString pic_label = gfxInfoAttributes.value("images");
QString dimensions_label = gfxInfoAttributes.value("oam");
@ -2811,10 +2809,10 @@ bool Project::readSpeciesIconPaths() {
const QMap<QString, QString> iconIncbins = parser.readCIncbinMulti(incfilename);
// Read species constants. If this fails we can get them from the icon table (but we shouldn't rely on it).
const QStringList prefixes = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_species_prefix))};
const QStringList regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_species_prefix))};
const QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_species);
fileWatcher.addPath(root + "/" + constantsFilename);
QStringList speciesNames = parser.readCDefineNames(constantsFilename, prefixes);
QStringList speciesNames = parser.readCDefineNames(constantsFilename, regexList);
if (speciesNames.isEmpty())
speciesNames = monIconNames.keys();

View file

@ -48,7 +48,6 @@ void ColorPicker::hover(int mouseX, int mouseY) {
return;
// 15 X 15 box with 8x magnification = 120px square)
QRect zoomRect(mouseX - zoom_box_dimensions / 2, mouseY - zoom_box_dimensions / 2, zoom_box_dimensions, zoom_box_dimensions);
QPixmap grab = screen->grabWindow(0, mouseX - zoom_box_dimensions / 2, mouseY - zoom_box_dimensions / 2, zoom_box_dimensions, zoom_box_dimensions);
int pixelRatio = grab.devicePixelRatio();

View file

@ -12,11 +12,6 @@ static inline QSpacerItem *createSpacerH() {
return new QSpacerItem(2, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
}
static inline QSpacerItem *createSpacerV() {
return new QSpacerItem(1, 2, QSizePolicy::Minimum, QSizePolicy::Expanding);
}
void EventFrame::setup() {
// delete default layout due to lack of parent at initialization

View file

@ -81,7 +81,7 @@ QSize FlowLayout::sizeHint() const {
QSize FlowLayout::minimumSize() const {
QSize size;
for (const QLayoutItem *item : qAsConst(itemList))
for (const QLayoutItem *item : std::as_const(itemList))
size = size.expandedTo(item->minimumSize());
const QMargins margins = contentsMargins();
@ -97,7 +97,7 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
int y = effectiveRect.y();
int lineHeight = 0;
for (QLayoutItem *item : qAsConst(itemList)) {
for (QLayoutItem *item : std::as_const(itemList)) {
const QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)

View file

@ -326,6 +326,7 @@ QPixmap MapImageExporter::getStitchedImage(QProgressDialog *progress, bool inclu
progress->setMaximum(stitchedMaps.size());
int numDrawn = 0;
QPixmap stitchedPixmap((maxX - minX) * 16, (maxY - minY) * 16);
stitchedPixmap.fill(Qt::black);
QPainter painter(&stitchedPixmap);
for (StitchedMap map : stitchedMaps) {
if (progress->wasCanceled()) {

View file

@ -19,7 +19,7 @@ NoScrollComboBox::NoScrollComboBox(QWidget *parent)
this->completer()->setFilterMode(Qt::MatchContains);
static const QRegularExpression re("[^\\s]*");
QValidator *validator = new QRegularExpressionValidator(re);
QValidator *validator = new QRegularExpressionValidator(re, this);
this->setValidator(validator);
}

View file

@ -1009,7 +1009,6 @@ void RegionMapEditor::on_tabWidget_Region_Map_currentChanged(int index) {
}
void RegionMapEditor::on_comboBox_RM_ConnectedMap_textActivated(const QString &mapsec) {
QString layer = this->region_map->getLayer();
this->region_map->setSquareMapSection(this->currIndex, mapsec);
onRegionMapLayoutSelectedTileChanged(this->currIndex);// re-draw layout image

View file

@ -996,7 +996,6 @@ void TilesetEditor::on_actionImport_Secondary_Metatiles_triggered()
void TilesetEditor::importTilesetMetatiles(Tileset *tileset, bool primary)
{
QString descriptor = primary ? "primary" : "secondary";
QString descriptorCaps = primary ? "Primary" : "Secondary";
QString filepath = QFileDialog::getOpenFileName(

View file

@ -234,10 +234,6 @@ void TilesetEditorMetatileSelector::drawUnused() {
int primaryLength = this->primaryTileset->metatiles.length();
int length_ = primaryLength + this->secondaryTileset->metatiles.length();
int height_ = length_ / this->numMetatilesWide;
if (length_ % this->numMetatilesWide != 0) {
height_++;
}
for (int i = 0; i < length_; i++) {
int tile = i;
@ -277,10 +273,6 @@ void TilesetEditorMetatileSelector::drawCounts() {
int primaryLength = this->primaryTileset->metatiles.length();
int length_ = primaryLength + this->secondaryTileset->metatiles.length();
int height_ = length_ / this->numMetatilesWide;
if (length_ % this->numMetatilesWide != 0) {
height_++;
}
for (int i = 0; i < length_; i++) {
int tile = i;

View file

@ -294,8 +294,6 @@ void TilesetEditorTileSelector::drawUnused() {
QPixmap redX(16, 16);
redX.fill(Qt::transparent);
QBitmap mask(16, 16);
QPen whitePen(Qt::white);
whitePen.setWidth(1);
QPen pinkPen(Qt::magenta);

View file

@ -33,6 +33,10 @@ UpdatePromoter::UpdatePromoter(QWidget *parent, NetworkAccessManager *manager)
this->resetDialog();
}
UpdatePromoter::~UpdatePromoter() {
delete ui;
}
void UpdatePromoter::resetDialog() {
this->button_Downloads->setEnabled(false);

View file

@ -218,7 +218,7 @@ bool WildMonChart::usesGroupLabels() const {
QChart* WildMonChart::createSpeciesDistributionChart() {
QList<QBarSet*> barSets;
for (const auto species : getSpeciesNamesAlphabetical()) {
for (const auto &species : getSpeciesNamesAlphabetical()) {
// Add encounter chance data
auto set = new QBarSet(species);
for (auto groupName : this->groupNamesReversed)
@ -326,7 +326,7 @@ QChart* WildMonChart::createLevelDistributionChart() {
levelRange = getLevelRange(species, groupName);
} else {
// Species box is inactive, we display data for all species in the table.
for (const auto species : this->speciesInLegendOrder)
for (const auto &species : this->speciesInLegendOrder)
barSets.append(createLevelDistributionBarSet(species, groupName, false));
levelRange = this->groupedLevelRanges.value(groupName);
}

View file

@ -136,7 +136,7 @@ bool QGifImagePrivate::load(QIODevice *device)
int error;
GifFileType *gifFile = DGifOpen(device, readFromIODevice, &error);
if (!gifFile) {
qWarning(GifErrorString(error));
qWarning("%s", GifErrorString(error));
return false;
}
@ -228,7 +228,7 @@ bool QGifImagePrivate::save(QIODevice *device) const
int error;
GifFileType *gifFile = EGifOpen(device, writeToIODevice, &error);
if (!gifFile) {
qWarning(GifErrorString(error));
qWarning("%s", GifErrorString(error));
return false;
}