git mv Code\Sandbox\Editor Code/Editor
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "AssetImporterDragAndDropHandler.h"
|
||||
|
||||
// Qt
|
||||
#include <QMimeData>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
|
||||
// AzQtComponents
|
||||
#include <AzQtComponents/DragAndDrop/MainWindowDragAndDrop.h>
|
||||
|
||||
// Editor
|
||||
#include "AssetImporter/AssetImporterManager/AssetImporterManager.h"
|
||||
|
||||
bool AssetImporterDragAndDropHandler::m_dragAccepted = false;
|
||||
|
||||
AssetImporterDragAndDropHandler::AssetImporterDragAndDropHandler(QObject* parent, AssetImporterManager* const assetImporterManager)
|
||||
: QObject(parent)
|
||||
, m_assetImporterManager(assetImporterManager)
|
||||
{
|
||||
AzQtComponents::DragAndDropEventsBus::Handler::BusConnect(AzQtComponents::DragAndDropContexts::EditorMainWindow);
|
||||
|
||||
// They are used to prevent opening the Asset Importer by dragging and dropping files and folders to the Main Window when it is already running
|
||||
connect(m_assetImporterManager, &AssetImporterManager::StartAssetImporter, this, &AssetImporterDragAndDropHandler::OnStartAssetImporter);
|
||||
connect(m_assetImporterManager, &AssetImporterManager::StopAssetImporter, this, &AssetImporterDragAndDropHandler::OnStopAssetImporter);
|
||||
}
|
||||
|
||||
AssetImporterDragAndDropHandler::~AssetImporterDragAndDropHandler()
|
||||
{
|
||||
AzQtComponents::DragAndDropEventsBus::Handler::BusDisconnect(AzQtComponents::DragAndDropContexts::EditorMainWindow);
|
||||
}
|
||||
|
||||
void AssetImporterDragAndDropHandler::DragEnter(QDragEnterEvent* event, AzQtComponents::DragAndDropContextBase& /*context*/)
|
||||
{
|
||||
if (!m_isAssetImporterRunning)
|
||||
{
|
||||
ProcessDragEnter(event);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetImporterDragAndDropHandler::Drop(QDropEvent* event, AzQtComponents::DragAndDropContextBase& /*context*/)
|
||||
{
|
||||
if (!m_dragAccepted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList fileList = GetFileList(event);
|
||||
|
||||
if (!fileList.isEmpty())
|
||||
{
|
||||
Q_EMIT OpenAssetImporterManager(fileList);
|
||||
}
|
||||
|
||||
// reset
|
||||
m_dragAccepted = false;
|
||||
}
|
||||
|
||||
void AssetImporterDragAndDropHandler::ProcessDragEnter(QDragEnterEvent* event)
|
||||
{
|
||||
m_dragAccepted = false;
|
||||
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
|
||||
// if the event hasn't been accepted already and the mimeData hasUrls()
|
||||
if (event->isAccepted() || !mimeData->hasUrls())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent users from dragging and dropping files from the Asset Browser
|
||||
if (mimeData->hasFormat(AzToolsFramework::AssetBrowser::AssetBrowserEntry::GetMimeType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QUrl> urlList = mimeData->urls();
|
||||
int urlListSize = urlList.size();
|
||||
|
||||
// runs through the file list first and checks for any "crate" files - if it finds ANY, return (and don't accept the event)
|
||||
for (int i = 0; i < urlListSize; ++i)
|
||||
{
|
||||
QUrl currentUrl = urlList.at(i);
|
||||
|
||||
if (currentUrl.isLocalFile())
|
||||
{
|
||||
QString path = urlList.at(i).toLocalFile();
|
||||
|
||||
if (ContainCrateFiles(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < urlListSize; ++i)
|
||||
{
|
||||
// Get the local file path
|
||||
QString path = urlList.at(i).toLocalFile();
|
||||
|
||||
QDir dir(path);
|
||||
QString relativePath = dir.relativeFilePath(path);
|
||||
QString absPath = dir.absolutePath();
|
||||
|
||||
// check if the files/folders are under the game root directory
|
||||
QDir gameRoot(Path::GetEditingGameDataFolder().c_str());
|
||||
QString gameRootAbsPath = gameRoot.absolutePath();
|
||||
|
||||
if (absPath.startsWith(gameRootAbsPath, Qt::CaseInsensitive))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDirIterator it(absPath, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories);
|
||||
|
||||
QFileInfo info(absPath);
|
||||
QString extension = info.completeSuffix();
|
||||
|
||||
// if it's not an empty folder directory or if it's a file,
|
||||
// then allow the drag and drop process.
|
||||
// Otherwise, prevent users from dragging and dropping empty folders
|
||||
if (it.hasNext() || !extension.isEmpty())
|
||||
{
|
||||
// this is used in Drop()
|
||||
m_dragAccepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, all files should be legal to be imported
|
||||
// since they are not in the database
|
||||
if (m_dragAccepted)
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList AssetImporterDragAndDropHandler::GetFileList(QDropEvent* event)
|
||||
{
|
||||
QStringList fileList;
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
|
||||
QList<QUrl> urlList = mimeData->urls();
|
||||
|
||||
for (int i = 0; i < urlList.size(); ++i)
|
||||
{
|
||||
QUrl currentUrl = urlList.at(i);
|
||||
|
||||
if (currentUrl.isLocalFile())
|
||||
{
|
||||
QString path = urlList.at(i).toLocalFile();
|
||||
|
||||
if (!ContainCrateFiles(path))
|
||||
{
|
||||
fileList.append(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fileList;
|
||||
}
|
||||
|
||||
void AssetImporterDragAndDropHandler::OnStartAssetImporter()
|
||||
{
|
||||
m_isAssetImporterRunning = true;
|
||||
}
|
||||
|
||||
void AssetImporterDragAndDropHandler::OnStopAssetImporter()
|
||||
{
|
||||
m_isAssetImporterRunning = false;
|
||||
}
|
||||
|
||||
|
||||
bool AssetImporterDragAndDropHandler::ContainCrateFiles(QString path)
|
||||
{
|
||||
QFileInfo fileInfo(path);
|
||||
|
||||
if (fileInfo.isFile())
|
||||
{
|
||||
return isCrateFile(fileInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
QDirIterator it(path, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
QString str = it.next();
|
||||
QFileInfo info(str);
|
||||
|
||||
if (isCrateFile(info))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssetImporterDragAndDropHandler::isCrateFile(QFileInfo fileInfo)
|
||||
{
|
||||
return QStringLiteral("crate").compare(fileInfo.suffix(), Qt::CaseInsensitive) == 0;
|
||||
}
|
||||
|
||||
#include <AssetImporter/AssetImporterManager/moc_AssetImporterDragAndDropHandler.cpp>
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
|
||||
#include <QObject>
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzQtComponents/Buses/DragAndDrop.h>
|
||||
#include <AzToolsFramework/API/AssetDatabaseBus.h>
|
||||
#include <AzCore/std/smart_ptr/scoped_ptr.h>
|
||||
#endif
|
||||
|
||||
class MainWindow;
|
||||
class AssetImporterManager;
|
||||
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetDatabase
|
||||
{
|
||||
class AssetDatabaseConnection;
|
||||
}
|
||||
}
|
||||
|
||||
class AssetImporterDragAndDropHandler
|
||||
: public QObject
|
||||
, public AzQtComponents::DragAndDropEventsBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AssetImporterDragAndDropHandler(QObject* parent, AssetImporterManager* const assetImporterManager);
|
||||
~AssetImporterDragAndDropHandler();
|
||||
|
||||
void DragEnter(QDragEnterEvent* event, AzQtComponents::DragAndDropContextBase& context) override;
|
||||
void Drop(QDropEvent* event, AzQtComponents::DragAndDropContextBase& context) override;
|
||||
|
||||
static void ProcessDragEnter(QDragEnterEvent* event);
|
||||
static QStringList GetFileList(QDropEvent* event);
|
||||
|
||||
Q_SIGNALS:
|
||||
void OpenAssetImporterManager(const QStringList& fileList);
|
||||
|
||||
public Q_SLOTS:
|
||||
void OnStartAssetImporter();
|
||||
void OnStopAssetImporter();
|
||||
|
||||
private:
|
||||
bool m_isAssetImporterRunning = false;
|
||||
AssetImporterManager* m_assetImporterManager;
|
||||
|
||||
static bool ContainCrateFiles(QString path);
|
||||
static bool isCrateFile(QFileInfo fileInfo);
|
||||
|
||||
// it is used because MainWindow's dropEvent will ask the Ebus to call the Drop() function in AssetImporterDragAndDropHandler.
|
||||
// That will cause the problem that even the crate objects are blocked by the DragEnter() in AssetImporterDragAndDropHandler,
|
||||
// it will still open the Asset Importer
|
||||
static bool m_dragAccepted;
|
||||
};
|
||||
@@ -0,0 +1,811 @@
|
||||
/*
|
||||
* 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>
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QMainWindow>
|
||||
#include <AssetImporter/UI/SelectDestinationDialog.h>
|
||||
#endif
|
||||
|
||||
class QStringList;
|
||||
class QFile;
|
||||
|
||||
enum class ImportFilesMethod
|
||||
{
|
||||
CopyFiles,
|
||||
MoveFiles
|
||||
};
|
||||
|
||||
enum class ProcessFilesMethod
|
||||
{
|
||||
OverwriteFile,
|
||||
KeepBothFile,
|
||||
SkipProcessingFile,
|
||||
OverwriteAllFiles,
|
||||
KeepBothAllFiles,
|
||||
SkipProcessingAllFiles,
|
||||
Cancel,
|
||||
|
||||
Default
|
||||
};
|
||||
|
||||
class AssetImporterManager
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AssetImporterManager(QWidget* parent = nullptr);
|
||||
~AssetImporterManager();
|
||||
|
||||
// Modal, but blocking.
|
||||
void Exec(); // for browsing files
|
||||
void Exec(const QStringList& dragAndDropFileList); // for drag and drop
|
||||
|
||||
Q_SIGNALS:
|
||||
void StartAssetImporter();
|
||||
void StopAssetImporter();
|
||||
|
||||
private Q_SLOTS:
|
||||
void reject();
|
||||
void OnDragAndDropFiles(const QStringList* fileList);
|
||||
bool OnBrowseFiles();
|
||||
void OnBrowseDestinationFilePath(QLineEdit* destinationLineEdit);
|
||||
void OnCopyFiles();
|
||||
void OnMoveFiles();
|
||||
bool OnOverwriteFiles(QString relativePath, QString oldAbsolutePath);
|
||||
bool OnKeepBothFiles(QString relativePath, QString oldAbsolutePath);
|
||||
void OnOpenLogDialog();
|
||||
void OnSetDestinationDirectory(QString destinationDirectory);
|
||||
|
||||
private:
|
||||
void OnOpenSelectDestinationDialog();
|
||||
|
||||
ProcessFilesMethod OnOpenFilesAlreadyExistDialog(QString message, int numberOfFiles);
|
||||
ProcessFilesMethod UpdateProcessFileMethod(ProcessFilesMethod processMethod, bool applyToAll);
|
||||
bool ProcessFileMethod(ProcessFilesMethod processMethod, QString relativePath, QString oldAbsolutePath);
|
||||
|
||||
void OnOpenProcessingAssetsDialog(int numberOfProcessedFiles);
|
||||
|
||||
void ProcessCopyFiles();
|
||||
void ProcessMoveFiles();
|
||||
|
||||
bool Copy(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath);
|
||||
bool Move(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath);
|
||||
bool Overwrite(QString relativePath, QString oldAbsolutePath, QString destinationAbsolutePath);
|
||||
|
||||
bool GetAndCheckAllFilesInFolder(QString path);
|
||||
void RemoveOldPath(QString oldAbsolutePath, QString oldRelativePath);
|
||||
void SetDestinationFileWritable(QFile& destinationFile);
|
||||
|
||||
QString CreateFileNameWithNumber(int number, QString fileName, int index, QString extension);
|
||||
QString GenerateAbsolutePath(QString relativePath);
|
||||
QString GetFileName(QString path);
|
||||
|
||||
ImportFilesMethod m_importMethod;
|
||||
|
||||
// Key = absolute path, Value = relative path
|
||||
QMap<QString, QString> m_pathMap;
|
||||
QString m_destinationRootDirectory;
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "FilesAlreadyExistDialog.h"
|
||||
|
||||
// Qt
|
||||
#include <QPushButton>
|
||||
#include <QStyle>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <AssetImporter/UI/ui_FilesAlreadyExistDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
FilesAlreadyExistDialog::FilesAlreadyExistDialog(QString message ,int numberOfFiles, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::FilesAlreadyExistDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
UpdateMessage(message);
|
||||
InitializeButtons();
|
||||
UpdateCheckBoxState(numberOfFiles);
|
||||
}
|
||||
|
||||
FilesAlreadyExistDialog::~FilesAlreadyExistDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::InitializeButtons()
|
||||
{
|
||||
m_ui->buttonBox->setContentsMargins(0, 0, 16, 16);
|
||||
QPushButton* overwriteButton = m_ui->buttonBox->addButton(tr("Overwrite"), QDialogButtonBox::AcceptRole);
|
||||
QPushButton* keepBothButton = m_ui->buttonBox->addButton(tr("Keep Both"), QDialogButtonBox::AcceptRole);
|
||||
QPushButton* skipButton = m_ui->buttonBox->addButton(tr("Skip"), QDialogButtonBox::AcceptRole);
|
||||
|
||||
overwriteButton->setProperty("class", "Primary");
|
||||
overwriteButton->setDefault(true);
|
||||
|
||||
keepBothButton->setProperty("class", "AssetImporterLargerButton");
|
||||
keepBothButton->style()->unpolish(keepBothButton);
|
||||
keepBothButton->style()->polish(keepBothButton);
|
||||
keepBothButton->update();
|
||||
|
||||
skipButton->setProperty("class", "AssetImporterButton");
|
||||
skipButton->style()->unpolish(skipButton);
|
||||
skipButton->style()->polish(skipButton);
|
||||
skipButton->update();
|
||||
|
||||
connect(overwriteButton, &QPushButton::clicked, this, &FilesAlreadyExistDialog::DoOverwrite);
|
||||
connect(keepBothButton, &QPushButton::clicked, this, &FilesAlreadyExistDialog::DoKeepBoth);
|
||||
connect(skipButton, &QPushButton::clicked, this, &FilesAlreadyExistDialog::DoSkipCurrentProcess);
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::UpdateMessage(QString message)
|
||||
{
|
||||
m_ui->message->setText(message);
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::DoSkipCurrentProcess()
|
||||
{
|
||||
QDialog::accept();
|
||||
Q_EMIT SkipCurrentProcess();
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::DoOverwrite()
|
||||
{
|
||||
QDialog::accept();
|
||||
Q_EMIT OverWriteFiles();
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::DoKeepBoth()
|
||||
{
|
||||
QDialog::accept();
|
||||
Q_EMIT KeepBothFiles();
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::DoApplyActionToAllFiles()
|
||||
{
|
||||
Q_EMIT ApplyActionToAllFiles(m_ui->applyToAllCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::UpdateCheckBoxState(int numberOfFiles)
|
||||
{
|
||||
m_ui->applyToAllCheckBox->setVisible((numberOfFiles > 1));
|
||||
connect(m_ui->applyToAllCheckBox, &QCheckBox::stateChanged, this, &FilesAlreadyExistDialog::DoApplyActionToAllFiles);
|
||||
}
|
||||
|
||||
void FilesAlreadyExistDialog::closeEvent([[maybe_unused]] QCloseEvent* ev)
|
||||
{
|
||||
QDialog::reject();
|
||||
Q_EMIT CancelAllProcesses();
|
||||
}
|
||||
|
||||
#include <AssetImporter/UI/moc_FilesAlreadyExistDialog.cpp>
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
class QTreeView;
|
||||
|
||||
namespace Ui {
|
||||
class FilesAlreadyExistDialog;
|
||||
}
|
||||
|
||||
class FilesAlreadyExistDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilesAlreadyExistDialog(QString message, int numberOfFiles, QWidget* parent = nullptr);
|
||||
~FilesAlreadyExistDialog();
|
||||
|
||||
Q_SIGNALS:
|
||||
void OverWriteFiles();
|
||||
void KeepBothFiles();
|
||||
void SkipCurrentProcess();
|
||||
void CancelAllProcesses();
|
||||
void ApplyActionToAllFiles(bool result);
|
||||
|
||||
public Q_SLOTS:
|
||||
void DoSkipCurrentProcess();
|
||||
void DoOverwrite();
|
||||
void DoKeepBoth();
|
||||
void DoApplyActionToAllFiles();
|
||||
|
||||
private:
|
||||
void InitializeButtons();
|
||||
void UpdateMessage(QString message);
|
||||
void UpdateCheckBoxState(int numberOfFiles);
|
||||
void closeEvent(QCloseEvent* ev) override;
|
||||
QScopedPointer<Ui::FilesAlreadyExistDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,193 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FilesAlreadyExistDialog</class>
|
||||
<widget class="QWidget" name="FilesAlreadyExistDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>587</width>
|
||||
<height>159</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>571</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Replace or Skip Files</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterDialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="mainVerticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>The destination already has a file named "". What would you like to do?</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>584</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="applyToAllCheckBox">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply to all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::NoButton</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "ProcessingAssetsDialog.h"
|
||||
|
||||
// Qt
|
||||
#include <QPushButton>
|
||||
#include <QStyle>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <AssetImporter/UI/ui_ProcessingAssetsDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
ProcessingAssetsDialog::ProcessingAssetsDialog(int numberOfProcessedFiles, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::ProcessingAssetsDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
UpdateTextsAndTitle(numberOfProcessedFiles);
|
||||
InitializeButtons();
|
||||
}
|
||||
|
||||
ProcessingAssetsDialog::~ProcessingAssetsDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void ProcessingAssetsDialog::InitializeButtons()
|
||||
{
|
||||
QPushButton* viewStatusButton = m_ui->buttonBox->addButton(tr("View status"), QDialogButtonBox::AcceptRole);
|
||||
QPushButton* closeButton = m_ui->buttonBox->addButton(tr("Close"), QDialogButtonBox::RejectRole);
|
||||
|
||||
viewStatusButton->setDefault(true);
|
||||
viewStatusButton->setProperty("class", "AssetImporterLargerButton");
|
||||
viewStatusButton->style()->unpolish(viewStatusButton);
|
||||
viewStatusButton->style()->polish(viewStatusButton);
|
||||
viewStatusButton->update();
|
||||
|
||||
closeButton->setProperty("class", "AssetImporterButton");
|
||||
closeButton->style()->unpolish(closeButton);
|
||||
closeButton->style()->polish(closeButton);
|
||||
closeButton->update();
|
||||
|
||||
connect(viewStatusButton, &QPushButton::clicked, this, &ProcessingAssetsDialog::accept);
|
||||
connect(closeButton, &QPushButton::clicked, this, &ProcessingAssetsDialog::reject);
|
||||
}
|
||||
|
||||
void ProcessingAssetsDialog::accept()
|
||||
{
|
||||
Q_EMIT OpenLogDialog();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ProcessingAssetsDialog::reject()
|
||||
{
|
||||
Q_EMIT CloseProcessingAssetsDialog();
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void ProcessingAssetsDialog::UpdateTextsAndTitle(int numberOfProcessedFiles)
|
||||
{
|
||||
if (numberOfProcessedFiles > 1)
|
||||
{
|
||||
setWindowTitle("Processing assets");
|
||||
m_ui->label->setText("The Asset Processor will process your assets and when they are finished they will appear in the Asset Browser. You can view the status of your assets in the Asset Processor.");
|
||||
}
|
||||
else
|
||||
{
|
||||
setWindowTitle("Processing asset");
|
||||
m_ui->label->setText("The Asset Processor will process your asset and when it is finished it will appear in the Asset Browser. You can view the status of your asset in the Asset Processor.");
|
||||
}
|
||||
}
|
||||
|
||||
#include <AssetImporter/UI/moc_ProcessingAssetsDialog.cpp>
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
class ProcessingAssetsDialog;
|
||||
}
|
||||
|
||||
class ProcessingAssetsDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProcessingAssetsDialog(int numberOfProcessedFiles, QWidget* parent = nullptr);
|
||||
~ProcessingAssetsDialog();
|
||||
|
||||
void InitializeButtons();
|
||||
|
||||
Q_SIGNALS:
|
||||
void CloseProcessingAssetsDialog();
|
||||
void OpenLogDialog();
|
||||
|
||||
public Q_SLOTS:
|
||||
void accept();
|
||||
void reject();
|
||||
|
||||
private:
|
||||
void UpdateTextsAndTitle(int numberOfProcessedFiles);
|
||||
QScopedPointer<Ui::ProcessingAssetsDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProcessingAssetsDialog</class>
|
||||
<widget class="QWidget" name="ProcessingAssetsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>187</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>440</width>
|
||||
<height>187</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Processing assets</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterDialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>408</width>
|
||||
<height>76</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<kerning>false</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>405</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>408</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::NoButton</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SelectDestinationDialog.h"
|
||||
|
||||
// Qt
|
||||
#include <QValidator>
|
||||
#include <QSettings>
|
||||
#include <QStyle>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <AssetImporter/UI/ui_SelectDestinationDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
|
||||
static const char* g_assetProcessorLink = "<a href=\"https://o3de.org/docs/user-guide/assets/pipeline/processor-ui/\">Asset Processor</a>";
|
||||
static const char* g_copyFilesMessage = "The original file will remain outside of the project and the %1 will not monitor the file.";
|
||||
static const char* g_moveFilesMessage = "The original file will be moved inside of the project and the %1 will monitor the file for changes.";
|
||||
static const char* g_selectDestinationFilesPath = "AssetImporter/SelectDestinationFilesPath";
|
||||
|
||||
static const char* g_toolTipInvalidRoot = "<p style='white-space:pre'> <span style=\"color:#cccccc;\">Invalid directory. Please choose a destination directory within your game project: %1.</span> </p>";
|
||||
static const char* g_toolTipPathMustExist = "<p style='white-space:pre'> <span style=\"color:#cccccc;\">Invalid directory. Please choose a destination directory that exists.</span> </p>";
|
||||
static const char* g_toolTipPathMustBeDirectory = "<p style='white-space:pre'> <span style=\"color:#cccccc;\">Invalid directory. Please choose a valid destination directory.</span> </p>";
|
||||
static const char* g_toolTipInvalidLength = "<p style='white-space:pre'> <span style=\"color:#cccccc;\">Invalid directory name length. Please choose a destination path that has fewer than %1 characters.</span> </p>";
|
||||
|
||||
namespace
|
||||
{
|
||||
static QString GetAbsoluteRootDirectoryPath()
|
||||
{
|
||||
QDir gameRoot(Path::GetEditingGameDataFolder().c_str());
|
||||
return gameRoot.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
class DestinationDialogValidator
|
||||
: public QValidator
|
||||
{
|
||||
public:
|
||||
DestinationDialogValidator(QObject* parent)
|
||||
: QValidator(parent)
|
||||
, m_gameRootAbsolutePath(GetAbsoluteRootDirectoryPath())
|
||||
{
|
||||
}
|
||||
|
||||
State validate(QString& input, [[maybe_unused]] int& pos) const override
|
||||
{
|
||||
m_toolTip = "";
|
||||
|
||||
if (input.isEmpty())
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
// The underlying file system code can't cope with long file paths, regardless of platform
|
||||
if (input.length() > (AZ_MAX_PATH_LEN - 1))
|
||||
{
|
||||
m_toolTip = QString(g_toolTipInvalidLength).arg(AZ_MAX_PATH_LEN);
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
|
||||
QString normalizedInput = QDir::fromNativeSeparators(input);
|
||||
|
||||
// Note: the check for the root directory is case insensitive.
|
||||
// We check if the directory actually exists after this, and at that point,
|
||||
// if the file path has to be case sensitive, the directory won't exist anyways
|
||||
// and QFileInfo::exists() will tell us so this should still work even on
|
||||
// case sensitive file systems (such as Mac and Linux)
|
||||
if (!normalizedInput.startsWith(m_gameRootAbsolutePath, Qt::CaseInsensitive))
|
||||
{
|
||||
m_toolTip = QString(g_toolTipInvalidRoot).arg(m_gameRootAbsolutePath);
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
|
||||
QFileInfo fileInfo(normalizedInput);
|
||||
if (!fileInfo.exists())
|
||||
{
|
||||
m_toolTip = g_toolTipPathMustExist;
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
|
||||
if (!fileInfo.isDir())
|
||||
{
|
||||
m_toolTip = g_toolTipPathMustBeDirectory;
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
QString infoToolTip() const
|
||||
{
|
||||
return m_toolTip;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_gameRootAbsolutePath;
|
||||
mutable QString m_toolTip;
|
||||
};
|
||||
|
||||
SelectDestinationDialog::SelectDestinationDialog(QString message, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::SelectDestinationDialog)
|
||||
, m_validator(new DestinationDialogValidator(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QString radioButtonMessage = QString(g_copyFilesMessage).arg(g_assetProcessorLink);
|
||||
m_ui->RaidoButtonMessage->setText(radioButtonMessage);
|
||||
|
||||
SetPreviousDestinationDirectory();
|
||||
|
||||
m_ui->DestinationLineEdit->setValidator(m_validator);
|
||||
m_ui->DestinationLineEdit->setAlignment(Qt::AlignVCenter);
|
||||
|
||||
// Based on the current code structure, in order to prevent texts from overlapping the
|
||||
// invalid icon, intentionally insert an empty icon at the end of the line edit field can do the trick.
|
||||
m_ui->DestinationLineEdit->addAction(QIcon(""), QLineEdit::TrailingPosition);
|
||||
|
||||
connect(m_ui->DestinationLineEdit, &QLineEdit::textChanged, this, &SelectDestinationDialog::ValidatePath);
|
||||
connect(m_ui->BrowseButton, &QPushButton::clicked, this, &SelectDestinationDialog::OnBrowseDestinationFilePath, Qt::UniqueConnection);
|
||||
connect(m_ui->CopyFileRadioButton, &QRadioButton::toggled, this, &SelectDestinationDialog::ShowMessage);
|
||||
|
||||
UpdateMessage(message);
|
||||
InitializeButtons();
|
||||
}
|
||||
|
||||
SelectDestinationDialog::~SelectDestinationDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::InitializeButtons()
|
||||
{
|
||||
m_ui->CopyFileRadioButton->setChecked(true);
|
||||
|
||||
m_ui->buttonBox->setContentsMargins(0, 0, 16, 16);
|
||||
|
||||
QPushButton* importButton = m_ui->buttonBox->addButton(tr("Import"), QDialogButtonBox::AcceptRole);
|
||||
QPushButton* cancelButton = m_ui->buttonBox->addButton(QDialogButtonBox::Cancel);
|
||||
|
||||
importButton->setProperty("class", "Primary");
|
||||
importButton->setDefault(true);
|
||||
|
||||
cancelButton->setProperty("class", "AssetImporterButton");
|
||||
cancelButton->style()->unpolish(cancelButton);
|
||||
cancelButton->style()->polish(cancelButton);
|
||||
cancelButton->update();
|
||||
|
||||
connect(importButton, &QPushButton::clicked, this, &SelectDestinationDialog::accept);
|
||||
connect(cancelButton, &QPushButton::clicked, this, &SelectDestinationDialog::reject);
|
||||
connect(this, &SelectDestinationDialog::UpdateImportButtonState, importButton, &QPushButton::setEnabled);
|
||||
|
||||
// To make sure the import button state is up to date
|
||||
ValidatePath();
|
||||
importButton->setAutoDefault(true);
|
||||
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::SetPreviousDestinationDirectory()
|
||||
{
|
||||
QString gameRootAbsPath = GetAbsoluteRootDirectoryPath();
|
||||
QSettings settings;
|
||||
QString previousDestination = settings.value(g_selectDestinationFilesPath).toString();
|
||||
|
||||
// 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 (previousDestination.isEmpty() || !QDir(previousDestination).exists() || !previousDestination.startsWith(gameRootAbsPath, Qt::CaseInsensitive))
|
||||
{
|
||||
previousDestination = gameRootAbsPath;
|
||||
}
|
||||
|
||||
m_ui->DestinationLineEdit->setText(QDir::toNativeSeparators(previousDestination));
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::accept()
|
||||
{
|
||||
QDialog::accept();
|
||||
|
||||
// This prevent users from not editing the destination line edit (manually type the directory or browse for the directory)
|
||||
Q_EMIT SetDestinationDirectory(DestinationDirectory());
|
||||
|
||||
if (m_ui->CopyFileRadioButton->isChecked())
|
||||
{
|
||||
Q_EMIT DoCopyFiles();
|
||||
}
|
||||
else if (m_ui->MoveFileRadioButton->isChecked())
|
||||
{
|
||||
Q_EMIT DoMoveFiles();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::reject()
|
||||
{
|
||||
Q_EMIT Cancel();
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::ShowMessage()
|
||||
{
|
||||
QString message = m_ui->CopyFileRadioButton->isChecked() ? g_copyFilesMessage : g_moveFilesMessage;
|
||||
m_ui->RaidoButtonMessage->setText(message.arg(g_assetProcessorLink));
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::OnBrowseDestinationFilePath()
|
||||
{
|
||||
Q_EMIT BrowseDestinationPath(m_ui->DestinationLineEdit);
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::UpdateMessage(QString message)
|
||||
{
|
||||
m_ui->NumberOfFilesMessage->setText(message);
|
||||
}
|
||||
|
||||
void SelectDestinationDialog::ValidatePath()
|
||||
{
|
||||
if (!m_ui->DestinationLineEdit->hasAcceptableInput())
|
||||
{
|
||||
m_ui->DestinationLineEdit->setToolTip(m_validator->infoToolTip());
|
||||
Q_EMIT UpdateImportButtonState(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString destinationDirectory = DestinationDirectory();
|
||||
int strLength = destinationDirectory.length();
|
||||
|
||||
// store the updated acceptable destination directory into the registry,
|
||||
// so that when users manually modify the directory,
|
||||
// the Asset Importer will remember it
|
||||
Q_EMIT SetDestinationDirectory(destinationDirectory);
|
||||
|
||||
m_ui->DestinationLineEdit->setToolTip("");
|
||||
Q_EMIT UpdateImportButtonState(strLength > 0);
|
||||
}
|
||||
}
|
||||
|
||||
QString SelectDestinationDialog::DestinationDirectory() const
|
||||
{
|
||||
return QDir::fromNativeSeparators(m_ui->DestinationLineEdit->text());
|
||||
}
|
||||
|
||||
#include <AssetImporter/UI/moc_SelectDestinationDialog.cpp>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzQtComponents/Components/StyledLineEdit.h>
|
||||
#include <QLabel>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#endif
|
||||
|
||||
class StyledLineEdit;
|
||||
class QValidator;
|
||||
|
||||
class DestinationDialogValidator;
|
||||
|
||||
namespace Ui {
|
||||
class SelectDestinationDialog;
|
||||
}
|
||||
|
||||
class SelectDestinationDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SelectDestinationDialog(QString message, QWidget* parent = nullptr);
|
||||
~SelectDestinationDialog();
|
||||
|
||||
Q_SIGNALS:
|
||||
void GoBack();
|
||||
void DoCopyFiles();
|
||||
void DoMoveFiles();
|
||||
void BrowseDestinationPath(QLineEdit* destinationLineEdit);
|
||||
void Cancel();
|
||||
void UpdateImportButtonState(bool enabled);
|
||||
void SetDestinationDirectory(QString destinationDirectory);
|
||||
|
||||
public Q_SLOTS:
|
||||
void accept();
|
||||
void reject();
|
||||
void ShowMessage();
|
||||
void OnBrowseDestinationFilePath();
|
||||
void ValidatePath();
|
||||
|
||||
private:
|
||||
void UpdateMessage(QString message);
|
||||
void InitializeButtons();
|
||||
void SetPreviousDestinationDirectory();
|
||||
QString DestinationDirectory() const;
|
||||
|
||||
QScopedPointer<Ui::SelectDestinationDialog> m_ui;
|
||||
DestinationDialogValidator* m_validator;
|
||||
};
|
||||
@@ -0,0 +1,500 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SelectDestinationDialog</class>
|
||||
<widget class="QWidget" name="SelectDestinationDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>587</width>
|
||||
<height>409</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>587</width>
|
||||
<height>409</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Import Asset(s)</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterDialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="mainVerticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="NumberOfFilesMessage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>329</width>
|
||||
<height>19</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Importing 0 asset(s).</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="DestinationFolderLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Destination Folder</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>8</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AzQtComponents::StyledLineEdit" name="DestinationLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLineEdit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>8</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="BrowseButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>76</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="QuestionMessage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>19</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>How should we import these file(s)?</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>8</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="radioButtonHorizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="CopyFileRadioButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy files</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterRadioButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="MoveFileRadioButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Move files</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterRadioButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="CopySpacer1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="RaidoButtonMessage">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>72</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string>AssetImporterLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="MoveSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>584</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::NoButton</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::StyledLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>AzQtComponents/Components/StyledLineEdit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user