Sun, 12 Mar 2017 11:03:44 +0200
More work on library collections
--- a/src/documentmanager.cpp Thu Mar 09 12:50:14 2017 +0200 +++ b/src/documentmanager.cpp Sun Mar 12 11:03:44 2017 +0200 @@ -39,7 +39,10 @@ m_loadingMainFile (false), m_isLoadingLogoedStuds (false), m_logoedStud (nullptr), - m_logoedStud2 (nullptr) {} + m_logoedStud2 (nullptr) +{ + m_libraries.addLibrary(configuration().lDrawPath(), "LDraw library"); +} DocumentManager::~DocumentManager() { @@ -189,85 +192,9 @@ return path; } -QString DocumentManager::findDocumentPath (QString relativePath, bool subdirs) +QString DocumentManager::findDocumentPath (QString relativePath) { - // LDraw models use backslashes as path separators. Replace those into forward slashes for Qt. - relativePath.replace ("\\", "/"); - - // Try find it relative to other currently open documents. We want a file in the immediate vicinity of a current - // part model to override stock LDraw stuff. - QString relativeTopDir = Basename (Dirname (relativePath)); - - for (LDDocument* document : m_documents) - { - QString partpath = format ("%1/%2", Dirname (document->fullPath()), relativePath); - QFileInfo fileinfo (partpath); - - if (fileinfo.exists()) - { - // Ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48 - QString partTopDir = Basename (Dirname (partpath)); - - for (QString subdir : specialSubdirectories) - { - if ((partTopDir == subdir) != (relativeTopDir == subdir)) - goto skipthis; - } - - return partpath; - } -skipthis: - continue; - } - - if (QFileInfo::exists (relativePath)) - return relativePath; - - // Try with just the LDraw path first - QString fullPath = format ("%1" DIRSLASH "%2", configuration().lDrawPath(), relativePath); - - if (QFileInfo::exists (fullPath)) - return fullPath; - - if (subdirs) - { - // Look in sub-directories: parts and p. Also look in the download path, since that's where we download parts - // from the PT to. - QStringList dirs = { configuration().lDrawPath(), configuration().downloadFilePath() }; - for (const QString& topdir : dirs) - { - for (const QString& subdir : QStringList ({ "parts", "p" })) - { - fullPath = format ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relativePath); - - if (QFile::exists (fullPath)) - return fullPath; - } - } - } - - // Did not find the file. - return ""; -} - -QFile* DocumentManager::openLDrawFile (QString relpath, bool subdirs, QString* pathpointer) -{ - print ("Opening %1...\n", relpath); - QString path = findDocumentPath (relpath, subdirs); - - if (pathpointer) - *pathpointer = path; - - if (path.isEmpty()) - return nullptr; - - QFile* fp = new QFile (path); - - if (fp->open (QIODevice::ReadOnly)) - return fp; - - fp->deleteLater(); - return nullptr; + return m_libraries.find(relativePath); } void DocumentManager::loadFileContents(QIODevice* input, Model& model, int* numWarnings, bool* ok) @@ -303,26 +230,24 @@ // Convert the file name to lowercase when searching because some parts contain subfile // subfile references with uppercase file names. I'll assume here that the library will always // use lowercase file names for the part files. - QFile* fp; QString fullpath; if (search) { - fp = openLDrawFile (path.toLower(), true, &fullpath); + print ("Opening %1...\n", path.toLower()); + fullpath = findDocumentPath(path.toLower()); + + if (fullpath.isEmpty()) + return nullptr; } else { - fp = new QFile (path); fullpath = path; - - if (not fp->open (QIODevice::ReadOnly)) - { - delete fp; - return nullptr; - } } - if (not fp) + QFile file {fullpath}; + + if (not file.open(QIODevice::ReadOnly)) return nullptr; LDDocument* load = (fileToOverride ? fileToOverride : m_window->newDocument (implicit)); @@ -335,10 +260,9 @@ int numWarnings; bool ok; Model model {this}; - loadFileContents(fp, model, &numWarnings, &ok); + loadFileContents(&file, model, &numWarnings, &ok); load->merge(model); - fp->close(); - fp->deleteLater(); + file.close(); if (aborted) *aborted = ok == false;
--- a/src/documentmanager.h Thu Mar 09 12:50:14 2017 +0200 +++ b/src/documentmanager.h Sun Mar 12 11:03:44 2017 +0200 @@ -20,6 +20,7 @@ #include <QSet> #include "main.h" #include "hierarchyelement.h" +#include "librarycollection.h" class Model; @@ -38,14 +39,14 @@ void clear(); LDDocument* createNew(); LDDocument* findDocumentByName (QString name); - QString findDocumentPath (QString relpath, bool subdirs); + QString findDocumentPath (QString relpath); LDDocument* getDocumentByName (QString filename); bool isSafeToCloseAll(); void loadFileContents(QIODevice* fp, Model& model, int* numWarnings, bool* ok); void loadLogoedStuds(); LDDocument* openDocument (QString path, bool search, bool implicit, LDDocument* fileToOverride = nullptr, bool* aborted = nullptr); - QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer); + QFile* openLDrawFile (QString relpath, QString* pathpointer); void openMainModel (QString path); bool preInline (LDDocument* doc, Model& model, bool deep, bool renderinline); @@ -58,6 +59,7 @@ Q_SLOT void printParseErrorMessage(QString message); Documents m_documents; + LibraryCollection m_libraries; bool m_loadingMainFile; bool m_isLoadingLogoedStuds; LDDocument* m_logoedStud;
--- a/src/librarycollection.cpp Thu Mar 09 12:50:14 2017 +0200 +++ b/src/librarycollection.cpp Sun Mar 12 11:03:44 2017 +0200 @@ -1,7 +1,30 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2017 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #include "librarycollection.h" const QStringList LibraryCollection::directoryNames = {"parts", "p"}; +void LibraryCollection::addLibrary(QDir dir, QString name) +{ + m_libraries.append({dir, name}); +} + /* * Searches the libraries for a file by relative path. */
--- a/src/librarycollection.h Thu Mar 09 12:50:14 2017 +0200 +++ b/src/librarycollection.h Sun Mar 12 11:03:44 2017 +0200 @@ -1,3 +1,21 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2017 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #pragma once #include <QDir> #include "main.h" @@ -24,6 +42,7 @@ FileType type; }; + void addLibrary(QDir dir, QString name); QString find(QString relativePath) const; QString find(const QString& name, FileType type) const; QString find(const FileSpec& spec) const;