mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-06-13 05:37:42 +02:00
Delete associated shortcuts when deleting instance (#3819)
This commit is contained in:
@ -69,6 +69,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
|
||||
m_settings->registerSetting("lastTimePlayed", 0);
|
||||
|
||||
m_settings->registerSetting("linkedInstances", "[]");
|
||||
m_settings->registerSetting("shortcuts", QString());
|
||||
|
||||
// Game time override
|
||||
auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
|
||||
@ -398,6 +399,57 @@ bool BaseInstance::syncInstanceDirName(const QString& newRoot) const
|
||||
return oldRoot == newRoot || QFile::rename(oldRoot, newRoot);
|
||||
}
|
||||
|
||||
void BaseInstance::registerShortcut(const ShortcutData& data)
|
||||
{
|
||||
auto currentShortcuts = shortcuts();
|
||||
currentShortcuts.append(data);
|
||||
qDebug() << "Registering shortcut for instance" << id() << "with name" << data.name << "and path" << data.filePath;
|
||||
setShortcuts(currentShortcuts);
|
||||
}
|
||||
|
||||
void BaseInstance::setShortcuts(const QList<ShortcutData>& shortcuts)
|
||||
{
|
||||
// FIXME: if no change, do not set. setting involves saving a file.
|
||||
QJsonArray array;
|
||||
for (const auto& elem : shortcuts) {
|
||||
array.append(QJsonObject{ { "name", elem.name }, { "filePath", elem.filePath }, { "target", static_cast<int>(elem.target) } });
|
||||
}
|
||||
|
||||
QJsonDocument document;
|
||||
document.setArray(array);
|
||||
m_settings->set("shortcuts", QString::fromUtf8(document.toJson(QJsonDocument::Compact)));
|
||||
}
|
||||
|
||||
QList<ShortcutData> BaseInstance::shortcuts() const
|
||||
{
|
||||
auto data = m_settings->get("shortcuts").toString().toUtf8();
|
||||
QJsonParseError parseError;
|
||||
auto document = QJsonDocument::fromJson(data, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError || !document.isArray())
|
||||
return {};
|
||||
|
||||
QList<ShortcutData> results;
|
||||
for (const auto& elem : document.array()) {
|
||||
if (!elem.isObject())
|
||||
continue;
|
||||
auto dict = elem.toObject();
|
||||
if (!dict.contains("name") || !dict.contains("filePath") || !dict.contains("target"))
|
||||
continue;
|
||||
int value = dict["target"].toInt(-1);
|
||||
if (!dict["name"].isString() || !dict["filePath"].isString() || value < 0 || value >= 3)
|
||||
continue;
|
||||
|
||||
QString shortcutName = dict["name"].toString();
|
||||
QString filePath = dict["filePath"].toString();
|
||||
if (!QDir(filePath).exists()) {
|
||||
qWarning() << "Shortcut" << shortcutName << "for instance" << name() << "have non-existent path" << filePath;
|
||||
continue;
|
||||
}
|
||||
results.append({ shortcutName, filePath, static_cast<ShortcutTarget>(value) });
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
QString BaseInstance::name() const
|
||||
{
|
||||
return m_settings->get("name").toString();
|
||||
|
@ -38,7 +38,9 @@
|
||||
#pragma once
|
||||
#include <cassert>
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QMenu>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
@ -66,6 +68,16 @@ class BaseInstance;
|
||||
// pointer for lazy people
|
||||
using InstancePtr = std::shared_ptr<BaseInstance>;
|
||||
|
||||
/// Shortcut saving target representations
|
||||
enum class ShortcutTarget { Desktop, Applications, Other };
|
||||
|
||||
/// Shortcut data representation
|
||||
struct ShortcutData {
|
||||
QString name;
|
||||
QString filePath;
|
||||
ShortcutTarget target = ShortcutTarget::Other;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Base class for instances.
|
||||
* This class implements many functions that are common between instances and
|
||||
@ -129,6 +141,11 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
|
||||
/// Sync name and rename instance dir accordingly; returns true if successful
|
||||
bool syncInstanceDirName(const QString& newRoot) const;
|
||||
|
||||
/// Register a created shortcut
|
||||
void registerShortcut(const ShortcutData& data);
|
||||
QList<ShortcutData> shortcuts() const;
|
||||
void setShortcuts(const QList<ShortcutData>& shortcuts);
|
||||
|
||||
/// Value used for instance window titles
|
||||
QString windowTitle() const;
|
||||
|
||||
|
@ -898,26 +898,26 @@ QString getApplicationsDir()
|
||||
}
|
||||
|
||||
// Cross-platform Shortcut creation
|
||||
bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
|
||||
QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
|
||||
{
|
||||
if (destination.isEmpty()) {
|
||||
destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name));
|
||||
}
|
||||
if (!ensureFilePathExists(destination)) {
|
||||
qWarning() << "Destination path can't be created!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
#if defined(Q_OS_MACOS)
|
||||
QDir application = destination + ".app/";
|
||||
|
||||
if (application.exists()) {
|
||||
qWarning() << "Application already exists!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!application.mkpath(".")) {
|
||||
qWarning() << "Couldn't create application";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
QDir content = application.path() + "/Contents/";
|
||||
@ -927,7 +927,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
|
||||
if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) {
|
||||
qWarning() << "Couldn't create directories within application";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
info.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
|
||||
@ -976,7 +976,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
"</dict>\n"
|
||||
"</plist>";
|
||||
|
||||
return true;
|
||||
return application.path();
|
||||
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated
|
||||
destination += ".desktop";
|
||||
@ -1002,32 +1002,32 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
|
||||
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
|
||||
|
||||
return true;
|
||||
return destination;
|
||||
#elif defined(Q_OS_WIN)
|
||||
QFileInfo targetInfo(target);
|
||||
|
||||
if (!targetInfo.exists()) {
|
||||
qWarning() << "Target file does not exist!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
target = targetInfo.absoluteFilePath();
|
||||
|
||||
if (target.length() >= MAX_PATH) {
|
||||
qWarning() << "Target file path is too long!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!icon.isEmpty() && icon.length() >= MAX_PATH) {
|
||||
qWarning() << "Icon path is too long!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
destination += ".lnk";
|
||||
|
||||
if (destination.length() >= MAX_PATH) {
|
||||
qWarning() << "Destination path is too long!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString argStr;
|
||||
@ -1046,7 +1046,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
|
||||
if (argStr.length() >= MAX_PATH) {
|
||||
qWarning() << "Arguments string is too long!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
HRESULT hres;
|
||||
@ -1055,7 +1055,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
hres = CoInitialize(nullptr);
|
||||
if (FAILED(hres)) {
|
||||
qWarning() << "Failed to initialize COM!";
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
WCHAR wsz[MAX_PATH];
|
||||
@ -1109,10 +1109,12 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri
|
||||
// go away COM, nobody likes you
|
||||
CoUninitialize();
|
||||
|
||||
return SUCCEEDED(hres);
|
||||
if (SUCCEEDED(hres))
|
||||
return destination;
|
||||
return QString();
|
||||
#else
|
||||
qWarning("Desktop Shortcuts not supported on your platform!");
|
||||
return false;
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -362,8 +362,9 @@ bool overrideFolder(QString overwritten_path, QString override_path);
|
||||
|
||||
/**
|
||||
* Creates a shortcut to the specified target file at the specified destination path.
|
||||
* Returns null QString if creation failed; otherwise returns the path to the created shortcut.
|
||||
*/
|
||||
bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon);
|
||||
QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon);
|
||||
|
||||
enum class FilesystemType {
|
||||
FAT,
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "NullInstance.h"
|
||||
#include "WatchLock.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/ShortcutUtils.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
@ -333,7 +334,7 @@ bool InstanceList::trashInstance(const InstanceId& id)
|
||||
{
|
||||
auto inst = getInstanceById(id);
|
||||
if (!inst) {
|
||||
qDebug() << "Cannot trash instance" << id << ". No such instance is present (deleted externally?).";
|
||||
qWarning() << "Cannot trash instance" << id << ". No such instance is present (deleted externally?).";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -348,26 +349,43 @@ bool InstanceList::trashInstance(const InstanceId& id)
|
||||
}
|
||||
|
||||
if (!FS::trash(inst->instanceRoot(), &trashedLoc)) {
|
||||
qDebug() << "Trash of instance" << id << "has not been completely successfully...";
|
||||
qWarning() << "Trash of instance" << id << "has not been completely successful...";
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "Instance" << id << "has been trashed by the launcher.";
|
||||
m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId });
|
||||
|
||||
// Also trash all of its shortcuts; we remove the shortcuts if trash fails since it is invalid anyway
|
||||
for (const auto& [name, filePath, target] : inst->shortcuts()) {
|
||||
if (!FS::trash(filePath, &trashedLoc)) {
|
||||
qWarning() << "Trash of shortcut" << name << "at path" << filePath << "for instance" << id
|
||||
<< "has not been successful, trying to delete it instead...";
|
||||
if (!FS::deletePath(filePath)) {
|
||||
qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id
|
||||
<< "has not been successful, given up...";
|
||||
} else {
|
||||
qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher.";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been trashed by the launcher.";
|
||||
m_trashHistory.top().shortcuts.append({ { name, filePath, target }, trashedLoc });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstanceList::trashedSomething()
|
||||
bool InstanceList::trashedSomething() const
|
||||
{
|
||||
return !m_trashHistory.empty();
|
||||
}
|
||||
|
||||
void InstanceList::undoTrashInstance()
|
||||
bool InstanceList::undoTrashInstance()
|
||||
{
|
||||
if (m_trashHistory.empty()) {
|
||||
qWarning() << "Nothing to recover from trash.";
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto top = m_trashHistory.pop();
|
||||
@ -377,21 +395,41 @@ void InstanceList::undoTrashInstance()
|
||||
top.path += "1";
|
||||
}
|
||||
|
||||
if (!QFile(top.trashPath).rename(top.path)) {
|
||||
qWarning() << "Moving" << top.trashPath << "back to" << top.path << "failed!";
|
||||
return false;
|
||||
}
|
||||
qDebug() << "Moving" << top.trashPath << "back to" << top.path;
|
||||
QFile(top.trashPath).rename(top.path);
|
||||
|
||||
bool ok = true;
|
||||
for (const auto& [data, trashPath] : top.shortcuts) {
|
||||
if (QDir(data.filePath).exists()) {
|
||||
// Don't try to append 1 here as the shortcut may have suffixes like .app, just warn and skip it
|
||||
qWarning() << "Shortcut" << trashPath << "original directory" << data.filePath << "already exists!";
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
if (!QFile(trashPath).rename(data.filePath)) {
|
||||
qWarning() << "Moving shortcut from" << trashPath << "back to" << data.filePath << "failed!";
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
qDebug() << "Moving shortcut from" << trashPath << "back to" << data.filePath;
|
||||
}
|
||||
|
||||
m_instanceGroupIndex[top.id] = top.groupName;
|
||||
increaseGroupCount(top.groupName);
|
||||
|
||||
saveGroupList();
|
||||
emit instancesChanged();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void InstanceList::deleteInstance(const InstanceId& id)
|
||||
{
|
||||
auto inst = getInstanceById(id);
|
||||
if (!inst) {
|
||||
qDebug() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?).";
|
||||
qWarning() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?).";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -404,11 +442,19 @@ void InstanceList::deleteInstance(const InstanceId& id)
|
||||
|
||||
qDebug() << "Will delete instance" << id;
|
||||
if (!FS::deletePath(inst->instanceRoot())) {
|
||||
qWarning() << "Deletion of instance" << id << "has not been completely successful ...";
|
||||
qWarning() << "Deletion of instance" << id << "has not been completely successful...";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Instance" << id << "has been deleted by the launcher.";
|
||||
|
||||
for (const auto& [name, filePath, target] : inst->shortcuts()) {
|
||||
if (!FS::deletePath(filePath)) {
|
||||
qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful...";
|
||||
continue;
|
||||
}
|
||||
qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher.";
|
||||
}
|
||||
}
|
||||
|
||||
static QMap<InstanceId, InstanceLocator> getIdMapping(const QList<InstancePtr>& list)
|
||||
@ -638,7 +684,12 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
|
||||
} else {
|
||||
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
|
||||
}
|
||||
qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot();
|
||||
qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot();
|
||||
|
||||
auto shortcut = inst->shortcuts();
|
||||
if (!shortcut.isEmpty())
|
||||
qDebug() << "Loaded" << shortcut.size() << "shortcut(s) for instance" << inst->name();
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,17 @@ enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateErro
|
||||
|
||||
enum class GroupsState { NotLoaded, Steady, Dirty };
|
||||
|
||||
struct TrashShortcutItem {
|
||||
ShortcutData data;
|
||||
QString trashPath;
|
||||
};
|
||||
|
||||
struct TrashHistoryItem {
|
||||
QString id;
|
||||
QString path;
|
||||
QString trashPath;
|
||||
QString groupName;
|
||||
QList<TrashShortcutItem> shortcuts;
|
||||
};
|
||||
|
||||
class InstanceList : public QAbstractListModel {
|
||||
@ -111,8 +117,8 @@ class InstanceList : public QAbstractListModel {
|
||||
void deleteGroup(const GroupId& name);
|
||||
void renameGroup(const GroupId& src, const GroupId& dst);
|
||||
bool trashInstance(const InstanceId& id);
|
||||
bool trashedSomething();
|
||||
void undoTrashInstance();
|
||||
bool trashedSomething() const;
|
||||
bool undoTrashInstance();
|
||||
void deleteInstance(const InstanceId& id);
|
||||
|
||||
// Wrap an instance creation task in some more task machinery and make it ready to be used
|
||||
|
@ -48,10 +48,10 @@
|
||||
|
||||
namespace ShortcutUtils {
|
||||
|
||||
void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
bool createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
{
|
||||
if (!shortcut.instance)
|
||||
return;
|
||||
return false;
|
||||
|
||||
QString appPath = QApplication::applicationFilePath();
|
||||
auto icon = APPLICATION->icons()->icon(shortcut.iconKey.isEmpty() ? shortcut.instance->iconKey() : shortcut.iconKey);
|
||||
@ -64,7 +64,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
if (appPath.startsWith("/private/var/")) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
iconPath = FS::PathCombine(shortcut.instance->instanceRoot(), "Icon.icns");
|
||||
@ -72,7 +72,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
QFile iconFile(iconPath);
|
||||
if (!iconFile.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for application."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon iconObj = icon->icon();
|
||||
@ -82,7 +82,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
if (!success) {
|
||||
iconFile.remove();
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for application."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
if (appPath.startsWith("/tmp/.mount_")) {
|
||||
@ -102,7 +102,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
QFile iconFile(iconPath);
|
||||
if (!iconFile.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG");
|
||||
iconFile.close();
|
||||
@ -110,7 +110,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
if (!success) {
|
||||
iconFile.remove();
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DesktopServices::isFlatpak()) {
|
||||
@ -128,7 +128,7 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
QFile iconFile(iconPath);
|
||||
if (!iconFile.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO");
|
||||
iconFile.close();
|
||||
@ -139,51 +139,58 @@ void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
|
||||
if (!success) {
|
||||
iconFile.remove();
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Failed to create icon for shortcut."));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Not supported on your platform!"));
|
||||
return;
|
||||
return false;
|
||||
#endif
|
||||
args.append({ "--launch", shortcut.instance->id() });
|
||||
args.append(shortcut.extraArgs);
|
||||
|
||||
if (!FS::createShortcut(filePath, appPath, args, shortcut.name, iconPath)) {
|
||||
QString shortcutPath = FS::createShortcut(filePath, appPath, args, shortcut.name, iconPath);
|
||||
if (shortcutPath.isEmpty()) {
|
||||
#if not defined(Q_OS_MACOS)
|
||||
iconFile.remove();
|
||||
#endif
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("Failed to create %1 shortcut!").arg(shortcut.targetString));
|
||||
return false;
|
||||
}
|
||||
|
||||
shortcut.instance->registerShortcut({ shortcut.name, shortcutPath, shortcut.target });
|
||||
return true;
|
||||
}
|
||||
|
||||
void createInstanceShortcutOnDesktop(const Shortcut& shortcut)
|
||||
bool createInstanceShortcutOnDesktop(const Shortcut& shortcut)
|
||||
{
|
||||
if (!shortcut.instance)
|
||||
return;
|
||||
return false;
|
||||
|
||||
QString desktopDir = FS::getDesktopDir();
|
||||
if (desktopDir.isEmpty()) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Couldn't find desktop?!"));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString shortcutFilePath = FS::PathCombine(desktopDir, FS::RemoveInvalidFilenameChars(shortcut.name));
|
||||
createInstanceShortcut(shortcut, shortcutFilePath);
|
||||
if (!createInstanceShortcut(shortcut, shortcutFilePath))
|
||||
return false;
|
||||
QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("Created a shortcut to this %1 on your desktop!").arg(shortcut.targetString));
|
||||
return true;
|
||||
}
|
||||
|
||||
void createInstanceShortcutInApplications(const Shortcut& shortcut)
|
||||
bool createInstanceShortcutInApplications(const Shortcut& shortcut)
|
||||
{
|
||||
if (!shortcut.instance)
|
||||
return;
|
||||
return false;
|
||||
|
||||
QString applicationsDir = FS::getApplicationsDir();
|
||||
if (applicationsDir.isEmpty()) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"), QObject::tr("Couldn't find applications folder?!"));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
||||
@ -193,20 +200,22 @@ void createInstanceShortcutInApplications(const Shortcut& shortcut)
|
||||
if (!applicationsDirQ.mkpath(".")) {
|
||||
QMessageBox::critical(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("Failed to create instances folder in applications folder!"));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString shortcutFilePath = FS::PathCombine(applicationsDir, FS::RemoveInvalidFilenameChars(shortcut.name));
|
||||
createInstanceShortcut(shortcut, shortcutFilePath);
|
||||
if (!createInstanceShortcut(shortcut, shortcutFilePath))
|
||||
return false;
|
||||
QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("Created a shortcut to this %1 in your applications folder!").arg(shortcut.targetString));
|
||||
return true;
|
||||
}
|
||||
|
||||
void createInstanceShortcutInOther(const Shortcut& shortcut)
|
||||
bool createInstanceShortcutInOther(const Shortcut& shortcut)
|
||||
{
|
||||
if (!shortcut.instance)
|
||||
return;
|
||||
return false;
|
||||
|
||||
QString defaultedDir = FS::getDesktopDir();
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
@ -225,13 +234,15 @@ void createInstanceShortcutInOther(const Shortcut& shortcut)
|
||||
shortcutFilePath = fileDialog.getSaveFileName(shortcut.parent, QObject::tr("Create Shortcut"), shortcutFilePath,
|
||||
QObject::tr("Desktop Entries") + " (*" + extension + ")");
|
||||
if (shortcutFilePath.isEmpty())
|
||||
return; // file dialog canceled by user
|
||||
return false; // file dialog canceled by user
|
||||
|
||||
if (shortcutFilePath.endsWith(extension))
|
||||
shortcutFilePath = shortcutFilePath.mid(0, shortcutFilePath.length() - extension.length());
|
||||
createInstanceShortcut(shortcut, shortcutFilePath);
|
||||
if (!createInstanceShortcut(shortcut, shortcutFilePath))
|
||||
return false;
|
||||
QMessageBox::information(shortcut.parent, QObject::tr("Create Shortcut"),
|
||||
QObject::tr("Created a shortcut to this %1!").arg(shortcut.targetString));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ShortcutUtils
|
||||
|
@ -38,6 +38,7 @@
|
||||
#pragma once
|
||||
#include "Application.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace ShortcutUtils {
|
||||
@ -49,18 +50,19 @@ struct Shortcut {
|
||||
QWidget* parent = nullptr;
|
||||
QStringList extraArgs = {};
|
||||
QString iconKey = "";
|
||||
ShortcutTarget target;
|
||||
};
|
||||
|
||||
/// Create an instance shortcut on the specified file path
|
||||
void createInstanceShortcut(const Shortcut& shortcut, const QString& filePath);
|
||||
bool createInstanceShortcut(const Shortcut& shortcut, const QString& filePath);
|
||||
|
||||
/// Create an instance shortcut on the desktop
|
||||
void createInstanceShortcutOnDesktop(const Shortcut& shortcut);
|
||||
bool createInstanceShortcutOnDesktop(const Shortcut& shortcut);
|
||||
|
||||
/// Create an instance shortcut in the Applications directory
|
||||
void createInstanceShortcutInApplications(const Shortcut& shortcut);
|
||||
bool createInstanceShortcutInApplications(const Shortcut& shortcut);
|
||||
|
||||
/// Create an instance shortcut in other directories
|
||||
void createInstanceShortcutInOther(const Shortcut& shortcut);
|
||||
bool createInstanceShortcutInOther(const Shortcut& shortcut);
|
||||
|
||||
} // namespace ShortcutUtils
|
||||
|
@ -1207,7 +1207,10 @@ void MainWindow::renameGroup(QString group)
|
||||
|
||||
void MainWindow::undoTrashInstance()
|
||||
{
|
||||
APPLICATION->instances()->undoTrashInstance();
|
||||
if (!APPLICATION->instances()->undoTrashInstance())
|
||||
QMessageBox::warning(
|
||||
this, tr("Failed to undo trashing instance"),
|
||||
tr("Some instances and shortcuts could not be restored.\nPlease check your trashbin to manually restore them."));
|
||||
ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
|
||||
}
|
||||
|
||||
@ -1406,11 +1409,15 @@ void MainWindow::on_actionDeleteInstance_triggered()
|
||||
}
|
||||
auto id = m_selectedInstance->id();
|
||||
|
||||
QString shortcutStr;
|
||||
auto shortcuts = m_selectedInstance->shortcuts();
|
||||
if (!shortcuts.isEmpty())
|
||||
shortcutStr = tr(" and its %n registered shortcut(s)", "", shortcuts.size());
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Deletion"),
|
||||
tr("You are about to delete \"%1\".\n"
|
||||
tr("You are about to delete \"%1\"%2.\n"
|
||||
"This may be permanent and will completely delete the instance.\n\n"
|
||||
"Are you sure?")
|
||||
.arg(m_selectedInstance->name()),
|
||||
.arg(m_selectedInstance->name(), shortcutStr),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
|
@ -83,12 +83,12 @@ CreateShortcutDialog::CreateShortcutDialog(InstancePtr instance, QWidget* parent
|
||||
QString applicationDir = FS::getApplicationsDir();
|
||||
|
||||
if (!desktopDir.isEmpty())
|
||||
ui->saveTargetSelectionBox->addItem(tr("Desktop"), QVariant::fromValue(SaveTarget::Desktop));
|
||||
ui->saveTargetSelectionBox->addItem(tr("Desktop"), QVariant::fromValue(ShortcutTarget::Desktop));
|
||||
|
||||
if (!applicationDir.isEmpty())
|
||||
ui->saveTargetSelectionBox->addItem(tr("Applications"), QVariant::fromValue(SaveTarget::Applications));
|
||||
ui->saveTargetSelectionBox->addItem(tr("Applications"), QVariant::fromValue(ShortcutTarget::Applications));
|
||||
}
|
||||
ui->saveTargetSelectionBox->addItem(tr("Other..."), QVariant::fromValue(SaveTarget::Other));
|
||||
ui->saveTargetSelectionBox->addItem(tr("Other..."), QVariant::fromValue(ShortcutTarget::Other));
|
||||
|
||||
// Populate worlds
|
||||
if (m_QuickJoinSupported) {
|
||||
@ -206,17 +206,17 @@ void CreateShortcutDialog::createShortcut()
|
||||
}
|
||||
}
|
||||
|
||||
auto target = ui->saveTargetSelectionBox->currentData().value<SaveTarget>();
|
||||
auto target = ui->saveTargetSelectionBox->currentData().value<ShortcutTarget>();
|
||||
auto name = ui->instNameTextBox->text();
|
||||
if (name.isEmpty())
|
||||
name = ui->instNameTextBox->placeholderText();
|
||||
if (ui->overrideAccountCheckbox->isChecked())
|
||||
extraArgs.append({ "--profile", ui->accountSelectionBox->currentData().toString() });
|
||||
|
||||
ShortcutUtils::Shortcut args{ m_instance.get(), name, targetString, this, extraArgs, InstIconKey };
|
||||
if (target == SaveTarget::Desktop)
|
||||
ShortcutUtils::Shortcut args{ m_instance.get(), name, targetString, this, extraArgs, InstIconKey, target };
|
||||
if (target == ShortcutTarget::Desktop)
|
||||
ShortcutUtils::createInstanceShortcutOnDesktop(args);
|
||||
else if (target == SaveTarget::Applications)
|
||||
else if (target == ShortcutTarget::Applications)
|
||||
ShortcutUtils::createInstanceShortcutInApplications(args);
|
||||
else
|
||||
ShortcutUtils::createInstanceShortcutInOther(args);
|
||||
|
@ -54,9 +54,6 @@ class CreateShortcutDialog : public QDialog {
|
||||
InstancePtr m_instance;
|
||||
bool m_QuickJoinSupported = false;
|
||||
|
||||
// Index representations
|
||||
enum class SaveTarget { Desktop, Applications, Other };
|
||||
|
||||
// Functions
|
||||
void stateChanged();
|
||||
};
|
||||
|
@ -194,6 +194,20 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="noteLabel">
|
||||
<property name="text">
|
||||
<string>Note: If a shortcut is moved after creation, it won't be deleted when deleting the instance.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="noteLabel2">
|
||||
<property name="text">
|
||||
<string>You'll need to delete them manually if that is the case.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
|
Reference in New Issue
Block a user