1 /*
2  * tilesetdocument.h
3  * Copyright 2015-2016, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
4  *
5  * This file is part of Tiled.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 #include "document.h"
24 #include "editabletileset.h"
25 #include "tileset.h"
26 #include "tilesetformat.h"
27 
28 #include <QList>
29 #include <QMap>
30 
31 #include <memory>
32 #include <unordered_map>
33 
34 namespace Tiled {
35 
36 class ObjectGroup;
37 class WangColor;
38 
39 class MapDocument;
40 class TilesetDocument;
41 class TilesetWangSetModel;
42 class WangColorModel;
43 
44 using TilesetDocumentPtr = QSharedPointer<TilesetDocument>;
45 
46 /**
47  * Represents an editable tileset.
48  */
49 class TilesetDocument : public Document
50 {
51     Q_OBJECT
52 
53 public:
54     TilesetDocument(const SharedTileset &tileset);
55     ~TilesetDocument() override;
56 
sharedFromThis()57     TilesetDocumentPtr sharedFromThis() { return qSharedPointerCast<TilesetDocument>(Document::sharedFromThis()); }
58 
59     bool save(const QString &fileName, QString *error = nullptr) override;
60 
61     bool canReload() const;
62     bool reload(QString *error);
63 
64     /**
65      * Loads a tileset and returns a TilesetDocument instance on success.
66      * Returns null on error and sets the \a error message.
67      */
68     static TilesetDocumentPtr load(const QString &fileName,
69                                    TilesetFormat *format,
70                                    QString *error = nullptr);
71 
72     TilesetFormat *writerFormat() const override;
73     void setWriterFormat(TilesetFormat *format);
74 
75     QString lastExportFileName() const override;
76     void setLastExportFileName(const QString &fileName) override;
77 
78     TilesetFormat *exportFormat() const override;
79     void setExportFormat(FileFormat *format) override;
80 
81     QString displayName() const override;
82     QString externalOrEmbeddedFileName() const;
83 
84     void swapTileset(SharedTileset &tileset);
85     const SharedTileset &tileset() const;
86 
87     EditableTileset *editable() override;
88 
89     bool isEmbedded() const;
90     void setClean();
91 
92     const QList<MapDocument*> &mapDocuments() const;
93     void addMapDocument(MapDocument *mapDocument);
94     void removeMapDocument(MapDocument *mapDocument);
95 
96     void setTilesetName(const QString &name);
97     void setTilesetTileOffset(QPoint tileOffset);
98     void setTilesetObjectAlignment(Alignment objectAlignment);
99     void setTilesetTransformationFlags(Tileset::TransformationFlags flags);
100 
101     void addTiles(const QList<Tile*> &tiles);
102     void removeTiles(const QList<Tile*> &tiles);
103     QList<int> relocateTiles(const QList<Tile *> &tiles, int location);
104 
105     const QList<Tile*> &selectedTiles() const;
106     void setSelectedTiles(const QList<Tile*> &selectedTiles);
107 
108     QList<Object*> currentObjects() const override;
109 
wangSetModel()110     TilesetWangSetModel *wangSetModel() const { return mWangSetModel; }
111 
112     WangColorModel *wangColorModel(WangSet *wangSet);
113 
114     void setTileType(Tile *tile, const QString &type);
115     void setTileImage(Tile *tile, const QPixmap &image, const QUrl &source);
116     void setTileProbability(Tile *tile, qreal probability);
117     void swapTileObjectGroup(Tile *tile, std::unique_ptr<ObjectGroup> &objectGroup);
118 
119     void checkIssues() override;
120 
121     static TilesetDocument* findDocumentForTileset(const SharedTileset &tileset);
122 
123 signals:
124     /**
125      * This signal is currently used when adding or removing tiles from a
126      * tileset, when changing the tileset column count or color, or when the
127      * tileset has been swapped.
128      *
129      * @todo Emit more specific signals.
130      */
131     void tilesetChanged(Tileset *tileset);
132 
133     void tilesAdded(const QList<Tile*> &tiles);
134     void tilesRemoved(const QList<Tile*> &tiles);
135 
136     void tilesetNameChanged(Tileset *tileset);
137     void tilesetTileOffsetChanged(Tileset *tileset);
138     void tilesetObjectAlignmentChanged(Tileset *tileset);
139 
140     void tileTypeChanged(Tile *tile);
141     void tileImageSourceChanged(Tile *tile);
142 
143     /**
144      * Notifies tileset models about changes to tile Wang information.
145      * All the \a tiles need to be from the same tileset.
146      */
147     void tileWangSetChanged(const QList<Tile*> &tiles);
148 
149     /**
150      * Emitted when the probability of a tile changed.
151      */
152     void tileProbabilityChanged(Tile *tile);
153 
154     /**
155      * Notifies the TileCollisionDock about the object group of a tile changing.
156      */
157     void tileObjectGroupChanged(Tile *tile);
158 
159     /**
160      * Emitted when the animation of a tile changed.
161      */
162     void tileAnimationChanged(Tile *tile);
163 
164     /**
165      * Emitted when the list of selected tiles in the tileset changed.
166      */
167     void selectedTilesChanged();
168 
169 private:
170     void onPropertyAdded(Object *object, const QString &name);
171     void onPropertyRemoved(Object *object, const QString &name);
172     void onPropertyChanged(Object *object, const QString &name);
173     void onPropertiesChanged(Object *object);
174 
175     void onWangSetRemoved(WangSet *wangSet);
176 
177     SharedTileset mTileset;
178     QList<MapDocument*> mMapDocuments;
179 
180     TilesetWangSetModel *mWangSetModel;
181     std::unordered_map<WangSet*, std::unique_ptr<WangColorModel>> mWangColorModels;
182 
183     QList<Tile*> mSelectedTiles;
184 
185     static QMap<SharedTileset, TilesetDocument*> sTilesetToDocument;
186 };
187 
188 
tileset()189 inline const SharedTileset &TilesetDocument::tileset() const
190 {
191     return mTileset;
192 }
193 
isEmbedded()194 inline bool TilesetDocument::isEmbedded() const
195 {
196     return fileName().isEmpty() && mMapDocuments.count() == 1;
197 }
198 
199 /**
200  * Returns the map documents this tileset is used in.
201  */
mapDocuments()202 inline const QList<MapDocument*> &TilesetDocument::mapDocuments() const
203 {
204     return mMapDocuments;
205 }
206 
207 /**
208  * Returns the list of selected tiles.
209  */
selectedTiles()210 inline const QList<Tile *> &TilesetDocument::selectedTiles() const
211 {
212     return mSelectedTiles;
213 }
214 
215 } // namespace Tiled
216