diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index ecb1e42d2..9d45f4af3 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -892,6 +892,11 @@ QString getDesktopDir() return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); } +QString getApplicationsDir() +{ + return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); +} + // Cross-platform Shortcut creation bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) { @@ -903,16 +908,7 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri return false; } #if defined(Q_OS_MACOS) - // Create the Application - QDir applicationDirectory = - QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; - - if (!applicationDirectory.mkpath(".")) { - qWarning() << "Couldn't create application directory"; - return false; - } - - QDir application = applicationDirectory.path() + "/" + name + ".app/"; + QDir application = destination + ".app/"; if (application.exists()) { qWarning() << "Application already exists!"; diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index bf91c603c..b1108eded 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -353,6 +353,9 @@ bool checkProblemticPathJava(QDir folder); // Get the Directory representing the User's Desktop QString getDesktopDir(); +// Get the Directory representing the User's Applications directory +QString getApplicationsDir(); + // Overrides one folder with the contents of another, preserving items exclusive to the first folder // Equivalent to doing QDir::rename, but allowing for overrides bool overrideFolder(QString overwritten_path, QString override_path); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 4043a4285..e30c50782 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -206,6 +206,26 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); exportInstanceMenu->addAction(ui->actionExportInstanceFlamePack); ui->actionExportInstance->setMenu(exportInstanceMenu); + + QList shortcutActions = { ui->actionCreateInstanceShortcutOther }; + if (!DesktopServices::isFlatpak()) { + QString desktopDir = FS::getDesktopDir(); + QString applicationDir = FS::getApplicationsDir(); + + if(!applicationDir.isEmpty()) + shortcutActions.push_front(ui->actionCreateInstanceShortcutApplications); + + if(!desktopDir.isEmpty()) + shortcutActions.push_front(ui->actionCreateInstanceShortcutDesktop); + } + + if(shortcutActions.length() > 1) { + auto shortcutInstanceMenu = new QMenu(this); + + for(auto action : shortcutActions) + shortcutInstanceMenu->addAction(action); + ui->actionCreateInstanceShortcut->setMenu(shortcutInstanceMenu); + } } // hide, disable and show stuff @@ -1514,18 +1534,11 @@ void MainWindow::on_actionKillInstance_triggered() } } -void MainWindow::on_actionCreateInstanceShortcut_triggered() +void MainWindow::createInstanceShortcut(QString shortcutFilePath) { 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; - } - QString desktopFilePath; QString appPath = QApplication::applicationFilePath(); QString iconPath; QStringList args; @@ -1594,13 +1607,6 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() } 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"; args.append({ "run", BuildConfig.LAUNCHER_APPID }); } @@ -1639,20 +1645,99 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() return; #endif args.append({ "--launch", m_selectedInstance->id() }); - if (FS::createShortcut(desktopFilePath, 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!")); -#endif - } else { + + if (!FS::createShortcut(std::move(shortcutFilePath), appPath, args, m_selectedInstance->name(), iconPath)) { #if not defined(Q_OS_MACOS) iconFile.remove(); #endif QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); + return; } } +void MainWindow::on_actionCreateInstanceShortcutOther_triggered() +{ + if (!m_selectedInstance) + return; + + QString defaultedDir = FS::getDesktopDir(); +#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + QString extension = ".desktop"; +#elif defined(Q_OS_WINDOWS) + QString extension = ".lnk"; +#else + QString extension = ""; +#endif + + QString shortcutFilePath = FS::PathCombine(defaultedDir, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + extension); + QFileDialog fileDialog; + // workaround to make sure the portal file dialog opens in the desktop directory + fileDialog.setDirectoryUrl(defaultedDir); + + shortcutFilePath = + fileDialog.getSaveFileName(this, tr("Create Shortcut"), shortcutFilePath, tr("Desktop Entries") + " (*" + extension + ")"); + if (shortcutFilePath.isEmpty()) + return; // file dialog canceled by user + + if(shortcutFilePath.endsWith(extension)) + shortcutFilePath = shortcutFilePath.mid(0, shortcutFilePath.length() - extension.length()); + createInstanceShortcut(shortcutFilePath); + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!")); +} + +void MainWindow::on_actionCreateInstanceShortcut_triggered() +{ + if (!m_selectedInstance) + return; + + if (DesktopServices::isFlatpak()) + on_actionCreateInstanceShortcutOther_triggered(); + else + on_actionCreateInstanceShortcutDesktop_triggered(); +} + +void MainWindow::on_actionCreateInstanceShortcutDesktop_triggered() +{ + if (!m_selectedInstance) + return; + + QString desktopDir = FS::getDesktopDir(); + if (desktopDir.isEmpty()) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); + return; + } + + QString shortcutFilePath = FS::PathCombine(FS::getDesktopDir(), FS::RemoveInvalidFilenameChars(m_selectedInstance->name())); + createInstanceShortcut(shortcutFilePath); + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); +} + +void MainWindow::on_actionCreateInstanceShortcutApplications_triggered() +{ + if (!m_selectedInstance) + return; + + QString applicationsDir = FS::getApplicationsDir(); + if (applicationsDir.isEmpty()) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find applications folder?!")); + return; + } + +#if defined(Q_OS_MACOS) || defined(Q_OS_WIN) + applicationsDir = FS::PathCombine(applicationsDir, BuildConfig.LAUNCHER_DISPLAYNAME + " Instances"); + + QDir applicationsDirQ(applicationsDir); + if (!applicationsDirQ.mkpath(".")) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instances folder in applications folder!")); + return; + } +#endif + + QString shortcutFilePath = FS::PathCombine(applicationsDir, FS::RemoveInvalidFilenameChars(m_selectedInstance->name())); + createInstanceShortcut(shortcutFilePath); + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance in your applications folder!")); +} + void MainWindow::taskEnd() { QObject* sender = QObject::sender(); diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 0e692eda7..f3f2de730 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -167,6 +167,10 @@ class MainWindow : public QMainWindow { void on_actionCreateInstanceShortcut_triggered(); + void on_actionCreateInstanceShortcutDesktop_triggered(); + void on_actionCreateInstanceShortcutApplications_triggered(); + void on_actionCreateInstanceShortcutOther_triggered(); + void taskEnd(); /** @@ -226,6 +230,7 @@ class MainWindow : public QMainWindow { void setSelectedInstanceById(const QString& id); void updateStatusCenter(); void setInstanceActionsEnabled(bool enabled); + void createInstanceShortcut(QString shortcutDirPath); void runModalTask(Task* task); void instanceFromInstanceTask(InstanceTask* task); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f20c34206..3fa30c97e 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -131,7 +131,7 @@ 0 0 800 - 27 + 22 @@ -235,8 +235,7 @@ - - .. + More news... @@ -250,8 +249,7 @@ true - - .. + &Meow @@ -286,8 +284,7 @@ - - .. + Add Instanc&e... @@ -298,8 +295,7 @@ - - .. + &Update... @@ -313,8 +309,7 @@ - - .. + Setti&ngs... @@ -328,8 +323,7 @@ - - .. + &Manage Accounts... @@ -337,8 +331,7 @@ - - .. + &Launch @@ -349,8 +342,7 @@ - - .. + &Kill @@ -364,8 +356,7 @@ - - .. + Rename @@ -376,8 +367,7 @@ - - .. + &Change Group... @@ -399,8 +389,7 @@ - - .. + &Edit... @@ -414,8 +403,7 @@ - - .. + &Folder @@ -426,8 +414,7 @@ - - .. + Dele&te @@ -441,8 +428,7 @@ - - .. + Cop&y... @@ -456,8 +442,7 @@ - - .. + E&xport... @@ -468,8 +453,7 @@ - - .. + Prism Launcher (zip) @@ -477,8 +461,7 @@ - - .. + Modrinth (mrpack) @@ -486,8 +469,7 @@ - - .. + CurseForge (zip) @@ -495,20 +477,18 @@ - - .. + Create Shortcut - Creates a shortcut on your desktop to launch the selected instance. + Creates a shortcut on a selected folder to launch the selected instance. - - .. + No accounts added! @@ -519,8 +499,7 @@ true - - .. + No Default Account @@ -531,8 +510,7 @@ - - .. + Close &Window @@ -546,8 +524,7 @@ - - .. + &Instances @@ -558,8 +535,7 @@ - - .. + Launcher &Root @@ -570,8 +546,7 @@ - - .. + &Central Mods @@ -582,8 +557,7 @@ - - .. + &Skins @@ -594,8 +568,7 @@ - - .. + Instance Icons @@ -606,8 +579,7 @@ - - .. + Logs @@ -623,8 +595,7 @@ - - .. + Report a Bug or Suggest a Feature @@ -635,8 +606,7 @@ - - .. + &Discord Guild @@ -647,8 +617,7 @@ - - .. + &Matrix Space @@ -659,8 +628,7 @@ - - .. + Sub&reddit @@ -671,8 +639,7 @@ - - .. + &About %1 @@ -686,8 +653,7 @@ - - .. + &Clear Metadata Cache @@ -698,8 +664,7 @@ - - .. + Install to &PATH @@ -710,8 +675,7 @@ - - .. + Folders @@ -722,8 +686,7 @@ - - .. + Help @@ -734,8 +697,7 @@ - - .. + Accounts @@ -743,8 +705,7 @@ - - .. + %1 &Help @@ -755,8 +716,7 @@ - - .. + &Widget Themes @@ -767,8 +727,7 @@ - - .. + I&con Theme @@ -779,8 +738,7 @@ - - .. + Cat Packs @@ -791,8 +749,7 @@ - - .. + Java @@ -801,6 +758,39 @@ Open the Java folder in a file browser. Only available if the built-in Java downloader is used. + + + Desktop + + + Creates an shortcut to this instance on your desktop + + + QAction::TextHeuristicRole + + + + + Applications + + + Create a shortcut of this instance on your start menu + + + QAction::TextHeuristicRole + + + + + Other... + + + Creates a shortcut in a folder selected by you + + + QAction::TextHeuristicRole + +