From cdebf2ee8d433a9538db03229df08e1e49e94276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Fri, 19 Jan 2024 13:35:49 +0100 Subject: [PATCH] Removed most world-specific signals Removed worldLoaded, worldReloaded, worldUnloaded and worldSaved. Made sure the following signals are also emitted for worlds: * assetOpened (replaces worldLoaded) * assetAboutToBeSaved * assetSaved (replaces worldSaved) Moved World.save() up to Asset.save(). Its behavior changed slightly, in that errors are now reported in a modal dialog, due to reusing the existing saving code. There is no replacement for worldReloaded and worldUnloaded, but hopefully worldsChanged suffices for most use-cases. Fixed tiled.worldsChanged to only fire when the editor is loaded, not on the CLI. --- docs/scripting-doc/index.d.ts | 52 ++++++++++++----------------------- src/tiled/command.cpp | 13 ++++++--- src/tiled/documentmanager.cpp | 2 ++ src/tiled/documentmanager.h | 11 ++++++++ src/tiled/editableasset.cpp | 18 +++++++++++- src/tiled/editableasset.h | 1 + src/tiled/editableworld.cpp | 7 ++--- src/tiled/editableworld.h | 1 - src/tiled/mainwindow.cpp | 32 ++++++++------------- src/tiled/scriptmodule.cpp | 9 ++---- src/tiled/scriptmodule.h | 4 --- 11 files changed, 73 insertions(+), 77 deletions(-) diff --git a/docs/scripting-doc/index.d.ts b/docs/scripting-doc/index.d.ts index 12953bf262..2fd4e4f239 100644 --- a/docs/scripting-doc/index.d.ts +++ b/docs/scripting-doc/index.d.ts @@ -1202,7 +1202,7 @@ declare class WorldPattern { * * @since 1.10.3 */ -declare class World extends TiledObject { +declare class World extends Asset { /** * The maps that are explicitly added to this world. It does not include * those maps which match due to patterns defined on the world. @@ -1274,11 +1274,6 @@ declare class World extends TiledObject { * @param map The TileMap instance to remove from this world. */ removeMap(map: TileMap): void; - - /** - * Save this world to disk. Returns true if the world was saved successfully. - */ - save(): boolean; } /** @@ -1572,6 +1567,21 @@ declare class Asset extends TiledObject { * @note The undo system is only enabled for assets loaded in the editor! */ redo(): void; + + /** + * Save this asset to disk. Returns true if the asset was saved successfully. + * + * Errors are reported by the UI. When an editor is open for this asset, this + * editor is activated when an error is reported. + * + * Only supported with the editor running, not when running scripts on the + * CLI. Also, the asset should already have an associated file. + * + * To save assets to a specific file or in a different format, use {@link + * tiled.mapFormat} or {@link tiled.tilesetFormat}. This is currently not + * supported for worlds. + */ + save(): boolean; } /** @@ -4565,38 +4575,10 @@ declare namespace tiled { export function unloadAllWorlds() : void; /** - * Signal emitted when any world is saved, loaded, unloaded, or reloaded. + * Signal emitted when any world is loaded, unloaded, reloaded or changed. * @since 1.10.3 */ export const worldsChanged : Signal; - - /** - * Signal emitted when a world is loaded. - * Provides the file name of the world that was loaded. - * @since 1.10.3 - */ - export const worldLoaded : Signal; - - /** - * Signal emitted when a world is reloaded. - * Provides the file name of the world that was reloaded. - * @since 1.10.3 - */ - export const worldReloaded : Signal; - - /** - * Signal emitted when a world is reloaded. - * Provides the file name of the world that was unloaded. - * @since 1.10.3 - */ - export const worldUnloaded : Signal; - - /** - * Signal emitted when a world is reloaded. - * Provides the file name of the world that was saved. - * @since 1.10.3 - */ - export const worldSaved : Signal; } /** diff --git a/src/tiled/command.cpp b/src/tiled/command.cpp index 71d6a8e144..04ada6e5e3 100644 --- a/src/tiled/command.cpp +++ b/src/tiled/command.cpp @@ -28,6 +28,7 @@ #include "mapobject.h" #include "projectmanager.h" #include "world.h" +#include "worlddocument.h" // used to know that WorldDocument is a Document #include "worldmanager.h" #include @@ -157,10 +158,14 @@ void Command::execute(bool inTerminal) const if (saveBeforeExecute) { ActionManager::instance()->action("Save")->trigger(); - if (Document *document = DocumentManager::instance()->currentDocument()) - if (document->type() == Document::MapDocumentType) - if (const World *world = WorldManager::instance().worldForMap(document->fileName())) - WorldManager::instance().saveWorld(world->fileName); + if (Document *document = DocumentManager::instance()->currentDocument()) { + if (document->type() == Document::MapDocumentType) { + if (const World *world = WorldManager::instance().worldForMap(document->fileName())) { + auto worldDocument = DocumentManager::instance()->ensureWorldDocument(world->fileName); + DocumentManager::instance()->saveDocument(worldDocument); + } + } + } } // Start the process diff --git a/src/tiled/documentmanager.cpp b/src/tiled/documentmanager.cpp index e45ccf4ed2..36599578ee 100644 --- a/src/tiled/documentmanager.cpp +++ b/src/tiled/documentmanager.cpp @@ -1302,6 +1302,8 @@ void DocumentManager::onWorldLoaded(const QString &worldFile) WorldDocument *worldDocument = new WorldDocument(worldFile); mWorldDocuments.insert(worldFile, worldDocument); mUndoGroup->addStack(worldDocument->undoStack()); + + emit documentOpened(worldDocument); } void DocumentManager::onWorldUnloaded(const QString &worldFile) diff --git a/src/tiled/documentmanager.h b/src/tiled/documentmanager.h index af65046678..d81ac8df0f 100644 --- a/src/tiled/documentmanager.h +++ b/src/tiled/documentmanager.h @@ -109,6 +109,7 @@ class DocumentManager : public QObject FileFormat *fileFormat = nullptr, QString *error = nullptr); + bool saveDocument(Document *document); bool saveDocument(Document *document, const QString &fileName); bool saveDocumentAs(Document *document); @@ -256,6 +257,16 @@ inline QUndoGroup *DocumentManager::undoGroup() const return mUndoGroup; } +/** + * Save the given document to its existing file name. + * + * @return true on success, false on failure + */ +inline bool DocumentManager::saveDocument(Document *document) +{ + return saveDocument(document, document->fileName()); +} + /** * Returns all open documents. */ diff --git a/src/tiled/editableasset.cpp b/src/tiled/editableasset.cpp index 9e21aba36e..757dec7d6a 100644 --- a/src/tiled/editableasset.cpp +++ b/src/tiled/editableasset.cpp @@ -20,7 +20,7 @@ #include "editableasset.h" -#include "document.h" +#include "documentmanager.h" #include "scriptmanager.h" #include @@ -74,6 +74,22 @@ bool EditableAsset::push(std::unique_ptr command) return true; } +bool EditableAsset::save() +{ + auto documentManager = DocumentManager::maybeInstance(); + if (!documentManager) { + ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Editor not available")); + return false; + } + + if (fileName().isEmpty()) { + ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Asset not associated with a file")); + return false; + } + + return documentManager->saveDocument(document()); +} + QJSValue EditableAsset::macro(const QString &text, QJSValue callback) { if (!callback.isCallable()) { diff --git a/src/tiled/editableasset.h b/src/tiled/editableasset.h index c74b4c8630..a99c8727df 100644 --- a/src/tiled/editableasset.h +++ b/src/tiled/editableasset.h @@ -70,6 +70,7 @@ class EditableAsset : public EditableObject bool push(QUndoCommand *command); bool push(std::unique_ptr command); + Q_INVOKABLE bool save(); Q_INVOKABLE QJSValue macro(const QString &text, QJSValue callback); Document *document() const; diff --git a/src/tiled/editableworld.cpp b/src/tiled/editableworld.cpp index 7c162c9e1d..92426c563a 100644 --- a/src/tiled/editableworld.cpp +++ b/src/tiled/editableworld.cpp @@ -147,11 +147,6 @@ void EditableWorld::removeMap(EditableMap *map) removeMap(map->fileName()); } -bool EditableWorld::save() -{ - return WorldManager::instance().saveWorld(world()->fileName); -} - QSharedPointer EditableWorld::createDocument() { // We don't currently support opening a world in its own tab, which this @@ -160,3 +155,5 @@ QSharedPointer EditableWorld::createDocument() } } // namespace Tiled + +#include "moc_editableworld.cpp" diff --git a/src/tiled/editableworld.h b/src/tiled/editableworld.h index 3849236080..e7f9a6d681 100644 --- a/src/tiled/editableworld.h +++ b/src/tiled/editableworld.h @@ -57,7 +57,6 @@ class EditableWorld final : public EditableAsset Q_INVOKABLE void addMap(EditableMap *map, int x, int y); Q_INVOKABLE void removeMap(const QString &mapFileName); Q_INVOKABLE void removeMap(EditableMap *map); - Q_INVOKABLE bool save(); QSharedPointer createDocument() override; }; diff --git a/src/tiled/mainwindow.cpp b/src/tiled/mainwindow.cpp index ca51cb9f7b..54975b52a5 100644 --- a/src/tiled/mainwindow.cpp +++ b/src/tiled/mainwindow.cpp @@ -71,6 +71,7 @@ #include "tmxmapformat.h" #include "utils.h" #include "world.h" +#include "worlddocument.h" #include "worldmanager.h" #include "zoomable.h" @@ -651,13 +652,12 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) mUi->menuSaveWorld->clear(); for (const World *world : WorldManager::instance().worlds()) { - if (!mDocumentManager->isWorldModified(world->fileName)) + auto worldDocument = mDocumentManager->ensureWorldDocument(world->fileName); + if (!worldDocument->isModified()) continue; - mUi->menuSaveWorld->addAction(world->fileName, this, [this, fileName = world->fileName] { - QString error; - if (!WorldManager::instance().saveWorld(fileName, &error)) - QMessageBox::critical(this, tr("Error Saving World"), error); + mUi->menuSaveWorld->addAction(world->fileName, this, [this, worldDocument] { + mDocumentManager->saveDocument(worldDocument); }); } }); @@ -1213,14 +1213,12 @@ void MainWindow::saveAll() } for (const World *world : WorldManager::instance().worlds()) { - if (!mDocumentManager->isWorldModified(world->fileName)) + auto worldDocument = mDocumentManager->ensureWorldDocument(world->fileName); + if (!worldDocument->isModified()) continue; - QString error; - if (!WorldManager::instance().saveWorld(world->fileName, &error)) { - QMessageBox::critical(this, tr("Error Saving World"), error); + if (!mDocumentManager->saveDocument(worldDocument)) return; - } } } @@ -1264,7 +1262,8 @@ bool MainWindow::confirmAllSave() bool MainWindow::confirmSaveWorld(const QString &fileName) { - if (!mDocumentManager->isWorldModified(fileName)) + auto worldDocument = mDocumentManager->ensureWorldDocument(fileName); + if (!worldDocument->isModified()) return true; int ret = QMessageBox::warning( @@ -1273,15 +1272,8 @@ bool MainWindow::confirmSaveWorld(const QString &fileName) QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); switch (ret) { - case QMessageBox::Save: { - QString error; - if (!WorldManager::instance().saveWorld(fileName, &error)) { - QMessageBox::critical(window(), tr("Error Saving World"), error); - return false; - } - - return true; - } + case QMessageBox::Save: + return mDocumentManager->saveDocument(worldDocument, fileName); case QMessageBox::Discard: return true; case QMessageBox::Cancel: diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index a2ee7955dc..148bcf1f8a 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -66,14 +66,9 @@ ScriptModule::ScriptModule(QObject *parent) connect(documentManager, &DocumentManager::documentSaved, this, &ScriptModule::documentSaved); connect(documentManager, &DocumentManager::documentAboutToClose, this, &ScriptModule::documentAboutToClose); connect(documentManager, &DocumentManager::currentDocumentChanged, this, &ScriptModule::currentDocumentChanged); - } - - connect(&WorldManager::instance(), &WorldManager::worldsChanged, this, &ScriptModule::worldsChanged); - connect(&WorldManager::instance(), &WorldManager::worldLoaded, this, &ScriptModule::worldLoaded); - connect(&WorldManager::instance(), &WorldManager::worldReloaded, this, &ScriptModule::worldReloaded); - connect(&WorldManager::instance(), &WorldManager::worldUnloaded, this, &ScriptModule::worldUnloaded); - connect(&WorldManager::instance(), &WorldManager::worldSaved, this, &ScriptModule::worldSaved); + connect(&WorldManager::instance(), &WorldManager::worldsChanged, this, &ScriptModule::worldsChanged); + } } ScriptModule::~ScriptModule() diff --git a/src/tiled/scriptmodule.h b/src/tiled/scriptmodule.h index ad467d4ec5..5b56296165 100644 --- a/src/tiled/scriptmodule.h +++ b/src/tiled/scriptmodule.h @@ -157,10 +157,6 @@ class ScriptModule : public QObject void activeAssetChanged(Tiled::EditableAsset *asset); void worldsChanged(); - void worldLoaded(const QString &fileName); - void worldReloaded(const QString &fileName); - void worldUnloaded(const QString &fileName); - void worldSaved(const QString &fileName); public slots: void trigger(const QByteArray &actionName) const;