|    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 				} |