1 /*
2 * logginginterface.h
3 * Copyright 2013, Samuli Tuomola <samuli.tuomola@gmail.com>
4 * Copyright 2015, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
5 *
6 * This file is part of libtiled.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 * EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #pragma once
31
32 #include "tiled_global.h"
33
34 #include <QObject>
35 #include <QPoint>
36 #include <QWeakPointer>
37
38 #include <functional>
39
40 class QString;
41
42 namespace Tiled {
43
44 class Layer;
45 class Map;
46 class MapObject;
47 class Object;
48 class Tile;
49 class Tileset;
50
51 class TILEDSHARED_EXPORT Issue
52 {
53 public:
54 enum Severity {
55 Error,
56 Warning
57 };
58
59 Issue();
60 Issue(Severity severity,
61 const QString &text,
62 const std::function<void()> &callback = std::function<void()>(),
63 const void *context = nullptr);
64
severity()65 Severity severity() const { return mSeverity; }
text()66 QString text() const { return mText; }
67
callback()68 std::function<void()> callback() const { return mCallback; }
69 void setCallback(std::function<void()> callback);
70
setContext(const void * context)71 void setContext(const void *context) { mContext = context; }
context()72 const void *context() const { return mContext; }
73
id()74 unsigned id() const { return mId; }
75
76 void addOccurrence(const Issue &issue);
occurrences()77 int occurrences() const { return mOccurrences; }
78
79 bool operator==(const Issue &o) const
80 {
81 return severity() == o.severity()
82 && text() == o.text();
83 }
84
85 private:
86 Issue::Severity mSeverity = Issue::Error;
87 QString mText;
88 std::function<void()> mCallback;
89 const void *mContext = nullptr;
90
91 int mOccurrences = 1;
92 unsigned mId = 0;
93
94 static unsigned mNextIssueId;
95 };
96
97 /**
98 * An interface for reporting issues.
99 *
100 * Normally you'd use the convenience functions in the Tiled namespace.
101 */
102 class TILEDSHARED_EXPORT LoggingInterface : public QObject
103 {
104 Q_OBJECT
105
106 explicit LoggingInterface(QObject *parent = nullptr);
107
108 public:
109 static LoggingInterface &instance();
110
111 enum OutputType {
112 INFO,
113 WARNING,
114 ERROR
115 };
116
117 void report(const Issue &issue);
118 void log(OutputType type, const QString &message);
119
120 signals:
121 void issue(const Tiled::Issue &issue);
122
123 void info(const QString &message);
124 void warning(const QString &message);
125 void error(const QString &message);
126
127 void removeIssuesWithContext(const void *context);
128 };
129
REPORT(const Issue & issue)130 inline void REPORT(const Issue &issue)
131 {
132 LoggingInterface::instance().report(issue);
133 }
134
INFO(const QString & message)135 inline void INFO(const QString &message)
136 {
137 LoggingInterface::instance().log(LoggingInterface::INFO, message);
138 }
139
140 inline void WARNING(const QString &message, std::function<void()> callback = std::function<void()>(), const void *context = nullptr)
141 {
142 REPORT(Issue { Issue::Warning, message, callback, context });
143 }
144
145 inline void ERROR(const QString &message, std::function<void()> callback = std::function<void()>(), const void *context = nullptr)
146 {
147 REPORT(Issue { Issue::Error, message, callback, context });
148 }
149
INFO(QLatin1String message)150 inline void INFO(QLatin1String message)
151 {
152 INFO(QString(message));
153 }
154
155 inline void WARNING(QLatin1String message, std::function<void()> callback = std::function<void()>(), const void *context = nullptr)
156 {
157 WARNING(QString(message), callback, context);
158 }
159
160 inline void ERROR(QLatin1String message, std::function<void()> callback = std::function<void()>(), const void *context = nullptr)
161 {
162 ERROR(QString(message), callback, context);
163 }
164
165 // TODO: Try "static inline" once we switch to C++17
166 #define ACTIVATABLE(Class) \
167 void operator() () const { activated(*this); } \
168 static std::function<void (const Class &)> activated;
169
170 struct TILEDSHARED_EXPORT OpenFile
171 {
172 QString file;
173
174 ACTIVATABLE(OpenFile)
175 };
176
177 struct TILEDSHARED_EXPORT JumpToTile
178 {
179 JumpToTile(const Map *map, QPoint tilePos, const Layer *layer = nullptr);
180
181 QString mapFile;
182 QPoint tilePos;
183 int layerId = -1;
184
185 ACTIVATABLE(JumpToTile)
186 };
187
188 struct TILEDSHARED_EXPORT JumpToObject
189 {
190 JumpToObject(const MapObject *object);
191
192 QString mapFile;
193 int objectId;
194
195 ACTIVATABLE(JumpToObject)
196 };
197
198 struct TILEDSHARED_EXPORT SelectLayer
199 {
200 SelectLayer(const Layer *layer);
201
202 QString mapFile;
203 int layerId;
204
205 ACTIVATABLE(SelectLayer)
206 };
207
208 struct TILEDSHARED_EXPORT SelectCustomProperty
209 {
210 SelectCustomProperty(QString fileName, QString propertyName, const Object *object);
211
212 QString fileName;
213 QString propertyName;
214 int objectType; // see Object::TypeId
215 int id = -1;
216
217 ACTIVATABLE(SelectCustomProperty)
218 };
219
220 struct TILEDSHARED_EXPORT SelectTile
221 {
222 SelectTile(const Tile *tile);
223
224 QWeakPointer<Tileset> tileset;
225 QString tilesetFile;
226 int tileId;
227
228 ACTIVATABLE(SelectTile)
229 };
230
231 #undef ACTIVATABLE
232
233 } // namespace Tiled
234
235 Q_DECLARE_METATYPE(Tiled::Issue)
236