1 /*
2 * brokenlinks.h
3 * Copyright 2015, 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 "mapdocument.h"
24 #include "tileset.h"
25
26 #include <QAbstractListModel>
27 #include <QWidget>
28
29 class QAbstractButton;
30 class QDialogButtonBox;
31 class QItemSelection;
32 class QLabel;
33 class QSortFilterProxyModel;
34 class QTreeView;
35
36 namespace Tiled {
37
38 class Tile;
39 class Tileset;
40 class ObjectTemplate;
41
42 class Document;
43 class TilesetDocument;
44
45 enum BrokenLinkType {
46 MapTilesetReference,
47 ObjectTemplateTilesetReference,
48 TilesetTileImageSource,
49 TilesetImageSource,
50 ObjectTemplateReference,
51 };
52
53 struct BrokenLink {
54 BrokenLinkType type;
55
56 union {
57 Tileset *_tileset;
58 Tile *_tile;
59 const ObjectTemplate *_objectTemplate;
60 };
61
62 QString filePath() const;
63 Tileset *tileset() const;
64 const ObjectTemplate *objectTemplate() const;
65 };
66
67
68 class BrokenLinksModel : public QAbstractListModel
69 {
70 Q_OBJECT
71 Q_PROPERTY(bool hasBrokenLinks READ hasBrokenLinks NOTIFY hasBrokenLinksChanged)
72
73 public:
74 BrokenLinksModel(QObject *parent = nullptr);
75
76 void setDocument(Document *document);
77 Document *document() const;
78
79 void refresh();
80 bool hasBrokenLinks() const;
81
82 const BrokenLink &brokenLink(int index) const;
83
84 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
85 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
86 QVariant data(const QModelIndex &index, int role) const override;
87 QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
88
89 signals:
90 void hasBrokenLinksChanged(bool hasBrokenLinks);
91
92 private:
93 void tileImageSourceChanged(Tile *tile);
94 void tilesetChanged(Tileset *tileset);
95
96 void tilesetAdded(int index, Tileset *tileset);
97 void tilesetRemoved(Tileset *tileset);
98
99 void connectToTileset(const SharedTileset &tileset);
100 void disconnectFromTileset(const SharedTileset &tileset);
101
102 void removeLink(int index);
103
104 Document *mDocument;
105 QVector<BrokenLink> mBrokenLinks;
106 };
107
108
document()109 inline Document *BrokenLinksModel::document() const
110 {
111 return mDocument;
112 }
113
hasBrokenLinks()114 inline bool BrokenLinksModel::hasBrokenLinks() const
115 {
116 return !mBrokenLinks.isEmpty();
117 }
118
brokenLink(int index)119 inline const BrokenLink &BrokenLinksModel::brokenLink(int index) const
120 {
121 return mBrokenLinks.at(index);
122 }
123
124
125 class BrokenLinksWidget : public QWidget
126 {
127 Q_OBJECT
128
129 public:
130 BrokenLinksWidget(BrokenLinksModel *brokenLinksModel, QWidget *parent = nullptr);
131
132 signals:
133 void ignore();
134
135 private:
136 void clicked(QAbstractButton *button);
137 void selectionChanged();
138
139 BrokenLinksModel *mBrokenLinksModel;
140 QSortFilterProxyModel *mProxyModel;
141 QLabel *mTitleLabel;
142 QLabel *mDescriptionLabel;
143 QTreeView *mView;
144 QDialogButtonBox *mButtons;
145 QAbstractButton *mLocateButton;
146 };
147
148
149 class LinkFixer
150 {
151 public:
152 LinkFixer(Document *document);
153
154 void tryFixLinks(const QVector<BrokenLink> &links);
155 void tryFixLink(const BrokenLink &link);
156 bool tryFixLink(const BrokenLink &link, const QString &newFilePath);
157
158 static QUrl locateImage(const QString &fileName);
159 static QString locateTileset();
160 static QString locateObjectTemplate();
161
162 void tryFixMapTilesetReference(const SharedTileset &tileset);
163 void tryFixObjectTemplateReference(const ObjectTemplate *objectTemplate);
164
165 private:
166 bool tryFixMapTilesetReference(const SharedTileset &tileset, const QString &newFilePath);
167 bool tryFixObjectTemplateReference(const ObjectTemplate *objectTemplate, const QString &newFilePath);
168
169 Document *mDocument;
170 };
171
172
173 struct LocateTileset
174 {
175 QWeakPointer<Tileset> mTileset;
176 QWeakPointer<MapDocument> mMapDocument;
177
178 void operator()() const;
179 };
180
181 struct LocateObjectTemplate
182 {
183 const ObjectTemplate *mObjectTemplate;
184 QWeakPointer<MapDocument> mMapDocument;
185
186 void operator()() const;
187 };
188
189 } // namespace Tiled
190