mirror of
https://github.com/huderlem/porymap.git
synced 2026-08-12 11:55:44 -05:00
Merge pull request #717 from GriffinRichards/write-errors
Better error handling if saving fails
This commit is contained in:
@@ -26,7 +26,7 @@ static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_
|
||||
class KeyValueConfigBase
|
||||
{
|
||||
public:
|
||||
void save();
|
||||
bool save();
|
||||
void load();
|
||||
virtual ~KeyValueConfigBase();
|
||||
virtual void reset() = 0;
|
||||
|
||||
@@ -116,9 +116,12 @@ public:
|
||||
void clearBorderCache();
|
||||
void cacheBorder();
|
||||
|
||||
void setClean();
|
||||
bool hasUnsavedChanges() const;
|
||||
|
||||
bool save(const QString &root);
|
||||
bool saveBorder(const QString &root);
|
||||
bool saveBlockdata(const QString &root);
|
||||
|
||||
bool layoutBlockChanged(int i, const Blockdata &cache);
|
||||
|
||||
uint16_t getBorderMetatileId(int x, int y);
|
||||
@@ -143,6 +146,7 @@ public:
|
||||
private:
|
||||
void setNewDimensionsBlockdata(int newWidth, int newHeight);
|
||||
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
|
||||
bool writeBlockdata(const QString &path, const Blockdata &blockdata) const;
|
||||
|
||||
static int getBorderDrawDistance(int dimension, qreal minimum);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace PaletteUtil {
|
||||
QList<QRgb> parse(QString filepath, bool *error);
|
||||
void writeJASC(QString filepath, QVector<QRgb> colors, int offset, int nColors);
|
||||
bool writeJASC(const QString &filepath, const QVector<QRgb> &colors, int offset, int nColors);
|
||||
}
|
||||
|
||||
#endif // PALETTEUTIL_H
|
||||
|
||||
@@ -55,17 +55,17 @@ public:
|
||||
static QString getExpectedDir(QString tilesetName, bool isSecondary);
|
||||
QString getExpectedDir();
|
||||
|
||||
void load();
|
||||
void loadMetatiles();
|
||||
void loadMetatileAttributes();
|
||||
void loadTilesImage(QImage *importedImage = nullptr);
|
||||
void loadPalettes();
|
||||
bool load();
|
||||
bool loadMetatiles();
|
||||
bool loadMetatileAttributes();
|
||||
bool loadTilesImage(QImage *importedImage = nullptr);
|
||||
bool loadPalettes();
|
||||
|
||||
void save();
|
||||
void saveMetatileAttributes();
|
||||
void saveMetatiles();
|
||||
void saveTilesImage();
|
||||
void savePalettes();
|
||||
bool save();
|
||||
bool saveMetatileAttributes();
|
||||
bool saveMetatiles();
|
||||
bool saveTilesImage();
|
||||
bool savePalettes();
|
||||
|
||||
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
|
||||
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
GridSettings gridSettings;
|
||||
|
||||
void setProject(Project * project);
|
||||
void saveAll();
|
||||
void saveCurrent();
|
||||
bool saveAll();
|
||||
bool saveCurrent();
|
||||
void saveEncounterTabData();
|
||||
|
||||
void closeProject();
|
||||
@@ -199,7 +199,7 @@ private:
|
||||
|
||||
EditMode editMode = EditMode::None;
|
||||
|
||||
void save(bool currentOnly);
|
||||
bool save(bool currentOnly);
|
||||
void clearMap();
|
||||
void clearMetatileSelector();
|
||||
void clearMovementPermissionSelector();
|
||||
|
||||
@@ -175,7 +175,7 @@ private slots:
|
||||
void on_action_Reload_Project_triggered();
|
||||
void on_action_Close_Project_triggered();
|
||||
void on_action_Save_Project_triggered();
|
||||
void save(bool currentOnly = false);
|
||||
bool save(bool currentOnly = false);
|
||||
|
||||
void openWarpMap(QString map_name, int event_id, Event::Group event_group);
|
||||
|
||||
|
||||
@@ -108,10 +108,6 @@ public:
|
||||
bool loadBlockdata(Layout *);
|
||||
bool loadLayoutBorder(Layout *);
|
||||
|
||||
void saveTextFile(QString path, QString text);
|
||||
void appendTextFile(QString path, QString text);
|
||||
void deleteFile(QString path);
|
||||
|
||||
bool readMapGroups();
|
||||
void addNewMapGroup(const QString &groupName);
|
||||
QString mapNameToMapGroup(const QString &mapName) const;
|
||||
@@ -168,25 +164,20 @@ public:
|
||||
bool loadLayout(Layout *);
|
||||
bool loadMapLayout(Map*);
|
||||
bool loadLayoutTilesets(Layout *);
|
||||
void loadTilesetAssets(Tileset*);
|
||||
bool loadTilesetAssets(Tileset*);
|
||||
void loadTilesetMetatileLabels(Tileset*);
|
||||
void readTilesetPaths(Tileset* tileset);
|
||||
|
||||
void saveAll();
|
||||
void saveGlobalData();
|
||||
void saveLayout(Layout *);
|
||||
void saveLayoutBlockdata(Layout *);
|
||||
void saveLayoutBorder(Layout *);
|
||||
void writeBlockdata(QString, const Blockdata &);
|
||||
void saveMap(Map *map, bool skipLayout = false);
|
||||
void saveConfig();
|
||||
void saveMapLayouts();
|
||||
void saveMapGroups();
|
||||
void saveRegionMapSections();
|
||||
void saveWildMonData();
|
||||
void saveHealLocations();
|
||||
void saveTilesets(Tileset*, Tileset*);
|
||||
void saveTilesetMetatileLabels(Tileset*, Tileset*);
|
||||
bool saveAll();
|
||||
bool saveGlobalData();
|
||||
bool saveConfig();
|
||||
bool saveLayout(Layout *layout);
|
||||
bool saveMap(Map *map, bool skipLayout = false);
|
||||
bool saveTextFile(const QString &path, const QString &text);
|
||||
bool saveRegionMapSections();
|
||||
bool saveTilesets(Tileset*, Tileset*);
|
||||
bool saveTilesetMetatileLabels(Tileset*, Tileset*);
|
||||
|
||||
void appendTilesetLabel(const QString &label, const QString &isSecondaryStr);
|
||||
bool readTilesetLabels();
|
||||
bool readTilesetMetatileLabels();
|
||||
@@ -309,8 +300,6 @@ private:
|
||||
};
|
||||
QHash<QString, LocationData> locationData;
|
||||
|
||||
void updateLayout(Layout *);
|
||||
|
||||
void setNewLayoutBlockdata(Layout *layout);
|
||||
void setNewLayoutBorder(Layout *layout);
|
||||
|
||||
@@ -318,6 +307,12 @@ private:
|
||||
void recordFileChange(const QString &filepath);
|
||||
void resetFileCache();
|
||||
|
||||
bool saveMapLayouts();
|
||||
bool saveMapGroups();
|
||||
bool saveWildMonData();
|
||||
bool saveHealLocations();
|
||||
bool appendTextFile(const QString &path, const QString &text);
|
||||
|
||||
QString findSpeciesIconPath(const QStringList &names) const;
|
||||
|
||||
int maxEventsPerGroup;
|
||||
|
||||
@@ -71,8 +71,6 @@ private slots:
|
||||
|
||||
void on_spinBox_paletteSelector_valueChanged(int arg1);
|
||||
|
||||
void on_actionSave_Tileset_triggered();
|
||||
|
||||
void on_actionImport_Primary_Tiles_triggered();
|
||||
|
||||
void on_actionImport_Secondary_Tiles_triggered();
|
||||
@@ -173,6 +171,8 @@ private:
|
||||
bool lockSelection = false;
|
||||
QSet<uint16_t> metatileReloadQueue;
|
||||
|
||||
bool save();
|
||||
|
||||
signals:
|
||||
void tilesetsSaved(QString, QString);
|
||||
};
|
||||
|
||||
@@ -233,7 +233,7 @@ void KeyValueConfigBase::load() {
|
||||
file.close();
|
||||
}
|
||||
|
||||
void KeyValueConfigBase::save() {
|
||||
bool KeyValueConfigBase::save() {
|
||||
QString text = "";
|
||||
QMap<QString, QString> map = this->getKeyValueMap();
|
||||
for (QMap<QString, QString>::iterator it = map.begin(); it != map.end(); it++) {
|
||||
@@ -241,12 +241,14 @@ void KeyValueConfigBase::save() {
|
||||
}
|
||||
|
||||
QFile file(this->getConfigFilepath());
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(text.toUtf8());
|
||||
file.close();
|
||||
} else {
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open config file '%1' for writing: ").arg(this->getConfigFilepath()) + file.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(text.toUtf8());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyValueConfigBase::getConfigBool(QString key, QString value) {
|
||||
|
||||
@@ -467,11 +467,50 @@ QPixmap Layout::getLayoutItemPixmap() {
|
||||
return this->layoutItem ? this->layoutItem->pixmap() : QPixmap();
|
||||
}
|
||||
|
||||
void Layout::setClean() {
|
||||
this->editHistory.setClean();
|
||||
this->hasUnsavedDataChanges = false;
|
||||
}
|
||||
|
||||
bool Layout::hasUnsavedChanges() const {
|
||||
return !this->editHistory.isClean() || this->hasUnsavedDataChanges || !this->newFolderPath.isEmpty();
|
||||
}
|
||||
|
||||
bool Layout::save(const QString &root) {
|
||||
if (!this->newFolderPath.isEmpty()) {
|
||||
// Layout directory doesn't exist yet, create it now.
|
||||
const QString fullPath = QString("%1/%2").arg(root).arg(this->newFolderPath);
|
||||
if (!QDir::root().mkpath(fullPath)) {
|
||||
logError(QString("Failed to create directory for new layout: '%1'").arg(fullPath));
|
||||
return false;
|
||||
}
|
||||
this->newFolderPath = QString();
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
if (!saveBorder(root)) success = false;
|
||||
if (!saveBlockdata(root)) success = false;
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
this->editHistory.setClean();
|
||||
this->hasUnsavedDataChanges = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Layout::saveBorder(const QString &root) {
|
||||
QString path = QString("%1/%2").arg(root).arg(this->border_path);
|
||||
return writeBlockdata(path, this->border);
|
||||
}
|
||||
|
||||
bool Layout::saveBlockdata(const QString &root) {
|
||||
QString path = QString("%1/%2").arg(root).arg(this->blockdata_path);
|
||||
return writeBlockdata(path, this->blockdata);
|
||||
}
|
||||
|
||||
bool Layout::writeBlockdata(const QString &path, const Blockdata &blockdata) const {
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(path).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = blockdata.serialize();
|
||||
file.write(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,14 @@ QList<QRgb> PaletteUtil::parse(QString filepath, bool *error) {
|
||||
return QList<QRgb>();
|
||||
}
|
||||
|
||||
void PaletteUtil::writeJASC(QString filepath, QVector<QRgb> palette, int offset, int nColors) {
|
||||
bool PaletteUtil::writeJASC(const QString &filepath, const QVector<QRgb> &palette, int offset, int nColors) {
|
||||
if (!nColors) {
|
||||
logWarn(QString("Cannot save a palette with no colors."));
|
||||
return;
|
||||
logError(QString("Cannot save a palette with no colors."));
|
||||
return false;
|
||||
}
|
||||
if (offset > palette.size() || offset + nColors > palette.size()) {
|
||||
logWarn("Palette offset out of range for color table.");
|
||||
return;
|
||||
logError("Palette offset out of range for color table.");
|
||||
return false;
|
||||
}
|
||||
|
||||
QString text = "JASC-PAL\r\n0100\r\n";
|
||||
@@ -59,11 +59,13 @@ void PaletteUtil::writeJASC(QString filepath, QVector<QRgb> palette, int offset,
|
||||
}
|
||||
|
||||
QFile file(filepath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(text.toUtf8());
|
||||
} else {
|
||||
logWarn(QString("Could not write to file '%1': ").arg(filepath) + file.errorString());
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not write to file '%1': ").arg(filepath) + file.errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(text.toUtf8());
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<QRgb> parsePal(QString filepath, bool *error) {
|
||||
|
||||
@@ -402,13 +402,13 @@ QHash<int, QString> Tileset::getHeaderMemberMap(bool usingAsm)
|
||||
return map;
|
||||
}
|
||||
|
||||
void Tileset::loadMetatiles() {
|
||||
bool Tileset::loadMetatiles() {
|
||||
clearMetatiles();
|
||||
|
||||
QFile metatiles_file(this->metatiles_path);
|
||||
if (!metatiles_file.open(QIODevice::ReadOnly)) {
|
||||
logError(QString("Could not open '%1' for reading.").arg(this->metatiles_path));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for reading: %2").arg(this->metatiles_path).arg(metatiles_file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = metatiles_file.readAll();
|
||||
@@ -425,13 +425,14 @@ void Tileset::loadMetatiles() {
|
||||
}
|
||||
m_metatiles.append(metatile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::saveMetatiles() {
|
||||
bool Tileset::saveMetatiles() {
|
||||
QFile metatiles_file(this->metatiles_path);
|
||||
if (!metatiles_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
logError(QString("Could not open '%1' for writing.").arg(this->metatiles_path));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(this->metatiles_path).arg(metatiles_file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
@@ -444,13 +445,14 @@ void Tileset::saveMetatiles() {
|
||||
}
|
||||
}
|
||||
metatiles_file.write(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::loadMetatileAttributes() {
|
||||
bool Tileset::loadMetatileAttributes() {
|
||||
QFile attrs_file(this->metatile_attrs_path);
|
||||
if (!attrs_file.open(QIODevice::ReadOnly)) {
|
||||
logError(QString("Could not open '%1' for reading.").arg(this->metatile_attrs_path));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for reading: %2").arg(this->metatile_attrs_path).arg(attrs_file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = attrs_file.readAll();
|
||||
@@ -467,13 +469,14 @@ void Tileset::loadMetatileAttributes() {
|
||||
attributes |= static_cast<unsigned char>(data.at(i * attrSize + j)) << (8 * j);
|
||||
m_metatiles.at(i)->setAttributes(attributes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::saveMetatileAttributes() {
|
||||
bool Tileset::saveMetatileAttributes() {
|
||||
QFile attrs_file(this->metatile_attrs_path);
|
||||
if (!attrs_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
logError(QString("Could not open '%1' for writing.").arg(this->metatile_attrs_path));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(this->metatile_attrs_path).arg(attrs_file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
@@ -483,9 +486,10 @@ void Tileset::saveMetatileAttributes() {
|
||||
data.append(static_cast<char>(attributes >> (8 * i)));
|
||||
}
|
||||
attrs_file.write(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::loadTilesImage(QImage *importedImage) {
|
||||
bool Tileset::loadTilesImage(QImage *importedImage) {
|
||||
QImage image;
|
||||
if (importedImage) {
|
||||
image = *importedImage;
|
||||
@@ -520,23 +524,25 @@ void Tileset::loadTilesImage(QImage *importedImage) {
|
||||
}
|
||||
this->tilesImage = image;
|
||||
this->tiles = tiles;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::saveTilesImage() {
|
||||
bool Tileset::saveTilesImage() {
|
||||
// Only write the tiles image if it was changed.
|
||||
// Porymap will only ever change an existing tiles image by importing a new one.
|
||||
if (!m_hasUnsavedTilesImage)
|
||||
return;
|
||||
return true;
|
||||
|
||||
if (!this->tilesImage.save(this->tilesImagePath, "PNG")) {
|
||||
logError(QString("Failed to save tiles image '%1'").arg(this->tilesImagePath));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hasUnsavedTilesImage = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::loadPalettes() {
|
||||
bool Tileset::loadPalettes() {
|
||||
this->palettes.clear();
|
||||
this->palettePreviews.clear();
|
||||
|
||||
@@ -559,26 +565,34 @@ void Tileset::loadPalettes() {
|
||||
this->palettes.append(palette);
|
||||
this->palettePreviews.append(palette);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::savePalettes() {
|
||||
bool Tileset::savePalettes() {
|
||||
bool success = true;
|
||||
int numPalettes = qMin(this->palettePaths.length(), this->palettes.length());
|
||||
for (int i = 0; i < numPalettes; i++) {
|
||||
PaletteUtil::writeJASC(this->palettePaths.at(i), this->palettes.at(i).toVector(), 0, 16);
|
||||
if (!PaletteUtil::writeJASC(this->palettePaths.at(i), this->palettes.at(i).toVector(), 0, 16))
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void Tileset::load() {
|
||||
loadMetatiles();
|
||||
loadMetatileAttributes();
|
||||
loadTilesImage();
|
||||
loadPalettes();
|
||||
bool Tileset::load() {
|
||||
bool success = true;
|
||||
if (!loadMetatiles()) success = false;
|
||||
if (!loadMetatileAttributes()) success = false;
|
||||
if (!loadTilesImage()) success = false;
|
||||
if (!loadPalettes()) success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
// Because metatile labels are global (and handled by the project) we don't save them here.
|
||||
void Tileset::save() {
|
||||
saveMetatiles();
|
||||
saveMetatileAttributes();
|
||||
saveTilesImage();
|
||||
savePalettes();
|
||||
bool Tileset::save() {
|
||||
bool success = true;
|
||||
if (!saveMetatiles()) success = false;
|
||||
if (!saveMetatileAttributes()) success = false;
|
||||
if (!saveTilesImage()) success = false;
|
||||
if (!savePalettes()) success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -68,30 +68,33 @@ Editor::~Editor()
|
||||
closeProject();
|
||||
}
|
||||
|
||||
void Editor::saveCurrent() {
|
||||
save(true);
|
||||
bool Editor::saveCurrent() {
|
||||
return save(true);
|
||||
}
|
||||
|
||||
void Editor::saveAll() {
|
||||
save(false);
|
||||
bool Editor::saveAll() {
|
||||
return save(false);
|
||||
}
|
||||
|
||||
void Editor::save(bool currentOnly) {
|
||||
bool Editor::save(bool currentOnly) {
|
||||
if (!this->project)
|
||||
return;
|
||||
return true;
|
||||
|
||||
saveEncounterTabData();
|
||||
|
||||
bool success = true;
|
||||
if (currentOnly) {
|
||||
if (this->map) {
|
||||
this->project->saveMap(this->map);
|
||||
success = this->project->saveMap(this->map);
|
||||
} else if (this->layout) {
|
||||
this->project->saveLayout(this->layout);
|
||||
success = this->project->saveLayout(this->layout);
|
||||
}
|
||||
this->project->saveGlobalData();
|
||||
if (!this->project->saveGlobalData())
|
||||
success = false;
|
||||
} else {
|
||||
this->project->saveAll();
|
||||
success = this->project->saveAll();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void Editor::setProject(Project * project) {
|
||||
|
||||
@@ -1634,16 +1634,15 @@ void MainWindow::on_action_Save_triggered() {
|
||||
save(true);
|
||||
}
|
||||
|
||||
void MainWindow::save(bool currentOnly) {
|
||||
if (currentOnly) {
|
||||
this->editor->saveCurrent();
|
||||
} else {
|
||||
this->editor->saveAll();
|
||||
bool MainWindow::save(bool currentOnly) {
|
||||
bool success = currentOnly ? this->editor->saveCurrent() : this->editor->saveAll();
|
||||
if (!success) {
|
||||
RecentErrorMessage::show(QStringLiteral("Failed to save some project changes."), this);
|
||||
}
|
||||
updateWindowTitle();
|
||||
updateMapList();
|
||||
|
||||
if (!porymapConfig.shownInGameReloadMessage) {
|
||||
if (success && !porymapConfig.shownInGameReloadMessage) {
|
||||
// Show a one-time warning that the user may need to reload their map to see their new changes.
|
||||
InfoMessage::show(QStringLiteral("Reload your map in-game!\n\nIf your game is currently saved on a map you have edited, "
|
||||
"the changes may not appear until you leave the map and return."),
|
||||
@@ -1652,6 +1651,7 @@ void MainWindow::save(bool currentOnly) {
|
||||
}
|
||||
|
||||
saveGlobalConfigs();
|
||||
return success;
|
||||
}
|
||||
|
||||
void MainWindow::duplicate() {
|
||||
@@ -3048,7 +3048,8 @@ bool MainWindow::closeProject() {
|
||||
|
||||
auto reply = msgBox.exec();
|
||||
if (reply == QMessageBox::Yes) {
|
||||
save();
|
||||
if (!save())
|
||||
return false;
|
||||
} else if (reply == QMessageBox::No) {
|
||||
logWarn("Closing project with unsaved changes.");
|
||||
} else if (reply == QMessageBox::Cancel) {
|
||||
|
||||
250
src/project.cpp
250
src/project.cpp
@@ -162,8 +162,10 @@ void Project::clearTilesetCache() {
|
||||
|
||||
Map* Project::loadMap(const QString &mapName) {
|
||||
Map* map = this->maps.value(mapName);
|
||||
if (!map)
|
||||
if (!map) {
|
||||
logError(QString("Unknown map name '%1'.").arg(mapName));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (isMapLoaded(map))
|
||||
return map;
|
||||
@@ -445,8 +447,13 @@ bool Project::loadLayout(Layout *layout) {
|
||||
|
||||
Layout *Project::loadLayout(QString layoutId) {
|
||||
Layout *layout = this->mapLayouts.value(layoutId);
|
||||
if (!layout || !loadLayout(layout)) {
|
||||
logError(QString("Failed to load layout '%1'").arg(layoutId));
|
||||
if (!layout) {
|
||||
logError(QString("Unknown layout ID '%1'.").arg(layoutId));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!loadLayout(layout)) {
|
||||
// Error should already be logged.
|
||||
return nullptr;
|
||||
}
|
||||
return layout;
|
||||
@@ -587,12 +594,12 @@ bool Project::readMapLayouts() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveMapLayouts() {
|
||||
bool Project::saveMapLayouts() {
|
||||
QString layoutsFilepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::json_layouts);
|
||||
QFile layoutsFile(layoutsFilepath);
|
||||
if (!layoutsFile.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Error: Could not open %1 for writing").arg(layoutsFilepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(layoutsFilepath).arg(layoutsFile.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedJson::object layoutsObj;
|
||||
@@ -626,6 +633,7 @@ void Project::saveMapLayouts() {
|
||||
OrderedJsonDoc jsonDoc(&layoutJson);
|
||||
jsonDoc.dump(&layoutsFile);
|
||||
layoutsFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::ignoreWatchedFileTemporarily(QString filepath) {
|
||||
@@ -651,12 +659,12 @@ void Project::recordFileChange(const QString &filepath) {
|
||||
emit fileChanged(filepath);
|
||||
}
|
||||
|
||||
void Project::saveMapGroups() {
|
||||
bool Project::saveMapGroups() {
|
||||
QString mapGroupsFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_map_groups));
|
||||
QFile mapGroupsFile(mapGroupsFilepath);
|
||||
if (!mapGroupsFile.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Error: Could not open %1 for writing").arg(mapGroupsFilepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(mapGroupsFilepath).arg(mapGroupsFile.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedJson::object mapGroupsObj;
|
||||
@@ -686,14 +694,15 @@ void Project::saveMapGroups() {
|
||||
OrderedJsonDoc jsonDoc(&mapGroupJson);
|
||||
jsonDoc.dump(&mapGroupsFile);
|
||||
mapGroupsFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveRegionMapSections() {
|
||||
bool Project::saveRegionMapSections() {
|
||||
const QString filepath = QString("%1/%2").arg(this->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_map_entries));
|
||||
QFile file(filepath);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open '%1' for writing").arg(filepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(filepath).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedJson::array mapSectionArray;
|
||||
@@ -727,16 +736,17 @@ void Project::saveRegionMapSections() {
|
||||
OrderedJsonDoc jsonDoc(&json);
|
||||
jsonDoc.dump(&file);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveWildMonData() {
|
||||
if (!this->wildEncountersLoaded) return;
|
||||
bool Project::saveWildMonData() {
|
||||
if (!this->wildEncountersLoaded) return true;
|
||||
|
||||
QString wildEncountersJsonFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_wild_encounters));
|
||||
QFile wildEncountersFile(wildEncountersJsonFilepath);
|
||||
if (!wildEncountersFile.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Error: Could not open %1 for writing").arg(wildEncountersJsonFilepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(wildEncountersJsonFilepath).arg(wildEncountersFile.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedJson::object wildEncountersObject;
|
||||
@@ -822,6 +832,7 @@ void Project::saveWildMonData() {
|
||||
OrderedJsonDoc jsonDoc(&encounterJson);
|
||||
jsonDoc.dump(&wildEncountersFile);
|
||||
wildEncountersFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// For a map with a constant of 'MAP_FOO', returns a unique 'HEAL_LOCATION_FOO'.
|
||||
@@ -838,12 +849,12 @@ QString Project::getNewHealLocationName(const Map* map) const {
|
||||
return toUniqueIdentifier(projectConfig.getIdentifier(ProjectIdentifier::define_heal_locations_prefix) + idName);
|
||||
}
|
||||
|
||||
void Project::saveHealLocations() {
|
||||
bool Project::saveHealLocations() {
|
||||
const QString filepath = QString("%1/%2").arg(this->root).arg(projectConfig.getFilePath(ProjectFilePath::json_heal_locations));
|
||||
QFile file(filepath);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open '%1' for writing").arg(filepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(filepath).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build the JSON data for output.
|
||||
@@ -880,17 +891,21 @@ void Project::saveHealLocations() {
|
||||
OrderedJsonDoc jsonDoc(&json);
|
||||
jsonDoc.dump(&file);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
saveTilesetMetatileLabels(primaryTileset, secondaryTileset);
|
||||
if (primaryTileset)
|
||||
primaryTileset->save();
|
||||
if (secondaryTileset)
|
||||
secondaryTileset->save();
|
||||
bool Project::saveTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
bool success = saveTilesetMetatileLabels(primaryTileset, secondaryTileset);
|
||||
if (primaryTileset && !primaryTileset->save())
|
||||
success = false;
|
||||
if (secondaryTileset && !secondaryTileset->save())
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
void Project::updateTilesetMetatileLabels(Tileset *tileset) {
|
||||
if (!tileset) return;
|
||||
|
||||
// Erase old labels, then repopulate with new labels
|
||||
const QString prefix = tileset->getMetatileLabelPrefix();
|
||||
this->metatileLabelsMap[tileset->name].clear();
|
||||
@@ -925,11 +940,11 @@ QString Project::buildMetatileLabelsText(const QMap<QString, uint16_t> defines)
|
||||
return output;
|
||||
}
|
||||
|
||||
void Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
bool Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
// Skip writing the file if there are no labels in both the new and old sets
|
||||
if (metatileLabelsMap[primaryTileset->name].size() == 0 && primaryTileset->metatileLabels.size() == 0
|
||||
&& metatileLabelsMap[secondaryTileset->name].size() == 0 && secondaryTileset->metatileLabels.size() == 0)
|
||||
return;
|
||||
if ((!primaryTileset || (metatileLabelsMap[primaryTileset->name].size() == 0 && primaryTileset->metatileLabels.size() == 0))
|
||||
&& (!secondaryTileset || (metatileLabelsMap[secondaryTileset->name].size() == 0 && secondaryTileset->metatileLabels.size() == 0)))
|
||||
return true;
|
||||
|
||||
updateTilesetMetatileLabels(primaryTileset);
|
||||
updateTilesetMetatileLabels(secondaryTileset);
|
||||
@@ -956,42 +971,23 @@ void Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *second
|
||||
|
||||
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels);
|
||||
ignoreWatchedFileTemporarily(root + "/" + filename);
|
||||
saveTextFile(root + "/" + filename, outputText);
|
||||
return saveTextFile(root + "/" + filename, outputText);
|
||||
}
|
||||
|
||||
bool Project::loadLayoutTilesets(Layout *layout) {
|
||||
layout->tileset_primary = getTileset(layout->tileset_primary_label);
|
||||
if (!layout->tileset_primary) {
|
||||
QString defaultTileset = this->getDefaultPrimaryTilesetLabel();
|
||||
layout->tileset_primary_label = defaultTileset;
|
||||
layout->tileset_primary = getTileset(layout->tileset_primary_label);
|
||||
if (!layout->tileset_primary) {
|
||||
logError(QString("%1 has invalid primary tileset '%2'.").arg(layout->name).arg(layout->tileset_primary_label));
|
||||
return false;
|
||||
}
|
||||
logWarn(QString("%1 has invalid primary tileset '%2'. Using default '%3'").arg(layout->name).arg(layout->tileset_primary_label).arg(defaultTileset));
|
||||
}
|
||||
|
||||
layout->tileset_secondary = getTileset(layout->tileset_secondary_label);
|
||||
if (!layout->tileset_secondary) {
|
||||
QString defaultTileset = this->getDefaultSecondaryTilesetLabel();
|
||||
layout->tileset_secondary_label = defaultTileset;
|
||||
layout->tileset_secondary = getTileset(layout->tileset_secondary_label);
|
||||
if (!layout->tileset_secondary) {
|
||||
logError(QString("%1 has invalid secondary tileset '%2'.").arg(layout->name).arg(layout->tileset_secondary_label));
|
||||
return false;
|
||||
}
|
||||
logWarn(QString("%1 has invalid secondary tileset '%2'. Using default '%3'").arg(layout->name).arg(layout->tileset_secondary_label).arg(defaultTileset));
|
||||
}
|
||||
return true;
|
||||
return layout->tileset_primary && layout->tileset_secondary;
|
||||
}
|
||||
|
||||
Tileset* Project::loadTileset(QString label, Tileset *tileset) {
|
||||
auto memberMap = Tileset::getHeaderMemberMap(this->usingAsmTilesets);
|
||||
if (this->usingAsmTilesets) {
|
||||
// Read asm tileset header. Backwards compatibility
|
||||
const QStringList values = parser.getLabelValues(parser.parseAsm(projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm)), label);
|
||||
const QString path = projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm);
|
||||
const QStringList values = parser.getLabelValues(parser.parseAsm(path), label);
|
||||
if (values.isEmpty()) {
|
||||
logError(QString("Failed to find header data in '%1' for tileset '%2'.").arg(path).arg(label));
|
||||
return nullptr;
|
||||
}
|
||||
if (tileset == nullptr) {
|
||||
@@ -1005,8 +1001,10 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) {
|
||||
tileset->metatile_attrs_label = values.value(memberMap.key("metatileAttributes"));
|
||||
} else {
|
||||
// Read C tileset header
|
||||
auto structs = parser.readCStructs(projectConfig.getFilePath(ProjectFilePath::tilesets_headers), label, memberMap);
|
||||
const QString path = projectConfig.getFilePath(ProjectFilePath::tilesets_headers);
|
||||
auto structs = parser.readCStructs(path, label, memberMap);
|
||||
if (!structs.contains(label)) {
|
||||
logError(QString("Failed to find header data in '%1' for tileset '%2'.").arg(path).arg(label));
|
||||
return nullptr;
|
||||
}
|
||||
if (tileset == nullptr) {
|
||||
@@ -1021,7 +1019,11 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) {
|
||||
tileset->metatile_attrs_label = tilesetAttributes.value("metatileAttributes");
|
||||
}
|
||||
|
||||
loadTilesetAssets(tileset);
|
||||
if (!loadTilesetAssets(tileset)) {
|
||||
// Error should already be logged.
|
||||
delete tileset;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tilesetCache.insert(label, tileset);
|
||||
return tileset;
|
||||
@@ -1110,38 +1112,22 @@ void Project::setNewLayoutBorder(Layout *layout) {
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(width, height);
|
||||
}
|
||||
|
||||
void Project::saveLayoutBorder(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->border_path);
|
||||
writeBlockdata(path, layout->border);
|
||||
}
|
||||
|
||||
void Project::saveLayoutBlockdata(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->blockdata_path);
|
||||
writeBlockdata(path, layout->blockdata);
|
||||
}
|
||||
|
||||
void Project::writeBlockdata(QString path, const Blockdata &blockdata) {
|
||||
QFile file(path);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
QByteArray data = blockdata.serialize();
|
||||
file.write(data);
|
||||
} else {
|
||||
logError(QString("Failed to open blockdata file for writing: '%1'").arg(path));
|
||||
}
|
||||
}
|
||||
|
||||
void Project::saveAll() {
|
||||
bool Project::saveAll() {
|
||||
bool success = true;
|
||||
for (auto map : this->maps) {
|
||||
saveMap(map, true); // Avoid double-saving the layouts
|
||||
if (!saveMap(map, true)) // Avoid double-saving the layouts
|
||||
success = false;
|
||||
}
|
||||
for (auto layout : this->mapLayouts) {
|
||||
saveLayout(layout);
|
||||
if (!saveLayout(layout))
|
||||
success = false;
|
||||
}
|
||||
saveGlobalData();
|
||||
if (!saveGlobalData()) success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
void Project::saveMap(Map *map, bool skipLayout) {
|
||||
if (!map || !isMapLoaded(map)) return;
|
||||
bool Project::saveMap(Map *map, bool skipLayout) {
|
||||
if (!map || !isMapLoaded(map)) return true;
|
||||
|
||||
// Create/Modify a few collateral files for brand new maps.
|
||||
const QString folderPath = projectConfig.getFilePath(ProjectFilePath::data_map_folders) + map->name();
|
||||
@@ -1149,7 +1135,7 @@ void Project::saveMap(Map *map, bool skipLayout) {
|
||||
if (!map->isPersistedToFile()) {
|
||||
if (!QDir::root().mkpath(fullPath)) {
|
||||
logError(QString("Failed to create directory for new map: '%1'").arg(fullPath));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create file data/maps/<map_name>/scripts.inc
|
||||
@@ -1173,8 +1159,8 @@ void Project::saveMap(Map *map, bool skipLayout) {
|
||||
QString mapFilepath = fullPath + "/map.json";
|
||||
QFile mapFile(mapFilepath);
|
||||
if (!mapFile.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Error: Could not open %1 for writing").arg(mapFilepath));
|
||||
return;
|
||||
logError(QString("Could not open '%1' for writing: %2").arg(mapFilepath).arg(mapFile.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedJson::object mapObj;
|
||||
@@ -1270,72 +1256,61 @@ void Project::saveMap(Map *map, bool skipLayout) {
|
||||
jsonDoc.dump(&mapFile);
|
||||
mapFile.close();
|
||||
|
||||
if (!skipLayout) saveLayout(map->layout());
|
||||
|
||||
// Try to record the MAPSEC name in case this is a new name.
|
||||
addNewMapsec(map->header()->location());
|
||||
|
||||
map->setClean();
|
||||
|
||||
if (!skipLayout && !saveLayout(map->layout()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveLayout(Layout *layout) {
|
||||
bool Project::saveLayout(Layout *layout) {
|
||||
if (!layout || !isLayoutLoaded(layout))
|
||||
return;
|
||||
return true;
|
||||
|
||||
if (!layout->newFolderPath.isEmpty()) {
|
||||
// Layout directory doesn't exist yet, create it now.
|
||||
const QString fullPath = QString("%1/%2").arg(this->root).arg(layout->newFolderPath);
|
||||
if (!QDir::root().mkpath(fullPath)) {
|
||||
logError(QString("Failed to create directory for new layout: '%1'").arg(fullPath));
|
||||
return;
|
||||
}
|
||||
layout->newFolderPath = QString();
|
||||
}
|
||||
|
||||
saveLayoutBorder(layout);
|
||||
saveLayoutBlockdata(layout);
|
||||
if (!layout->save(this->root))
|
||||
return false;
|
||||
|
||||
// Update global data structures with current map data.
|
||||
updateLayout(layout);
|
||||
|
||||
layout->setClean();
|
||||
}
|
||||
|
||||
void Project::updateLayout(Layout *layout) {
|
||||
if (!this->layoutIdsMaster.contains(layout->id)) {
|
||||
this->layoutIdsMaster.append(layout->id);
|
||||
}
|
||||
|
||||
if (this->mapLayoutsMaster.contains(layout->id)) {
|
||||
this->mapLayoutsMaster[layout->id]->copyFrom(layout);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this->mapLayoutsMaster.insert(layout->id, layout->copy());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveGlobalData() {
|
||||
saveMapLayouts();
|
||||
saveMapGroups();
|
||||
saveRegionMapSections();
|
||||
saveHealLocations();
|
||||
saveWildMonData();
|
||||
saveConfig();
|
||||
bool Project::saveGlobalData() {
|
||||
bool success = true;
|
||||
if (!saveMapLayouts()) success = false;
|
||||
if (!saveMapGroups()) success = false;
|
||||
if (!saveRegionMapSections()) success = false;
|
||||
if (!saveHealLocations()) success = false;
|
||||
if (!saveWildMonData()) success = false;
|
||||
if (!saveConfig()) success = false;
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
this->hasUnsavedDataChanges = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::saveConfig() {
|
||||
projectConfig.save();
|
||||
userConfig.save();
|
||||
bool Project::saveConfig() {
|
||||
bool success = true;
|
||||
if (!projectConfig.save()) success = false;
|
||||
if (!userConfig.save()) success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
void Project::loadTilesetAssets(Tileset* tileset) {
|
||||
if (tileset->name.isNull()) {
|
||||
return;
|
||||
}
|
||||
bool Project::loadTilesetAssets(Tileset* tileset) {
|
||||
readTilesetPaths(tileset);
|
||||
loadTilesetMetatileLabels(tileset);
|
||||
tileset->load();
|
||||
return tileset->load();
|
||||
}
|
||||
|
||||
void Project::readTilesetPaths(Tileset* tileset) {
|
||||
@@ -1529,6 +1504,8 @@ bool Project::readTilesetMetatileLabels() {
|
||||
}
|
||||
|
||||
void Project::loadTilesetMetatileLabels(Tileset* tileset) {
|
||||
if (!tileset || tileset->name.isEmpty()) return;
|
||||
|
||||
QString metatileLabelPrefix = tileset->getMetatileLabelPrefix();
|
||||
|
||||
// Reverse map for faster lookup by metatile id
|
||||
@@ -1570,29 +1547,24 @@ Tileset* Project::getTileset(QString label, bool forceLoad) {
|
||||
}
|
||||
}
|
||||
|
||||
void Project::saveTextFile(QString path, QString text) {
|
||||
bool Project::saveTextFile(const QString &path, const QString &text) {
|
||||
QFile file(path);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(text.toUtf8());
|
||||
} else {
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open '%1' for writing: ").arg(path) + file.errorString());
|
||||
return false;
|
||||
}
|
||||
file.write(text.toUtf8());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::appendTextFile(QString path, QString text) {
|
||||
bool Project::appendTextFile(const QString &path, const QString &text) {
|
||||
QFile file(path);
|
||||
if (file.open(QIODevice::Append)) {
|
||||
file.write(text.toUtf8());
|
||||
} else {
|
||||
if (!file.open(QIODevice::Append)) {
|
||||
logError(QString("Could not open '%1' for appending: ").arg(path) + file.errorString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Project::deleteFile(QString path) {
|
||||
QFile file(path);
|
||||
if (file.exists() && !file.remove()) {
|
||||
logError(QString("Could not delete file '%1': ").arg(path) + file.errorString());
|
||||
}
|
||||
file.write(text.toUtf8());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Project::readWildMonData() {
|
||||
|
||||
@@ -33,6 +33,8 @@ TilesetEditor::TilesetEditor(Project *project, Layout *layout, QWidget *parent)
|
||||
this->tileYFlip = ui->checkBox_yFlip->isChecked();
|
||||
this->paletteId = ui->spinBox_paletteSelector->value();
|
||||
|
||||
connect(ui->actionSave_Tileset, &QAction::triggered, this, &TilesetEditor::save);
|
||||
|
||||
ui->actionShow_Tileset_Divider->setChecked(porymapConfig.showTilesetEditorDivider);
|
||||
ui->actionShow_Raw_Metatile_Attributes->setChecked(porymapConfig.showTilesetEditorRawAttributes);
|
||||
|
||||
@@ -94,7 +96,7 @@ void TilesetEditor::updateTilesets(QString primaryTilesetLabel, QString secondar
|
||||
QMessageBox::No | QMessageBox::Yes,
|
||||
QMessageBox::Yes);
|
||||
if (result == QMessageBox::Yes)
|
||||
this->on_actionSave_Tileset_triggered();
|
||||
this->save();
|
||||
}
|
||||
this->setTilesets(primaryTilesetLabel, secondaryTilesetLabel);
|
||||
this->refresh();
|
||||
@@ -688,19 +690,23 @@ void TilesetEditor::commitLayerType() {
|
||||
this->metatileSelector->drawSelectedMetatile(); // Changing the layer type can affect how fully transparent metatiles appear
|
||||
}
|
||||
|
||||
void TilesetEditor::on_actionSave_Tileset_triggered()
|
||||
{
|
||||
bool TilesetEditor::save() {
|
||||
// Need this temporary flag to stop selection resetting after saving.
|
||||
// This is a workaround; redrawing the map's metatile selector shouldn't emit the same signal as when it's selected.
|
||||
this->lockSelection = true;
|
||||
this->project->saveTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
|
||||
bool success = this->project->saveTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
emit this->tilesetsSaved(this->primaryTileset->name, this->secondaryTileset->name);
|
||||
if (this->paletteEditor) {
|
||||
this->paletteEditor->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
}
|
||||
this->ui->statusbar->showMessage(QString("Saved primary and secondary Tilesets!"), 5000);
|
||||
this->hasUnsavedChanges = false;
|
||||
this->ui->statusbar->showMessage(success ? QStringLiteral("Saved primary and secondary Tilesets!")
|
||||
: QStringLiteral("Failed to save tilesets! See log for details."), 5000);
|
||||
if (success) {
|
||||
this->hasUnsavedChanges = false;
|
||||
}
|
||||
this->lockSelection = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
void TilesetEditor::on_actionImport_Primary_Tiles_triggered()
|
||||
@@ -812,8 +818,11 @@ void TilesetEditor::closeEvent(QCloseEvent *event)
|
||||
QMessageBox::Yes);
|
||||
|
||||
if (result == QMessageBox::Yes) {
|
||||
this->on_actionSave_Tileset_triggered();
|
||||
event->accept();
|
||||
if (this->save()) {
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
} else if (result == QMessageBox::No) {
|
||||
this->reset();
|
||||
event->accept();
|
||||
@@ -1143,12 +1152,6 @@ void TilesetEditor::countMetatileUsage() {
|
||||
this->metatileSelector->usedMetatiles.fill(0);
|
||||
|
||||
for (auto layout : this->project->mapLayouts) {
|
||||
// It's possible for a layout's tileset labels to change if they are invalid,
|
||||
// so we need to load all the tilesets even if they aren't the tileset we're looking for.
|
||||
// Otherwise the metatile usage counts may change because the layouts with invalid tilesets
|
||||
// were updated to use a tileset we were looking for.
|
||||
this->project->loadLayoutTilesets(layout);
|
||||
|
||||
bool usesPrimary = (layout->tileset_primary_label == this->primaryTileset->name);
|
||||
bool usesSecondary = (layout->tileset_secondary_label == this->secondaryTileset->name);
|
||||
|
||||
@@ -1187,10 +1190,10 @@ void TilesetEditor::countTileUsage() {
|
||||
QSet<Tileset*> secondaryTilesets;
|
||||
|
||||
for (auto &layout : this->project->mapLayouts) {
|
||||
this->project->loadLayoutTilesets(layout);
|
||||
if (layout->tileset_primary_label == this->primaryTileset->name
|
||||
|| layout->tileset_secondary_label == this->secondaryTileset->name) {
|
||||
// need to check metatiles
|
||||
this->project->loadLayoutTilesets(layout);
|
||||
if (layout->tileset_primary && layout->tileset_secondary) {
|
||||
primaryTilesets.insert(layout->tileset_primary);
|
||||
secondaryTilesets.insert(layout->tileset_secondary);
|
||||
|
||||
Reference in New Issue
Block a user