# HG changeset patch # User Teemu Piippo # Date 1572796641 -7200 # Node ID fe67489523b5f0207964b437aba9e5cb1fd13c85 # Parent 771168ee2c766a98c771be26133e36fb56aae5db added dependency loading diff -r 771168ee2c76 -r fe67489523b5 locale/fi.ts --- a/locale/fi.ts Sun Nov 03 13:18:55 2019 +0200 +++ b/locale/fi.ts Sun Nov 03 17:57:21 2019 +0200 @@ -1,9 +1,10 @@ - + Document + Form @@ -11,50 +12,62 @@ LibrariesEditor + Form + + Add + Browse LDraw library + Library does not exist + The directory %1 does not exist. + Unreadable library + The directory %1 cannot be read. + Remove library + Set role + Move up + Move down @@ -62,22 +75,27 @@ LibraryManager + Official library + Unofficial library + Working library + Path + Role @@ -85,85 +103,106 @@ MainWindow - File - Tiedosto - - - Quit - Poistu - - - Open… - Avaa... - - - Ctrl+O - Ctrl+O - - - New - Uusi - - - Ctrl+N - Ctrl+N - - - Language - Kieli - - - Open model - Avaa malli - - - LDraw models (*.ldr *.dat) - LDraw-mallit (*.ldr *.dat) - - - Problem opening file - Ongelma tiedoston avaamisessa - - - Could not open %1: %2 - Ei voitu avata %1: %2 - - + LDForge + + File + + + + Recent files + + Quit + + + + + Open… + + + + + Ctrl+O + + + + + New + + + + + Ctrl+N + + + + Preferences… + + + Open model + + + + + LDraw models (*.ldr *.dat) + + + + + Problem loading references + + + + + Problem opening file + + + + + Could not open %1: %2 + + SettingsEditor + Dialog + General + Language: + + System language + English + LDraw parts libraries diff -r 771168ee2c76 -r fe67489523b5 locale/sv.ts --- a/locale/sv.ts Sun Nov 03 13:18:55 2019 +0200 +++ b/locale/sv.ts Sun Nov 03 17:57:21 2019 +0200 @@ -193,6 +193,10 @@ Recent files + + Problem loading references + + SettingsEditor diff -r 771168ee2c76 -r fe67489523b5 src/documentmanager.cpp --- a/src/documentmanager.cpp Sun Nov 03 13:18:55 2019 +0200 +++ b/src/documentmanager.cpp Sun Nov 03 17:57:21 2019 +0200 @@ -94,3 +94,72 @@ 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, modelobjects::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); + } + } + } +} diff -r 771168ee2c76 -r fe67489523b5 src/documentmanager.h --- a/src/documentmanager.h Sun Nov 03 13:18:55 2019 +0200 +++ b/src/documentmanager.h Sun Nov 03 17:57:21 2019 +0200 @@ -1,5 +1,5 @@ #pragma once -#include "main.h" +#include "libraries.h" #include "model.h" class DocumentManager : public QObject @@ -16,7 +16,15 @@ Model* findModelByName(const QString& name); QString openModel(const QString& path, QTextStream& errorStream); QString makeNewModelName(); + void loadDependenciesForModel(const QString& modelName, + const LibraryManager& libraries, + QTextStream& errorStream); private: int untitledNameCounter = 0; std::map openModels; + void loadDependenciesForModel(const QString& modelName, + const LibraryManager& libraries, + QStringList& missing, + QStringList& processed, + QTextStream& errorStream); }; diff -r 771168ee2c76 -r fe67489523b5 src/libraries.cpp --- a/src/libraries.cpp Sun Nov 03 13:18:55 2019 +0200 +++ b/src/libraries.cpp Sun Nov 03 17:57:21 2019 +0200 @@ -44,22 +44,30 @@ * @param fileName File to search for * @return Full path to the file, or empty string if not found. */ -QFileInfo LibraryManager::findFile(QString fileName) const +QString LibraryManager::findFile(QString fileName) const { - QFileInfo path; + QString path; fileName.replace("\\", "/"); bool found = false; for (const Library& library : this->libraries) { - path = library.path.absoluteFilePath(fileName); - if (path.exists() && path.isFile()) + for (const QString& subdirectory : {"parts", "p"}) { - found = true; + QDir directory = library.path; + directory.cd(subdirectory); + QFileInfo fileInfo = directory.absoluteFilePath(fileName); + if (fileInfo.exists() && fileInfo.isFile()) + { + path = fileInfo.absoluteFilePath(); + found = true; + break; + } + } + if (found) + { break; } } - if (not found) - path = {}; return path; } diff -r 771168ee2c76 -r fe67489523b5 src/libraries.h --- a/src/libraries.h Sun Nov 03 13:18:55 2019 +0200 +++ b/src/libraries.h Sun Nov 03 17:57:21 2019 +0200 @@ -35,7 +35,7 @@ LibraryManager(QSettings* settings, QObject* parent = nullptr); QVector::const_iterator begin() const; QVector::const_iterator end() const; - QFileInfo findFile(QString fileName) const; + QString findFile(QString fileName) const; void addLibrary(const Library& library); void removeLibrary(const int libraryIndex); const Library& library(int libraryIndex) const; diff -r 771168ee2c76 -r fe67489523b5 src/mainwindow.cpp --- a/src/mainwindow.cpp Sun Nov 03 13:18:55 2019 +0200 +++ b/src/mainwindow.cpp Sun Nov 03 17:57:21 2019 +0200 @@ -55,6 +55,14 @@ QString modelName = this->documents.openModel(path, errorStream); if (not modelName.isEmpty()) { + this->documents.loadDependenciesForModel(modelName, this->libraries, errorStream); + if (not errorString.isEmpty()) + { + QMessageBox::warning( + this, + tr("Problem loading references"), + errorString); + } this->openModelForEditing(modelName); this->addRecentlyOpenedFile(path); } diff -r 771168ee2c76 -r fe67489523b5 src/model.cpp --- a/src/model.cpp Sun Nov 03 13:18:55 2019 +0200 +++ b/src/model.cpp Sun Nov 03 17:57:21 2019 +0200 @@ -53,6 +53,12 @@ } } +QVariant Model::getObjectProperty(const int index, const modelobjects::Property property) const +{ + const modelobjects::BaseObject* object = this->body[index].get(); + return object->getProperty(property); +} + void Model::append(ModelObjectPointer&& object) { this->body.push_back(std::move(object)); diff -r 771168ee2c76 -r fe67489523b5 src/model.h --- a/src/model.h Sun Nov 03 13:18:55 2019 +0200 +++ b/src/model.h Sun Nov 03 17:57:21 2019 +0200 @@ -23,6 +23,7 @@ QVariant data(const QModelIndex& index, int role) const override; QVariant getHeaderProperty(const HeaderProperty property); const QString& getName() const; + QVariant getObjectProperty(const int index, const modelobjects::Property property) const; signals: void objectAdded(modelobjects::Id id, int position); private: diff -r 771168ee2c76 -r fe67489523b5 src/parser.cpp --- a/src/parser.cpp Sun Nov 03 13:18:55 2019 +0200 +++ b/src/parser.cpp Sun Nov 03 17:57:21 2019 +0200 @@ -380,7 +380,7 @@ try { const QStringList tokens = line.split(QRegExp{R"(\s+)"}); - if (tokens.empty()) + if (tokens.empty() or tokens == QStringList{{""}}) { return std::make_unique(); }