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/AssetImporterDragAndDropHan...

215 lines
5.8 KiB
C++

/*
* 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>