diff options
| author | flow <flowlnlnln@gmail.com> | 2022-05-17 18:25:08 -0300 |
|---|---|---|
| committer | flow <flowlnlnln@gmail.com> | 2022-05-17 18:25:08 -0300 |
| commit | ff9f3cb31ff75c2d657146cf8fe646084439fd0f (patch) | |
| tree | 6c098648df6a4da447aa305420709037115f81f0 /launcher/ui | |
| parent | 17bbfe8d8951ddc7acca0222c6d2e38fb29eef25 (diff) | |
| parent | cc13310083fe8d0c3bb423fa3e31db7b1f7b25e1 (diff) | |
| download | PrismLauncher-ff9f3cb31ff75c2d657146cf8fe646084439fd0f.tar.gz PrismLauncher-ff9f3cb31ff75c2d657146cf8fe646084439fd0f.tar.bz2 PrismLauncher-ff9f3cb31ff75c2d657146cf8fe646084439fd0f.zip | |
fix conflicts with develop
Diffstat (limited to 'launcher/ui')
20 files changed, 1184 insertions, 101 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index f34cf1ab..f016dc76 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -238,6 +238,9 @@ public: TranslatedAction actionREDDIT; TranslatedAction actionAbout; + TranslatedAction actionNoAccountsAdded; + TranslatedAction actionNoDefaultAccount; + QVector<TranslatedToolButton *> all_toolbuttons; QWidget *centralWidget = nullptr; @@ -746,6 +749,9 @@ public: // disabled until we have an instance selected instanceToolBar->setEnabled(false); instanceToolBar->setMovable(true); + // Qt doesn't like vertical moving toolbars, so we have to force them... + // See https://github.com/PolyMC/PolyMC/issues/493 + connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly); instanceToolBar->setFloatable(false); @@ -828,7 +834,7 @@ public: QMetaObject::connectSlotsByName(MainWindow); } // setupUi - void retranslateUi(QMainWindow *MainWindow) + void retranslateUi(MainWindow *MainWindow) { QString winTitle = tr("%1 - Version %2", "Launcher - Version X").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()); MainWindow->setWindowTitle(winTitle); @@ -848,6 +854,12 @@ public: // submenu buttons foldersMenuButton->setText(tr("Folders")); helpMenuButton->setText(tr("Help")); + + // playtime counter + if (MainWindow->m_statusCenter) + { + MainWindow->updateStatusCenter(); + } } // retranslateUi }; @@ -950,6 +962,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow ui->mainToolBar->addWidget(spacer); accountMenu = new QMenu(this); + // Use undocumented property... https://stackoverflow.com/questions/7121718/create-a-scrollbar-in-a-submenu-qt + accountMenu->setStyleSheet("QMenu { menu-scrollable: 1; }"); repopulateAccountsMenu(); @@ -1252,10 +1266,14 @@ void MainWindow::repopulateAccountsMenu() if (accounts->count() <= 0) { - QAction *action = new QAction(tr("No accounts added!"), this); - action->setEnabled(false); - accountMenu->addAction(action); - ui->profileMenu->addAction(action); + ui->all_actions.removeAll(&ui->actionNoAccountsAdded); + ui->actionNoAccountsAdded = TranslatedAction(this); + ui->actionNoAccountsAdded->setObjectName(QStringLiteral("actionNoAccountsAdded")); + ui->actionNoAccountsAdded.setTextId(QT_TRANSLATE_NOOP("MainWindow", "No accounts added!")); + ui->actionNoAccountsAdded->setEnabled(false); + accountMenu->addAction(ui->actionNoAccountsAdded); + ui->profileMenu->addAction(ui->actionNoAccountsAdded); + ui->all_actions.append(&ui->actionNoAccountsAdded); } else { @@ -1295,18 +1313,23 @@ void MainWindow::repopulateAccountsMenu() accountMenu->addSeparator(); ui->profileMenu->addSeparator(); - QAction *action = new QAction(tr("No Default Account"), this); - action->setCheckable(true); - action->setIcon(APPLICATION->getThemedIcon("noaccount")); - action->setData(-1); - action->setShortcut(QKeySequence(tr("Ctrl+0"))); + ui->all_actions.removeAll(&ui->actionNoDefaultAccount); + ui->actionNoDefaultAccount = TranslatedAction(this); + ui->actionNoDefaultAccount->setObjectName(QStringLiteral("actionNoDefaultAccount")); + ui->actionNoDefaultAccount.setTextId(QT_TRANSLATE_NOOP("MainWindow", "No Default Account")); + ui->actionNoDefaultAccount->setCheckable(true); + ui->actionNoDefaultAccount->setIcon(APPLICATION->getThemedIcon("noaccount")); + ui->actionNoDefaultAccount->setData(-1); + ui->actionNoDefaultAccount->setShortcut(QKeySequence(tr("Ctrl+0"))); if (!defaultAccount) { - action->setChecked(true); + ui->actionNoDefaultAccount->setChecked(true); } - accountMenu->addAction(action); - ui->profileMenu->addAction(action); - connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); + accountMenu->addAction(ui->actionNoDefaultAccount); + ui->profileMenu->addAction(ui->actionNoDefaultAccount); + connect(ui->actionNoDefaultAccount, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); + ui->all_actions.append(&ui->actionNoDefaultAccount); + ui->actionNoDefaultAccount.retranslate(); accountMenu->addSeparator(); ui->profileMenu->addSeparator(); diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index d02ea476..305e85c0 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -13,7 +13,7 @@ #include <QDialogButtonBox> #include "ui/widgets/PageContainer.h" -#include "ui/pages/modplatform/modrinth/ModrinthPage.h" +#include "ui/pages/modplatform/modrinth/ModrinthModPage.h" #include "ModDownloadTask.h" @@ -98,7 +98,7 @@ void ModDownloadDialog::accept() QList<BasePage *> ModDownloadDialog::getPages() { - modrinthPage = new ModrinthPage(this, m_instance); + modrinthPage = new ModrinthModPage(this, m_instance); flameModPage = new FlameModPage(this, m_instance); return { diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 309d89d0..782dc361 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -16,7 +16,7 @@ class ModDownloadDialog; class PageContainer; class QDialogButtonBox; -class ModrinthPage; +class ModrinthModPage; class ModDownloadDialog : public QDialog, public BasePageProvider { @@ -50,7 +50,7 @@ private: QVBoxLayout *m_verticalLayout = nullptr; - ModrinthPage *modrinthPage = nullptr; + ModrinthModPage *modrinthPage = nullptr; FlameModPage *flameModPage = nullptr; QHash<QString, ModDownloadTask*> modTask; BaseInstance *m_instance; diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index b402839c..05ea091d 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -39,6 +39,7 @@ #include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/flame/FlamePage.h" #include "ui/pages/modplatform/ImportPage.h" +#include "ui/pages/modplatform/modrinth/ModrinthPage.h" #include "ui/pages/modplatform/technic/TechnicPage.h" @@ -134,6 +135,7 @@ QList<BasePage *> NewInstanceDialog::getPages() flamePage, new FtbPage(this), new LegacyFTB::Page(this), + new ModrinthPage(this), technicPage }; } diff --git a/launcher/ui/dialogs/SkinUploadDialog.cpp b/launcher/ui/dialogs/SkinUploadDialog.cpp index 6a5a324f..8d137afc 100644 --- a/launcher/ui/dialogs/SkinUploadDialog.cpp +++ b/launcher/ui/dialogs/SkinUploadDialog.cpp @@ -100,7 +100,8 @@ void SkinUploadDialog::on_buttonBox_accepted() void SkinUploadDialog::on_skinBrowseBtn_clicked() { - QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), "*.png"); + auto filter = QMimeDatabase().mimeTypeForName("image/png").filterString(); + QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), filter); if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) { return; diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index a48c4d69..b4562843 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -101,6 +101,20 @@ void InstanceSettingsPage::applySettings() { SettingsObject::Lock lock(m_settings); + // Miscellaneous + bool miscellaneous = ui->miscellaneousSettingsBox->isChecked(); + m_settings->set("OverrideMiscellaneous", miscellaneous); + if (miscellaneous) + { + m_settings->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked()); + m_settings->set("QuitAfterGameStop", ui->quitAfterGameStopCheck->isChecked()); + } + else + { + m_settings->reset("CloseAfterLaunch"); + m_settings->reset("QuitAfterGameStop"); + } + // Console bool console = ui->consoleSettingsBox->isChecked(); m_settings->set("OverrideConsole", console); @@ -247,6 +261,11 @@ void InstanceSettingsPage::applySettings() void InstanceSettingsPage::loadSettings() { + // Miscellaneous + ui->miscellaneousSettingsBox->setChecked(m_settings->get("OverrideMiscellaneous").toBool()); + ui->closeAfterLaunchCheck->setChecked(m_settings->get("CloseAfterLaunch").toBool()); + ui->quitAfterGameStopCheck->setChecked(m_settings->get("QuitAfterGameStop").toBool()); + // Console ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool()); ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool()); diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 5db2d147..cb66b3ce 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -350,6 +350,35 @@ </widget> </item> <item> + <widget class="QGroupBox" name="miscellaneousSettingsBox"> + <property name="title"> + <string>Miscellaneous</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_12"> + <item> + <widget class="QCheckBox" name="closeAfterLaunchCheck"> + <property name="text"> + <string>Close the launcher after game window opens</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="quitAfterGameStopCheck"> + <property name="text"> + <string>Quit the launcher after game window closes</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> <spacer name="verticalSpacerMinecraft_2"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index e694ebe3..2cf17b32 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -251,7 +251,7 @@ ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent) m_model.reset(new QFileSystemModel()); m_filterModel.reset(new FilterModel()); m_filterModel->setSourceModel(m_model.get()); - m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable); + m_model->setFilter(QDir::Files); m_model->setReadOnly(false); m_model->setNameFilters({"*.png"}); m_model->setNameFilterDisables(false); @@ -343,6 +343,29 @@ void ScreenshotsPage::onItemActivated(QModelIndex index) DesktopServices::openFile(info.absoluteFilePath()); } +void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection &selected) +{ + bool allReadable = !selected.isEmpty(); + bool allWritable = !selected.isEmpty(); + + for (auto index : selected.indexes()) + { + if (!index.isValid()) + break; + auto info = m_model->fileInfo(index); + if (!info.isReadable()) + allReadable = false; + if (!info.isWritable()) + allWritable = false; + } + + ui->actionUpload->setEnabled(allReadable); + ui->actionCopy_Image->setEnabled(allReadable); + ui->actionCopy_File_s->setEnabled(allReadable); + ui->actionDelete->setEnabled(allWritable); + ui->actionRename->setEnabled(allWritable); +} + void ScreenshotsPage::on_actionView_Folder_triggered() { DesktopServices::openDirectory(m_folder, true); @@ -503,6 +526,8 @@ void ScreenshotsPage::openedImpl() if(idx.isValid()) { ui->listView->setModel(m_filterModel.get()); + connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ScreenshotsPage::onCurrentSelectionChanged); + onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states ui->listView->setRootIndex(m_filterModel->mapFromSource(idx)); } else diff --git a/launcher/ui/pages/instance/ScreenshotsPage.h b/launcher/ui/pages/instance/ScreenshotsPage.h index 50cf1a17..c22706af 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.h +++ b/launcher/ui/pages/instance/ScreenshotsPage.h @@ -100,6 +100,7 @@ private slots: void on_actionRename_triggered(); void on_actionView_Folder_triggered(); void onItemActivated(QModelIndex); + void onCurrentSelectionChanged(const QItemSelection &selected); void ShowContextMenu(const QPoint &pos); private: diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 487bf77b..c7bc13d8 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> + * Copyright (c) 2022 Sefa Eyeoglu <contact@scrumplex.net> * * 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 @@ -109,7 +110,11 @@ void ImportPage::updateState() { // FIXME: actually do some validation of what's inside here... this is fake AF QFileInfo fi(input); - if(fi.exists() && fi.suffix() == "zip") + // mrpack is a modrinth pack + + // Allow non-latin people to use ZIP files! + auto zip = QMimeDatabase().mimeTypeForUrl(url).suffixes().contains("zip"); + if(fi.exists() && (zip || fi.suffix() == "mrpack")) { QFileInfo fi(url.fileName()); dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url)); @@ -143,7 +148,9 @@ void ImportPage::setUrl(const QString& url) void ImportPage::on_modpackBtn_clicked() { - const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)")); + auto filter = QMimeDatabase().mimeTypeForName("application/zip").filterString(); + filter += ";;" + tr("Modrinth pack (*.mrpack)"); + const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter); if (url.isValid()) { if (url.isLocalFile()) diff --git a/launcher/ui/pages/modplatform/ImportPage.ui b/launcher/ui/pages/modplatform/ImportPage.ui index eb63cbe9..77bc5da5 100644 --- a/launcher/ui/pages/modplatform/ImportPage.ui +++ b/launcher/ui/pages/modplatform/ImportPage.ui @@ -11,28 +11,75 @@ </rect> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="1"> - <widget class="QPushButton" name="modpackBtn"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="1" column="0"> + <item row="2" column="0"> <widget class="QLineEdit" name="modpackEdit"> <property name="placeholderText"> <string notr="true">http://</string> </property> </widget> </item> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="modpackLabel"> + <item row="2" column="1"> + <widget class="QPushButton" name="modpackBtn"> <property name="text"> - <string>Local file or link to a direct download:</string> + <string>Browse</string> </property> </widget> </item> - <item row="2" column="0" colspan="2"> + <item row="3" column="0" rowspan="2" colspan="2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>The following file types are implemented (both for local files and URLs):</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>- Curseforge modpacks (ZIP)</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>- Modrinth modpacks (ZIP and mrpack)</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>- PolyMC / MultiMC exported instances (ZIP)</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>- Technic modpacks (ZIP)</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item row="5" column="0" colspan="2"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -45,6 +92,13 @@ </property> </spacer> </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="modpackLabel"> + <property name="text"> + <string>Local file or link to a direct download:</string> + </property> + </widget> + </item> </layout> </widget> <resources/> diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.cpp new file mode 100644 index 00000000..1d9f4d60 --- /dev/null +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.cpp @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * 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 "ModrinthModModel.h" + +#include "modplatform/modrinth/ModrinthPackIndex.h" + +namespace Modrinth { + +// NOLINTNEXTLINE(modernize-avoid-c-arrays) +const char* ListModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; + +void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) +{ + Modrinth::loadIndexedPack(m, obj); +} + +void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) +{ + Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); +} + +auto ListModel::documentToArray(QJsonDocument& obj) const -> QJsonArray +{ + return obj.object().value("hits").toArray(); +} + +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.h new file mode 100644 index 00000000..ae7b0bdd --- /dev/null +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModModel.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * 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 "ModrinthModPage.h" + +namespace Modrinth { + +class ListModel : public ModPlatform::ListModel { + Q_OBJECT + + public: + ListModel(ModrinthModPage* parent) : ModPlatform::ListModel(parent){}; + ~ListModel() override = default; + + private: + void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; + void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + + auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; + + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + static const char* sorts[5]; + inline auto getSorts() const -> const char** override { return sorts; }; +}; + +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp new file mode 100644 index 00000000..d3a1f859 --- /dev/null +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * 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/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ModrinthModPage.h" +#include "modplatform/modrinth/ModrinthAPI.h" +#include "ui_ModPage.h" + +#include "ModrinthModModel.h" +#include "ui/dialogs/ModDownloadDialog.h" + +ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instance) + : ModPage(dialog, instance, new ModrinthAPI()) +{ + listModel = new Modrinth::ListModel(this); + ui->packView->setModel(listModel); + + // index is used to set the sorting with the modrinth api + ui->sortByBox->addItem(tr("Sort by Relevance")); + ui->sortByBox->addItem(tr("Sort by Downloads")); + ui->sortByBox->addItem(tr("Sort by Follows")); + ui->sortByBox->addItem(tr("Sort by Last Updated")); + ui->sortByBox->addItem(tr("Sort by Newest")); + + // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, + // so it's best not to connect them in the parent's constructor... + connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthModPage::onSelectionChanged); + connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthModPage::onVersionSelectionChanged); + connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthModPage::onModSelected); +} + +auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader) const -> bool +{ + auto loaderStrings = ModrinthAPI::getModLoaderStrings(loader); + + auto loaderCompatible = false; + for (auto remoteLoader : ver.loaders) + { + if (loaderStrings.contains(remoteLoader)) { + loaderCompatible = true; + break; + } + } + return ver.mcVersion.contains(mineVer) && loaderCompatible; +} + +// I don't know why, but doing this on the parent class makes it so that +// other mod providers start loading before being selected, at least with +// my Qt, so we need to implement this in every derived class... +auto ModrinthModPage::shouldDisplay() const -> bool { return true; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.h new file mode 100644 index 00000000..b1e72bfe --- /dev/null +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * 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/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "modplatform/ModAPI.h" +#include "ui/pages/modplatform/ModPage.h" + +#include "modplatform/modrinth/ModrinthAPI.h" + +class ModrinthModPage : public ModPage { + Q_OBJECT + + public: + explicit ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instance); + ~ModrinthModPage() override = default; + + inline auto displayName() const -> QString override { return "Modrinth"; } + inline auto icon() const -> QIcon override { return APPLICATION->getThemedIcon("modrinth"); } + inline auto id() const -> QString override { return "modrinth"; } + inline auto helpPage() const -> QString override { return "Mod-platform"; } + + inline auto debugName() const -> QString override { return "Modrinth"; } + inline auto metaEntryBase() const -> QString override { return "ModrinthPacks"; }; + + auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader = ModAPI::Unspecified) const -> bool override; + + auto shouldDisplay() const -> bool override; +}; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index b788860a..7cacf37a 100644 |
