Wed, 01 Jan 2020 17:45:56 +0200
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); } } } }