Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qt: Cache drag-and-drop result when moving it #14207

Merged
merged 1 commit into from Jul 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 45 additions & 25 deletions rpcs3/rpcs3qt/main_window.cpp
Expand Up @@ -3248,11 +3248,26 @@ Check data for valid file types and cache their paths if necessary
*/
main_window::drop_type main_window::IsValidFile(const QMimeData& md, QStringList* drop_paths)
{
auto drop_type = drop_type::drop_error;
drop_type type = drop_type::drop_error;

const QList<QUrl> list = md.urls(); // get list of all the dropped file urls
QList<QUrl> list = md.urls(); // get list of all the dropped file urls

for (auto&& url : list) // check each file in url list for valid type
// Try to cache the data for half a second
if (m_drop_file_timestamp != umax && m_drop_file_url_list == list && get_system_time() - m_drop_file_timestamp < 500'000)
{
return m_drop_file_cached_drop_type;
}

m_drop_file_url_list = std::move(list);

auto set_result = [&](drop_type _type)
{
m_drop_file_timestamp = get_system_time();
m_drop_file_cached_drop_type = type;
return type;
};

for (auto&& url : m_drop_file_url_list) // check each file in url list for valid type
{
const QString path = url.toLocalFile(); // convert url to filepath
const QFileInfo info(path);
Expand All @@ -3262,72 +3277,77 @@ main_window::drop_type main_window::IsValidFile(const QMimeData& md, QStringList
// check for directories first, only valid if all other paths led to directories until now.
if (info.isDir())
{
if (drop_type != drop_type::drop_dir && drop_type != drop_type::drop_error)
if (type != drop_type::drop_dir && type != drop_type::drop_error)
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

drop_type = drop_type::drop_dir;
type = drop_type::drop_dir;
}
else if (!info.exists())
{
// If does not exist (anymore), ignore it
continue;
}
else if (info.size() < 0x4)
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}
else if (info.suffix() == "PUP")
{
if (list.size() != 1)
if (m_drop_file_url_list.size() != 1)
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

drop_type = drop_type::drop_pup;
type = drop_type::drop_pup;
}
else if (info.fileName().toLower() == "param.sfo")
{
if (drop_type != drop_type::drop_psf && drop_type != drop_type::drop_error)
if (type != drop_type::drop_psf && type != drop_type::drop_error)
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

drop_type = drop_type::drop_psf;
type = drop_type::drop_psf;
}
else if (suffix_lo == "pkg")
{
if (drop_type != drop_type::drop_rap_edat_pkg && drop_type != drop_type::drop_error)
if (type != drop_type::drop_rap_edat_pkg && type != drop_type::drop_error)
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

drop_type = drop_type::drop_rap_edat_pkg;
type = drop_type::drop_rap_edat_pkg;
}
else if (suffix_lo == "rap" || suffix_lo == "edat")
{
if (info.size() < 0x10 || (drop_type != drop_type::drop_rap_edat_pkg && drop_type != drop_type::drop_error))
if (info.size() < 0x10 || (type != drop_type::drop_rap_edat_pkg && type != drop_type::drop_error))
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

drop_type = drop_type::drop_rap_edat_pkg;
type = drop_type::drop_rap_edat_pkg;
}
else if (list.size() == 1)
else if (m_drop_file_url_list.size() == 1)
{
if (suffix_lo == "rrc")
{
drop_type = drop_type::drop_rrc;
type = drop_type::drop_rrc;
}
// The emulator allows to execute ANY filetype, just not from drag-and-drop because it is confusing to users
else if (suffix_lo == "savestat" || suffix_lo == "sprx" || suffix_lo == "self" || suffix_lo == "bin" || suffix_lo == "prx" || suffix_lo == "elf" || suffix_lo == "o")
{
drop_type = drop_type::drop_game;
type = drop_type::drop_game;
}
else
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}
}
else
{
return drop_type::drop_error;
return set_result(drop_type::drop_error);
}

if (drop_paths) // we only need to know the paths on drop
Expand All @@ -3336,7 +3356,7 @@ main_window::drop_type main_window::IsValidFile(const QMimeData& md, QStringList
}
}

return drop_type;
return set_result(type);
}

void main_window::dropEvent(QDropEvent* event)
Expand Down
7 changes: 6 additions & 1 deletion rpcs3/rpcs3qt/main_window.h
Expand Up @@ -8,6 +8,8 @@
#include <QActionGroup>
#include <QMainWindow>
#include <QIcon>
#include <QList>
#include <QUrl>
#include <QMimeData>

#include "update_manager.h"
Expand Down Expand Up @@ -156,7 +158,10 @@ private Q_SLOTS:
void ExtractTar();
void ExtractMSELF();

static drop_type IsValidFile(const QMimeData& md, QStringList* drop_paths = nullptr);
QList<QUrl> m_drop_file_url_list;
u64 m_drop_file_timestamp = umax;
drop_type m_drop_file_cached_drop_type = drop_type::drop_error;
drop_type IsValidFile(const QMimeData& md, QStringList* drop_paths = nullptr);
static void AddGamesFromDir(const QString& path);

QAction* CreateRecentAction(const q_string_pair& entry, const uint& sc_idx);
Expand Down