aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml8
-rw-r--r--.gitmodules4
-rw-r--r--CMakeLists.txt22
-rw-r--r--launcher/CMakeLists.txt4
-rw-r--r--launcher/InstanceCreationTask.cpp11
-rw-r--r--launcher/InstanceCreationTask.h4
-rw-r--r--launcher/modplatform/ModAPI.h17
-rw-r--r--launcher/modplatform/flame/FlameAPI.h6
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.h15
-rw-r--r--launcher/ui/dialogs/ModDownloadDialog.cpp6
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp27
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h6
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp58
-rw-r--r--launcher/ui/pages/modplatform/ModPage.h9
-rw-r--r--launcher/ui/pages/modplatform/ModPage.ui24
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.cpp90
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.h7
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.ui307
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModPage.h2
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.h2
-rw-r--r--launcher/ui/widgets/ModFilterWidget.cpp109
-rw-r--r--launcher/ui/widgets/ModFilterWidget.h69
-rw-r--r--launcher/ui/widgets/ModFilterWidget.ui54
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.cpp6
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.h2
-rw-r--r--libraries/LocalPeer/CMakeLists.txt2
-rw-r--r--libraries/iconfix/CMakeLists.txt2
-rw-r--r--libraries/javacheck/CMakeLists.txt2
-rw-r--r--libraries/katabasis/CMakeLists.txt2
-rw-r--r--libraries/launcher/CMakeLists.txt2
m---------libraries/libnbtplusplus0
-rw-r--r--libraries/optional-bare/CMakeLists.txt2
-rw-r--r--libraries/rainbow/CMakeLists.txt2
-rw-r--r--libraries/xz-embedded/CMakeLists.txt2
-rw-r--r--program_info/CMakeLists.txt1
-rw-r--r--program_info/polymc.6.txt (renamed from doc/polymc.1.txt)4
36 files changed, 733 insertions, 157 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c2571e91..0123c99a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -131,24 +131,24 @@ jobs:
- name: Configure CMake
if: runner.os != 'Linux' && runner.os != 'Windows'
run: |
- cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -G Ninja
+ cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -G Ninja
- name: Configure CMake on Windows
if: runner.os == 'Windows' && matrix.portable != true
shell: msys2 {0}
run: |
- cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DLauncher_PORTABLE=OFF -G Ninja
+ cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_PORTABLE=OFF -G Ninja
- name: Configure CMake on Windows portable
if: runner.os == 'Windows' && matrix.portable == true
shell: msys2 {0}
run: |
- cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -G Ninja
+ cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -G Ninja
- name: Configure CMake on Linux
if: runner.os == 'Linux' && matrix.portable != true
run: |
- cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DLauncher_PORTABLE=OFF -G Ninja
+ cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DLauncher_PORTABLE=OFF -DENABLE_LTO=ON -G Ninja
- name: Configure CMake on Linux Portable
if: runner.os == 'Linux' && matrix.portable == true
diff --git a/.gitmodules b/.gitmodules
index 10575207..08b94c96 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,7 @@
[submodule "depends/libnbtplusplus"]
path = libraries/libnbtplusplus
- url = https://github.com/MultiMC/libnbtplusplus.git
- pushurl = git@github.com:MultiMC/libnbtplusplus.git
+ url = https://github.com/PolyMC/libnbtplusplus.git
+ pushurl = git@github.com:PolyMC/libnbtplusplus.git
[submodule "libraries/quazip"]
path = libraries/quazip
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d45d4975..1350a3ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
if(WIN32)
# In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
@@ -43,12 +43,28 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type")
# Fix build with Qt 5.13
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
+option(ENABLE_LTO "Enable Link Time Optimization" off)
+
+if(ENABLE_LTO)
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error)
+
+ if(ipo_supported AND (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel"))
+ message(STATUS "IPO / LTO enabled")
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+ elseif(ipo_supported)
+ message(STATUS "Not enabling IPO / LTO on debug builds")
+ else()
+ message(STATUS "IPO / LTO not supported: <${ipo_error}>")
+ endif()
+endif()
+
##################################### Set Application options #####################################
######## Set URLs ########
set(Launcher_NEWS_RSS_URL "https://polymc.org/feed/feed.xml" CACHE STRING "URL to fetch PolyMC's news RSS feed from.")
set(Launcher_NEWS_OPEN_URL "https://polymc.org/news" CACHE STRING "URL that gets opened when the user clicks 'More News'")
-set(Launcher_HELP_URL "https://polymc.org/wiki/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
+set(Launcher_HELP_URL "https://polymc.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
######## Set version numbers ########
set(Launcher_VERSION_MAJOR 1)
@@ -204,6 +220,7 @@ elseif(UNIX)
set(LAUNCHER_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory")
set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory")
set(LAUNCHER_ICON_DEST_DIR "share/icons/hicolor/scalable/apps" CACHE STRING "Path to the scalable icon directory")
+ set(LAUNCHER_MAN_DEST_DIR "share/man/man6" CACHE STRING "Path to the man page directory")
# jars path is determined on runtime, relative to "Application root path", generally /usr for Launcher_PORTABLE=0
set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_JARS_LOCATION=${JARS_DEST_DIR}")
@@ -211,6 +228,7 @@ elseif(UNIX)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR})
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR} RENAME "${Launcher_APP_BINARY_NAME}.6")
endif()
# install as bundle with no dependencies included
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 42348792..0ab398e8 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -825,7 +825,6 @@ SET(LAUNCHER_SOURCES
ui/dialogs/ModDownloadDialog.cpp
ui/dialogs/ModDownloadDialog.h
-
# GUI - widgets
ui/widgets/Common.cpp
ui/widgets/Common.h
@@ -849,6 +848,8 @@ SET(LAUNCHER_SOURCES
ui/widgets/LogView.h
ui/widgets/MCModInfoFrame.cpp
ui/widgets/MCModInfoFrame.h
+ ui/widgets/ModFilterWidget.cpp
+ ui/widgets/ModFilterWidget.h
ui/widgets/ModListView.cpp
ui/widgets/ModListView.h
ui/widgets/PageContainer.cpp
@@ -907,6 +908,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/widgets/InstanceCardWidget.ui
ui/widgets/CustomCommands.ui
ui/widgets/MCModInfoFrame.ui
+ ui/widgets/ModFilterWidget.ui
ui/dialogs/CopyInstanceDialog.ui
ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui
diff --git a/launcher/InstanceCreationTask.cpp b/launcher/InstanceCreationTask.cpp
index 4c37bd7f..24bc5f46 100644
--- a/launcher/InstanceCreationTask.cpp
+++ b/launcher/InstanceCreationTask.cpp
@@ -9,6 +9,15 @@
InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version)
{
m_version = version;
+ m_usingLoader = false;
+}
+
+InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loaderVersion)
+{
+ m_version = version;
+ m_usingLoader = true;
+ m_loader = loader;
+ m_loaderVersion = loaderVersion;
}
void InstanceCreationTask::executeTask()
@@ -21,6 +30,8 @@ void InstanceCreationTask::executeTask()
auto components = inst.getPackProfile();
components->buildingFromScratch();
components->setComponentVersion("net.minecraft", m_version->descriptor(), true);
+ if(m_usingLoader)
+ components->setComponentVersion(m_loader, m_loaderVersion->descriptor(), true);
inst.setName(m_instName);
inst.setIconKey(m_instIcon);
instanceSettings->resumeSave();
diff --git a/launcher/InstanceCreationTask.h b/launcher/InstanceCreationTask.h
index 54997116..23367c3f 100644
--- a/launcher/InstanceCreationTask.h
+++ b/launcher/InstanceCreationTask.h
@@ -12,6 +12,7 @@ class InstanceCreationTask : public InstanceTask
Q_OBJECT
public:
explicit InstanceCreationTask(BaseVersionPtr version);
+ explicit InstanceCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loaderVersion);
protected:
//! Entry point for tasks.
@@ -19,4 +20,7 @@ protected:
private: /* data */
BaseVersionPtr m_version;
+ bool m_usingLoader;
+ QString m_loader;
+ BaseVersionPtr m_loaderVersion;
};
diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h
index 1a562172..8e6cd45c 100644
--- a/launcher/modplatform/ModAPI.h
+++ b/launcher/modplatform/ModAPI.h
@@ -3,6 +3,8 @@
#include <QString>
#include <QList>
+#include "Version.h"
+
namespace ModPlatform {
class ListModel;
}
@@ -22,7 +24,7 @@ class ModAPI {
QString search;
QString sorting;
ModLoaderType mod_loader;
- QString version;
+ std::list<Version> versions;
};
virtual void searchMods(CallerType* caller, SearchArgs&& args) const = 0;
@@ -30,7 +32,7 @@ class ModAPI {
struct VersionSearchArgs {
QString addonId;
- QList<QString> mcVersions;
+ std::list<Version> mcVersions;
ModLoaderType loader;
};
@@ -53,4 +55,15 @@ class ModAPI {
}
return "";
}
+
+ protected:
+ inline auto getGameVersionsString(std::list<Version> mcVersions) const -> QString
+ {
+ QString s;
+ for(auto& ver : mcVersions){
+ s += QString("%1,").arg(ver.toString());
+ }
+ s.remove(s.length() - 1, 1); //remove last comma
+ return s;
+ }
};
diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h
index 8654a693..9bcc357e 100644
--- a/launcher/modplatform/flame/FlameAPI.h
+++ b/launcher/modplatform/flame/FlameAPI.h
@@ -6,6 +6,8 @@ class FlameAPI : public NetworkModAPI {
private:
inline auto getModSearchURL(SearchArgs& args) const -> QString override
{
+ auto gameVersionStr = args.versions.size() != 0 ? QString("gameVersion=%1").arg(args.versions.front().toString()) : QString();
+
return QString(
"https://addons-ecs.forgesvc.net/api/v2/addon/search?"
"gameId=432&"
@@ -17,12 +19,12 @@ class FlameAPI : public NetworkModAPI {
"searchFilter=%2&"
"sort=%3&"
"modLoaderType=%4&"
- "gameVersion=%5")
+ "%5")
.arg(args.offset)
.arg(args.search)
.arg(args.sorting)
.arg(args.mod_loader)
- .arg(args.version);
+ .arg(gameVersionStr);
};
inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override
diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h
index eefa4a85..6604d772 100644
--- a/launcher/modplatform/modrinth/ModrinthAPI.h
+++ b/launcher/modplatform/modrinth/ModrinthAPI.h
@@ -22,12 +22,12 @@ class ModrinthAPI : public NetworkModAPI {
"limit=25&"
"query=%2&"
"index=%3&"
- "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]")
+ "facets=[[\"categories:%4\"],%5[\"project_type:mod\"]]")
.arg(args.offset)
.arg(args.search)
.arg(args.sorting)
.arg(getModLoaderString(args.mod_loader))
- .arg(args.version);
+ .arg(getGameVersionsArray(args.versions));
};
inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override
@@ -40,15 +40,14 @@ class ModrinthAPI : public NetworkModAPI {
.arg(getModLoaderString(args.loader));
};
- inline auto getGameVersionsString(QList<QString> mcVersions) const -> QString
+ auto getGameVersionsArray(std::list<Version> mcVersions) const -> QString
{
QString s;
- for(int i = 0; i < mcVersions.count(); i++){
- s += mcVersions.at(i);
- if(i < mcVersions.count() - 1)
- s += ",";
+ for(auto& ver : mcVersions){
+ s += QString("\"versions:%1\",").arg(ver.toString());
}
- return s;
+ s.remove(s.length() - 1, 1); //remove last comma
+ return s.isEmpty() ? QString() : QString("[%1],").arg(s);
}
static auto getModLoaderString(ModLoaderType type) -> const QString
diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp
index a53f93e8..d02ea476 100644
--- a/launcher/ui/dialogs/ModDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ModDownloadDialog.cpp
@@ -22,7 +22,9 @@ ModDownloadDialog::ModDownloadDialog(const std::shared_ptr<ModFolderModel> &mods
: QDialog(parent), mods(mods), m_instance(instance)
{
setObjectName(QStringLiteral("ModDownloadDialog"));
- resize(400, 347);
+
+ resize(std::max(0.5*parent->width(), 400.0), std::max(0.75*parent->height(), 400.0));
+
m_verticalLayout = new QVBoxLayout(this);
m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
@@ -80,7 +82,7 @@ void ModDownloadDialog::confirm()
tr("Confirm mods to download")
);
- for(auto task : keys){
+ for(auto& task : keys){
confirm_dialog->appendMod(task, modTask.find(task).value()->getFilename());
}
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index f75d2847..da0331b5 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -72,14 +72,11 @@ void ListModel::performPaginatedSearch()
auto profile = (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))->getPackProfile();
m_parent->apiProvider()->searchMods(this,
- { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], profile->getModLoader(), getMineVersions().at(0) });
+ { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], profile->getModLoader(), getMineVersions() });
}
-void ListModel::searchWithTerm(const QString& term, const int sort)
+void ListModel::refresh()
{
- if (currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { return; }
- currentSearchTerm = term;
- currentSort = sort;
if (jobPtr) {
jobPtr->abort();
searchState = ResetRequested;
@@ -94,6 +91,20 @@ void ListModel::searchWithTerm(const QString& term, const int sort)
performPaginatedSearch();
}
+void ListModel::searchWithTerm(const QString& term, const int sort, const bool filter_changed)
+{
+ if (currentSearchTerm == term
+ && currentSearchTerm.isNull() == term.isNull()
+ && currentSort == sort
+ && !filter_changed)
+ { return; }
+
+ currentSearchTerm = term;
+ currentSort = sort;
+
+ refresh();
+}
+
void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback)
{
if (m_logoMap.contains(logo)) {
@@ -223,9 +234,7 @@ void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId)
/******** Helpers ********/
-auto ModPlatform::ListModel::getMineVersions() const -> QList<QString>
+auto ModPlatform::ListModel::getMineVersions() const -> std::list<Version>
{
- return { (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))
- ->getPackProfile()
- ->getComponentVersion("net.minecraft") };
+ return m_parent->getFilter()->versions;
}
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index dbadbeee..d460cff2 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -7,6 +7,7 @@
#include "net/NetJob.h"
class ModPage;
+class Version;
namespace ModPlatform {
@@ -33,7 +34,8 @@ class ListModel : public QAbstractListModel {
/* Ask the API for more information */
void fetchMore(const QModelIndex& parent) override;
- void searchWithTerm(const QString& term, const int sort);
+ void refresh();
+ void searchWithTerm(const QString& term, const int sort, const bool filter_changed);
void requestModVersions(const ModPlatform::IndexedPack& current);
virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
@@ -62,7 +64,7 @@ class ListModel : public QAbstractListModel {
void requestLogo(QString file, QString url);
- inline auto getMineVersions() const -> QList<QString>;
+ inline auto getMineVersions() const -> std::list<Version>;
protected:
ModPage* m_parent;
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index eabd8379..29f6b601 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -2,21 +2,39 @@
#include "ui_ModPage.h"
#include <QKeyEvent>
+#include <memory>
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "ui/dialogs/ModDownloadDialog.h"
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api)
- : QWidget(dialog), m_instance(instance), ui(new Ui::ModPage), dialog(dialog), api(api)
+ : QWidget(dialog)
+ , m_instance(instance)
+ , ui(new Ui::ModPage)
+ , dialog(dialog)
+ , filter_widget(static_cast<MinecraftInstance*>(instance)->getPackProfile()->getComponentVersion("net.minecraft"), this)
+ , api(api)
{
ui->setupUi(this);
connect(ui->searchButton, &QPushButton::clicked, this, &ModPage::triggerSearch);
+ connect(ui->modFilterButton, &QPushButton::clicked, this, &ModPage::filterMods);
ui->searchEdit->installEventFilter(this);
ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
+ ui->gridLayout_3->addWidget(&filter_widget, 0, 0, 1, ui->gridLayout_3->columnCount());
+
+ filter_widget.setInstance(static_cast<MinecraftInstance*>(m_instance));
+ m_filter = filter_widget.getFilter();
+
+ connect(&filter_widget, &ModFilterWidget::filterChanged, this, [&]{
+ ui->searchButton->setStyleSheet("text-decoration: underline");
+ });
+ connect(&filter_widget, &ModFilterWidget::filterUnchanged, this, [&]{
+ ui->searchButton->setStyleSheet("text-decoration: none");
+ });
}
ModPage::~ModPage()
@@ -49,9 +67,24 @@ auto ModPage::eventFilter(QObject* watched, QEvent* event) -> bool
/******** Callbacks to events in the UI (set up in the derived classes) ********/
+void ModPage::filterMods()
+{
+ filter_widget.setHidden(!filter_widget.isHidden());
+}
+
void ModPage::triggerSearch()
{
- listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex());
+ auto changed = filter_widget.changed();
+ m_filter = filter_widget.getFilter();
+
+ if(changed){
+ ui->packView->clearSelection();
+ ui->packDescription->clear();
+ ui->versionSelectionBox->clear();
+ updateSelectionButton();
+ }
+
+ listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex(), changed);
}
void ModPage::onSelectionChanged(QModelIndex first, QModelIndex second)
@@ -131,7 +164,7 @@ void ModPage::retranslate()
ui->retranslateUi(this);
}
-void ModPage::updateModVersions()
+void ModPage::updateModVersions(int prev_count)
{
auto packProfile = (dynamic_cast<MinecraftInstance*>(m_instance))->getPackProfile();
@@ -141,15 +174,22 @@ void ModPage::updateModVersions()
for (int i = 0; i < current.versions.size(); i++) {
auto version = current.versions[i];
- //NOTE: Flame doesn't care about loaderString, so passing it changes nothing.
- if (!validateVersion(version, mcVersion, loaderString)) {
- continue;
+ bool valid = false;
+ for(auto& mcVer : m_filter->versions){
+ //NOTE: Flame doesn't care about loaderString, so passing it changes nothing.
+ if (validateVersion(version, mcVer.toString(), loaderString)) {
+ valid = true;
+ break;
+ }
}
- ui->versionSelectionBox->addItem(version.version, QVariant(i));
+ if(valid || m_filter->versions.size() == 0)
+ ui->versionSelectionBox->addItem(version.version, QVariant(i));
+ }
+ if (ui->versionSelectionBox->count() == 0 && prev_count != 0) {
+ ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1));
+ ui->modSelectionButton->setText(tr("Cannot select invalid version :("));
}
- if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); }
- ui->modSelectionButton->setText(tr("Cannot select invalid version :("));
updateSelectionButton();
}
diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h
index 0cd13f37..85aaede9 100644
--- a/launcher/ui/pages/modplatform/ModPage.h
+++ b/launcher/ui/pages/modplatform/ModPage.h
@@ -7,6 +7,7 @@
#include "modplatform/ModIndex.h"
#include "ui/pages/BasePage.h"
#include "ui/pages/modplatform/ModModel.h"
+#include "ui/widgets/ModFilterWidget.h"
class ModDownloadDialog;
@@ -39,9 +40,10 @@ class ModPage : public QWidget, public BasePage {
virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const -> bool = 0;
auto apiProvider() const -> const ModAPI* { return api.get(); };
+ auto getFilter() const -> const std::shared_ptr<ModFilterWidget::Filter> { return m_filter; }
auto getCurrent() -> ModPlatform::IndexedPack& { return current; }
- void updateModVersions();
+ void updateModVersions(int prev_count = -1);
void openedImpl() override;
auto eventFilter(QObject* watched, QEvent* event) -> bool override;
@@ -52,6 +54,7 @@ class ModPage : public QWidget, public BasePage {
void updateSelectionButton();
protected slots:
+ virtual void filterMods();
void triggerSearch();
void onSelectionChanged(QModelIndex first, QModelIndex second);
void onVersionSelectionChanged(QString data);
@@ -60,6 +63,10 @@ class ModPage : public QWidget, public BasePage {
protected:
Ui::ModPage* ui = nullptr;
ModDownloadDialog* dialog = nullptr;
+
+ ModFilterWidget filter_widget;
+ std::shared_ptr<ModFilterWidget::Filter> m_filter;
+
ModPlatform::ListModel* listModel = nullptr;
ModPlatform::IndexedPack current;
diff --git a/launcher/ui/pages/modplatform/ModPage.ui b/launcher/ui/pages/modplatform/ModPage.ui
index 508f1bac..afcd9bb7 100644
--- a/launcher/ui/pages/modplatform/ModPage.ui
+++ b/launcher/ui/pages/modplatform/ModPage.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0" colspan="2">
+ <item row="1" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="2">
<widget class="QTextBrowser" name="packDescription">
@@ -41,7 +41,7 @@
</item>
</layout>
</item>
- <item row="0" column="1">
+ <item row="0" column="3">
<widget class="QPushButton" name="searchButton">
<property name="text">
<string>Search</string>
@@ -51,12 +51,12 @@
<item row="0" column="0">
<widget class="QLineEdit" name="searchEdit">
<property name="placeholderText">
- <string>Search and filter...</string>
+ <string>Search for mods...</string>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0,0">
+ <item row="2" column="0" colspan="4">
+ <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0">
<item row="0" column="2">
<widget class="QComboBox" name="versionSelectionBox"/>
</item>
@@ -82,6 +82,20 @@
</item>
</layout>
</item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="modFilterButton">
+ <property name="text">
+ <string>Filter options</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<tabstops>
diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp
index c691128f..207d0130 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.cpp
+++ b/launcher/ui/pages/modplatform/VanillaPage.cpp
@@ -44,6 +44,7 @@
#include "ui/dialogs/NewInstanceDialog.h"
#include "Filter.h"
#include "InstanceCreationTask.h"
+#include "Version.h"
VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
: QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
@@ -59,6 +60,15 @@ VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh);
+
+ connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedLoaderVersion);
+ connect(ui->noneFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged);
+ connect(ui->forgeFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged);
+ connect(ui->fabricFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged);
+ connect(ui->quiltFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged);
+ connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged);
+ connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &VanillaPage::loaderRefresh);
+
}
void VanillaPage::openedImpl()
@@ -80,6 +90,13 @@ void VanillaPage::refresh()
ui->versionList->loadList();
}
+void VanillaPage::loaderRefresh()
+{
+ if(ui->noneFilter->isChecked())
+ return;
+ ui->loaderVersionList->loadList();
+}
+
void VanillaPage::filterChanged()
{
QStringList out;
@@ -99,6 +116,52 @@ void VanillaPage::filterChanged()
ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false));
}
+void VanillaPage::loaderFilterChanged()
+{
+ auto minecraftVersion = m_selectedVersion->descriptor();
+ if(ui->noneFilter->isChecked())
+ {
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list
+ ui->loaderVersionList->setEmptyString(tr("No mod loader is selected."));
+ ui->loaderVersionList->setEmptyMode(VersionListView::String);
+ return;
+ }
+ else if(ui->forgeFilter->isChecked())
+ {
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion);
+ m_selectedLoader = "net.minecraftforge";
+ }
+ else if(ui->fabricFilter->isChecked())
+ {
+ // FIXME: dirty hack because the launcher is unaware of Fabric's dependencies
+ if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "");
+ else // Fabric/Quilt unsupported
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list
+ m_selectedLoader = "net.fabricmc.fabric-loader";
+ }
+ else if(ui->quiltFilter->isChecked())
+ {
+ // FIXME: dirty hack because the launcher is unaware of Quilt's dependencies (same as Fabric)
+ if (Version(minecraftVersion) >= Version("1.14")) // Fabric/Quilt supported
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "");
+ else // Fabric/Quilt unsupported
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // clear list
+ m_selectedLoader = "org.quiltmc.quilt-loader";
+ }
+ else if(ui->liteLoaderFilter->isChecked())
+ {
+ ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion);
+ m_selectedLoader = "com.mumfrey.liteloader";
+ }
+
+ auto vlist = APPLICATION->metadataIndex()->get(m_selectedLoader);
+ ui->loaderVersionList->initialize(vlist.get());
+ ui->loaderVersionList->selectRecommended();
+ suggestCurrent();
+ ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion));
+}
+
VanillaPage::~VanillaPage()
{
delete ui;
@@ -119,6 +182,16 @@ BaseVersionPtr VanillaPage::selectedVersion() const
return m_selectedVersion;
}
+BaseVersionPtr VanillaPage::selectedLoaderVersion() const
+{
+ return m_selectedLoaderVersion;
+}
+
+QString VanillaPage::selectedLoader() const
+{
+ return m_selectedLoader;
+}
+
void VanillaPage::suggestCurrent()
{
if (!isOpened)
@@ -132,7 +205,15 @@ void VanillaPage::suggestCurrent()
return;
}
- dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
+ // List is empty if either no mod loader is selected, or no versions are available
+ if(!ui->loaderVersionList->hasVersions())
+ dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
+ else
+ {
+ dialog->setSuggestedPack(m_selectedVersion->descriptor(),
+ new InstanceCreationTask(m_selectedVersion, m_selectedLoader,
+ m_selectedLoaderVersion));
+ }
dialog->setSuggestedIcon("default");
}
@@ -140,4 +221,11 @@ void VanillaPage::setSelectedVersion(BaseVersionPtr version)
{
m_selectedVersion = version;
suggestCurrent();
+ loaderFilterChanged();
+}
+
+void VanillaPage::setSelectedLoaderVersion(BaseVersionPtr version)
+{
+ m_selectedLoaderVersion = version;
+ suggestCurrent();
}
diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h
index 4e7479df..7193597d 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.h
+++ b/launcher/ui/pages/modplatform/VanillaPage.h
@@ -77,15 +77,20 @@ public:
void openedImpl() override;
BaseVersionPtr selectedVersion() const;
+ BaseVersionPtr selectedLoaderVersion() const;
+ QString selectedLoader() const;
public slots:
void setSelectedVersion(BaseVersionPtr version);
+ void setSelectedLoaderVersion(BaseVersionPtr version);
private slots:
void filterChanged();
+ void loaderFilterChanged();
private:
void refresh();
+ void loaderRefresh();
void suggestCurrent();
private:
@@ -94,4 +99,6 @@ private:
Ui::VanillaPage *ui = nullptr;
bool m_versionSetByUser = false;
BaseVersionPtr m_selectedVersion;
+ BaseVersionPtr m_selectedLoaderVersion;
+ QString m_selectedLoader;
};
diff --git a/launcher/ui/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/VanillaPage.ui
index 870ff161..43110927 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.ui
+++ b/launcher/ui/pages/modplatform/VanillaPage.ui
@@ -33,113 +33,231 @@
<string notr="true"/>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Filter</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="releaseFilter">
- <property name="text">
- <string>Releases</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="snapshotFilter">
- <property name="text">
- <string>Snapshots</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="oldSnapshotFilter">
- <property name="text">
- <string>Old Snapshots</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
+ <item row="2" column="0">
+ <widget class="Line" name="line">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="minecraftLayout">
<item>
- <widget class="QCheckBox" name="betaFilter">
- <property name="text">
- <string>Betas</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
+ <widget class="VersionSelectWidget" name="versionList" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="alphaFilter">
- <property name="text">
- <string>Alphas</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="releaseFilter">
+ <property name="text">
+ <string>Releases</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="snapshotFilter">
+ <property name="text">
+ <string>Snapshots</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="oldSnapshotFilter">
+ <property name="text">
+ <string>Old Snapshots</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="betaFilter">
+ <property name="text">
+ <string>Betas</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="alphaFilter">
+ <property name="text">
+ <string>Alphas</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="experimentsFilter">
+ <property name="text">
+ <string>Experiments</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="refreshBtn">
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <layout class="QHBoxLayout" name="loaderLayout">
<item>
- <widget class="QCheckBox" name="experimentsFilter">
- <property name="text">
- <string>Experiments</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
+ <widget class="VersionSelectWidget" name="loaderVersionList" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="refreshBtn">
- <property name="text">
- <string>Refresh</string>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="loaderLabel">
+ <property name="text">
+ <string>Mod Loader</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="noneFilter">
+ <property name="text">
+ <string>None</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">loaderBtnGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="forgeFilter">
+ <property name="text">
+ <string>Forge</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">loaderBtnGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="fabricFilter">
+ <property name="text">
+ <string>Fabric</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">loaderBtnGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="quiltFilter">
+ <property name="text">
+ <string>Quilt</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">loaderBtnGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="liteLoaderFilter">
+ <property name="text">
+ <string>LiteLoader</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">loaderBtnGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="loaderRefreshBtn">
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</item>
- <item row="0" column="0">
- <widget class="VersionSelectWidget" name="versionList" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
</layout>
</widget>
</widget>
@@ -166,4 +284,7 @@
</tabstops>
<resources/>
<connections/>
+ <buttongroups>
+ <buttongroup name="loaderBtnGroup"/>
+ </buttongroups>
</ui>
diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h
index dc58fd7f..d96a0720 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModPage.h
+++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h
@@ -49,7 +49,7 @@ class FlameModPage : public ModPage {
inline auto displayName() const -> QString override { return "CurseForge"; }
inline auto icon() const -> QIcon override { return APPLICATION->getThemedIcon("flame"); }
inline auto id() const -> QString override { return "curseforge"; }
- inline auto helpPage() const -> QString override { return "Flame-platform"; }
+ inline auto helpPage() const -> QString override { return "Mod-platform"; }
inline auto debugName() const -> QString override { return "Flame"; }
inline auto metaEntryBase() const -> QString override { return "FlameMods"; };
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
index aa5ed793..0bde43eb 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
@@ -49,7 +49,7 @@ class ModrinthPage : public ModPage {
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 "Modrinth-platform"; }
+ 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"; };
diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp
new file mode 100644
index 00000000..ffc8d05d
--- /dev/null
+++ b/launcher/ui/widgets/ModFilterWidget.cpp
@@ -0,0 +1,109 @@
+#include "ModFilterWidget.h"
+#include "ui_ModFilterWidget.h"
+
+ModFilterWidget::ModFilterWidget(Version def, QWidget* parent)
+ : QTabWidget(parent), m_filter(new Filter()), ui(new Ui::ModFilterWidget)
+{
+ ui->setupUi(this);
+
+ m_mcVersion_buttons.addButton(ui->strictVersionButton, VersionButtonID::Strict);
+ ui->strictVersionButton->click();
+ m_mcVersion_buttons.addButton(ui->majorVersionButton, VersionButtonID::Major);
+ m_mcVersion_buttons.addButton(ui->allVersionsButton, VersionButtonID::All);
+ //m_mcVersion_buttons.addButton(ui->betweenVersionsButton, VersionButtonID::Between);
+
+ connect(&m_mcVersion_buttons, SIGNAL(idClicked(int)), this, SLOT(onVersionFilterChanged(int)));
+
+ m_filter->versions.push_front(def);
+
+ setHidden(true);
+}
+
+void ModFilterWidget::setInstance(MinecraftInstance* instance)
+{
+ m_instance = instance;
+
+ auto mcVersionSplit = mcVersionStr().split(".");
+
+ ui->strictVersionButton->setText(
+ tr("Strict match (= %1)").arg(mcVersionStr()));
+ ui->majorVersionButton->setText(
+ tr("Major version match (= %1.%2.x)").arg(mcVersionSplit[0], mcVersionSplit[1]));
+ ui->allVersionsButton->setText(
+ tr("Any version"));
+ //ui->betweenVersionsButton->setText(
+ // tr("Between two versions"));
+}
+
+auto ModFilterWidget::getFilter() -> std::shared_ptr<Filter>
+{
+ m_last_version_id = m_version_id;
+ emit filterUnchanged();
+ return m_filter;
+}
+
+void ModFilterWidget::disableVersionButton(VersionButtonID id)
+{
+ switch(id){
+ case(VersionButtonID::Strict):
+ ui->strictVersionButton->setEnabled(false);
+ break;
+ case(VersionButtonID::Major):
+ ui->majorVersionButton->setEnabled(false);
+ break;
+ case(VersionButtonID::All):
+ ui->allVersionsButton->setEnabled(false);
+ break;
+ case(VersionButtonID::Between):
+ // ui->betweenVersionsButton->setEnabled(false);
+ break;
+ default:
+ break;
+ }
+}
+
+void ModFilterWidget::onVersionFilterChanged(int id)
+{
+ //ui->lowerVersionComboBox->setEnabled(id == VersionButtonID::Between);
+ //ui->upperVersionComboBox->setEnabled(id == VersionButtonID::Between);
+
+ auto versionSplit = mcVersionStr().split(".");
+ int index = 0;
+
+ auto cast_id = (VersionButtonID) id;
+ if (cast_id != m_version_id) {
+ m_version_id = cast_id;
+ } else {
+ return;
+ }
+
+ m_filter->versions.clear();
+
+ switch(cast_id){
+ case(VersionButtonID::Strict):
+ m_filter->versions.push_front(mcVersion());
+ break;
+ case(VersionButtonID::Major):
+ for(auto i = Version(QString("%1.%2").arg(versionSplit[0], versionSplit[1])); i <= mcVersion(); index++){
+ m_filter->versions.push_front(i);
+ i = Version(QString("%1.%2.%3").arg(versionSplit[0], versionSplit[1], QString("%1").arg(index)));
+ }
+ break;
+ case(VersionButtonID::All):
+ // Empty list to avoid enumerating all versions :P
+ break;
+ case(VersionButtonID::Between):
+ // TODO
+ break;
+ }
+
+ if(changed())
+ emit filterChanged();
+ else
+ emit filterUnchanged();
+}
+
+ModFilterWidget::~ModFilterWidget()
+{
+ delete ui;
+}
diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h
new file mode 100644
index 00000000..334fc672
--- /dev/null
+++ b/launcher/ui/widgets/ModFilterWidget.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <QTabWidget>
+#include <QButtonGroup>
+
+#include "Version.h"
+#include "minecraft/MinecraftInstance.h"
+#include "minecraft/PackProfile.h"
+
+class MinecraftInstance;
+
+namespace Ui {
+class ModFilterWidget;
+}
+
+class ModFilterWidget : public QTabWidget
+{
+ Q_OBJECT
+public:
+ enum VersionButtonID {
+ Strict = 0,
+ Major = 1,
+ All = 2,
+ Between = 3
+ };
+
+ struct Filter {
+ std::list<Version> versions;
+
+ bool operator==(const Filter& other) const { return versions == other.versions; }
+ bool operator!=(const Filter& other) const { return !(*this == other); }
+ };
+
+ std::shared_ptr<Filter> m_filter;
+
+public:
+ explicit ModFilterWidget(Version def, QWidget* parent = nullptr);
+ ~ModFilterWidget();
+
+ void setInstance(MinecraftInstance* instance);
+
+ /// By default all buttons are enabled
+ void disableVersionButton(VersionButtonID);
+
+ auto getFilter() -> std::shared_ptr<Filter>;
+ auto changed() const -> bool { return m_last_version_id != m_version_id; }
+
+private:
+ inline auto mcVersionStr() const -> QString { return m_instance ? m_instance->getPackProfile()->getComponentVersion("net.minecraft") : ""; }
+ inline auto mcVersion() const -> Version { return { mcVersionStr() }; }
+
+private slots:
+ void onVersionFilterChanged(int id);
+
+public: signals:
+ void filterChanged();
+ void filterUnchanged();
+
+private:
+ Ui::ModFilterWidget* ui;
+
+ MinecraftInstance* m_instance = nullptr;
+
+ QButtonGroup m_mcVersion_buttons;
+
+ /* Used to tell if the filter was changed since the last getFilter() call */
+ VersionButtonID m_last_version_id = VersionButtonID::Strict;
+ VersionButtonID m_version_id = VersionButtonID::Strict;
+};
diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui
new file mode 100644
index 00000000..ad1090e2
--- /dev/null
+++ b/launcher/ui/widgets/ModFilterWidget.ui
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ModFilterWidget</class>
+ <widget class="QTabWidget" name="ModFilterWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <widget class="QWidget" name="VersionPage">
+ <attribute name="title">
+ <string>Minecraft versions</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="2" column="0">
+ <widget class="QRadioButton" name="allVersionsButton">
+ <property name="text">
+ <string>allVersions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="strictVersionButton">
+ <property name="text">
+ <string>strictVersion</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QRadioButton" name="majorVersionButton">
+ <property name="text">
+ <string>majorVersion</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp
index 1209f118..cc4fc6a2 100644
--- a/launcher/ui/widgets/VersionSelectWidget.cpp
+++ b/launcher/ui/widgets/VersionSelectWidget.cpp
@@ -4,7 +4,6 @@
#include <QVBoxLayout>
#include <QHeaderView>
-#include "VersionListView.h"
#include "VersionProxyModel.h"
#include "ui/dialogs/CustomMessageBox.h"
@@ -57,6 +56,11 @@ void VersionSelectWidget::setEmptyErrorString(QString emptyErrorString)
listView->setEmptyErrorString(emptyErrorString);
}
+void VersionSelectWidget::setEmptyMode(VersionListView::EmptyMode mode)
+{
+ listView->setEmptyMode(mode);
+}
+
VersionSelectWidget::~VersionSelectWidget()
{
}
diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h
index 0a649408..f56daa8a 100644
--- a/launcher/ui/widgets/VersionSelectWidget.h
+++ b/launcher/ui/widgets/VersionSelectWidget.h
@@ -18,6 +18,7 @@
#include <QWidget>
#include <QSortFilterProxyModel>
#include "BaseVersionList.h"
+#include "VersionListView.h"
class VersionProxyModel;
class VersionListView;
@@ -49,6 +50,7 @@ public:
void setFilter(BaseVersionList::ModelRoles role, Filter *filter);
void setEmptyString(QString emptyString);
void setEmptyErrorString(QString emptyErrorString);
+ void setEmptyMode(VersionListView::EmptyMode mode);
void setResizeOn(int column);
signals:
diff --git a/libraries/LocalPeer/CMakeLists.txt b/libraries/LocalPeer/CMakeLists.txt
index 1e7557ec..0b434803 100644
--- a/libraries/LocalPeer/CMakeLists.txt
+++ b/libraries/LocalPeer/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(LocalPeer)
find_package(Qt5 COMPONENTS Core Network REQUIRED)
diff --git a/libraries/iconfix/CMakeLists.txt b/libraries/iconfix/CMakeLists.txt
index 049879c4..08441203 100644
--- a/libraries/iconfix/CMakeLists.txt
+++ b/libraries/iconfix/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(iconfix)
find_package(Qt5Core REQUIRED QUIET)
diff --git a/libraries/javacheck/CMakeLists.txt b/libraries/javacheck/CMakeLists.txt
index f599bf15..735de443 100644
--- a/libraries/javacheck/CMakeLists.txt
+++ b/libraries/javacheck/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(launcher Java)
find_package(Java 1.7 REQUIRED COMPONENTS Development)
diff --git a/libraries/katabasis/CMakeLists.txt b/libraries/katabasis/CMakeLists.txt
index d579dc29..77db286a 100644
--- a/libraries/katabasis/CMakeLists.txt
+++ b/libraries/katabasis/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.6)
+cmake_minimum_required(VERSION 3.9.4)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD)
if(IS_IN_SOURCE_BUILD)
diff --git a/libraries/launcher/CMakeLists.txt b/libraries/launcher/CMakeLists.txt
index 54913fd4..0eccae8b 100644
--- a/libraries/launcher/CMakeLists.txt
+++ b/libraries/launcher/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(launcher Java)
find_package(Java 1.7 REQUIRED COMPONENTS Development)
diff --git a/libraries/libnbtplusplus b/libraries/libnbtplusplus
-Subproject dc72a20b7efd304d12af2025223fad07b4b7846
+Subproject 129be45a7f91920e76673af104534d215c497d8
diff --git a/libraries/optional-bare/CMakeLists.txt b/libraries/optional-bare/CMakeLists.txt
index b8b498c5..952df6e2 100644
--- a/libraries/optional-bare/CMakeLists.txt
+++ b/libraries/optional-bare/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(optional-bare)
add_library(optional-bare INTERFACE)
diff --git a/libraries/rainbow/CMakeLists.txt b/libraries/rainbow/CMakeLists.txt
index e57dbbc2..94cc1b49 100644
--- a/libraries/rainbow/CMakeLists.txt
+++ b/libraries/rainbow/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(rainbow)
find_package(Qt5Core REQUIRED QUIET)
diff --git a/libraries/xz-embedded/CMakeLists.txt b/libraries/xz-embedded/CMakeLists.txt
index 86ac60c8..4ce46102 100644
--- a/libraries/xz-embedded/CMakeLists.txt
+++ b/libraries/xz-embedded/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9.4)
project(xz-embedded LANGUAGES C)
option(XZ_BUILD_BCJ "Build xz-embedded with BCJ support (native binary optimization)" OFF)
diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt
index f9d7621d..9c243826 100644
--- a/program_info/CMakeLists.txt
+++ b/program_info/CMakeLists.txt
@@ -11,6 +11,7 @@ set(Launcher_DesktopFileName "org.polymc.PolyMC.desktop" PARENT_SCOPE)
set(Launcher_Desktop "program_info/org.polymc.PolyMC.desktop" PARENT_SCOPE)
set(Launcher_MetaInfo "program_info/org.polymc.PolyMC.metainfo.xml" PARENT_SCOPE)
+set(Launcher_ManPage "program_info/polymc.6.txt" PARENT_SCOPE)
set(Launcher_SVG "program_info/org.polymc.PolyMC.svg" PARENT_SCOPE)
set(Launcher_Branding_ICNS "program_info/polymc.icns" PARENT_SCOPE)
set(Launcher_Branding_WindowsRC "program_info/polymc.rc" PARENT_SCOPE)
diff --git a/doc/polymc.1.txt b/program_info/polymc.6.txt
index 9ba34662..8f126cce 100644
--- a/doc/polymc.1.txt
+++ b/program_info/polymc.6.txt
@@ -59,8 +59,6 @@ Main website: <https://polymc.org>
AUTHORS
-------
-peterix <peterix@gmail.com>
-
-swurl <swurl@swurl.xyz>
+PolyMC Contributors
// vim: syntax=asciidoc