339 }; |
339 }; |
340 QObject::connect(model, &QTextDocument::contentsChanged, modelModified); |
340 QObject::connect(model, &QTextDocument::contentsChanged, modelModified); |
341 } |
341 } |
342 } |
342 } |
343 |
343 |
344 static QString findFile( |
344 static QFileInfo findFile( |
345 QString referenceName, |
345 QString referenceName, |
346 const QString& modelPath, |
346 const QString& modelPath, |
347 const LibrariesModel& libraries) |
347 const LibrariesModel& libraries) |
348 { |
348 { |
349 // Try to find the file in the same place as the model itself |
349 // Try to find the file in the same place as the model itself |
350 referenceName.replace("\\", "/"); |
350 referenceName.replace("\\", "/"); |
351 const QDir dir = QFileInfo{modelPath}.dir(); |
351 const QDir dir = QFileInfo{modelPath}.dir(); |
352 QString referencedFilePath = dir.filePath(referenceName); |
352 QFileInfo referencedFilePath = {dir.filePath(referenceName)}; |
353 if (not QFileInfo{referencedFilePath}.exists()) |
353 if (not referencedFilePath.exists()) |
354 { |
354 { |
355 // Look for it in the libraries |
355 // Look for it in the libraries |
356 referencedFilePath = libraries.findFile(referenceName); |
356 referencedFilePath = libraries.findFile(referenceName); |
357 } |
357 } |
358 return referencedFilePath; |
358 return referencedFilePath; |
371 } |
371 } |
372 |
372 |
373 struct Dependency |
373 struct Dependency |
374 { |
374 { |
375 QString name; |
375 QString name; |
376 QString path; |
376 QFileInfo path; |
377 bool operator<(const Dependency& other) const |
377 bool operator<(const Dependency& other) const |
378 { |
378 { |
379 if (this->name != other.name) { |
379 if (this->name != other.name) { |
380 return this->name < other.name; |
380 return this->name < other.name; |
381 } |
381 } |
382 else { |
382 else { |
383 return this->path < other.path; |
383 return this->path.absoluteFilePath() < other.path.absoluteFilePath(); |
384 } |
384 } |
385 } |
385 } |
386 }; |
386 }; |
387 |
387 |
388 static std::set<Dependency> resolveReferencePaths( |
388 static std::set<Dependency> resolveReferencePaths( |
391 { |
391 { |
392 std::set<Dependency> result; |
392 std::set<Dependency> result; |
393 const std::set<QString> refNames = referenceNames(modelInfo->model.get()); |
393 const std::set<QString> refNames = referenceNames(modelInfo->model.get()); |
394 if (modelInfo != nullptr) { |
394 if (modelInfo != nullptr) { |
395 for (const QString& name : refNames) { |
395 for (const QString& name : refNames) { |
396 const QString path = findFile(name, modelInfo->path, *libraries); |
396 const QFileInfo path = findFile(name, modelInfo->path, *libraries); |
397 if (not path.isEmpty()) { |
397 if (path.exists()) |
|
398 { |
398 result.insert(Dependency{.name = name, .path = path}); |
399 result.insert(Dependency{.name = name, .path = path}); |
399 } |
400 } |
400 } |
401 } |
401 } |
402 } |
402 return result; |
403 return result; |
417 for (const Dependency& dep : dependencies) { |
418 for (const Dependency& dep : dependencies) { |
418 const ModelId* const idp = findInMap(olddeps, dep.name); |
419 const ModelId* const idp = findInMap(olddeps, dep.name); |
419 if (idp != nullptr) { |
420 if (idp != nullptr) { |
420 info->dependencies[dep.name] = *idp; |
421 info->dependencies[dep.name] = *idp; |
421 } |
422 } |
422 else if (not info->dependencies.contains(dep.name) and not missing.contains(dep.path)) { |
423 else if (not info->dependencies.contains(dep.name) and not missing.contains(dep.path.absoluteFilePath())) { |
423 QString loadErrorString; |
424 QString loadErrorString; |
424 QTextStream localErrorStream{&loadErrorString}; |
425 QTextStream localErrorStream{&loadErrorString}; |
425 const std::optional<ModelId> modelIdOpt = documents->openModel( |
426 const std::optional<ModelId> modelIdOpt = documents->openModel( |
426 dep.path, |
427 dep.path.absoluteFilePath(), |
427 localErrorStream, |
428 localErrorStream, |
428 OpenType::AutomaticallyOpened); |
429 OpenType::AutomaticallyOpened); |
429 if (not modelIdOpt.has_value()) { |
430 if (not modelIdOpt.has_value()) { |
430 const QString& errorMessage = QObject::tr("could not load '%1': %2") |
431 const QString& errorMessage = QObject::tr("could not load '%1': %2") |
431 .arg(dep.path, loadErrorString); |
432 .arg(dep.path.absoluteFilePath(), loadErrorString); |
432 missing[dep.path] = errorMessage; |
433 missing[dep.path.absoluteFilePath()] = errorMessage; |
433 } |
434 } |
434 else { |
435 else { |
435 info->dependencies[dep.name] = modelIdOpt.value(); |
436 info->dependencies[dep.name] = modelIdOpt.value(); |
436 repeat = true; |
437 repeat = true; |
437 } |
438 } |