diff options
-rw-r--r-- | launcher/FileSystem.cpp | 2 | ||||
-rw-r--r-- | launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 3 | ||||
-rw-r--r-- | launcher/modplatform/modpacksch/FTBPackInstallTask.cpp | 3 | ||||
-rw-r--r-- | launcher/resources/breeze_dark/scalable/new.svg | 15 | ||||
-rw-r--r-- | launcher/resources/breeze_light/scalable/new.svg | 15 | ||||
-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 |
9 files changed, 138 insertions, 81 deletions
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 1da50e21..3e8e10a5 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -372,8 +372,6 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - destination += ".desktop"; - QFile f(destination); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index eae66ec7..729268d7 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -406,6 +406,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) blocked_mod.hash = result.hash; blocked_mod.matched = false; blocked_mod.localPath = ""; + blocked_mod.targetFolder = result.targetFolder; blocked_mods.append(blocked_mod); @@ -451,7 +452,7 @@ void FlameCreationTask::copyBlockedMods(QList<BlockedMod> const& blocked_mods) continue; } - auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", "mods", mod.name); + auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name); setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 48caa938..2979663d 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -195,6 +195,7 @@ void PackInstallTask::onResolveModsSucceeded() blocked_mod.hash = results_file.hash; blocked_mod.matched = false; blocked_mod.localPath = ""; + blocked_mod.targetFolder = results_file.targetFolder; m_blocked_mods.append(blocked_mod); @@ -366,7 +367,7 @@ void PackInstallTask::copyBlockedMods() continue; } - auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", "mods", mod.name); + auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", mod.targetFolder, mod.name); setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); diff --git a/launcher/resources/breeze_dark/scalable/new.svg b/launcher/resources/breeze_dark/scalable/new.svg index 9ee910e7..31601727 100644 --- a/launcher/resources/breeze_dark/scalable/new.svg +++ b/launcher/resources/breeze_dark/scalable/new.svg @@ -1,18 +1,13 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"> - <defs - id="defs3051"> - <style - type="text/css" - id="current-color-scheme"> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> .ColorScheme-Text { color:#eff0f1; } </style> </defs> - <path - style="fill:currentColor;fill-opacity:1;stroke:none" - d="M 4 4 L 4 28 L 17 28 L 17 27 L 5 27 L 5 14 L 10 14 L 13 11 L 27 11 L 27 17 L 28 17 L 28 7 L 18 7 L 15 4 L 4 4 z M 22 17 L 22 22 L 17 22 L 17 23 L 22 23 L 22 28 L 23 28 L 23 23 L 28 23 L 28 22 L 23 22 L 23 17 L 22 17 z " - id="path99" + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 3 2 L 3 14 L 8 14 L 8 13 L 4 13 L 4 3 L 9 3 L 9 6 L 12 6 L 12 9 L 13 9 L 13 6 L 13 5 L 10 2 L 9 2 L 3 2 z M 10 9 L 10 11 L 8 11 L 8 12 L 10 12 L 10 14 L 11 14 L 11 12 L 13 12 L 13 11 L 11 11 L 11 9 L 10 9 z " class="ColorScheme-Text" /> </svg> diff --git a/launcher/resources/breeze_light/scalable/new.svg b/launcher/resources/breeze_light/scalable/new.svg index 51babd76..6434a18e 100644 --- a/launcher/resources/breeze_light/scalable/new.svg +++ b/launcher/resources/breeze_light/scalable/new.svg @@ -1,18 +1,13 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"> - <defs - id="defs3051"> - <style - type="text/css" - id="current-color-scheme"> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> .ColorScheme-Text { color:#232629; } </style> </defs> - <path - style="fill:currentColor;fill-opacity:1;stroke:none" - d="M 4 4 L 4 28 L 17 28 L 17 27 L 5 27 L 5 14 L 10 14 L 13 11 L 27 11 L 27 17 L 28 17 L 28 7 L 18 7 L 15 4 L 4 4 z M 22 17 L 22 22 L 17 22 L 17 23 L 22 23 L 22 28 L 23 28 L 23 23 L 28 23 L 28 22 L 23 22 L 23 17 L 22 17 z " - id="path99" + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 3 2 L 3 14 L 8 14 L 8 13 L 4 13 L 4 3 L 9 3 L 9 6 L 12 6 L 12 9 L 13 9 L 13 6 L 13 5 L 10 2 L 9 2 L 3 2 z M 10 9 L 10 11 L 8 11 L 8 12 L 10 12 L 10 14 L 11 14 L 11 12 L 13 12 L 13 11 L 11 11 L 11 9 L 10 9 z " class="ColorScheme-Text" /> </svg> 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> |