Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed map reload in case map is open as part of a world #3939

Merged
merged 2 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Automapping: Added per-input-layer properties for ignoring flip flags (#3803)
* AutoMapping: Always apply output sets with empty index
* Windows: Fixed the support for WebP images (updated to Qt 6.6.1, #3661)
* Fixed issues related to map and tileset reloading
* Fixed possible crash after assigning to tiled.activeAsset
* Fixed the option to resolve properties on export to also resolve class members (#3411, #3315)
* Fixed terrain tool behavior and terrain overlays after changing terrain set type (#3204, #3260)
Expand Down
7 changes: 7 additions & 0 deletions docs/scripting-doc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4607,6 +4607,13 @@ declare namespace tiled {
*/
export const assetOpened: Signal<Asset>;

/**
* An asset has been reloaded.
*
* @since 1.11
*/
export const assetReloaded: Signal<Asset>;

/**
* An asset is about to be saved. Can be used to make last-minute
* changes.
Expand Down
1 change: 0 additions & 1 deletion src/libtiled/imagecache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "imagecache.h"

#include "logginginterface.h"
#include "map.h"
#include "mapformat.h"
#include "minimaprenderer.h"

Expand Down
2 changes: 1 addition & 1 deletion src/libtiled/layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ bool LayerIterator::operator==(const LayerIterator &other) const
* Returns the global layer index for the given \a layer. Obtained by iterating
* the layer's map while incrementing the index until layer is found.
*/
int globalIndex(Layer *layer)
int globalIndex(const Layer *layer)
{
if (!layer)
return -1;
Expand Down
2 changes: 1 addition & 1 deletion src/libtiled/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ inline Layer *LayerIterator::operator->() const
}


TILEDSHARED_EXPORT int globalIndex(Layer *layer);
TILEDSHARED_EXPORT int globalIndex(const Layer *layer);
TILEDSHARED_EXPORT Layer *layerAtGlobalIndex(const Map *map, int index);

} // namespace Tiled
Expand Down
6 changes: 6 additions & 0 deletions src/libtiled/wangset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,12 @@ WangSet::WangSet(Tileset *tileset,
setType(type);
}

WangSet::~WangSet()
{
for (auto &color : std::as_const(mColors))
color->mWangSet = nullptr;
}

/**
* Changes the type of this Wang set.
*
Expand Down
1 change: 1 addition & 0 deletions src/libtiled/wangset.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class TILEDSHARED_EXPORT WangSet : public Object
const QString &name,
Type type,
int imageTileId = -1);
~WangSet();

Tileset *tileset() const;
void setTileset(Tileset *tileset);
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/abstractworldtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void AbstractWorldTool::showContextMenu(QGraphicsSceneMouseEvent *event)
this, [=] { addAnotherMapToWorld(insertPos); });

if (targetDocument != nullptr && targetDocument != currentDocument) {
const QString targetFilename = targetDocument->fileName();
const QString &targetFilename = targetDocument->fileName();
menu.addAction(QIcon(QLatin1String(":images/24/world-map-remove-this.png")),
tr("Remove \"%1\" from World \"%2\"")
.arg(targetDocument->displayName(),
Expand Down
34 changes: 29 additions & 5 deletions src/tiled/brokenlinks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "brokenlinks.h"

#include "changeevents.h"
#include "changetileimagesource.h"
#include "documentmanager.h"
#include "fileformat.h"
Expand Down Expand Up @@ -117,6 +118,9 @@ void BrokenLinksModel::setDocument(Document *document)

if (mDocument) {
if (auto mapDocument = qobject_cast<MapDocument*>(mDocument)) {
connect(mDocument, &Document::changed,
this, &BrokenLinksModel::documentChanged);

connect(mapDocument, &MapDocument::tilesetAdded,
this, &BrokenLinksModel::tilesetAdded);
connect(mapDocument, &MapDocument::tilesetRemoved,
Expand All @@ -127,8 +131,6 @@ void BrokenLinksModel::setDocument(Document *document)
for (const SharedTileset &tileset : mapDocument->map()->tilesets())
connectToTileset(tileset);

connect(DocumentManager::instance(), &DocumentManager::templateTilesetReplaced,
this, &BrokenLinksModel::refresh);
} else if (auto tilesetDocument = qobject_cast<TilesetDocument*>(mDocument)) {
connectToTileset(tilesetDocument->tileset());
}
Expand Down Expand Up @@ -304,15 +306,37 @@ QVariant BrokenLinksModel::headerData(int section, Qt::Orientation orientation,
return QVariant();
}

void BrokenLinksModel::documentChanged(const ChangeEvent &event)
{
switch (event.type) {
case ChangeEvent::DocumentAboutToReload:
if (auto mapDocument = qobject_cast<MapDocument*>(mDocument)) {
for (const SharedTileset &tileset : mapDocument->map()->tilesets())
disconnectFromTileset(tileset);
}
break;
case ChangeEvent::DocumentReloaded:
refresh();

if (auto mapDocument = qobject_cast<MapDocument*>(mDocument)) {
for (const SharedTileset &tileset : mapDocument->map()->tilesets())
connectToTileset(tileset);
}
break;
default:
break;
}
}

void BrokenLinksModel::tileImageSourceChanged(Tile *tile)
{
auto matchesTile = [tile](const BrokenLink &link) {
return link.type == TilesetTileImageSource && link._tile == tile;
};

QVector<BrokenLink>::iterator it = std::find_if(mBrokenLinks.begin(),
mBrokenLinks.end(),
matchesTile);
auto it = std::find_if(mBrokenLinks.begin(),
mBrokenLinks.end(),
matchesTile);

if (!tile->imageSource().isEmpty() && tile->imageStatus() == LoadingError) {
if (it != mBrokenLinks.end()) {
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/brokenlinks.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class BrokenLinksModel : public QAbstractListModel
void hasBrokenLinksChanged(bool hasBrokenLinks);

private:
void documentChanged(const ChangeEvent &event);

void tileImageSourceChanged(Tile *tile);
void tilesetChanged(Tileset *tileset);

Expand Down
18 changes: 18 additions & 0 deletions src/tiled/changeevents.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ChangeEvent
{
public:
enum Type {
DocumentAboutToReload,
DocumentReloaded,
ObjectsChanged,
MapChanged,
LayerChanged,
Expand Down Expand Up @@ -71,6 +73,22 @@ class ChangeEvent
{}
};

class AboutToReloadEvent : public ChangeEvent
{
public:
AboutToReloadEvent()
: ChangeEvent(DocumentAboutToReload)
{}
};

class ReloadEvent : public ChangeEvent
{
public:
ReloadEvent()
: ChangeEvent(DocumentReloaded)
{}
};

class ObjectsChangeEvent : public ChangeEvent
{
public:
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static QString replaceVariables(const QString &string, bool quoteValues = true)

// Perform variable replacement
if (Document *document = DocumentManager::instance()->currentDocument()) {
const QString fileName = document->fileName();
const QString &fileName = document->fileName();
QFileInfo fileInfo(fileName);
const QString mapPath = fileInfo.absolutePath();
const QString projectPath = QFileInfo(ProjectManager::instance()->project().fileName()).absolutePath();
Expand Down
26 changes: 10 additions & 16 deletions src/tiled/document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "changeevents.h"
#include "containerhelpers.h"
#include "documentmanager.h"
#include "editableasset.h"
#include "logginginterface.h"
#include "object.h"
Expand All @@ -34,8 +35,6 @@

namespace Tiled {

QHash<QString, Document*> Document::sDocumentInstances;

Document::Document(DocumentType type, const QString &fileName,
QObject *parent)
: QObject(parent)
Expand All @@ -48,8 +47,7 @@ Document::Document(DocumentType type, const QString &fileName,
mCanonicalFilePath = fileInfo.canonicalFilePath();
mReadOnly = fileInfo.exists() && !fileInfo.isWritable();

if (!mCanonicalFilePath.isEmpty())
sDocumentInstances.insert(mCanonicalFilePath, this);
DocumentManager::instance()->registerDocument(this);

connect(mUndoStack, &QUndoStack::indexChanged, this, &Document::updateIsModified);
connect(mUndoStack, &QUndoStack::cleanChanged, this, &Document::updateIsModified);
Expand All @@ -61,11 +59,8 @@ Document::~Document()
if (mCurrentObjectDocument)
mCurrentObjectDocument->disconnect(this);

if (!mCanonicalFilePath.isEmpty()) {
auto i = sDocumentInstances.find(mCanonicalFilePath);
if (i != sDocumentInstances.end() && *i == this)
sDocumentInstances.erase(i);
}
if (auto manager = DocumentManager::maybeInstance())
manager->unregisterDocument(this);
}

EditableAsset *Document::editable()
Expand All @@ -88,19 +83,14 @@ void Document::setFileName(const QString &fileName)

QString oldFileName = mFileName;

if (!mCanonicalFilePath.isEmpty()) {
auto i = sDocumentInstances.find(mCanonicalFilePath);
if (i != sDocumentInstances.end() && *i == this)
sDocumentInstances.erase(i);
}
DocumentManager::instance()->unregisterDocument(this);

const QFileInfo fileInfo { fileName };
mFileName = fileName;
mCanonicalFilePath = fileInfo.canonicalFilePath();
setReadOnly(fileInfo.exists() && !fileInfo.isWritable());

if (!mCanonicalFilePath.isEmpty())
sDocumentInstances.insert(mCanonicalFilePath, this);
DocumentManager::instance()->registerDocument(this);

emit fileNameChanged(fileName, oldFileName);
}
Expand Down Expand Up @@ -168,6 +158,10 @@ void Document::setCurrentObject(Object *object, Document *owningDocument)
void Document::currentObjectDocumentChanged(const ChangeEvent &change)
{
switch (change.type) {
case ChangeEvent::DocumentAboutToReload:
setCurrentObject(nullptr);
break;

case ChangeEvent::TilesAboutToBeRemoved: {
auto tilesEvent = static_cast<const TilesEvent&>(change);

Expand Down
19 changes: 6 additions & 13 deletions src/tiled/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ class Document : public QObject,

DocumentType type() const { return mType; }

QString fileName() const;
QString canonicalFilePath() const;
const QString &fileName() const;
const QString &canonicalFilePath() const;

/**
* Returns the name with which to display this document. It is the file name
Expand All @@ -88,6 +88,8 @@ class Document : public QObject,
*/
virtual bool save(const QString &fileName, QString *error = nullptr) = 0;

virtual bool canReload() const { return false; }

virtual FileFormat *writerFormat() const = 0;

QDateTime lastSaved() const { return mLastSaved; }
Expand Down Expand Up @@ -126,8 +128,6 @@ class Document : public QObject,

virtual void checkIssues() {}

static const QHash<QString, Document *> &documentInstances();

signals:
void changed(const ChangeEvent &change);
void saved();
Expand Down Expand Up @@ -184,17 +184,15 @@ class Document : public QObject,
bool mModified = false;
bool mChangedOnDisk = false;
bool mIgnoreBrokenLinks = false;

static QHash<QString, Document*> sDocumentInstances;
};


inline QString Document::fileName() const
inline const QString &Document::fileName() const
{
return mFileName;
}

inline QString Document::canonicalFilePath() const
inline const QString &Document::canonicalFilePath() const
{
return mCanonicalFilePath;
}
Expand Down Expand Up @@ -243,11 +241,6 @@ inline bool Document::isReadOnly() const
return mReadOnly;
}

inline const QHash<QString, Document *> &Document::documentInstances()
{
return sDocumentInstances;
}

using DocumentPtr = QSharedPointer<Document>;

} // namespace Tiled
Loading
Loading