src/librarycollection.cpp

Thu, 29 Mar 2018 12:09:05 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 29 Mar 2018 12:09:05 +0300
changeset 1360
c20bd2837e9d
parent 1212
851ab72bb850
permissions
-rw-r--r--

Branch close

/*
 *  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, bool frozen)
{
	_libraries.emplace_back(dir, name, frozen);
}

/*
 * Searches the libraries for a file by relative path.
 */
QString LibraryCollection::find(QString relativePath) const
{
	// LDraw uses backslashes for directory separators. We need to convert them to forward
	// slashes so that Qt understands them on all platforms.
	relativePath.replace('\\', '/');

	for (const Library& library : _libraries)
	{
		for (const QString& directoryName : directoryNames)
		{
			QDir dir = library.path();

			if (dir.exists() and dir.cd(directoryName) and dir.exists(relativePath))
				return QDir::cleanPath(dir.absoluteFilePath(relativePath));
		}
	}

	return "";
}

/*
 * Searches the libraries for a file. This overload takes the parameters of a FileSpec and
 * calls another overload with a ready spec.
 */
QString LibraryCollection::find(const QString &name, Library::FileType type) const
{
	return find(FileSpec {name, type});
}

/*
 * Searches the libraries for a file by the given file specification. The type attribute
 * specifies what kind of file we are looking for.
 */
QString LibraryCollection::find(const FileSpec& spec) const
{
	for (const Library& library : _libraries)
	{
		try
		{
			QDir subdirectory = library.subdirectory(spec.type);
			if (subdirectory.exists(spec.name))
				return QDir::cleanPath(subdirectory.absoluteFilePath(spec.name));
		}
		catch (Library::SubdirectoryNotFoundError&) {}
	}

	return "";
}

/*
 * Constructs a new library.
 */
Library::Library(const QDir& path, const QString& name, bool frozen) :
    _path {path},
    _name {name},
    _frozen {frozen} {}

/*
 * Returns the appropriate subdirectory for the given file type.
 */
QDir Library::subdirectory(FileType type) const
{
	QString subdirectory = subdirectoryName(type);

	if (path().exists(subdirectory))
		return path().absolutePath() + "/" + subdirectory;
	else
		throw SubdirectoryNotFoundError {};
}

/*
 * Returns the appropriate subdirectory name for the given file type.
 */
QString Library::subdirectoryName(FileType type)
{
	switch (type)
	{
	case Part:
		return "/parts/";

	case Subpart:
		return "/parts/s/";

	case Primitive:
		return "/p/";

	case HighResolutionPrimitive:
		return "/p/48/";

	case LowResolutionPrimitive:
		return "/p/8/";
	}

	return "";
}

QDir Library::path() const
{
	return _path;
}

std::vector<Library>::iterator LibraryCollection::begin()
{
	return _libraries.begin();
}

std::vector<Library>::iterator LibraryCollection::end()
{
	return _libraries.end();
}

LibraryCollectionTableModel::LibraryCollectionTableModel(LibraryCollection& collection, QObject* parent) :
    QAbstractTableModel {parent},
    _collection {collection}
{

}

mercurial