src/documentmanager.cpp

changeset 147
37f936073cac
parent 140
2f383e88acf4
child 148
e1ced2523cad
--- a/src/documentmanager.cpp	Tue Sep 28 23:09:09 2021 +0300
+++ b/src/documentmanager.cpp	Sun Oct 24 11:33:32 2021 +0300
@@ -22,6 +22,7 @@
 #include "documentmanager.h"
 #include "modeleditcontext.h"
 #include "linetypes/comment.h"
+#include "linetypes/subfilereference.h"
 #include "parser.h"
 
 /**
@@ -59,7 +60,7 @@
 	}
 	else
 	{
-		return iterator->second.get();
+		return iterator->second.model.get();
 	}
 }
 
@@ -84,7 +85,14 @@
 	return result;
 }
 
-QString DocumentManager::openModel(const QString& path, QTextStream& errorStream)
+/**
+ * @brief Tries to open the model at the specified path
+ * @param path Path to the model to open
+ * @param errorStream Where to write any errors
+ * @param openType rationale behind opening this file
+ * @returns file name or "" on error
+ */
+QString DocumentManager::openModel(const QString& path, QTextStream& errorStream, const OpenType openType)
 {
 	QFile file{path};
 	const QString name = pathToName(path);
@@ -97,7 +105,7 @@
 	QString result;
 	if (file.error() == QFile::NoError)
 	{
-		openModels[name] = std::move(newModel);
+		openModels[name] = {std::move(newModel), openType};
 		result = name;
 	}
 	else
@@ -131,6 +139,43 @@
 	}
 }
 
+void DocumentManager::closeDocument(const QString &name)
+{
+	const auto& it = this->openModels.find(name);
+	if (it != this->openModels.end())
+	{
+		this->openModels.erase(it);
+	}
+	QSet<QString> referenced;
+	for (const auto& it : this->openModels)
+	{
+		if (it.second.opentype == OpenType::ManuallyOpened)
+		{
+			this->collectReferences(referenced, it.first, it.second.model.get());
+		}
+	}
+	
+}
+
+void DocumentManager::collectReferences(QSet<QString>& referenced, const QString &name, const Model *model)
+{
+	if (not referenced.contains(name))
+	{
+		referenced.insert(name);
+		model->apply<ldraw::SubfileReference>([&](const ldraw::SubfileReference* referenceObject)
+		{
+			const ldraw::id_t id = referenceObject->id;
+			const QString& referenceName = model->getObjectProperty<ldraw::Property::ReferenceName>(id);
+			auto it = this->openModels.find(referenceName);
+			if (it != this->openModels.end())
+			{
+				const Model* const model = it->second.model.get();
+				this->collectReferences(referenced, referenceName, model);
+			}
+		});
+	}
+}
+
 static QString findFile(QString referenceName, const QString& path, const LibraryManager& libraries)
 {
 	// Try to find the file in the same place as the model itself
@@ -175,7 +220,10 @@
 				}
 				QString errorString;
 				QTextStream localErrorStream{&errorString};
-				QString resultName = this->openModel(referencedFilePath, localErrorStream);
+				QString resultName = this->openModel(
+					referencedFilePath,
+					localErrorStream,
+					OpenType::AutomaticallyOpened);
 				if (resultName.isEmpty())
 				{
 					throw LoadingError{utility::format(

mercurial