| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <QDirIterator> |
| | #include <QFileInfo> |
| | #include <QVector> |
| |
|
| |
|
| |
|
| | #include <App/Application.h> |
| |
|
| | #include "MaterialFilter.h" |
| | #include "MaterialLibrary.h" |
| | #include "MaterialLoader.h" |
| | #include "MaterialManager.h" |
| | #include "Materials.h" |
| | #include "ModelManager.h" |
| |
|
| |
|
| | using namespace Materials; |
| |
|
| | |
| |
|
| | TYPESYSTEM_SOURCE(Materials::MaterialLibrary, Base::BaseClass) |
| |
|
| | MaterialLibrary::MaterialLibrary(const QString& libraryName, const QString& icon, bool readOnly) |
| | : Library(libraryName, icon, readOnly) |
| | {} |
| |
|
| | MaterialLibrary::MaterialLibrary(const QString& libraryName, |
| | const QString& dir, |
| | const QString& icon, |
| | bool readOnly) |
| | : Library(libraryName, dir, icon, readOnly) |
| | {} |
| |
|
| | MaterialLibrary::MaterialLibrary(const Library& library) |
| | : Library(library) |
| | {} |
| |
|
| | std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> |
| | MaterialLibrary::getMaterialTree(const Materials::MaterialFilter& filter, |
| | const Materials::MaterialFilterOptions& options) const |
| | { |
| | std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> materialTree = |
| | std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>(); |
| |
|
| | auto materials = MaterialManager::getManager().libraryMaterials(getName(), filter, options, isLocal()); |
| | for (auto& it : *materials) { |
| | auto uuid = it.getUUID(); |
| | auto path = it.getPath(); |
| | auto filename = it.getName(); |
| |
|
| | QStringList list = path.split(QStringLiteral("/")); |
| |
|
| | |
| | std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> node = |
| | materialTree; |
| | for (auto& itp : list) { |
| | if (!itp.isEmpty()) { |
| | |
| | if (!node->contains(itp)) { |
| | auto mapPtr = std::make_shared< |
| | std::map<QString, std::shared_ptr<MaterialTreeNode>>>(); |
| | std::shared_ptr<MaterialTreeNode> child = |
| | std::make_shared<MaterialTreeNode>(); |
| | child->setFolder(mapPtr); |
| | child->setReadOnly(isReadOnly()); |
| | (*node)[itp] = child; |
| | node = mapPtr; |
| | } |
| | else { |
| | node = (*node)[itp]->getFolder(); |
| | } |
| | } |
| | } |
| | std::shared_ptr<MaterialTreeNode> child = std::make_shared<MaterialTreeNode>(); |
| | child->setUUID(uuid); |
| | child->setReadOnly(isReadOnly()); |
| | if (isLocal()) { |
| | auto material = MaterialManager::getManager().getMaterial(uuid); |
| | child->setOldFormat(material->isOldFormat()); |
| | } |
| | (*node)[filename] = child; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | return materialTree; |
| | } |
| |
|
| | |
| |
|
| | TYPESYSTEM_SOURCE(Materials::MaterialLibraryLocal, Materials::MaterialLibrary) |
| |
|
| | MaterialLibraryLocal::MaterialLibraryLocal(const QString& libraryName, |
| | const QString& dir, |
| | const QString& icon, |
| | bool readOnly) |
| | : MaterialLibrary(libraryName, dir, icon, readOnly) |
| | , _materialPathMap(std::make_unique<std::map<QString, std::shared_ptr<Material>>>()) |
| | { |
| | setLocal(true); |
| | } |
| |
|
| | void MaterialLibraryLocal::createFolder(const QString& path) |
| | { |
| | QString filePath = getLocalPath(path); |
| |
|
| | QDir fileDir(filePath); |
| | if (!fileDir.exists()) { |
| | if (!fileDir.mkpath(filePath)) { |
| | Base::Console().error("Unable to create directory path '%s'\n", |
| | filePath.toStdString().c_str()); |
| | } |
| | } |
| | } |
| |
|
| | void MaterialLibraryLocal::renameFolder(const QString& oldPath, const QString& newPath) |
| | { |
| | QString filePath = getLocalPath(oldPath); |
| | QString newFilePath = getLocalPath(newPath); |
| |
|
| | QDir fileDir(filePath); |
| | if (fileDir.exists()) { |
| | if (!fileDir.rename(filePath, newFilePath)) { |
| | Base::Console().error("Unable to rename directory path '%s'\n", |
| | filePath.toStdString().c_str()); |
| | } |
| | } |
| |
|
| | updatePaths(oldPath, newPath); |
| | } |
| |
|
| | void MaterialLibraryLocal::deleteRecursive(const QString& path) |
| | { |
| | if (isRoot(path)) { |
| | return; |
| | } |
| |
|
| | QString filePath = getLocalPath(path); |
| | auto& manager = MaterialManager::getManager(); |
| |
|
| | QFileInfo info(filePath); |
| | if (info.isDir()) { |
| | deleteDir(manager, filePath); |
| | } |
| | else { |
| | deleteFile(manager, filePath); |
| | } |
| | } |
| |
|
| | |
| | void MaterialLibraryLocal::deleteDir(MaterialManager& manager, const QString& path) |
| | { |
| | |
| | QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); |
| |
|
| | |
| | QVector<QString> dirList; |
| | QVector<QString> fileList; |
| | while (it.hasNext()) { |
| | auto pathname = it.next(); |
| | QFileInfo file(pathname); |
| | if (file.isFile()) { |
| | fileList.push_back(pathname); |
| | } |
| | else if (file.isDir()) { |
| | dirList.push_back(pathname); |
| | } |
| | } |
| |
|
| | |
| | while (!dirList.isEmpty()) { |
| | QString dirPath = dirList.takeFirst(); |
| | deleteDir(manager, dirPath); |
| | } |
| |
|
| | |
| | while (!fileList.isEmpty()) { |
| | QString filePath = fileList.takeFirst(); |
| | deleteFile(manager, filePath); |
| | } |
| |
|
| | |
| | QDir dir; |
| | if (!dir.rmdir(path)) { |
| | throw DeleteError(path); |
| | } |
| | } |
| |
|
| | |
| | void MaterialLibraryLocal::deleteFile(MaterialManager& manager, const QString& path) |
| | { |
| | if (QFile::remove(path)) { |
| | |
| | QString rPath = getRelativePath(path); |
| | try { |
| | auto material = getMaterialByPath(rPath); |
| | manager.remove(material->getUUID()); |
| | } |
| | catch (const MaterialNotFound&) { |
| | Base::Console().log("Unable to remove file from materials list\n"); |
| | } |
| | _materialPathMap->erase(rPath); |
| | } |
| | else { |
| | QString error = QStringLiteral("DeleteError: Unable to delete ") + path; |
| | throw DeleteError(error); |
| | } |
| | } |
| |
|
| | void MaterialLibraryLocal::updatePaths(const QString& oldPath, const QString& newPath) |
| | { |
| | |
| | QString op = getRelativePath(oldPath); |
| | QString np = getRelativePath(newPath); |
| | std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> pathMap = |
| | std::make_unique<std::map<QString, std::shared_ptr<Material>>>(); |
| | for (auto& itp : *_materialPathMap) { |
| | QString path = itp.first; |
| | if (path.startsWith(op)) { |
| | path = np + path.remove(0, op.size()); |
| | } |
| | itp.second->setDirectory(path); |
| | (*pathMap)[path] = itp.second; |
| | } |
| |
|
| | _materialPathMap = std::move(pathMap); |
| | } |
| |
|
| | std::shared_ptr<Material> |
| | MaterialLibraryLocal::saveMaterial(const std::shared_ptr<Material>& material, |
| | const QString& path, |
| | bool overwrite, |
| | bool saveAsCopy, |
| | bool saveInherited) |
| | { |
| | QString filePath = getLocalPath(path); |
| | QFile file(filePath); |
| |
|
| | QFileInfo info(file); |
| | QDir fileDir(info.path()); |
| | if (!fileDir.exists()) { |
| | if (!fileDir.mkpath(info.path())) { |
| | Base::Console().error("Unable to create directory path '%s'\n", |
| | info.path().toStdString().c_str()); |
| | } |
| | } |
| |
|
| | if (info.exists()) { |
| | if (!overwrite) { |
| | Base::Console().error("File already exists '%s'\n", info.path().toStdString().c_str()); |
| | throw MaterialExists(); |
| | } |
| | } |
| |
|
| | if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { |
| | QTextStream stream(&file); |
| | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) |
| | stream.setCodec("UTF-8"); |
| | #endif |
| | stream.setGenerateByteOrderMark(true); |
| |
|
| | |
| | material->setName(info.fileName().remove(QStringLiteral(".FCMat"), Qt::CaseInsensitive)); |
| | material->setLibrary(getptr()); |
| | material->setDirectory(getRelativePath(path)); |
| | material->save(stream, overwrite, saveAsCopy, saveInherited); |
| | } |
| |
|
| | return addMaterial(material, path); |
| | } |
| |
|
| | bool MaterialLibraryLocal::fileExists(const QString& path) const |
| | { |
| | QString filePath = getLocalPath(path); |
| | QFileInfo info(filePath); |
| |
|
| | return info.exists(); |
| | } |
| |
|
| | std::shared_ptr<Material> |
| | MaterialLibraryLocal::addMaterial(const std::shared_ptr<Material>& material, const QString& path) |
| | { |
| | QString filePath = getRelativePath(path); |
| | QFileInfo info(filePath); |
| | std::shared_ptr<Material> newMaterial = std::make_shared<Material>(*material); |
| | newMaterial->setLibrary(getptr()); |
| | newMaterial->setDirectory(getLibraryPath(filePath, info.fileName())); |
| | newMaterial->setFilename(info.fileName()); |
| |
|
| | (*_materialPathMap)[filePath] = newMaterial; |
| |
|
| | return newMaterial; |
| | } |
| |
|
| | std::shared_ptr<Material> MaterialLibraryLocal::getMaterialByPath(const QString& path) const |
| | { |
| | QString filePath = getRelativePath(path); |
| |
|
| | auto search = _materialPathMap->find(filePath); |
| | if (search != _materialPathMap->end()) { |
| | return search->second; |
| | } |
| |
|
| | throw MaterialNotFound(); |
| | } |
| |
|
| | QString MaterialLibraryLocal::getUUIDFromPath(const QString& path) const |
| | { |
| | QString filePath = getRelativePath(path); |
| |
|
| | auto search = _materialPathMap->find(filePath); |
| | if (search != _materialPathMap->end()) { |
| | return search->second->getUUID(); |
| | } |
| |
|
| | throw MaterialNotFound(); |
| | } |
| |
|