src/documentmanager.cpp

Fri, 01 Jul 2022 16:46:43 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Fri, 01 Jul 2022 16:46:43 +0300
changeset 312
2637134bc37c
parent 264
76a025db4948
child 328
3ea38fd469ca
permissions
-rw-r--r--

Fix right click to delete not really working properly
Instead of removing the point that had been added, it would remove
the point that is being drawn, which would cause it to overwrite the
previous point using the new point, causing a bit of a delay

24
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
1 /*
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
2 * LDForge: LDraw parts authoring CAD
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
3 * Copyright (C) 2013 - 2020 Teemu Piippo
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
4 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
5 * This program is free software: you can redistribute it and/or modify
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
6 * it under the terms of the GNU General Public License as published by
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
7 * the Free Software Foundation, either version 3 of the License, or
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
8 * (at your option) any later version.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
9 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
10 * This program is distributed in the hope that it will be useful,
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
13 * GNU General Public License for more details.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
14 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
15 * You should have received a copy of the GNU General Public License
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
17 */
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 23
diff changeset
18
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
19 #include <QFile>
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
20 #include <QDir>
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
21 #include <QFileInfo>
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
22 #include <QSaveFile>
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
23 #include <deque>
264
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 262
diff changeset
24 #include "src/documentmanager.h"
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 262
diff changeset
25 #include "src/parser.h"
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
27 DocumentManager::DocumentManager(QObject *parent) :
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
28 QObject{parent}
5
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
29 {
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
30 }
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
31
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
32 /**
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
33 * @brief Creates a new model.
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
34 * @returns the ID of the new model
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
35 */
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
36 ModelId DocumentManager::newModel()
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
37 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
38 const ModelId modelId{++this->modelIdCounter};
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
39 this->openModels.emplace(std::make_pair(modelId, ModelInfo{
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
40 .model = std::make_unique<Model>(this),
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
41 .id = modelId,
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
42 .opentype = OpenType::ManuallyOpened,
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
43 }));
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
44 this->makePolygonCacheForModel(modelId);
235
7ef03c2b46ab Add a basic message log
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 230
diff changeset
45 Q_EMIT this->message(logInfo(tr("New model %1 created").arg(modelId.value)));
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
46 return modelId;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
47 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
48
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
49 Model* DocumentManager::findDependencyByName(const ModelId modelId, const QString& name)
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
50 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
51 const auto modelsIterator = this->openModels.find(modelId);
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
52 if (modelsIterator != std::end(this->openModels)) {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
53 const auto& dependencies = modelsIterator->second.dependencies;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
54 const auto dependenciesIterator = dependencies.find(name);
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
55 if (dependenciesIterator != dependencies.end()) {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
56 ModelInfo& modelInfo = this->openModels[dependenciesIterator->second];
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
57 return modelInfo.model.get();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
58 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
59 else {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
60 return nullptr;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
61 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
62 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
63 else {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
64 return nullptr;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
65 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
66 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
67
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
68 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
69 * @brief Gets a model pointer by id or nullptr if not found
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
70 * @param modelId id of model to find
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
71 * @returns model pointer or null
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
72 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
73 Model *DocumentManager::getModelById(ModelId modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
74 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
75 const auto iterator = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
76 if (iterator != this->openModels.end())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
77 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
78 return iterator->second.model.get();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
79 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
80 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
81 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
82 return nullptr;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
83 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
84 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
85
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
86 QString pathToName(const QFileInfo& path)
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
88 static const char* paths[] = {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
89 "s",
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
90 "48"
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
91 "8"
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
92 };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
93 const QString baseName = path.fileName();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
94 const QString dirName = QFileInfo{path.dir().path()}.fileName();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
95 QString result;
17
a5111f4e6412 added teapot rendering
Teemu Piippo <teemu@hecknology.net>
parents: 14
diff changeset
96 if (std::find(std::begin(paths), std::end(paths), dirName) != std::end(paths))
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
97 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
98 result = dirName + "\\" + baseName;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
99 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
100 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
101 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
102 result = baseName;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
103 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
104 return result;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
106
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
107 /**
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
108 * @brief Tries to open the model at the specified path
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
109 * @param path Path to the model to open
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
110 * @param errorStream Where to write any errors
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
111 * @param openType rationale behind opening this file
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
112 * @returns model id, or no value on error
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
113 */
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
114 std::optional<ModelId> DocumentManager::openModel(
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
115 const QString& path,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
116 QTextStream& errorStream,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
117 const OpenType openType
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
118 ) {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
119 QFile file{path};
259
c27612f0eac0 - Made it build under Qt6
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 235
diff changeset
120 const QString name = pathToName(QFileInfo{path});
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
121 file.open(QFile::ReadOnly | QFile::Text);
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
122 std::unique_ptr<Model> newModel = std::make_unique<Model>(nullptr);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
123 QTextStream textStream{&file};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
124 Parser parser{file};
152
03f8e6d42e13 Major refactoring
Teemu Piippo <teemu@hecknology.net>
parents: 151
diff changeset
125 parser.parseBody(*newModel);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
126 std::optional<ModelId> result;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
127 if (file.error() == QFile::NoError)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
128 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
129 const ModelId modelId{++this->modelIdCounter};
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
130 this->openModels.emplace(std::make_pair(modelId, ModelInfo{
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
131 .model = std::move(newModel),
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
132 .id = modelId,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
133 .path = path,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
134 .opentype = openType,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
135 .polygonCache = {},
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
136 }));
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
137 this->makePolygonCacheForModel(modelId);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
138 result = modelId;
235
7ef03c2b46ab Add a basic message log
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 230
diff changeset
139 Q_EMIT this->message(logInfo(tr("Opened %1 as model %2").arg(quoted(path)).arg(modelId.value)));
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
140 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
141 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
142 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
143 errorStream << file.errorString();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
144 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
145 return result;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
146 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
147
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
148 void DocumentManager::closeDocument(const ModelId modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
149 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
150 ModelInfo* modelInfo = findInMap(this->openModels, modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
151 if (modelInfo != nullptr)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
152 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
153 modelInfo->opentype = OpenType::AutomaticallyOpened;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
154 this->prune();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
155 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
156 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
157
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
158 const QString *DocumentManager::modelPath(ModelId modelId) const
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
159 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
160 const auto iterator = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
161 if (iterator != this->openModels.end())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
162 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
163 return &iterator->second.path;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
164 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
165 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
166 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
167 return nullptr;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
168 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
169 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
170
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
171 //! \brief Changes the path of the specified model. This can cause dependencies
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
172 //! to be resolved differently. As such, dependencies need to be resolved for
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
173 //! all files after this operation.
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
174 void DocumentManager::setModelPath(
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
175 const ModelId modelId,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
176 const QString &newPath,
230
a1f3f7d9078b rename LibraryManager -> LibrariesModel
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
177 const LibrariesModel &libraries,
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
178 QTextStream &errorStream)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
179 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
180 ModelInfo* info = findInMap(this->openModels, modelId);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
181 if (info != nullptr and info->opentype == OpenType::ManuallyOpened) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
182 info->path = newPath;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
183 const MissingDependencies missing = this->loadDependenciesForAllModels(libraries);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
184 if (not missing.empty()) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
185 errorStream << errorStringFromMissingDependencies(missing);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
186 }
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
187 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
188 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
189
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
190 bool DocumentManager::saveModel(const ModelId modelId, QTextStream &errors)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
191 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
192 ModelInfo* info = findInMap(this->openModels, modelId);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
193 if (info != nullptr)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
194 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
195 QSaveFile file{info->path};
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
196 file.setDirectWriteFallback(true);
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
197 if (file.open(QSaveFile::WriteOnly)) {
262
dc33f8a707c4 Add action to make a model unofficial (modifies the !LDRAW_ORG line)
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 259
diff changeset
198 ::save(*info->model.get(), &file);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
199 const bool commitSucceeded = file.commit();
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
200 if (not commitSucceeded) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
201 errors << QObject::tr("Could not save: %1").arg(file.errorString());
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
202 return false;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
203 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
204 else {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
205 return true;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
206 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
207 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
208 else {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
209 errors << QObject::tr("Could not open %1 for writing: %2")
206
654661eab7f3 More refactor, merged main.h, basics.h and utility.h into one header file basics.h and removed plenty of unused code
Teemu Piippo <teemu@hecknology.net>
parents: 201
diff changeset
210 .arg(file.fileName(), file.errorString());
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
211 return false;
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
212 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
213 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
214 else {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
215 errors << QObject::tr("Bad model ID %1").arg(modelId.value);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
216 return false;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
217 }
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
218 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
219
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
220 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
221 * @brief Searches the open models for the specified model and returns its id if found
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
222 * @param model model to look for
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
223 * @return id or no value if not found
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
224 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
225 std::optional<ModelId> DocumentManager::findIdForModel(const Model *model) const
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
226 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
227 std::optional<ModelId> result;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
228 for (auto it = this->openModels.begin(); it != this->openModels.end(); ++it)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
229 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
230 if (it->second.model.get() == model)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
231 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
232 result = it->first;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
233 break;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
234 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
235 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
236 return result;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
237 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
238
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
239 PolygonCache *DocumentManager::getPolygonCacheForModel(ModelId modelId)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
240 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
241 ModelInfo* info = findInMap(this->openModels, modelId);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
242 if (info != nullptr) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
243 return &info->polygonCache;
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
244 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
245 else {
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
246 return nullptr;
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
247 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
248 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
249
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
250 const DocumentManager::ModelInfo *DocumentManager::find(ModelId modelId) const
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
251 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
252 return findInMap(this->openModels, modelId);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
253 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
254
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
255 void DocumentManager::setModelPayload(ModelId modelId, QObject *object)
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
256 {
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
257 ModelInfo* info = findInMap(this->openModels, modelId);
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
258 if (info != nullptr) {
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
259 info->payload = object;
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
260 object->setParent(this);
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
261 }
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
262 }
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 213
diff changeset
263
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
264 QString errorStringFromMissingDependencies(const DocumentManager::MissingDependencies& missing)
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
265 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
266 QString missingString;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
267 forValueInMap(missing, [&missingString](const QString& path){
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
268 missingString = joined(missingString, QStringLiteral(", "), path);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
269 });
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
270 return QObject::tr("The following files could not be opened: %1")
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
271 .arg(missingString);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
272 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
273
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
274 template<typename T, typename K>
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
275 void removeFromSet(std::set<T>& set, K&& valueToRemove)
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
276 {
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
277 const auto it = std::lower_bound(set.begin(), set.end(), valueToRemove);
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
278 if (it != set.end() and *it == valueToRemove) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
279 set.erase(it);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
280 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
281 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
282
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
283 //! @brief Cleans up and erases models that are no longer required.
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
284 void DocumentManager::prune()
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
285 {
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
286 Graph<ModelId> dependencyGraph;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
287 forValueInMap(this->openModels, [&dependencyGraph](const ModelInfo& info) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
288 forValueInMap(info.dependencies, [&dependencyGraph, &info](ModelId dep){
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
289 dependencyGraph.push_back({.from = info.id, .to = dep});
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
290 });
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
291 });
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
292 std::set<ModelId> autoOpened;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
293 forValueInMap(this->openModels, [&autoOpened](const ModelInfo& info) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
294 if (info.opentype == OpenType::AutomaticallyOpened) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
295 autoOpened.insert(info.id);
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
296 }
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
297 });
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
298 bool repeat = true;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
299 while (repeat) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
300 repeat = false;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
301 std::set<ModelId> prunable = autoOpened;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
302 for (const auto& pair : dependencyGraph) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
303 removeFromSet(prunable, pair.to);
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
304 }
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
305 for (ModelId idToPrune : prunable) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
306 auto it = this->openModels.find(idToPrune);
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
307 if (it != this->openModels.end()) {
235
7ef03c2b46ab Add a basic message log
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 230
diff changeset
308 Q_EMIT this->message(logInfo(tr("Model %1 (%2) pruned").arg(idToPrune.value).arg(it->second.path)));
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
309 this->openModels.erase(it);
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
310 }
213
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
311 removeFromSet(autoOpened, idToPrune);
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
312 std::erase_if(dependencyGraph, [&idToPrune](const GraphEdge<ModelId>& edge) {
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
313 return edge.from == idToPrune;
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
314 });
ee5758ddb6d2 Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 212
diff changeset
315 repeat = true;
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
316 }
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
317 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
318 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
319
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
320 void DocumentManager::makePolygonCacheForModel(const ModelId modelId)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
321 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
322 Model* model = this->getModelById(modelId);
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
323 if (model != nullptr)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
324 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
325 const auto modelModified = [this, model]{
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
326 const std::optional<ModelId> modelId = this->findIdForModel(model);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
327 if (modelId.has_value()) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
328 ModelInfo* info = findInMap(this->openModels, *modelId);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
329 if (info != nullptr) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
330 info->polygonCache.needRecache = true;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
331 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
332 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
333 };
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
334 QObject::connect(model, &Model::dataChanged, modelModified);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
335 QObject::connect(model, &Model::rowsInserted, modelModified);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
336 QObject::connect(model, &Model::rowsRemoved, modelModified);
193
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
337 }
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
338 }
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
339
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
340 static QString findFile(
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
341 QString referenceName,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
342 const QString& modelPath,
230
a1f3f7d9078b rename LibraryManager -> LibrariesModel
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
343 const LibrariesModel& libraries)
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
344 {
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
345 // Try to find the file in the same place as the model itself
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
346 referenceName.replace("\\", "/");
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
347 const QDir dir = QFileInfo{modelPath}.dir();
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
348 QString referencedFilePath = dir.filePath(referenceName);
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
349 if (not QFileInfo{referencedFilePath}.exists())
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
350 {
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
351 // Look for it in the libraries
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
352 referencedFilePath = libraries.findFile(referenceName);
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
353 }
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
354 return referencedFilePath;
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
355 }
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
356
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
357 static std::set<QString> referenceNames(const Model* model)
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
358 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
359 std::set<QString> result;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
360 iterate<Colored<SubfileReference>>(*model, [&result](const SubfileReference& ref){
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
361 result.insert(ref.name);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
362 });
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
363 return result;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
364 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
365
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
366 struct Dependency
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
367 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
368 QString name;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
369 QString path;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
370 bool operator<(const Dependency& other) const
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
371 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
372 if (this->name != other.name) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
373 return this->name < other.name;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
374 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
375 else {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
376 return this->path < other.path;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
377 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
378 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
379 };
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
380
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
381 static std::set<Dependency> resolveReferencePaths(
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
382 const DocumentManager::ModelInfo* modelInfo,
230
a1f3f7d9078b rename LibraryManager -> LibrariesModel
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
383 const LibrariesModel* libraries)
200
ca23936b455b Giant refactor
Teemu Piippo <teemu@hecknology.net>
parents: 195
diff changeset
384 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
385 std::set<Dependency> result;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
386 const std::set<QString> refNames = referenceNames(modelInfo->model.get());
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
387 if (modelInfo != nullptr) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
388 for (const QString& name : refNames) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
389 const QString path = findFile(name, modelInfo->path, *libraries);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
390 if (not path.isEmpty()) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
391 result.insert(Dependency{.name = name, .path = path});
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
392 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
393 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
394 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
395 return result;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
396 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
397
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
398 static void loadDependenciesForModel(
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
399 DocumentManager::ModelInfo* info,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
400 DocumentManager* documents,
230
a1f3f7d9078b rename LibraryManager -> LibrariesModel
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
401 const LibrariesModel* libraries,
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
402 std::map<QString, QString>& missing)
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
403 {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
404 bool repeat = true;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
405 info->dependencies.clear();
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
406 while (repeat) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
407 repeat = false;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
408 const std::set<Dependency> dependencies = resolveReferencePaths(info, libraries);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
409 for (const Dependency& dep : dependencies) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
410 if (not info->dependencies.contains(dep.name) and not missing.contains(dep.path)) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
411 QString loadErrorString;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
412 QTextStream localErrorStream{&loadErrorString};
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
413 const std::optional<ModelId> modelIdOpt = documents->openModel(
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
414 dep.path,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
415 localErrorStream,
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
416 OpenType::AutomaticallyOpened);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
417 if (not modelIdOpt.has_value()) {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
418 const QString& errorMessage = QObject::tr("could not load '%1': %2")
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
419 .arg(dep.path, loadErrorString);
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
420 missing[dep.path] = errorMessage;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
421 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
422 else {
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
423 info->dependencies[dep.name] = modelIdOpt.value();
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
424 repeat = true;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
425 }
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
426 }
200
ca23936b455b Giant refactor
Teemu Piippo <teemu@hecknology.net>
parents: 195
diff changeset
427 }
ca23936b455b Giant refactor
Teemu Piippo <teemu@hecknology.net>
parents: 195
diff changeset
428 }
ca23936b455b Giant refactor
Teemu Piippo <teemu@hecknology.net>
parents: 195
diff changeset
429 }
ca23936b455b Giant refactor
Teemu Piippo <teemu@hecknology.net>
parents: 195
diff changeset
430
230
a1f3f7d9078b rename LibraryManager -> LibrariesModel
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
431 std::map<QString, QString> DocumentManager::loadDependenciesForAllModels(const LibrariesModel& libraries)
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
432 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
433 std::map<QString, QString> missing;
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
434 for (auto& modelInfoPair : this->openModels)
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
435 {
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
436 loadDependenciesForModel(&modelInfoPair.second, this, &libraries, missing);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
437 }
212
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
438 this->prune();
27259810da6d Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 206
diff changeset
439 return missing;
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
440 }

mercurial