src/documentmanager.cpp

Wed, 25 May 2022 20:36:34 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 25 May 2022 20:36:34 +0300
changeset 199
6988973515d2
parent 195
6e79c1cb83e6
child 200
ca23936b455b
permissions
-rw-r--r--

Fix pick() picking from weird places on the screen with high DPI scaling

glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account

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>
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 #include "documentmanager.h"
153
2f79053c2e9a Renamed modeleditcontext.cpp -> modeleditor.cpp
Teemu Piippo <teemu@hecknology.net>
parents: 152
diff changeset
24 #include "modeleditor.h"
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
25 #include "linetypes/subfilereference.h"
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
26 #include "parser.h"
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
28 /**
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
29 * @brief Constructs a new document manager
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
30 * @param parent Parent object
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
31 */
5
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
32 DocumentManager::DocumentManager(QObject* parent) :
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
33 QObject{parent}
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
34 {
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
35 }
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
36
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
37 /**
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
38 * @brief Creates a new model.
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
39 * @returns the ID of the new model
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
40 */
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
41 ModelId DocumentManager::newModel()
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
42 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
43 const ModelId modelId{++this->modelIdCounter};
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
44 const QString name = makeNewModelName();
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
45 this->openModels[modelId] = ModelInfo{
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
46 .model = std::make_unique<Model>(),
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
47 .id = modelId,
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
48 .opentype = OpenType::ManuallyOpened,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
49 };
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
50 this->makePolygonCacheForModel(modelId);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
51 return modelId;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
52 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
53
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
54 /**
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
55 * @brief Looks for a model by name
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
56 * @param name Name of the model
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
57 * @returns model or null
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
58 */
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
59 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
60 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
61 const auto modelsIterator = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
62 if (modelsIterator != std::end(this->openModels))
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
63 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
64 const auto& dependencies = modelsIterator->second.dependencies;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
65 const auto dependenciesIterator = dependencies.find(name);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
66 if (dependenciesIterator != dependencies.end())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
67 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
68 ModelInfo& modelInfo = this->openModels[dependenciesIterator->second];
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
69 return modelInfo.model.get();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
70 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
71 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
72 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
73 return nullptr;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
74 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
75 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
76 else
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
77 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
78 return nullptr;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
79 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
80 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
81
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
82 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
83 * @brief Gets a model pointer by id or nullptr if not found
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
84 * @param modelId id of model to find
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
85 * @returns model pointer or null
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
86 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
87 Model *DocumentManager::getModelById(ModelId modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
88 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
89 const auto iterator = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
90 if (iterator != this->openModels.end())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
91 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
92 return iterator->second.model.get();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
93 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
94 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
95 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
96 return nullptr;
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 }
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 QString pathToName(const QFileInfo& path)
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
102 static const char* paths[] = {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
103 "s",
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
104 "48"
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
105 "8"
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
106 };
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
107 const QString baseName = path.fileName();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
108 const QString dirName = QFileInfo{path.dir().path()}.fileName();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
109 QString result;
17
a5111f4e6412 added teapot rendering
Teemu Piippo <teemu@hecknology.net>
parents: 14
diff changeset
110 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
111 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
112 result = dirName + "\\" + baseName;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
113 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
114 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
115 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
116 result = baseName;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
117 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
118 return result;
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119 }
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
120
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
121 /**
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
122 * @brief Tries to open the model at the specified path
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
123 * @param path Path to the model to open
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
124 * @param errorStream Where to write any errors
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
125 * @param openType rationale behind opening this file
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
126 * @returns model id, or no value on error
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
127 */
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
128 std::optional<ModelId> DocumentManager::openModel(
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
129 const QString& path,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
130 QTextStream& errorStream,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
131 const OpenType openType
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
132 ) {
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
133 QFile file{path};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
134 const QString name = pathToName(path);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
135 file.open(QFile::ReadOnly | QFile::Text);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
136 std::unique_ptr<Model> newModel = std::make_unique<Model>(this);
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
137 QTextStream textStream{&file};
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
138 Parser parser{file};
152
03f8e6d42e13 Major refactoring
Teemu Piippo <teemu@hecknology.net>
parents: 151
diff changeset
139 parser.parseBody(*newModel);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
140 std::optional<ModelId> result;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
141 if (file.error() == QFile::NoError)
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
142 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
143 const ModelId modelId{++this->modelIdCounter};
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
144 this->openModels[modelId] = {std::move(newModel), modelId, path, openType};
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
145 this->makePolygonCacheForModel(modelId);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
146 result = modelId;
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
147 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
148 else
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
149 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
150 errorStream << file.errorString();
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
151 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
152 return result;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
153 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
154
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
155 QString DocumentManager::makeNewModelName()
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
156 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
157 untitledNameCounter += 1;
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
158 return "untitled-" + QString::number(untitledNameCounter);
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
159 }
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
160
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
161 void DocumentManager::loadDependenciesForAllModels(const LibraryManager& libraries, QTextStream& errorStream)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
162 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
163 for (const auto& modelInfoPair : this->openModels)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
164 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
165 this->loadDependenciesForModel(modelInfoPair.first, modelInfoPair.second.path, libraries, errorStream);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
166 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
167 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
168
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
169 struct DocumentManager::LoadDepedenciesBag
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
170 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
171 const LibraryManager& libraries;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
172 QStringList missing;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
173 QSet<ModelId> processed;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
174 QTextStream& errorStream;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
175 };
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
176
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
177 void DocumentManager::loadDependenciesForModel(
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
178 const ModelId modelId,
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
179 const QString& path,
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
180 const LibraryManager& libraries,
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
181 QTextStream& errorStream)
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
182 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
183 LoadDepedenciesBag bag {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
184 .libraries = libraries,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
185 .missing = {},
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
186 .processed = {},
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
187 .errorStream = errorStream,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
188 };
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
189 this->loadDependenciesForModel(modelId, path, bag);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
190 if (not bag.missing.empty())
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
191 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
192 bag.missing.sort(Qt::CaseInsensitive);
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
193 errorStream << utility::format(
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
194 "The following files could not be opened: %1",
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
195 bag.missing.join(", "));
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
196 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
197 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
198
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
199 void DocumentManager::closeDocument(const ModelId modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
200 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
201 ModelInfo* modelInfo = findInMap(this->openModels, modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
202 if (modelInfo != nullptr)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
203 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
204 modelInfo->opentype = OpenType::AutomaticallyOpened;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
205 this->prune();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
206 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
207 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
208
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
209 const QString *DocumentManager::modelPath(ModelId modelId) const
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
210 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
211 const auto iterator = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
212 if (iterator != this->openModels.end())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
213 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
214 return &iterator->second.path;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
215 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
216 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
217 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
218 return nullptr;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
219 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
220 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
221
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
222 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
223 * @brief Changes the path of the specified model. Since the name of the file may change,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
224 * changing the path can cause dependencies to be resolved differently. As such, dependencies
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
225 * need to be resolved for all files after this operation.
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
226 * @param modelId Model to change the path of
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
227 * @param newPath New path
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
228 * @param libraries Library manager for the purpose of dependency resolving
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
229 * @param errorStream Where to write any errors regarding dependency resolving
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
230 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
231 void DocumentManager::setModelPath(
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
232 const ModelId modelId,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
233 const QString &newPath,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
234 const LibraryManager &libraries,
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
235 QTextStream &errorStream)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
236 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
237 auto modelInfoPair = this->openModels.find(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
238 if (true
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
239 and modelInfoPair != this->openModels.end()
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
240 and modelInfoPair->second.opentype == OpenType::ManuallyOpened
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
241 ) {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
242 modelInfoPair->second.path = newPath;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
243 this->loadDependenciesForAllModels(libraries, errorStream);
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
244 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
245 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
246
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
247 bool DocumentManager::saveModel(const ModelId modelId, QTextStream &errors)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
248 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
249 const QString* const path = this->modelPath(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
250 if (path != nullptr)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
251 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
252 QSaveFile file{*path};
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
253 file.setDirectWriteFallback(true);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
254 if (file.open(QSaveFile::WriteOnly))
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
255 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
256 // if path is not nullptr, getModelById will always return a value as well
151
e628fc2e0c72 Clean up Model
Teemu Piippo <teemu@hecknology.net>
parents: 150
diff changeset
257 ::save(*this->getModelById(modelId), &file);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
258 const bool commitSucceeded = file.commit();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
259 if (not commitSucceeded)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
260 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
261 errors << tr("Could not save: %1").arg(file.errorString());
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
262 return false;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
263 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
264 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
265 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
266 return true;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
267 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
268 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
269 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
270 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
271 errors << tr("Could not open %1 for writing: %2")
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
272 .arg(file.fileName())
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
273 .arg(file.errorString());
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
274 return false;
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
275 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
276 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
277 else
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
278 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
279 errors << tr("Bad model ID %1").arg(modelId.value);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
280 return false;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
281 }
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
282 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
283
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
284 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
285 * @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
286 * @param model model to look for
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
287 * @return id or no value if not found
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
288 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
289 std::optional<ModelId> DocumentManager::findIdForModel(const Model *model) const
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
290 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
291 std::optional<ModelId> result;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
292 for (auto it = this->openModels.begin(); it != this->openModels.end(); ++it)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
293 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
294 if (it->second.model.get() == model)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
295 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
296 result = it->first;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
297 break;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
298 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
299 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
300 return result;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
301 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
302
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
303 PolygonCache *DocumentManager::getPolygonCacheForModel(ModelId modelId)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
304 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
305 auto it = this->polygonCaches.find(modelId);
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
306 if (it != this->polygonCaches.end())
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
307 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
308 return &it->second;
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
309 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
310 else
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
311 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
312 return nullptr;
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
313 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
314 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
315
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
316 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
317 * @brief Cleans up and erases models that are no longer required.
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
318 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
319 void DocumentManager::prune()
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
320 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
321 for (auto it = this->openModels.begin(); it != this->openModels.end(); ++it)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
322 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
323 // Find models that are not edited by the user and are not needed by any other model
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
324 if (true
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
325 and it->second.opentype == OpenType::AutomaticallyOpened
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
326 and not this->isReferencedByAnything(it->first)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
327 ) {
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
328 // Remove its polygon cache
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
329 const auto polygonCache = this->polygonCaches.find(it->first);
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
330 if (polygonCache != this->polygonCaches.end())
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
331 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
332 this->polygonCaches.erase(polygonCache);
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
333 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
334 // Remove the model
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
335 this->openModels.erase(it);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
336 // We need to start over now. It is possible that other models that previously
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
337 // were referenced by the model we just erased have become prunable.
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
338 // Moreover, our iterator is invalid now and we cannot continue in this for loop.
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
339 this->prune();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
340 break;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
341 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
342 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
343 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
344
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
345 /**
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
346 * @brief Finds out whether the specified model id is referenced by any other model
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
347 * @param modelId
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
348 * @returns bool
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
349 */
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
350 bool DocumentManager::isReferencedByAnything(const ModelId modelId) const
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
351 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
352 for (auto& haystackModelPair : this->openModels)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
353 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
354 if (haystackModelPair.first != modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
355 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
356 for (auto& dependencyPair : haystackModelPair.second.dependencies)
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
357 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
358 if (dependencyPair.second == modelId)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
359 {
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
360 return true;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
361 }
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
362 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
363 }
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
364 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
365 return false;
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
366 }
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
367
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
368 void DocumentManager::makePolygonCacheForModel(const ModelId modelId)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
369 {
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
370 Model* model = this->getModelById(modelId);
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
371 if (model != nullptr)
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
372 {
193
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
373 this->polygonCaches[modelId] = {};
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
374 connect(model, &Model::dataChanged, this, &DocumentManager::modelModified);
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
375 connect(model, &Model::rowsInserted, this, &DocumentManager::modelModified);
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
376 connect(model, &Model::rowsRemoved, this, &DocumentManager::modelModified);
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
377 }
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
378 }
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
379
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
380 void DocumentManager::modelModified()
b4beff48bb7a Simplify PolygonCache
Teemu Piippo <teemu@hecknology.net>
parents: 176
diff changeset
381 {
195
6e79c1cb83e6 added a missing const
Teemu Piippo <teemu@hecknology.net>
parents: 194
diff changeset
382 Model* const model = qobject_cast<Model*>(this->sender());
194
be056e87c8ca simplify further
Teemu Piippo <teemu@hecknology.net>
parents: 193
diff changeset
383 const std::optional<ModelId> modelId = this->findIdForModel(model);
be056e87c8ca simplify further
Teemu Piippo <teemu@hecknology.net>
parents: 193
diff changeset
384 if (modelId.has_value()) {
be056e87c8ca simplify further
Teemu Piippo <teemu@hecknology.net>
parents: 193
diff changeset
385 this->polygonCaches[*modelId].needRecache = true;
150
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
386 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
387 }
b6cbba6e29a1 extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents: 148
diff changeset
388
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
389 static QString findFile(QString referenceName, const QString& path, const LibraryManager& libraries)
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
390 {
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
391 // 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
392 referenceName.replace("\\", "/");
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
393 const QDir dir = QFileInfo{path}.dir();
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
394 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
395 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
396 {
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
397 // 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
398 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
399 }
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
400 return referencedFilePath;
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
401 }
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
402
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
403 void DocumentManager::loadDependenciesForModel(
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
404 const ModelId modelId,
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
405 const QString &path,
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
406 LoadDepedenciesBag& bag)
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
407 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
408 QSet<QString> failedToOpen;
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
409 struct LoadingError
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
410 {
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
411 QString message;
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
412 };
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
413 bag.processed.insert(modelId);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
414 if (not this->openModels.contains(modelId))
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
415 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
416 bag.errorStream << tr("bad model ID %1").arg(modelId.value);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
417 return;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
418 }
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
419 ModelInfo& modelInfo = this->openModels[modelId];
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
420 modelInfo.dependencies.clear();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
421 for (int i = 0; i < modelInfo.model->size(); i += 1)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
422 {
151
e628fc2e0c72 Clean up Model
Teemu Piippo <teemu@hecknology.net>
parents: 150
diff changeset
423 const QString referenceName = (*modelInfo.model)[i]->getProperty(ldraw::Property::ReferenceName).toString();
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
424 if (not referenceName.isEmpty()
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
425 and modelInfo.dependencies.count(referenceName) == 0
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
426 and not failedToOpen.contains(referenceName))
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
427 {
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
428 try
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
429 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
430 const QString referencedFilePath = ::findFile(referenceName, path, bag.libraries);
23
3387a84ddaba fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
431 if (referencedFilePath.isEmpty())
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
432 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
433 throw LoadingError{tr("could not find '%1'").arg(referenceName)};
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
434 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
435 QString loadErrorString;
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
436 QTextStream localErrorStream{&loadErrorString};
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
437 const std::optional<ModelId> modelIdOpt = this->openModel(
147
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
438 referencedFilePath,
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
439 localErrorStream,
Teemu Piippo <teemu@hecknology.net>
parents: 140
diff changeset
440 OpenType::AutomaticallyOpened);
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
441 if (not modelIdOpt.has_value())
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
442 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
443 const QString& errorMessage = tr("could not load '%1': %2")
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
444 .arg(referencedFilePath)
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
445 .arg(loadErrorString);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
446 throw LoadingError{errorMessage};
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
447 }
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
448 modelInfo.dependencies[referenceName] = modelIdOpt.value();
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
449 if (not bag.processed.contains(modelIdOpt.value()))
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
450 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
451 this->loadDependenciesForModel(modelIdOpt.value(), referencedFilePath, bag);
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
452 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
453 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
454 catch(const LoadingError& error)
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
455 {
148
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
456 bag.errorStream << error.message << "\n";
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
457 failedToOpen.insert(referenceName);
e1ced2523cad reworking
Teemu Piippo <teemu@hecknology.net>
parents: 147
diff changeset
458 bag.missing.append(referenceName);
12
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
459 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
460 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
461 }
fe67489523b5 added dependency loading
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
462 }

mercurial