src/documentmanager.cpp

Wed, 01 Jan 2020 17:45:56 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 01 Jan 2020 17:45:56 +0200
changeset 21
0133e565e072
parent 17
a5111f4e6412
child 23
3387a84ddaba
permissions
-rw-r--r--

things

#include <QFile>
#include <QDir>
#include <QFileInfo>
#include "documentmanager.h"
#include "modeleditcontext.h"
#include "linetypes/comment.h"
#include "parser.h"

/**
 * @brief Constructs a new document manager
 * @param parent Parent object
 */
DocumentManager::DocumentManager(QObject* parent) :
	QObject{parent}
{
}

/**
 * @brief Creates a new model.
 * @returns the name to the new model
 */
QString DocumentManager::newModel()
{
	const QString name = makeNewModelName();
	this->openModels.emplace(name, new Model);
	return name;
}

/**
 * @brief Looks for a model by name
 * @param name Name of the model
 * @returns model or null
 * '
 */
Model* DocumentManager::findModelByName(const QString& name)
{
	const auto iterator = this->openModels.find(name);
	if (iterator == std::end(this->openModels))
	{
		return nullptr;
	}
	else
	{
		return iterator->second.get();
	}
}

QString pathToName(const QFileInfo& path)
{
	static const char* paths[] = {
		"s",
		"48"
		"8"
	};
	const QString baseName = path.fileName();
	const QString dirName = QFileInfo{path.dir().path()}.fileName();
	QString result;
	if (std::find(std::begin(paths), std::end(paths), dirName) != std::end(paths))
	{
		result = dirName + "\\" + baseName;
	}
	else
	{
		result = baseName;
	}
	return result;
}

QString DocumentManager::openModel(const QString& path, QTextStream& errorStream)
{
	QFile file{path};
	const QString name = pathToName(path);
	file.open(QFile::ReadOnly | QFile::Text);
	std::unique_ptr<Model> newModel = std::make_unique<Model>();
	QTextStream textStream{&file};
	Model::EditContext editor = newModel->edit();
	Parser parser{file};
	parser.parseBody(editor);
	QString result;
	if (file.error() == QFile::NoError)
	{
		openModels[name] = std::move(newModel);
		result = name;
	}
	else
	{
		errorStream << file.errorString();
	}
	return result;
}

QString DocumentManager::makeNewModelName()
{
	untitledNameCounter += 1;
	return "untitled-" + QString::number(untitledNameCounter);
}

void DocumentManager::loadDependenciesForModel(
	const QString& modelName,
	const LibraryManager& libraries,
	QTextStream& errorStream)
{
	QStringList missing;
	QStringList processed;
	loadDependenciesForModel(modelName, libraries, missing, processed, errorStream);
	if (not missing.empty())
	{
		missing.sort(Qt::CaseInsensitive);
		errorStream << utility::format(
			"The following files could not be opened: %1",
			missing.join(", "));
	}
}

void DocumentManager::loadDependenciesForModel(
	const QString& modelName,
	const LibraryManager& libraries,
	QStringList& missing,
	QStringList& processed,
	QTextStream& errorStream)
{
	struct LoadingError
	{
		QString message;
	};
	processed.append(modelName);
	Model* model = this->findModelByName(modelName);
	for (int i = 0; i < model->size(); i += 1)
	{
		const QString referenceName = model->getObjectProperty(i, linetypes::Property::ReferenceName).toString();
		if (not referenceName.isEmpty()
			and openModels.find(referenceName) == std::end(openModels)
			and not missing.contains(referenceName))
		{
			try
			{
				const QString path = libraries.findFile(referenceName);
				if (path.isEmpty())
				{
					throw LoadingError{utility::format("'%1' was not found.", referenceName)};
				}
				QString errorString;
				QTextStream localErrorStream{&errorString};
				QString resultName = this->openModel(path, localErrorStream);
				if (resultName.isEmpty())
				{
					throw LoadingError{utility::format(
						"could not load '%1': %2",
						path,
						errorString)};
				}
				if (not processed.contains(referenceName))
				{
					loadDependenciesForModel(referenceName, libraries, missing, processed, errorStream);
				}
			}
			catch(const LoadingError& error)
			{
				errorStream << error.message << "\n";
				missing.append(referenceName);
				processed.append(referenceName);
			}
		}
	}
}

mercurial