summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar boludoz2023-10-17 02:57:35 -0300
committerGravatar boludoz2023-10-17 02:57:35 -0300
commit9908434c14d68faa7fde933258aafd7da15b3b3b (patch)
tree554f22f093dbac67d9e58f67dba63f0a3ffcd22b /src
parentMerge branch 'yuzu-emu:master' into new-shortcut (diff)
downloadyuzu-9908434c14d68faa7fde933258aafd7da15b3b3b.tar.gz
yuzu-9908434c14d68faa7fde933258aafd7da15b3b3b.tar.xz
yuzu-9908434c14d68faa7fde933258aafd7da15b3b3b.zip
Final refactorization
Diffstat (limited to 'src')
-rw-r--r--src/yuzu/main.cpp131
1 files changed, 45 insertions, 86 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 0e0d7ef0e..01b64e165 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2846,48 +2846,13 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2846 const std::filesystem::path& command, 2846 const std::filesystem::path& command,
2847 const std::string& arguments, const std::string& categories, 2847 const std::string& arguments, const std::string& categories,
2848 const std::string& keywords, const std::string& name) try { 2848 const std::string& keywords, const std::string& name) try {
2849
2850#if defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32) // Linux, FreeBSD and Windows
2851 // Plus 'name' is required
2852 if (name.empty()) {
2853 LOG_ERROR(Frontend, "Name is empty");
2854 return false;
2855 }
2856
2857 // Copy characters if they are not illegal in Windows filenames
2858 std::string filename = "";
2859 const std::string illegal_chars = "<>:\"/\\|?*";
2860 filename.reserve(name.size());
2861 std::copy_if(name.begin(), name.end(), std::back_inserter(filename),
2862 [&illegal_chars](char c) { return illegal_chars.find(c) == std::string::npos; });
2863
2864 if (filename.empty()) {
2865 LOG_ERROR(Frontend, "Filename is empty");
2866 return false;
2867 }
2868
2869 if (!std::filesystem::is_regular_file(command)) {
2870 LOG_ERROR(Frontend, "Command is not a regular file");
2871 return false;
2872 }
2873
2874 std::filesystem::path shortcut_path_full = shortcut_path / filename;
2875#endif
2876
2877#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD 2849#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD
2878 // Reference for the desktop file template: 2850 std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop");
2879 // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html
2880
2881 // Append .desktop extension
2882 shortcut_path_full += ".desktop";
2883
2884 // Create shortcut file
2885 std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc); 2851 std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
2886 if (!shortcut_stream.is_open()) { 2852 if (!shortcut_stream.is_open()) {
2887 LOG_ERROR(Frontend, "Failed to create shortcut"); 2853 LOG_ERROR(Frontend, "Failed to create shortcut");
2888 return false; 2854 return false;
2889 } 2855 }
2890
2891 fmt::print(shortcut_stream, "[Desktop Entry]\n"); 2856 fmt::print(shortcut_stream, "[Desktop Entry]\n");
2892 fmt::print(shortcut_stream, "Type=Application\n"); 2857 fmt::print(shortcut_stream, "Type=Application\n");
2893 fmt::print(shortcut_stream, "Version=1.0\n"); 2858 fmt::print(shortcut_stream, "Version=1.0\n");
@@ -2899,11 +2864,7 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2899 fmt::print(shortcut_stream, "Icon={}\n", icon_path.string()); 2864 fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
2900 } 2865 }
2901 fmt::print(shortcut_stream, "TryExec={}\n", command.string()); 2866 fmt::print(shortcut_stream, "TryExec={}\n", command.string());
2902 fmt::print(shortcut_stream, "Exec={}", command.string()); 2867 fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments);
2903 if (!arguments.empty()) {
2904 fmt::print(shortcut_stream, " {}", arguments);
2905 }
2906 fmt::print(shortcut_stream, "\n");
2907 if (!categories.empty()) { 2868 if (!categories.empty()) {
2908 fmt::print(shortcut_stream, "Categories={}\n", categories); 2869 fmt::print(shortcut_stream, "Categories={}\n", categories);
2909 } 2870 }
@@ -2912,15 +2873,14 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2912 } 2873 }
2913 return true; 2874 return true;
2914#elif defined(_WIN32) // Windows 2875#elif defined(_WIN32) // Windows
2915 HRESULT hr = CoInitialize(NULL); 2876 HRESULT hr = CoInitialize(nullptr);
2916 if (FAILED(hr)) { 2877 if (FAILED(hr)) {
2917 LOG_ERROR(Frontend, "CoInitialize failed"); 2878 LOG_ERROR(Frontend, "CoInitialize failed");
2918 return false; 2879 return false;
2919 } 2880 }
2920 2881 SCOPE_EXIT({ CoUninitialize(); });
2921 IShellLinkW* ps1 = nullptr; 2882 IShellLinkW* ps1 = nullptr;
2922 IPersistFile* persist_file = nullptr; 2883 IPersistFile* persist_file = nullptr;
2923
2924 SCOPE_EXIT({ 2884 SCOPE_EXIT({
2925 if (persist_file != nullptr) { 2885 if (persist_file != nullptr) {
2926 persist_file->Release(); 2886 persist_file->Release();
@@ -2928,40 +2888,50 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2928 if (ps1 != nullptr) { 2888 if (ps1 != nullptr) {
2929 ps1->Release(); 2889 ps1->Release();
2930 } 2890 }
2931
2932 CoUninitialize();
2933 }); 2891 });
2934 2892 HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
2935 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, 2893 reinterpret_cast<void**>(&ps1));
2936 (void**)&ps1); 2894 if (FAILED(hres)) {
2937 2895 LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
2938 if (SUCCEEDED(hres)) {
2939 hres = ps1->SetPath(Common::UTF8ToUTF16W(command.string()).data());
2940 } else {
2941 LOG_ERROR(Frontend, "Failed to create CoCreateInstance");
2942 return false; 2896 return false;
2943 } 2897 }
2944 if (SUCCEEDED(hres) && !arguments.empty()) { 2898 hres = ps1->SetPath(command.c_str());
2899 if (FAILED(hres)) {
2900 LOG_ERROR(Frontend, "Failed to set path");
2901 return false;
2902 }
2903 if (!arguments.empty()) {
2945 hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data()); 2904 hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
2905 if (FAILED(hres)) {
2906 LOG_ERROR(Frontend, "Failed to set arguments");
2907 return false;
2908 }
2946 } 2909 }
2947 if (SUCCEEDED(hres) && !comment.empty()) { 2910 if (!comment.empty()) {
2948 hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data()); 2911 hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
2912 if (FAILED(hres)) {
2913 LOG_ERROR(Frontend, "Failed to set description");
2914 return false;
2915 }
2949 } 2916 }
2950 if (SUCCEEDED(hres) && std::filesystem::is_regular_file(icon_path)) { 2917 if (std::filesystem::is_regular_file(icon_path)) {
2951 hres = ps1->SetIconLocation(Common::UTF8ToUTF16W(icon_path.string()).data(), 0); 2918 hres = ps1->SetIconLocation(icon_path.c_str(), 0);
2952 } 2919 if (FAILED(hres)) {
2953 if (SUCCEEDED(hres)) { 2920 LOG_ERROR(Frontend, "Failed to set icon location");
2954 hres = ps1->QueryInterface(IID_IPersistFile, (void**)&persist_file); 2921 return false;
2922 }
2955 } 2923 }
2956 if (SUCCEEDED(hres) && persist_file != nullptr) { 2924 hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&persist_file));
2957 hres = persist_file->Save( 2925 if (FAILED(hres)) {
2958 Common::UTF8ToUTF16W((shortcut_path_full).string() + ".lnk").data(), TRUE); 2926 LOG_ERROR(Frontend, "Failed to get IPersistFile interface");
2927 return false;
2959 } 2928 }
2960 if (SUCCEEDED(hres)) { 2929 hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE);
2961 return true; 2930 if (FAILED(hres)) {
2931 LOG_ERROR(Frontend, "Failed to save shortcut");
2932 return false;
2962 } 2933 }
2963 LOG_ERROR(Frontend, "Failed to create shortcut"); 2934 return true;
2964 return false;
2965#else // Unsupported platform 2935#else // Unsupported platform
2966 return false; 2936 return false;
2967#endif 2937#endif
@@ -2969,7 +2939,6 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2969 LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what()); 2939 LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
2970 return false; 2940 return false;
2971} 2941}
2972
2973// Messages in pre-defined message boxes for less code spaghetti 2942// Messages in pre-defined message boxes for less code spaghetti
2974bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) { 2943bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) {
2975 int result = 0; 2944 int result = 0;
@@ -3009,7 +2978,6 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt
3009 2978
3010bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name, 2979bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
3011 std::filesystem::path& out_icon_path) { 2980 std::filesystem::path& out_icon_path) {
3012
3013 // Get path to Yuzu icons directory & icon extension 2981 // Get path to Yuzu icons directory & icon extension
3014 std::string ico_extension = "png"; 2982 std::string ico_extension = "png";
3015#if defined(_WIN32) 2983#if defined(_WIN32)
@@ -3038,20 +3006,16 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi
3038 3006
3039void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path, 3007void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
3040 GameListShortcutTarget target) { 3008 GameListShortcutTarget target) {
3041
3042 std::string game_title; 3009 std::string game_title;
3043 QString qt_game_title; 3010 QString qt_game_title;
3044 std::filesystem::path out_icon_path; 3011 std::filesystem::path out_icon_path;
3045
3046 // Get path to yuzu executable 3012 // Get path to yuzu executable
3047 const QStringList args = QApplication::arguments(); 3013 const QStringList args = QApplication::arguments();
3048 std::filesystem::path yuzu_command = args[0].toStdString(); 3014 std::filesystem::path yuzu_command = args[0].toStdString();
3049
3050 // If relative path, make it an absolute path 3015 // If relative path, make it an absolute path
3051 if (yuzu_command.c_str()[0] == '.') { 3016 if (yuzu_command.c_str()[0] == '.') {
3052 yuzu_command = Common::FS::GetCurrentDir() / yuzu_command; 3017 yuzu_command = Common::FS::GetCurrentDir() / yuzu_command;
3053 } 3018 }
3054
3055 // Shortcut path 3019 // Shortcut path
3056 std::filesystem::path shortcut_path{}; 3020 std::filesystem::path shortcut_path{};
3057 if (target == GameListShortcutTarget::Desktop) { 3021 if (target == GameListShortcutTarget::Desktop) {
@@ -3061,7 +3025,6 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
3061 shortcut_path = 3025 shortcut_path =
3062 QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString(); 3026 QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString();
3063 } 3027 }
3064
3065 // Icon path and title 3028 // Icon path and title
3066 if (std::filesystem::exists(shortcut_path)) { 3029 if (std::filesystem::exists(shortcut_path)) {
3067 // Get title from game file 3030 // Get title from game file
@@ -3070,17 +3033,20 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
3070 const auto control = pm.GetControlMetadata(); 3033 const auto control = pm.GetControlMetadata();
3071 const auto loader = 3034 const auto loader =
3072 Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::Mode::Read)); 3035 Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::Mode::Read));
3073
3074 game_title = fmt::format("{:016X}", program_id); 3036 game_title = fmt::format("{:016X}", program_id);
3075
3076 if (control.first != nullptr) { 3037 if (control.first != nullptr) {
3077 game_title = control.first->GetApplicationName(); 3038 game_title = control.first->GetApplicationName();
3078 } else { 3039 } else {
3079 loader->ReadTitle(game_title); 3040 loader->ReadTitle(game_title);
3080 } 3041 }
3081 3042 // Delete illegal characters from title
3043 const std::string illegal_chars = "<>:\"/\\|?*.";
3044 for (auto it = game_title.rbegin(); it != game_title.rend(); ++it) {
3045 if (illegal_chars.find(*it) != std::string::npos) {
3046 game_title.erase(it.base() - 1);
3047 }
3048 }
3082 qt_game_title = QString::fromStdString(game_title); 3049 qt_game_title = QString::fromStdString(game_title);
3083
3084 // Get icon from game file 3050 // Get icon from game file
3085 std::vector<u8> icon_image_file{}; 3051 std::vector<u8> icon_image_file{};
3086 if (control.second != nullptr) { 3052 if (control.second != nullptr) {
@@ -3088,23 +3054,19 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
3088 } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) { 3054 } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) {
3089 LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path); 3055 LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path);
3090 } 3056 }
3091
3092 QImage icon_data = 3057 QImage icon_data =
3093 QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size())); 3058 QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
3094
3095 if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) { 3059 if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
3096 if (!SaveIconToFile(out_icon_path, icon_data)) { 3060 if (!SaveIconToFile(out_icon_path, icon_data)) {
3097 LOG_ERROR(Frontend, "Could not write icon to file"); 3061 LOG_ERROR(Frontend, "Could not write icon to file");
3098 } 3062 }
3099 } 3063 }
3100
3101 } else { 3064 } else {
3102 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, 3065 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
3103 qt_game_title); 3066 qt_game_title);
3104 LOG_ERROR(Frontend, "Invalid shortcut target"); 3067 LOG_ERROR(Frontend, "Invalid shortcut target");
3105 return; 3068 return;
3106 } 3069 }
3107
3108#if defined(_WIN32) 3070#if defined(_WIN32)
3109 if (!IsUserAnAdmin() && target == GameListShortcutTarget::Applications) { 3071 if (!IsUserAnAdmin() && target == GameListShortcutTarget::Applications) {
3110 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ADMIN, 3072 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ADMIN,
@@ -3125,7 +3087,6 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
3125 UISettings::values.shortcut_already_warned = true; 3087 UISettings::values.shortcut_already_warned = true;
3126 } 3088 }
3127#endif // __linux__ 3089#endif // __linux__
3128
3129 // Create shortcut 3090 // Create shortcut
3130 std::string arguments = fmt::format("-g \"{:s}\"", game_path); 3091 std::string arguments = fmt::format("-g \"{:s}\"", game_path);
3131 if (GMainWindow::CreateShortcutMessagesGUI( 3092 if (GMainWindow::CreateShortcutMessagesGUI(
@@ -3142,7 +3103,6 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
3142 qt_game_title); 3103 qt_game_title);
3143 return; 3104 return;
3144 } 3105 }
3145
3146 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, 3106 GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
3147 qt_game_title); 3107 qt_game_title);
3148} 3108}
@@ -4177,7 +4137,6 @@ void GMainWindow::OnLoadAmiibo() {
4177bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text, 4137bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text,
4178 QMessageBox::StandardButtons buttons, 4138 QMessageBox::StandardButtons buttons,
4179 QMessageBox::StandardButton defaultButton) { 4139 QMessageBox::StandardButton defaultButton) {
4180
4181 QMessageBox* box_dialog = new QMessageBox(parent); 4140 QMessageBox* box_dialog = new QMessageBox(parent);
4182 box_dialog->setWindowTitle(title); 4141 box_dialog->setWindowTitle(title);
4183 box_dialog->setText(text); 4142 box_dialog->setText(text);