added instance shortcut feature

Signed-off-by: sshcrack <34072808+sshcrack@users.noreply.github.com>
This commit is contained in:
sshcrack
2024-10-22 20:53:57 +02:00
parent 79439a0217
commit a737d5df42
6 changed files with 238 additions and 149 deletions

View File

@ -1495,141 +1495,158 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
{
if (!m_selectedInstance)
return;
auto desktopPath = FS::getDesktopDir();
if (desktopPath.isEmpty()) {
// TODO come up with an alternative solution (open "save file" dialog)
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!"));
return;
std::vector<QString> paths;
QString mode = APPLICATION->settings()->get("ShortcutCreationMode").toString();
if (mode == "Applications") {
paths.push_back(FS::getApplicationsDir());
} else if (mode == "Both") {
paths.push_back(FS::getDesktopDir());
paths.push_back(FS::getApplicationsDir());
} else {
// Default to desktop
paths.push_back(FS::getDesktopDir());
}
QString desktopFilePath;
QString appPath = QApplication::applicationFilePath();
QString iconPath;
QStringList args;
#if defined(Q_OS_MACOS)
appPath = QApplication::applicationFilePath();
if (appPath.startsWith("/private/var/")) {
QMessageBox::critical(this, tr("Create instance shortcut"),
tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts."));
return;
}
auto pIcon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (pIcon == nullptr) {
pIcon = APPLICATION->icons()->icon("grass");
}
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "Icon.icns");
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
return;
}
QIcon icon = pIcon->icon();
bool success = icon.pixmap(1024, 1024).save(iconPath, "ICNS");
iconFile.close();
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
return;
}
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
if (appPath.startsWith("/tmp/.mount_")) {
// AppImage!
appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE"));
if (appPath.isEmpty()) {
QMessageBox::critical(this, tr("Create instance shortcut"),
tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)"));
} else if (appPath.endsWith("/")) {
appPath.chop(1);
for (const QString& shortcutDirPath : paths) {
if (shortcutDirPath.isEmpty()) {
// TODO come up with an alternative solution (open "save file" dialog)
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!"));
return;
}
}
auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (icon == nullptr) {
icon = APPLICATION->icons()->icon("grass");
}
QString shortcutFilePath;
QString appPath = QApplication::applicationFilePath();
QString iconPath;
QStringList args;
#if defined(Q_OS_MACOS)
appPath = QApplication::applicationFilePath();
if (appPath.startsWith("/private/var/")) {
QMessageBox::critical(this, tr("Create instance shortcut"),
tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts."));
return;
}
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png");
auto pIcon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (pIcon == nullptr) {
pIcon = APPLICATION->icons()->icon("grass");
}
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG");
iconFile.close();
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "Icon.icns");
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
return;
}
if (DesktopServices::isFlatpak()) {
desktopFilePath = FS::PathCombine(desktopPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + ".desktop");
QFileDialog fileDialog;
// workaround to make sure the portal file dialog opens in the desktop directory
fileDialog.setDirectoryUrl(desktopPath);
desktopFilePath = fileDialog.getSaveFileName(this, tr("Create Shortcut"), desktopFilePath, tr("Desktop Entries") + " (*.desktop)");
if (desktopFilePath.isEmpty())
return; // file dialog canceled by user
appPath = "flatpak";
QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME;
flatpakAppId.remove(".desktop");
args.append({ "run", flatpakAppId });
}
QIcon icon = pIcon->icon();
bool success = icon.pixmap(1024, 1024).save(iconPath, "ICNS");
iconFile.close();
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
return;
}
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
if (appPath.startsWith("/tmp/.mount_")) {
// AppImage!
appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE"));
if (appPath.isEmpty()) {
QMessageBox::critical(this, tr("Create instance shortcut"),
tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)"));
} else if (appPath.endsWith("/")) {
appPath.chop(1);
}
}
auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (icon == nullptr) {
icon = APPLICATION->icons()->icon("grass");
}
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png");
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG");
iconFile.close();
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
if (DesktopServices::isFlatpak()) {
shortcutFilePath = FS::PathCombine(shortcutDirPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + ".desktop");
QFileDialog fileDialog;
// workaround to make sure the portal file dialog opens in the desktop directory
fileDialog.setDirectoryUrl(shortcutDirPath);
shortcutFilePath =
fileDialog.getSaveFileName(this, tr("Create Shortcut"), shortcutFilePath, tr("Desktop Entries") + " (*.desktop)");
if (shortcutFilePath.isEmpty())
return; // file dialog canceled by user
appPath = "flatpak";
QString flatpakAppId = BuildConfig.LAUNCHER_DESKTOPFILENAME;
flatpakAppId.remove(".desktop");
args.append({ "run", flatpakAppId });
}
#elif defined(Q_OS_WIN)
auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (icon == nullptr) {
icon = APPLICATION->icons()->icon("grass");
}
auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
if (icon == nullptr) {
icon = APPLICATION->icons()->icon("grass");
}
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico");
iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico");
// part of fix for weird bug involving the window icon being replaced
// dunno why it happens, but this 2-line fix seems to be enough, so w/e
auto appIcon = APPLICATION->getThemedIcon("logo");
// part of fix for weird bug involving the window icon being replaced
// dunno why it happens, but this 2-line fix seems to be enough, so w/e
auto appIcon = APPLICATION->getThemedIcon("logo");
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO");
iconFile.close();
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO");
iconFile.close();
// restore original window icon
QGuiApplication::setWindowIcon(appIcon);
// restore original window icon
QGuiApplication::setWindowIcon(appIcon);
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
if (!success) {
iconFile.remove();
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
return;
}
#else
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!"));
return;
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!"));
return;
#endif
args.append({ "--launch", m_selectedInstance->id() });
if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) {
args.append({ "--launch", m_selectedInstance->id() });
if (shortcutFilePath.isEmpty())
shortcutFilePath = FS::PathCombine(shortcutDirPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()));
if (!FS::createShortcut(shortcutFilePath, appPath, args, m_selectedInstance->name(), iconPath)) {
#if not defined(Q_OS_MACOS)
QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
#else
QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!"));
iconFile.remove();
#endif
} else {
#if not defined(Q_OS_MACOS)
iconFile.remove();
#endif
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
}
}
#if not defined(Q_OS_MACOS)
QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!"));
#else
QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!"));
#endif
}
void MainWindow::taskEnd()