109 * @param path Path to the model to open |
109 * @param path Path to the model to open |
110 * @param errorStream Where to write any errors |
110 * @param errorStream Where to write any errors |
111 * @param openType rationale behind opening this file |
111 * @param openType rationale behind opening this file |
112 * @returns model id, or no value on error |
112 * @returns model id, or no value on error |
113 */ |
113 */ |
|
114 #include <QPlainTextDocumentLayout> |
114 std::optional<ModelId> DocumentManager::openModel( |
115 std::optional<ModelId> DocumentManager::openModel( |
115 const QString& path, |
116 const QString& path, |
116 QTextStream& errorStream, |
117 QTextStream& errorStream, |
117 const OpenType openType |
118 const OpenType openType |
118 ) { |
119 ) { |
119 QFile file{path}; |
120 QFile file{path}; |
120 const QString name = pathToName(QFileInfo{path}); |
121 const QString name = pathToName(QFileInfo{path}); |
121 file.open(QFile::ReadOnly | QFile::Text); |
122 file.open(QFile::ReadOnly | QFile::Text); |
122 std::unique_ptr<Model> newModel = std::make_unique<Model>(nullptr); |
123 std::unique_ptr<QTextDocument> newModel = std::make_unique<QTextDocument>(nullptr); |
123 QTextStream textStream{&file}; |
124 newModel->setDocumentLayout(new QPlainTextDocumentLayout{newModel.get()}); |
124 Parser parser{textStream}; |
125 newModel->setPlainText(file.readAll()); |
125 parser.parseBody(*newModel); |
|
126 std::optional<ModelId> result; |
126 std::optional<ModelId> result; |
127 if (file.error() == QFile::NoError) |
127 if (file.error() == QFile::NoError) |
128 { |
128 { |
129 const ModelId modelId{++this->modelIdCounter}; |
129 const ModelId modelId{++this->modelIdCounter}; |
130 this->openModels.emplace(std::make_pair(modelId, ModelInfo{ |
130 this->openModels.emplace(std::make_pair(modelId, ModelInfo{ |
193 if (info != nullptr) |
193 if (info != nullptr) |
194 { |
194 { |
195 QSaveFile file{info->path}; |
195 QSaveFile file{info->path}; |
196 file.setDirectWriteFallback(true); |
196 file.setDirectWriteFallback(true); |
197 if (file.open(QSaveFile::WriteOnly)) { |
197 if (file.open(QSaveFile::WriteOnly)) { |
198 QTextStream stream{&file}; |
198 file.write(info->model->toPlainText().toUtf8()); |
199 ::save(*info->model.get(), &stream); |
|
200 const bool commitSucceeded = file.commit(); |
199 const bool commitSucceeded = file.commit(); |
201 if (not commitSucceeded) { |
200 if (not commitSucceeded) { |
202 errors << QObject::tr("Could not save: %1").arg(file.errorString()); |
201 errors << QObject::tr("Could not save: %1").arg(file.errorString()); |
203 return false; |
202 return false; |
204 } |
203 } |
330 if (info != nullptr) { |
329 if (info != nullptr) { |
331 info->polygonCache.needRecache = true; |
330 info->polygonCache.needRecache = true; |
332 } |
331 } |
333 } |
332 } |
334 }; |
333 }; |
335 QObject::connect(model, &Model::dataChanged, modelModified); |
334 QObject::connect(model, &QTextDocument::contentsChanged, modelModified); |
336 QObject::connect(model, &Model::rowsInserted, modelModified); |
|
337 QObject::connect(model, &Model::rowsRemoved, modelModified); |
|
338 QObject::connect(model, &Model::modelReset, modelModified); |
|
339 } |
335 } |
340 } |
336 } |
341 |
337 |
342 static QString findFile( |
338 static QString findFile( |
343 QString referenceName, |
339 QString referenceName, |
357 } |
353 } |
358 |
354 |
359 static std::set<QString> referenceNames(const Model* model) |
355 static std::set<QString> referenceNames(const Model* model) |
360 { |
356 { |
361 std::set<QString> result; |
357 std::set<QString> result; |
362 iterate<Colored<SubfileReference>>(*model, [&result](const SubfileReference& ref){ |
358 for (const QString& line : model->toPlainText().split("\n")) { |
363 result.insert(ref.name); |
359 const opt<ParsedLine> parsed = parse(line); |
364 }); |
360 if (parsed.has_value() and std::holds_alternative<LineType1>(*parsed)) { |
|
361 result.insert(std::get<LineType1>(*parsed).value.name); |
|
362 } |
|
363 } |
365 return result; |
364 return result; |
366 } |
365 } |
367 |
366 |
368 struct Dependency |
367 struct Dependency |
369 { |
368 { |