diff options
Diffstat (limited to 'launcher/ui')
-rw-r--r-- | launcher/ui/MainWindow.cpp | 26 | ||||
-rw-r--r-- | launcher/ui/dialogs/BlockedModsDialog.cpp | 84 | ||||
-rw-r--r-- | launcher/ui/dialogs/BlockedModsDialog.h | 33 | ||||
-rw-r--r-- | launcher/ui/dialogs/BlockedModsDialog.ui | 38 |
4 files changed, 124 insertions, 57 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 91cc5f29..cc81d8e3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -548,8 +548,9 @@ public: fileMenu->addAction(actionChangeInstGroup); fileMenu->addAction(actionViewSelectedInstFolder); fileMenu->addAction(actionExportInstance); - fileMenu->addAction(actionDeleteInstance); fileMenu->addAction(actionCopyInstance); + fileMenu->addAction(actionDeleteInstance); + fileMenu->addAction(actionCreateInstanceShortcut); fileMenu->addSeparator(); fileMenu->addAction(actionSettings); @@ -2269,10 +2270,25 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); return; } - - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - appPath, { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), iconPath)) { + + QString desktopFilePath = FS::PathCombine(desktopPath, m_selectedInstance->name() + ".desktop"); + QStringList args; + if (DesktopServices::isFlatpak()) { + 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 }); + } + args.append({ "--launch", m_selectedInstance->id() }); + if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) { QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); } else diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 214eeeaa..8b49bd1a 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -1,14 +1,41 @@ +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net> +// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com> +// SPDX-FileCopyrightText: 2022 kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> +// +// SPDX-License-Identifier: GPL-3.0-only + +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com> + * Copyright (C) 2022 kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #include "BlockedModsDialog.h" -#include <QDesktopServices> -#include <QDialogButtonBox> -#include <QPushButton> -#include "Application.h" #include "ui_BlockedModsDialog.h" +#include "Application.h" +#include "modplatform/helpers/HashUtils.h" + #include <QDebug> +#include <QDesktopServices> +#include <QDialogButtonBox> #include <QDragEnterEvent> #include <QFileDialog> #include <QFileInfo> +#include <QPushButton> #include <QStandardPaths> BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods) @@ -19,8 +46,8 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons ui->setupUi(this); - auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); - connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); + m_openMissingButton = ui->buttonBox->addButton(tr("Open Missing"), QDialogButtonBox::ActionRole); + connect(m_openMissingButton, &QPushButton::clicked, this, [this]() { openAll(true); }); auto downloadFolderButton = ui->buttonBox->addButton(tr("Add Download Folder"), QDialogButtonBox::ActionRole); connect(downloadFolderButton, &QPushButton::clicked, this, &BlockedModsDialog::addDownloadFolder); @@ -34,15 +61,8 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons this->setWindowTitle(title); ui->labelDescription->setText(text); - ui->labelExplain->setText( - QString(tr("Your configured global mods folder and default downloads folder " - "are automatically checked for the downloaded mods and they will be copied to the instance if found.<br/>" - "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch " - "if you did not download the mods to a default location.")) - .arg(APPLICATION->settings()->get("CentralModsDir").toString(), - QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))); - - // force all URL handeling as external + + // force all URL handling as external connect(ui->textBrowserWatched, &QTextBrowser::anchorClicked, this, [](const QUrl url) { QDesktopServices::openUrl(url); }); setAcceptDrops(true); @@ -64,7 +84,15 @@ void BlockedModsDialog::dragEnterEvent(QDragEnterEvent* e) void BlockedModsDialog::dropEvent(QDropEvent* e) { - for (const QUrl& url : e->mimeData()->urls()) { + for (QUrl& url : e->mimeData()->urls()) { + if (url.scheme().isEmpty()) { // ensure isLocalFile() works correctly + url.setScheme("file"); + } + + if (!url.isLocalFile()) { // can't drop external files here. + continue; + } + QString filePath = url.toLocalFile(); qDebug() << "[Blocked Mods Dialog] Dropped file:" << filePath; addHashTask(filePath); @@ -85,10 +113,12 @@ void BlockedModsDialog::done(int r) disconnect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged); } -void BlockedModsDialog::openAll() +void BlockedModsDialog::openAll(bool missingOnly) { for (auto& mod : m_mods) { - QDesktopServices::openUrl(mod.websiteUrl); + if (!missingOnly || !mod.matched) { + QDesktopServices::openUrl(mod.websiteUrl); + } } } @@ -131,8 +161,10 @@ void BlockedModsDialog::update() if (allModsMatched()) { ui->labelModsFound->setText("<span style=\"color:green\">✔</span>" + tr("All mods found")); + m_openMissingButton->setDisabled(true); } else { ui->labelModsFound->setText(tr("Please download the missing mods.")); + m_openMissingButton->setDisabled(false); } } @@ -243,14 +275,24 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path) /// @return boolean: did the path match the name of a blocked mod? bool BlockedModsDialog::checkValidPath(QString path) { - QFileInfo file = QFileInfo(path); - QString filename = file.fileName(); + const QFileInfo file = QFileInfo(path); + const QString filename = file.fileName(); + QString laxFilename(filename); + laxFilename.replace('+', ' '); + + auto compare = [](QString fsfilename, QString metadataFilename) { + return metadataFilename.compare(fsfilename, Qt::CaseInsensitive) == 0; + }; for (auto& mod : m_mods) { - if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) { + if (compare(filename, mod.name)) { qDebug() << "[Blocked Mods Dialog] Name match found:" << mod.name << "| From path:" << path; return true; } + if (compare(laxFilename, mod.name)) { + qDebug() << "[Blocked Mods Dialog] Lax name match found:" << mod.name << "| From path:" << path; + return true; + } } return false; diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index f5aef8bf..014f488a 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -1,3 +1,28 @@ +// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net> +// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com> +// SPDX-FileCopyrightText: 2022 kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> +// +// SPDX-License-Identifier: GPL-3.0-only + +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com> + * Copyright (C) 2022 kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #pragma once #include <QDialog> @@ -6,16 +31,17 @@ #include <QFileSystemWatcher> -#include "modplatform/helpers/HashUtils.h" - #include "tasks/ConcurrentTask.h" +class QPushButton; + struct BlockedMod { QString name; QString websiteUrl; QString hash; bool matched; QString localPath; + QString targetFolder; }; QT_BEGIN_NAMESPACE @@ -46,8 +72,9 @@ class BlockedModsDialog : public QDialog { shared_qobject_ptr<ConcurrentTask> m_hashing_task; QSet<QString> m_pending_hash_paths; bool m_rehash_pending; + QPushButton* m_openMissingButton; - void openAll(); + void openAll(bool missingOnly); void addDownloadFolder(); void update(); void directoryChanged(QString path); diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui index 88105178..2292b99c 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.ui +++ b/launcher/ui/dialogs/BlockedModsDialog.ui @@ -7,17 +7,23 @@ <x>0</x> <y>0</y> <width>400</width> - <height>455</height> + <height>400</height> </rect> </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>350</height> + </size> + </property> <property name="windowTitle"> <string notr="true">BlockedModsDialog</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> + <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,3,0,1,0"> <item> <widget class="QLabel" name="labelDescription"> <property name="text"> - <string notr="true"/> + <string notr="true">Placeholder description</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -30,7 +36,7 @@ <item> <widget class="QLabel" name="labelExplain"> <property name="text"> - <string/> + <string><html><head/><body><p>Your configured global mods folder and default downloads folder are automatically checked for the downloaded mods and they will be copied to the instance if found.</p><p>Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch if you did not download the mods to a default location.</p></body></html></string> </property> <property name="wordWrap"> <bool>true</bool> @@ -42,12 +48,6 @@ </item> <item> <widget class="QTextBrowser" name="textBrowserModsListing"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>165</height> - </size> - </property> <property name="acceptRichText"> <bool>true</bool> </property> @@ -58,12 +58,6 @@ </item> <item> <widget class="QLabel" name="labelWatched"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> <property name="text"> <string>Watched Folders:</string> </property> @@ -71,18 +65,6 @@ </item> <item> <widget class="QTextBrowser" name="textBrowserWatched"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>16</height> - </size> - </property> <property name="baseSize"> <size> <width>0</width> |