21 #include <QFileInfo> |
21 #include <QFileInfo> |
22 #include <QFont> |
22 #include <QFont> |
23 #include <QSaveFile> |
23 #include <QSaveFile> |
24 #include "model.h" |
24 #include "model.h" |
25 #include "modeleditcontext.h" |
25 #include "modeleditcontext.h" |
|
26 #include "documentmanager.h" |
26 |
27 |
27 /** |
28 /** |
28 * @brief Constructs a model |
29 * @brief Constructs a model |
29 * @param parent QObject parent to pass forward |
30 * @param parent QObject parent to pass forward |
30 */ |
31 */ |
31 Model::Model(QObject* parent) : |
32 Model::Model(QObject *parent) : |
32 Model{"", parent} {} |
33 QAbstractListModel{parent} |
33 |
|
34 /** |
|
35 * @brief Constructs a model |
|
36 * @param path Path that was used to open the model |
|
37 * @param parent QObject parent to pass forward |
|
38 */ |
|
39 Model::Model(const QString& path, QObject *parent) : |
|
40 QAbstractListModel{parent}, |
|
41 storedPath{path} |
|
42 { |
34 { |
43 connect(this, &Model::dataChanged, [&](){ this->needRecache = true; }); |
35 connect(this, &Model::dataChanged, [&](){ this->needRecache = true; }); |
44 } |
36 } |
45 |
37 |
46 /** |
38 /** |
148 std::vector<gl::Polygon> Model::getPolygons(DocumentManager* documents) const |
140 std::vector<gl::Polygon> Model::getPolygons(DocumentManager* documents) const |
149 { |
141 { |
150 if (this->needRecache) |
142 if (this->needRecache) |
151 { |
143 { |
152 this->cachedPolygons.clear(); |
144 this->cachedPolygons.clear(); |
153 ldraw::GetPolygonsContext context{documents}; |
145 const std::optional<ModelId> modelId = documents->findIdForModel(this); |
154 for (int i = 0; i < this->size(); i += 1) |
146 if (modelId.has_value()) |
155 { |
147 { |
156 this->getObjectPolygons(i, this->cachedPolygons, &context); |
148 ldraw::GetPolygonsContext context{modelId.value(), documents}; |
|
149 for (int i = 0; i < this->size(); i += 1) |
|
150 { |
|
151 this->getObjectPolygons(i, this->cachedPolygons, &context); |
|
152 } |
157 } |
153 } |
158 this->needRecache = false; |
154 this->needRecache = false; |
159 } |
155 } |
160 return this->cachedPolygons; |
156 return this->cachedPolygons; |
161 } |
157 } |
186 ldraw::id_t Model::resolve(const QModelIndex& index) const |
182 ldraw::id_t Model::resolve(const QModelIndex& index) const |
187 { |
183 { |
188 return this->objectAt(index)->id; |
184 return this->objectAt(index)->id; |
189 } |
185 } |
190 |
186 |
191 /** |
187 #if 0 |
192 * @brief Gets the path to the model |
|
193 * @return path |
|
194 */ |
|
195 const QString& Model::path() const |
|
196 { |
|
197 return this->storedPath; |
|
198 } |
|
199 |
|
200 /** |
188 /** |
201 * @brief Sets the path to the model |
189 * @brief Sets the path to the model |
202 * @param path New path to use |
190 * @param path New path to use |
203 */ |
191 */ |
204 void Model::setPath(const QString &path) |
192 void Model::setPath(const QString &path) |
218 editor.setObjectProperty<ldraw::Property::Text>(id, "Name: " + this->header.name); |
206 editor.setObjectProperty<ldraw::Property::Text>(id, "Name: " + this->header.name); |
219 } |
207 } |
220 } |
208 } |
221 } |
209 } |
222 } |
210 } |
|
211 #endif |
223 |
212 |
224 /** |
213 /** |
225 * @brief Gets the GL polygons of the object at the specified position in the model |
214 * @brief Gets the GL polygons of the object at the specified position in the model |
226 * @param index Index of object in the model |
215 * @param index Index of object in the model |
227 * @param polygons_out Vector to add polygons into |
216 * @param polygons_out Vector to add polygons into |
302 return this->body[unsigned_cast(index.row())].get(); |
291 return this->body[unsigned_cast(index.row())].get(); |
303 } |
292 } |
304 |
293 |
305 /** |
294 /** |
306 * @brief Attempts the save the model |
295 * @brief Attempts the save the model |
307 * @param errors Where to write any errors |
296 */ |
308 * @returns whether it succeeded |
297 void Model::save(QIODevice* device) const |
309 */ |
298 { |
310 bool Model::save(QTextStream &errors) const |
299 QTextStream out{device}; |
311 { |
300 for (const ModelObjectPointer& object : this->body) |
312 QSaveFile file{this->path()}; |
301 { |
313 file.setDirectWriteFallback(true); |
302 out << object.get()->toLDrawCode() << "\r\n"; |
314 if (file.open(QSaveFile::WriteOnly)) |
|
315 { |
|
316 QTextStream out{&file}; |
|
317 for (const ModelObjectPointer& object : this->body) |
|
318 { |
|
319 out << object.get()->toLDrawCode() << "\r\n"; |
|
320 } |
|
321 const bool commitSucceeded = file.commit(); |
|
322 if (not commitSucceeded) |
|
323 { |
|
324 errors << tr("Could not save to %1: %2") |
|
325 .arg(this->path()) |
|
326 .arg(file.errorString()); |
|
327 return false; |
|
328 } |
|
329 else |
|
330 { |
|
331 return true; |
|
332 } |
|
333 } |
|
334 else |
|
335 { |
|
336 errors << tr("Could not open %1 for writing: %2") |
|
337 .arg(file.fileName()) |
|
338 .arg(file.errorString()); |
|
339 return false; |
|
340 } |
303 } |
341 } |
304 } |
342 |
305 |
343 /** |
306 /** |
344 * @brief Modifies the !LDRAW_ORG line so that it becomes unofficial |
307 * @brief Modifies the !LDRAW_ORG line so that it becomes unofficial |