2024-03-29 05:43:46 +00:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-08-19 04:25:15 +00:00
|
|
|
#include <QClipboard>
|
2024-03-29 05:43:46 +00:00
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QMenu>
|
2024-07-05 23:57:54 +00:00
|
|
|
#include <QMessageBox>
|
2024-03-29 05:43:46 +00:00
|
|
|
#include <QTreeWidget>
|
|
|
|
#include <QTreeWidgetItem>
|
2024-07-05 23:57:54 +00:00
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
#include "cheats_patches.h"
|
2024-03-29 05:43:46 +00:00
|
|
|
#include "game_info.h"
|
2024-06-11 02:42:21 +00:00
|
|
|
#include "trophy_viewer.h"
|
2024-03-29 05:43:46 +00:00
|
|
|
|
2024-07-05 23:57:54 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
#include <ShlObj.h>
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <objbase.h>
|
|
|
|
#include <shlguid.h>
|
|
|
|
#include <shobjidl.h>
|
|
|
|
#endif
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
#include "common/path_util.h"
|
2024-07-05 23:57:54 +00:00
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
class GuiContextMenus : public QObject {
|
|
|
|
Q_OBJECT
|
2024-03-29 05:43:46 +00:00
|
|
|
public:
|
|
|
|
void RequestGameMenu(const QPoint& pos, QVector<GameInfo> m_games, QTableWidget* widget,
|
|
|
|
bool isList) {
|
|
|
|
QPoint global_pos = widget->viewport()->mapToGlobal(pos);
|
|
|
|
int itemID = 0;
|
|
|
|
if (isList) {
|
|
|
|
itemID = widget->currentRow();
|
|
|
|
} else {
|
|
|
|
itemID = widget->currentRow() * widget->columnCount() + widget->currentColumn();
|
|
|
|
}
|
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
// Do not show the menu if an item is selected
|
|
|
|
if (itemID == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
// Setup menu.
|
|
|
|
QMenu menu(widget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction createShortcut(tr("Create Shortcut"), widget);
|
|
|
|
QAction openFolder(tr("Open Game Folder"), widget);
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
QAction openCheats(tr("Cheats / Patches"), widget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction openSfoViewer(tr("SFO Viewer"), widget);
|
|
|
|
QAction openTrophyViewer(tr("Trophy Viewer"), widget);
|
2024-03-29 05:43:46 +00:00
|
|
|
|
|
|
|
menu.addAction(&openFolder);
|
2024-07-10 16:20:19 +00:00
|
|
|
menu.addAction(&createShortcut);
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
menu.addAction(&openCheats);
|
2024-03-29 05:43:46 +00:00
|
|
|
menu.addAction(&openSfoViewer);
|
2024-06-11 02:42:21 +00:00
|
|
|
menu.addAction(&openTrophyViewer);
|
2024-07-05 23:57:54 +00:00
|
|
|
|
2024-08-19 04:25:15 +00:00
|
|
|
// "Copy" submenu.
|
2024-08-25 08:45:26 +00:00
|
|
|
QMenu* copyMenu = new QMenu(tr("Copy info"), widget);
|
|
|
|
QAction* copyName = new QAction(tr("Copy Name"), widget);
|
|
|
|
QAction* copySerial = new QAction(tr("Copy Serial"), widget);
|
|
|
|
QAction* copyNameAll = new QAction(tr("Copy All"), widget);
|
2024-08-19 04:25:15 +00:00
|
|
|
|
|
|
|
copyMenu->addAction(copyName);
|
|
|
|
copyMenu->addAction(copySerial);
|
|
|
|
copyMenu->addAction(copyNameAll);
|
|
|
|
|
|
|
|
menu.addMenu(copyMenu);
|
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
// Show menu.
|
|
|
|
auto selected = menu.exec(global_pos);
|
|
|
|
if (!selected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == &openFolder) {
|
|
|
|
QString folderPath = QString::fromStdString(m_games[itemID].path);
|
|
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == &openSfoViewer) {
|
|
|
|
PSF psf;
|
2024-06-11 02:42:21 +00:00
|
|
|
if (psf.open(m_games[itemID].path + "/sce_sys/param.sfo", {})) {
|
2024-03-29 05:43:46 +00:00
|
|
|
int rows = psf.map_strings.size() + psf.map_integers.size();
|
|
|
|
QTableWidget* tableWidget = new QTableWidget(rows, 2);
|
2024-06-11 02:42:21 +00:00
|
|
|
tableWidget->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, tableWidget,
|
2024-08-23 19:38:55 +00:00
|
|
|
[tableWidget]() { tableWidget->deleteLater(); });
|
2024-06-11 02:42:21 +00:00
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
tableWidget->verticalHeader()->setVisible(false); // Hide vertical header
|
|
|
|
int row = 0;
|
|
|
|
|
|
|
|
for (const auto& pair : psf.map_strings) {
|
|
|
|
QTableWidgetItem* keyItem =
|
|
|
|
new QTableWidgetItem(QString::fromStdString(pair.first));
|
|
|
|
QTableWidgetItem* valueItem =
|
|
|
|
new QTableWidgetItem(QString::fromStdString(pair.second));
|
|
|
|
|
|
|
|
tableWidget->setItem(row, 0, keyItem);
|
|
|
|
tableWidget->setItem(row, 1, valueItem);
|
|
|
|
keyItem->setFlags(keyItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
valueItem->setFlags(valueItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
for (const auto& pair : psf.map_integers) {
|
|
|
|
QTableWidgetItem* keyItem =
|
|
|
|
new QTableWidgetItem(QString::fromStdString(pair.first));
|
|
|
|
QTableWidgetItem* valueItem = new QTableWidgetItem(
|
|
|
|
QString("0x").append(QString::number(pair.second, 16)));
|
|
|
|
|
|
|
|
tableWidget->setItem(row, 0, keyItem);
|
|
|
|
tableWidget->setItem(row, 1, valueItem);
|
|
|
|
keyItem->setFlags(keyItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
valueItem->setFlags(valueItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
tableWidget->resizeColumnsToContents();
|
|
|
|
tableWidget->resizeRowsToContents();
|
|
|
|
|
|
|
|
int width = tableWidget->horizontalHeader()->sectionSize(0) +
|
|
|
|
tableWidget->horizontalHeader()->sectionSize(1) + 2;
|
|
|
|
int height = (rows + 1) * (tableWidget->rowHeight(0));
|
|
|
|
tableWidget->setFixedSize(width, height);
|
|
|
|
tableWidget->sortItems(0, Qt::AscendingOrder);
|
|
|
|
tableWidget->horizontalHeader()->setVisible(false);
|
|
|
|
|
|
|
|
tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
2024-08-25 08:45:26 +00:00
|
|
|
tableWidget->setWindowTitle(tr("SFO Viewer"));
|
2024-03-29 05:43:46 +00:00
|
|
|
tableWidget->show();
|
|
|
|
}
|
|
|
|
}
|
2024-06-11 02:42:21 +00:00
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
if (selected == &openCheats) {
|
|
|
|
QString gameName = QString::fromStdString(m_games[itemID].name);
|
|
|
|
QString gameSerial = QString::fromStdString(m_games[itemID].serial);
|
|
|
|
QString gameVersion = QString::fromStdString(m_games[itemID].version);
|
|
|
|
QString gameSize = QString::fromStdString(m_games[itemID].size);
|
|
|
|
QPixmap gameImage(QString::fromStdString(m_games[itemID].icon_path));
|
|
|
|
CheatsPatches* cheatsPatches =
|
|
|
|
new CheatsPatches(gameName, gameSerial, gameVersion, gameSize, gameImage);
|
|
|
|
cheatsPatches->show();
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, cheatsPatches,
|
|
|
|
[widget, cheatsPatches]() { cheatsPatches->deleteLater(); });
|
|
|
|
}
|
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
if (selected == &openTrophyViewer) {
|
|
|
|
QString trophyPath = QString::fromStdString(m_games[itemID].serial);
|
|
|
|
QString gameTrpPath = QString::fromStdString(m_games[itemID].path);
|
|
|
|
TrophyViewer* trophyViewer = new TrophyViewer(trophyPath, gameTrpPath);
|
|
|
|
trophyViewer->show();
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, trophyViewer,
|
2024-08-23 19:38:55 +00:00
|
|
|
[trophyViewer]() { trophyViewer->deleteLater(); });
|
2024-06-11 02:42:21 +00:00
|
|
|
}
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
if (selected == &createShortcut) {
|
|
|
|
QString targetPath = QString::fromStdString(m_games[itemID].path);
|
|
|
|
QString ebootPath = targetPath + "/eboot.bin";
|
|
|
|
|
|
|
|
// Get the full path to the icon
|
|
|
|
QString iconPath = QString::fromStdString(m_games[itemID].icon_path);
|
|
|
|
QFileInfo iconFileInfo(iconPath);
|
|
|
|
QString icoPath = iconFileInfo.absolutePath() + "/" + iconFileInfo.baseName() + ".ico";
|
|
|
|
|
|
|
|
// Path to shortcut/link
|
|
|
|
QString linkPath;
|
|
|
|
|
|
|
|
// Path to the shadps4.exe executable
|
|
|
|
QString exePath;
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
linkPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" +
|
2024-07-09 03:55:48 +00:00
|
|
|
QString::fromStdString(m_games[itemID].name)
|
|
|
|
.remove(QRegularExpression("[\\\\/:*?\"<>|]")) +
|
|
|
|
".lnk";
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
exePath = QCoreApplication::applicationFilePath().replace("\\", "/");
|
|
|
|
|
|
|
|
#else
|
|
|
|
linkPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" +
|
2024-07-09 03:55:48 +00:00
|
|
|
QString::fromStdString(m_games[itemID].name)
|
|
|
|
.remove(QRegularExpression("[\\\\/:*?\"<>|]")) +
|
|
|
|
".desktop";
|
2024-07-05 23:57:54 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Convert the icon to .ico if necessary
|
|
|
|
if (iconFileInfo.suffix().toLower() == "png") {
|
|
|
|
// Convert icon from PNG to ICO
|
|
|
|
if (convertPngToIco(iconPath, icoPath)) {
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (createShortcutWin(linkPath, ebootPath, icoPath, exePath)) {
|
|
|
|
#else
|
|
|
|
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
|
|
|
|
#endif
|
|
|
|
QMessageBox::information(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Shortcut creation"),
|
|
|
|
QString(tr("Shortcut created successfully!\n %1")).arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
} else {
|
|
|
|
QMessageBox::critical(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Error"),
|
|
|
|
QString(tr("Error creating shortcut!\n %1")).arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
2024-08-25 08:45:26 +00:00
|
|
|
QMessageBox::critical(nullptr, tr("Error"), tr("Failed to convert icon."));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If the icon is already in ICO format, we just create the shortcut
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (createShortcutWin(linkPath, ebootPath, iconPath, exePath)) {
|
|
|
|
#else
|
|
|
|
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
|
|
|
|
#endif
|
|
|
|
QMessageBox::information(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Shortcut creation"),
|
|
|
|
QString(tr("Shortcut created successfully!\n %1")).arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
} else {
|
2024-08-25 08:45:26 +00:00
|
|
|
QMessageBox::critical(
|
|
|
|
nullptr, tr("Error"),
|
|
|
|
QString(tr("Error creating shortcut!\n %1")).arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-19 04:25:15 +00:00
|
|
|
|
|
|
|
// Handle the "Copy" actions
|
|
|
|
if (selected == copyName) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
clipboard->setText(QString::fromStdString(m_games[itemID].name));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == copySerial) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
clipboard->setText(QString::fromStdString(m_games[itemID].serial));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == copyNameAll) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
QString combinedText = QString("Name:%1 | Serial:%2 | Version:%3 | Size:%4")
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].name))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].serial))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].version))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].size));
|
|
|
|
clipboard->setText(combinedText);
|
|
|
|
}
|
2024-03-29 05:43:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) {
|
|
|
|
int row = 0;
|
|
|
|
for (int i = 0; i < treeWidget->topLevelItemCount(); i++) { // check top level/parent items
|
|
|
|
QTreeWidgetItem* currentItem = treeWidget->topLevelItem(i);
|
|
|
|
if (currentItem == item) {
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
|
|
|
|
if (currentItem->childCount() > 0) { // check child items
|
|
|
|
for (int j = 0; j < currentItem->childCount(); j++) {
|
|
|
|
QTreeWidgetItem* childItem = currentItem->child(j);
|
|
|
|
if (childItem == item) {
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
void RequestGameMenuPKGViewer(
|
|
|
|
const QPoint& pos, QStringList m_pkg_app_list, QTreeWidget* treeWidget,
|
|
|
|
std::function<void(std::filesystem::path, int, int)> InstallDragDropPkg) {
|
2024-03-29 05:43:46 +00:00
|
|
|
QPoint global_pos = treeWidget->viewport()->mapToGlobal(pos); // context menu position
|
|
|
|
QTreeWidgetItem* currentItem = treeWidget->currentItem(); // current clicked item
|
|
|
|
int itemIndex = GetRowIndex(treeWidget, currentItem); // row
|
|
|
|
|
|
|
|
QMenu menu(treeWidget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction installPackage(tr("Install PKG"), treeWidget);
|
2024-03-29 05:43:46 +00:00
|
|
|
|
|
|
|
menu.addAction(&installPackage);
|
|
|
|
|
|
|
|
auto selected = menu.exec(global_pos);
|
|
|
|
if (!selected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == &installPackage) {
|
2024-03-30 06:03:15 +00:00
|
|
|
QStringList pkg_app_ = m_pkg_app_list[itemIndex].split(";;");
|
2024-06-11 02:42:21 +00:00
|
|
|
std::filesystem::path path(pkg_app_[9].toStdString());
|
|
|
|
#ifdef _WIN32
|
|
|
|
path = std::filesystem::path(pkg_app_[9].toStdWString());
|
|
|
|
#endif
|
|
|
|
InstallDragDropPkg(path, 1, 1);
|
2024-03-29 05:43:46 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool convertPngToIco(const QString& pngFilePath, const QString& icoFilePath) {
|
|
|
|
// Load the PNG image
|
|
|
|
QImage image(pngFilePath);
|
|
|
|
if (image.isNull()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scale the image to the default icon size (256x256 pixels)
|
|
|
|
QImage scaledImage =
|
|
|
|
image.scaled(QSize(256, 256), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
|
|
|
|
|
// Convert the image to QPixmap
|
|
|
|
QPixmap pixmap = QPixmap::fromImage(scaledImage);
|
|
|
|
|
|
|
|
// Save the pixmap as an ICO file
|
|
|
|
if (pixmap.save(icoFilePath, "ICO")) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
bool createShortcutWin(const QString& linkPath, const QString& targetPath,
|
|
|
|
const QString& iconPath, const QString& exePath) {
|
|
|
|
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
|
|
|
|
|
|
|
// Create the ShellLink object
|
|
|
|
IShellLink* pShellLink = nullptr;
|
|
|
|
HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
|
|
|
|
IID_IShellLink, (LPVOID*)&pShellLink);
|
|
|
|
if (SUCCEEDED(hres)) {
|
|
|
|
// Defines the path to the program executable
|
|
|
|
pShellLink->SetPath((LPCWSTR)exePath.utf16());
|
|
|
|
|
|
|
|
// Sets the home directory ("Start in")
|
|
|
|
pShellLink->SetWorkingDirectory((LPCWSTR)QFileInfo(exePath).absolutePath().utf16());
|
|
|
|
|
|
|
|
// Set arguments, eboot.bin file location
|
|
|
|
QString arguments = QString("\"%1\"").arg(targetPath);
|
|
|
|
pShellLink->SetArguments((LPCWSTR)arguments.utf16());
|
|
|
|
|
|
|
|
// Set the icon for the shortcut
|
|
|
|
pShellLink->SetIconLocation((LPCWSTR)iconPath.utf16(), 0);
|
|
|
|
|
|
|
|
// Save the shortcut
|
|
|
|
IPersistFile* pPersistFile = nullptr;
|
|
|
|
hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&pPersistFile);
|
|
|
|
if (SUCCEEDED(hres)) {
|
|
|
|
hres = pPersistFile->Save((LPCWSTR)linkPath.utf16(), TRUE);
|
|
|
|
pPersistFile->Release();
|
|
|
|
}
|
|
|
|
pShellLink->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
return SUCCEEDED(hres);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
bool createShortcutLinux(const QString& linkPath, const QString& targetPath,
|
|
|
|
const QString& iconPath) {
|
|
|
|
QFile shortcutFile(linkPath);
|
|
|
|
if (!shortcutFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
|
|
QMessageBox::critical(nullptr, "Error",
|
2024-08-04 13:07:10 +00:00
|
|
|
QString("Error creating shortcut!\n %1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QTextStream out(&shortcutFile);
|
|
|
|
out << "[Desktop Entry]\n";
|
|
|
|
out << "Version=1.0\n";
|
2024-07-06 18:10:28 +00:00
|
|
|
out << "Name=" << QFileInfo(linkPath).baseName() << "\n";
|
2024-07-06 16:40:26 +00:00
|
|
|
out << "Exec=" << QCoreApplication::applicationFilePath() << " \"" << targetPath << "\"\n";
|
2024-07-06 16:42:53 +00:00
|
|
|
out << "Icon=" << iconPath << "\n";
|
2024-07-05 23:57:54 +00:00
|
|
|
out << "Terminal=false\n";
|
|
|
|
out << "Type=Application\n";
|
|
|
|
shortcutFile.close();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
2024-03-29 05:43:46 +00:00
|
|
|
};
|