You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp

812 lines
28 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "AssetImporterManager.h"
// Qt
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QStandardPaths>
// AzFramework
#include <AzFramework/Asset/AssetSystemBus.h>
// AzToolsFramework
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
// Editor
#include "AssetImporter/UI/FilesAlreadyExistDialog.h"
#include "AssetImporter/UI/ProcessingAssetsDialog.h"
namespace AssetImporterManagerPrivate
{
const char* g_selectFilesPath = "AssetImporter/SelectFilesPath";
const char* g_selectDestinationFilesPath = "AssetImporter/SelectDestinationFilesPath";
const char* g_errorMessageBoxTitle = "File failed to process.";
const char* g_crateError = "Crate files cannot be imported.";
static const char* s_crateFileExtension = "crate";
};
AssetImporterManager::AssetImporterManager(QWidget* parent)
: QObject(parent)
{
}
AssetImporterManager::~AssetImporterManager()
{
}
void AssetImporterManager::Exec()
{
// tell the AssetImporterDragAndDropHandler that the Asset Importer now is running
Q_EMIT StartAssetImporter();
bool success = OnBrowseFiles();
// prevent users from selecting crate files from the File Explorer and open the Asset Importer.
if (!success)
{
reject();
}
else
{
OnOpenSelectDestinationDialog();
}
}
void AssetImporterManager::Exec(const QStringList& dragAndDropFileList)
{
// note: dragging and dropping an empty folder can also trigger this condition
if (!dragAndDropFileList.isEmpty())
{
OnDragAndDropFiles(&dragAndDropFileList);
// only open the Asset Importer when the folder contains correct type files
if (!m_pathMap.isEmpty())
{
// tell the AssetImporterDragAndDropHandler that the Asset Importer now is running
Q_EMIT StartAssetImporter();
OnOpenSelectDestinationDialog();
}
else
{
reject();
}
}
}
// used to cancel actions and close the dialog
void AssetImporterManager::reject()
{
m_pathMap.clear();
m_destinationRootDirectory = "";
Q_EMIT StopAssetImporter();
}
void AssetImporterManager::OnDragAndDropFiles(const QStringList* fileList)
{
for (int i = 0; i < fileList->size(); ++i)
{
// if the list contains a crate file,
// the whole process should stop
if (!GetAndCheckAllFilesInFolder(fileList->at(i)))
{
QMessageBox::warning(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, AssetImporterManagerPrivate::g_crateError);
reject();
return;
}
}
}
bool AssetImporterManager::OnBrowseFiles()
{
QFileDialog fileDialog;
fileDialog.setFileMode(QFileDialog::ExistingFiles);
fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal);
fileDialog.setViewMode(QFileDialog::Detail);
fileDialog.setWindowTitle(tr("Select files to import"));
fileDialog.setLabelText(QFileDialog::Accept, "Select");
QSettings settings;
QString currentAbsolutePath = settings.value(AssetImporterManagerPrivate::g_selectFilesPath).toString();
QDir gameRoot(Path::GetEditingGameDataFolder().c_str());
QString gameRootAbsPath = gameRoot.absolutePath();
// Case 1: if currentAbsolutePath is empty at this point, that means this is the first time
// users using the Asset Importer, set the default directory to be users' PC's desktop.
// Case 2: if the current folder directory stored in the registry doesn't exist anymore,
// that means users have removed the directory already (deleted or use the Move feature).
// Case 3: if it's a directory under the game root folder, then in general,
// users have modified the folder directory in the registry. It should not be happening.
if (currentAbsolutePath.isEmpty() || !QFile(currentAbsolutePath).exists() || currentAbsolutePath.startsWith(gameRootAbsPath, Qt::CaseInsensitive))
{
currentAbsolutePath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
}
fileDialog.setDirectory(currentAbsolutePath);
if (!fileDialog.exec())
{
return false;
}
bool encounteredCrate = false;
QStringList invalidFiles;
for (QString path : fileDialog.selectedFiles())
{
QString fileName = GetFileName(path);
QFileInfo info(path);
QString extension = info.completeSuffix(); // extension without '.'
if (QString(AssetImporterManagerPrivate::s_crateFileExtension).compare(extension, Qt::CaseInsensitive) != 0)
{
// prevent users from importing files under the game root directory
if (path.startsWith(gameRootAbsPath, Qt::CaseInsensitive))
{
invalidFiles << fileName;
}
else
{
// store paths into the map.
m_pathMap[path] = fileName;
}
}
else
{
encounteredCrate = true;
}
}
if (invalidFiles.size() > 0)
{
QString fileWarning = QString("Files cannot be imported into their own project. The following files will not be moved or copied:\n");
fileWarning.append(invalidFiles.join(", "));
fileWarning.append('.');
QMessageBox::warning(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, fileWarning);
}
if (encounteredCrate)
{
QMessageBox::warning(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, AssetImporterManagerPrivate::g_crateError);
}
currentAbsolutePath = fileDialog.directory().absolutePath();
settings.setValue(AssetImporterManagerPrivate::g_selectFilesPath, currentAbsolutePath);
// prevent users from selecting crate files from the File Explorer and open the Asset Importer.
return (m_pathMap.size() > 0);
}
void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLineEdit)
{
QFileDialog fileDialog;
fileDialog.setOption(QFileDialog::ShowDirsOnly, true);
fileDialog.setViewMode(QFileDialog::List);
fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal);
fileDialog.setWindowTitle(tr("Select import destination"));
QSettings settings;
QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString();
QDir gameRoot(Path::GetEditingGameDataFolder().c_str());
QString gameRootAbsPath = gameRoot.absolutePath();
// Case 1: if currentDestination is empty at this point, that means this is the first time
// users using the Asset Importer, set the default directory to be the current game project's root folder
// Case 2: if the current folder directory stored in the registry doesn't exist anymore,
// that means users have removed the directory already (deleted or use the Move feature).
// Case 3: if it's a directory outside of the game root folder, then in general,
// users have modified the folder directory in the registry. It should not be happening.
if (currentDestination.isEmpty() || !QDir(currentDestination).exists() || !currentDestination.startsWith(gameRootAbsPath, Qt::CaseInsensitive))
{
currentDestination = gameRootAbsPath;
}
fileDialog.setDirectory(currentDestination);
// The default file path is the game project root folder.
// After that, the default file path will be the previous opened folder path.
connect(&fileDialog, &QFileDialog::directoryEntered, this, [&fileDialog, &gameRoot, &gameRootAbsPath](const QString& path)
{
// get current relative path
QString relativePath = gameRoot.relativeFilePath(path);
// Guard against navigating outside of the project folder. Lambda used as the dialog had to be captured.
// checking the directory and prevent users from changing the directory outside of the game root
if (!path.startsWith(gameRootAbsPath, Qt::CaseInsensitive) || (relativePath.length() > 2 && relativePath[0] == '.' && relativePath[1] == '.'))
{
fileDialog.setDirectory(gameRoot);
}
});
if (!fileDialog.exec())
{
return;
}
// users can only select one folder at a time, so the index is always 0.
// This fixes the issue that QFileDialog does not select the highlighted folder
QString destinationDirectory = fileDialog.selectedFiles().at(0);
OnSetDestinationDirectory(destinationDirectory);
destinationLineEdit->setText(destinationDirectory);
}
// Copy + Paste
void AssetImporterManager::OnCopyFiles()
{
m_importMethod = ImportFilesMethod::CopyFiles;
ProcessCopyFiles();
}
// Cut + Paste
void AssetImporterManager::OnMoveFiles()
{
m_importMethod = ImportFilesMethod::MoveFiles;
ProcessMoveFiles();
}
bool AssetImporterManager::OnOverwriteFiles(QString relativePath, QString oldAbsolutePath)
{
// this is the absolute path in the destination folder
QString destinationAbsolutePath = GenerateAbsolutePath(relativePath);
return Overwrite(relativePath, oldAbsolutePath, destinationAbsolutePath);
}
bool AssetImporterManager::OnKeepBothFiles(QString relativePath, QString oldAbsolutePath)
{
// this is the absolute path in the destination folder
QString destinationAbsolutePath = GenerateAbsolutePath(relativePath);
QString subPath = QFileInfo(destinationAbsolutePath).absoluteDir().absolutePath();
QFileInfo info(destinationAbsolutePath);
QString extension = info.completeSuffix(); // extension without '.'
QString fileName = info.baseName(); //file name without extension
int number = 1;
int index = destinationAbsolutePath.indexOf(extension);
QString newFileName = CreateFileNameWithNumber(number, fileName, index, extension);
QString newDestinationAbsolutePath = subPath + '/' + newFileName;
while (QFile(newDestinationAbsolutePath).exists())
{
number++;
newFileName = CreateFileNameWithNumber(number, fileName, index, extension);
newDestinationAbsolutePath = subPath + '/' + newFileName;
}
if (m_importMethod == ImportFilesMethod::CopyFiles)
{
return Copy(relativePath, oldAbsolutePath, newDestinationAbsolutePath);
}
else if (m_importMethod == ImportFilesMethod::MoveFiles)
{
return Move(relativePath, oldAbsolutePath, newDestinationAbsolutePath);
}
return false;
}
void AssetImporterManager::OnOpenLogDialog()
{
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::ShowAssetProcessor);
reject();
}
void AssetImporterManager::OnSetDestinationDirectory(QString destinationDirectory)
{
QSettings settings;
QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString();
m_destinationRootDirectory = (!destinationDirectory.isEmpty()) ? destinationDirectory : currentDestination;
settings.setValue(AssetImporterManagerPrivate::g_selectDestinationFilesPath, destinationDirectory);
}
void AssetImporterManager::OnOpenSelectDestinationDialog()
{
QWidget* mainWindow = nullptr;
AzToolsFramework::EditorRequestBus::BroadcastResult(mainWindow, &AzToolsFramework::EditorRequests::GetMainWindow);
QString numberOfFilesMessage = m_pathMap.size() == 1 ? QString(tr("Importing 1 asset")) : QString(tr("Importing %1 assets").arg(m_pathMap.size()));
SelectDestinationDialog selectDestinationDialog(numberOfFilesMessage, mainWindow);
// Browse Destination File Path
connect(&selectDestinationDialog, &SelectDestinationDialog::BrowseDestinationPath, this, &AssetImporterManager::OnBrowseDestinationFilePath);
connect(&selectDestinationDialog, &SelectDestinationDialog::DoCopyFiles, this, &AssetImporterManager::OnCopyFiles);
connect(&selectDestinationDialog, &SelectDestinationDialog::DoMoveFiles, this, &AssetImporterManager::OnMoveFiles);
connect(&selectDestinationDialog, &SelectDestinationDialog::Cancel, this, &AssetImporterManager::reject);
connect(&selectDestinationDialog, &SelectDestinationDialog::SetDestinationDirectory, this, &AssetImporterManager::OnSetDestinationDirectory);
selectDestinationDialog.exec();
}
ProcessFilesMethod AssetImporterManager::OnOpenFilesAlreadyExistDialog(QString message, int numberOfFiles)
{
ProcessFilesMethod processMethod = ProcessFilesMethod::Default;
// make sure the dialog is opened in front of the Editor main window
QWidget* mainWindow = nullptr;
AzToolsFramework::EditorRequestBus::BroadcastResult(mainWindow, &AzToolsFramework::EditorRequests::GetMainWindow);
FilesAlreadyExistDialog filesAlreadyExistDialog(message, numberOfFiles, mainWindow);
bool applyToAll = false;
connect(&filesAlreadyExistDialog, &FilesAlreadyExistDialog::ApplyActionToAllFiles, this, [&applyToAll](bool result)
{
applyToAll = result;
});
connect(&filesAlreadyExistDialog, &FilesAlreadyExistDialog::OverWriteFiles, this, [this, &processMethod, &applyToAll]()
{
processMethod = UpdateProcessFileMethod(ProcessFilesMethod::OverwriteFile, applyToAll);
});
connect(&filesAlreadyExistDialog, &FilesAlreadyExistDialog::KeepBothFiles, this, [this, &processMethod, &applyToAll]()
{
processMethod = UpdateProcessFileMethod(ProcessFilesMethod::KeepBothFile, applyToAll);
});
connect(&filesAlreadyExistDialog, &FilesAlreadyExistDialog::SkipCurrentProcess, this, [this, &processMethod, &applyToAll]()
{
processMethod = UpdateProcessFileMethod(ProcessFilesMethod::SkipProcessingFile, applyToAll);
});
connect(&filesAlreadyExistDialog, &FilesAlreadyExistDialog::CancelAllProcesses, this, [&processMethod]()
{
processMethod = ProcessFilesMethod::Cancel;
});
if (!applyToAll && processMethod != ProcessFilesMethod::Cancel)
{
filesAlreadyExistDialog.exec();
}
return processMethod;
}
ProcessFilesMethod AssetImporterManager::UpdateProcessFileMethod(ProcessFilesMethod processMethod, bool applyToAll)
{
if (applyToAll)
{
switch (processMethod)
{
case ProcessFilesMethod::OverwriteFile:
processMethod = ProcessFilesMethod::OverwriteAllFiles;
break;
case ProcessFilesMethod::KeepBothFile:
processMethod = ProcessFilesMethod::KeepBothAllFiles;
break;
case ProcessFilesMethod::SkipProcessingFile:
processMethod = ProcessFilesMethod::SkipProcessingAllFiles;
}
}
return processMethod;
}
bool AssetImporterManager::ProcessFileMethod(ProcessFilesMethod processMethod, QString relativePath, QString oldAbsolutePath)
{
switch (processMethod)
{
case ProcessFilesMethod::OverwriteFile:
case ProcessFilesMethod::OverwriteAllFiles:
return OnOverwriteFiles(relativePath, oldAbsolutePath);
case ProcessFilesMethod::KeepBothFile:
case ProcessFilesMethod::KeepBothAllFiles:
return OnKeepBothFiles(relativePath, oldAbsolutePath);
case ProcessFilesMethod::SkipProcessingAllFiles:
return false;
}
return false;
}
void AssetImporterManager::OnOpenProcessingAssetsDialog(int numberOfProcessedFiles)
{
// make sure the dialog is opened in front of the Editor main window
QWidget* mainWindow = nullptr;
AzToolsFramework::EditorRequestBus::BroadcastResult(mainWindow, &AzToolsFramework::EditorRequests::GetMainWindow);
ProcessingAssetsDialog processingAssetsDialog(numberOfProcessedFiles, mainWindow);
connect(&processingAssetsDialog, &ProcessingAssetsDialog::OpenLogDialog, this, &AssetImporterManager::OnOpenLogDialog);
connect(&processingAssetsDialog, &ProcessingAssetsDialog::CloseProcessingAssetsDialog, this, &AssetImporterManager::reject);
processingAssetsDialog.exec();
}
void AssetImporterManager::ProcessCopyFiles()
{
int numberOfFiles = m_pathMap.size();
int numberOfProcessedFiles = 0;
ProcessFilesMethod processMethod = ProcessFilesMethod::Default;
for (int i = 0; i < m_pathMap.size(); ++i)
{
QString relativePath = m_pathMap.values().at(i);
QString oldAbsolutePath = m_pathMap.keys().at(i);
// this is the absolute path in the destination folder
QString destinationAbsolutePath = GenerateAbsolutePath(relativePath);
// check if the file exists in the destination folder
if (!QFile::exists(destinationAbsolutePath))
{
if (Copy(relativePath, oldAbsolutePath, destinationAbsolutePath))
{
numberOfProcessedFiles++;
}
}
else
{
if (processMethod == ProcessFilesMethod::Default ||
processMethod == ProcessFilesMethod::OverwriteFile ||
processMethod == ProcessFilesMethod::KeepBothFile ||
processMethod == ProcessFilesMethod::SkipProcessingFile)
{
QString fileName = GetFileName(oldAbsolutePath);
QString message = QString("The destination already has a file named \"%1\". What would you like to do?").arg(fileName);
processMethod = OnOpenFilesAlreadyExistDialog(message, numberOfFiles);
}
if (ProcessFileMethod(processMethod, relativePath, oldAbsolutePath))
{
numberOfProcessedFiles++;
}
}
numberOfFiles--;
}
if (numberOfProcessedFiles > 0)
{
OnOpenProcessingAssetsDialog(numberOfProcessedFiles);
}
else
{
reject();
}
}
void AssetImporterManager::ProcessMoveFiles()
{
int numberOfFiles = m_pathMap.size();
int numberOfProcessedFiles = 0;
ProcessFilesMethod processMethod = ProcessFilesMethod::Default;
for (int i = 0; i < m_pathMap.size(); ++i)
{
QString relativePath = m_pathMap.values().at(i);
QString oldAbsolutePath = m_pathMap.keys().at(i);
// this is the absolute path in the destination folder
QString destinationAbsolutePath = GenerateAbsolutePath(relativePath);
// check if the file exists in the destination folder
if (!QFile::exists(destinationAbsolutePath))
{
if (Move(relativePath, oldAbsolutePath, destinationAbsolutePath))
{
numberOfProcessedFiles++;
}
}
else
{
if (processMethod == ProcessFilesMethod::Default ||
processMethod == ProcessFilesMethod::OverwriteFile ||
processMethod == ProcessFilesMethod::KeepBothFile ||
processMethod == ProcessFilesMethod::SkipProcessingFile)
{
QString fileName = GetFileName(oldAbsolutePath);
QString message = QString("The destination already has a file named \"%1\". What would you like to do?").arg(fileName);
processMethod = OnOpenFilesAlreadyExistDialog(message, numberOfFiles);
}
if (ProcessFileMethod(processMethod, relativePath, oldAbsolutePath))
{
numberOfProcessedFiles++;
}
}
numberOfFiles--;
}
if (numberOfProcessedFiles > 0)
{
OnOpenProcessingAssetsDialog(numberOfProcessedFiles);
}
else
{
reject();
}
}
bool AssetImporterManager::Copy(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath)
{
QString fileName = GetFileName(destinationAbsolutePath);
QString subPath = QFileInfo(destinationAbsolutePath).absoluteDir().absolutePath();
QDir dir;
bool directoryExistedAlready = QDir(subPath).exists();
if (!directoryExistedAlready)
{
dir.mkpath(subPath);
}
QString newDestinationAbsolutePath = subPath;
newDestinationAbsolutePath = newDestinationAbsolutePath.append('/' + fileName);
// Copy the file from the old path to the new path
if (!QFile::copy(oldAbsolutePath, newDestinationAbsolutePath))
{
QString reason = tr("an unknown issue occurred.");
if (!directoryExistedAlready)
{
dir.rmdir(subPath);
}
// if the original files got deleted at this condition
if (!QFile(oldAbsolutePath).exists())
{
reason = tr("%1 no longer exists.").arg(fileName);
}
// if users manually copy the file into the destination folder at this condition
if (QFile(newDestinationAbsolutePath).exists())
{
reason = tr("%1 already exists in the target directory.").arg(fileName);
}
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, QObject::tr("We're sorry, but the file failed to process because %1").arg(reason));
return false;
}
// set the destination file to be writable by user himself/herself if it's read-only
QFile destinationFile(newDestinationAbsolutePath);
SetDestinationFileWritable(destinationFile);
return true;
}
bool AssetImporterManager::Move(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath)
{
QString fileName = GetFileName(destinationAbsolutePath);
QString subPath = QFileInfo(destinationAbsolutePath).absoluteDir().absolutePath();
QString newDestinationAbsolutePath = subPath;
QDir dir;
bool directoryExistedAlready = QDir(subPath).exists();
if (!directoryExistedAlready)
{
dir.mkpath(subPath);
}
if (QFile::rename(oldAbsolutePath, newDestinationAbsolutePath.append('/' + fileName)))
{
QString oldFileName = GetFileName(oldAbsolutePath);
// Only remove the old directory if the relative path is the file name itself.
// That also means users are dragging and dropping files, but not a folder containing those files.
if (oldFileName.compare(relativePath) != 0)
{
RemoveOldPath(oldAbsolutePath, relativePath);
}
// set the destination file to be writable by user himself/herself if it's read-only
QFile destinationFile(newDestinationAbsolutePath);
SetDestinationFileWritable(destinationFile);
return true;
}
else
{
QString reason = tr("an unknown issue occurred.");
QString oldFileName = GetFileName(oldAbsolutePath);
if (!directoryExistedAlready)
{
dir.rmdir(subPath);
}
// if the original files got deleted at this condition
if (!QFile(oldAbsolutePath).exists())
{
reason = tr("%1 no longer exists.").arg(oldFileName);
}
// if users manually copy the file into the destination folder at this condition
if (QFile(newDestinationAbsolutePath).exists())
{
reason = tr("%1 already exists in the target directory.").arg(oldFileName);
}
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, QObject::tr("We're sorry, but the file failed to process because %1").arg(reason));
return false;
}
}
bool AssetImporterManager::Overwrite(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath)
{
QFile newFile(destinationAbsolutePath);
QFile oldFile(oldAbsolutePath);
// double check if paths are valid
if ((!oldFile.open(QIODevice::ReadOnly)))
{
QString fileName = GetFileName(oldAbsolutePath);
QString reason = tr("%1 no longer exists.").arg(fileName);
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, QObject::tr("We're sorry, but the file failed to process because %1").arg(reason));
return false;
}
if (!newFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
QString reason = tr("We're sorry, but the file failed to process.");
QString fileName = GetFileName(destinationAbsolutePath);
if (!newFile.exists())
{
reason = tr("%1 from the destination directory is removed.").arg(fileName);
}
else
{
reason = tr("%1 from the destination directory cannot be overwritten.").arg(fileName);
}
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), AssetImporterManagerPrivate::g_errorMessageBoxTitle, QObject::tr("We're sorry, but the file failed to process because %1").arg(reason));
return false;
}
QDataStream dataStream(&oldFile);
QDataStream out(&newFile);
int bufferSize = 1024 * 1024;
char* buffer = new char[bufferSize];
while (!dataStream.atEnd())
{
int bytesRead = dataStream.readRawData(buffer, bufferSize);
out.writeRawData(buffer, bytesRead);
}
delete[] buffer;
oldFile.close();
newFile.close();
// if it's the move file method, got to remove the original files
if (m_importMethod == ImportFilesMethod::MoveFiles)
{
QString fileName = GetFileName(oldAbsolutePath);
QFile file(oldAbsolutePath);
QDir absoluteDir = QFileInfo(oldAbsolutePath).absoluteDir();
if (file.exists())
{
// if the original file is read-only,
// then it got to be writable in order to be deleted successfully
SetDestinationFileWritable(file);
absoluteDir.remove(fileName);
}
// Only remove the old directory if the relative path is the file name itself.
// That also means users are dragging and dropping files, but not a folder containing those files.
if (fileName.compare(relativePath) != 0)
{
RemoveOldPath(oldAbsolutePath, relativePath);
}
}
return true;
}
bool AssetImporterManager::GetAndCheckAllFilesInFolder(QString path)
{
QString formattedPath = path;
// Paths ending with '/' return from QFileInfo().fileName() with a value of ""
// Strip a trailing slash so we can correctly get rootFolderName on all platforms
if (formattedPath.endsWith("/"))
{
formattedPath.truncate(formattedPath.lastIndexOf(QChar('/')));
}
QString rootFolderName = GetFileName(formattedPath);
QDirIterator it(formattedPath, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories);
QFileInfo info(formattedPath);
if (!info.isDir() && !it.hasNext() && info.exists())
{
m_pathMap[formattedPath] = rootFolderName;
return true;
}
// Get the index of the last sub folder name in the path
QStringList directoryNameList = formattedPath.split('/');
int lastFolderIndex = directoryNameList.size() - 1;
QString pathToBeRelativeTo = directoryNameList.mid(0, lastFolderIndex).join('/');
while (it.hasNext())
{
QString absolutePath = it.next();
QFileInfo absoluteInfo(absolutePath);
QString extension = absoluteInfo.completeSuffix();
if (QString(AssetImporterManagerPrivate::s_crateFileExtension).compare(extension, Qt::CaseInsensitive) == 0)
{
return false;
}
Q_ASSERT(absolutePath.startsWith(pathToBeRelativeTo));
QString relativePath = absolutePath.mid(pathToBeRelativeTo.size() + 1);
m_pathMap[absolutePath] = relativePath;
}
return true;
}
void AssetImporterManager::RemoveOldPath(QString oldAbsolutePath, QString oldRelativePath)
{
QDir absoluteDir = QFileInfo(oldAbsolutePath).absoluteDir();
QStringList directoryList = oldRelativePath.split('/');
// remove each folder from the leave to the root, based on the relative path
for (int i = 0; i < directoryList.size(); ++i)
{
QString currentDir = absoluteDir.path();
absoluteDir.rmpath(currentDir);
absoluteDir.cdUp();
}
}
void AssetImporterManager::SetDestinationFileWritable(QFile& destinationFile)
{
if (destinationFile.open(QIODevice::ReadOnly))
{
destinationFile.setPermissions(QFile::WriteOwner | destinationFile.permissions());
}
destinationFile.close();
}
QString AssetImporterManager::CreateFileNameWithNumber(int number, QString fileName, int index, QString extension)
{
QString newFileName;
newFileName = fileName.isEmpty() ? fileName : fileName.left(index);
newFileName += "(" + QString::number(number) + ")";
if (extension.size() > 0)
{
newFileName += "." + extension;
}
return newFileName;
}
QString AssetImporterManager::GenerateAbsolutePath(QString relativePath)
{
return QDir(m_destinationRootDirectory).absoluteFilePath(relativePath);
}
QString AssetImporterManager::GetFileName(QString path)
{
return QFileInfo(path).fileName();
}
#include <AssetImporter/AssetImporterManager/moc_AssetImporterManager.cpp>