src/documentmanager.cpp

changeset 1210
0b3b35f560f2
parent 1206
743dc95e0be6
child 1211
83b8ed708909
equal deleted inserted replaced
1209:c2723022b173 1210:0b3b35f560f2
37 QObject (parent), 37 QObject (parent),
38 HierarchyElement (parent), 38 HierarchyElement (parent),
39 m_loadingMainFile (false), 39 m_loadingMainFile (false),
40 m_isLoadingLogoedStuds (false), 40 m_isLoadingLogoedStuds (false),
41 m_logoedStud (nullptr), 41 m_logoedStud (nullptr),
42 m_logoedStud2 (nullptr) {} 42 m_logoedStud2 (nullptr)
43 {
44 m_libraries.addLibrary(configuration().lDrawPath(), "LDraw library");
45 }
43 46
44 DocumentManager::~DocumentManager() 47 DocumentManager::~DocumentManager()
45 { 48 {
46 clear(); 49 clear();
47 } 50 }
187 return path.mid (lastpos + 1); 190 return path.mid (lastpos + 1);
188 191
189 return path; 192 return path;
190 } 193 }
191 194
192 QString DocumentManager::findDocumentPath (QString relativePath, bool subdirs) 195 QString DocumentManager::findDocumentPath (QString relativePath)
193 { 196 {
194 // LDraw models use backslashes as path separators. Replace those into forward slashes for Qt. 197 return m_libraries.find(relativePath);
195 relativePath.replace ("\\", "/");
196
197 // Try find it relative to other currently open documents. We want a file in the immediate vicinity of a current
198 // part model to override stock LDraw stuff.
199 QString relativeTopDir = Basename (Dirname (relativePath));
200
201 for (LDDocument* document : m_documents)
202 {
203 QString partpath = format ("%1/%2", Dirname (document->fullPath()), relativePath);
204 QFileInfo fileinfo (partpath);
205
206 if (fileinfo.exists())
207 {
208 // Ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48
209 QString partTopDir = Basename (Dirname (partpath));
210
211 for (QString subdir : specialSubdirectories)
212 {
213 if ((partTopDir == subdir) != (relativeTopDir == subdir))
214 goto skipthis;
215 }
216
217 return partpath;
218 }
219 skipthis:
220 continue;
221 }
222
223 if (QFileInfo::exists (relativePath))
224 return relativePath;
225
226 // Try with just the LDraw path first
227 QString fullPath = format ("%1" DIRSLASH "%2", configuration().lDrawPath(), relativePath);
228
229 if (QFileInfo::exists (fullPath))
230 return fullPath;
231
232 if (subdirs)
233 {
234 // Look in sub-directories: parts and p. Also look in the download path, since that's where we download parts
235 // from the PT to.
236 QStringList dirs = { configuration().lDrawPath(), configuration().downloadFilePath() };
237 for (const QString& topdir : dirs)
238 {
239 for (const QString& subdir : QStringList ({ "parts", "p" }))
240 {
241 fullPath = format ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relativePath);
242
243 if (QFile::exists (fullPath))
244 return fullPath;
245 }
246 }
247 }
248
249 // Did not find the file.
250 return "";
251 }
252
253 QFile* DocumentManager::openLDrawFile (QString relpath, bool subdirs, QString* pathpointer)
254 {
255 print ("Opening %1...\n", relpath);
256 QString path = findDocumentPath (relpath, subdirs);
257
258 if (pathpointer)
259 *pathpointer = path;
260
261 if (path.isEmpty())
262 return nullptr;
263
264 QFile* fp = new QFile (path);
265
266 if (fp->open (QIODevice::ReadOnly))
267 return fp;
268
269 fp->deleteLater();
270 return nullptr;
271 } 198 }
272 199
273 void DocumentManager::loadFileContents(QIODevice* input, Model& model, int* numWarnings, bool* ok) 200 void DocumentManager::loadFileContents(QIODevice* input, Model& model, int* numWarnings, bool* ok)
274 { 201 {
275 if (numWarnings) 202 if (numWarnings)
301 bool* aborted) 228 bool* aborted)
302 { 229 {
303 // Convert the file name to lowercase when searching because some parts contain subfile 230 // Convert the file name to lowercase when searching because some parts contain subfile
304 // subfile references with uppercase file names. I'll assume here that the library will always 231 // subfile references with uppercase file names. I'll assume here that the library will always
305 // use lowercase file names for the part files. 232 // use lowercase file names for the part files.
306 QFile* fp;
307 QString fullpath; 233 QString fullpath;
308 234
309 if (search) 235 if (search)
310 { 236 {
311 fp = openLDrawFile (path.toLower(), true, &fullpath); 237 print ("Opening %1...\n", path.toLower());
238 fullpath = findDocumentPath(path.toLower());
239
240 if (fullpath.isEmpty())
241 return nullptr;
312 } 242 }
313 else 243 else
314 { 244 {
315 fp = new QFile (path);
316 fullpath = path; 245 fullpath = path;
317 246 }
318 if (not fp->open (QIODevice::ReadOnly)) 247
319 { 248 QFile file {fullpath};
320 delete fp; 249
321 return nullptr; 250 if (not file.open(QIODevice::ReadOnly))
322 }
323 }
324
325 if (not fp)
326 return nullptr; 251 return nullptr;
327 252
328 LDDocument* load = (fileToOverride ? fileToOverride : m_window->newDocument (implicit)); 253 LDDocument* load = (fileToOverride ? fileToOverride : m_window->newDocument (implicit));
329 load->setFullPath (fullpath); 254 load->setFullPath (fullpath);
330 load->setName (LDDocument::shortenName (load->fullPath())); 255 load->setName (LDDocument::shortenName (load->fullPath()));
333 load->history()->setIgnoring (true); 258 load->history()->setIgnoring (true);
334 259
335 int numWarnings; 260 int numWarnings;
336 bool ok; 261 bool ok;
337 Model model {this}; 262 Model model {this};
338 loadFileContents(fp, model, &numWarnings, &ok); 263 loadFileContents(&file, model, &numWarnings, &ok);
339 load->merge(model); 264 load->merge(model);
340 fp->close(); 265 file.close();
341 fp->deleteLater();
342 266
343 if (aborted) 267 if (aborted)
344 *aborted = ok == false; 268 *aborted = ok == false;
345 269
346 if (not ok) 270 if (not ok)

mercurial