diff --git a/launcher/Filter.cpp b/launcher/Filter.cpp index fc1c42344..adeb2209e 100644 --- a/launcher/Filter.cpp +++ b/launcher/Filter.cpp @@ -1,16 +1,12 @@ #include "Filter.h" -Filter::~Filter() {} - ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern) {} -ContainsFilter::~ContainsFilter() {} bool ContainsFilter::accepts(const QString& value) { return value.contains(pattern); } ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern) {} -ExactFilter::~ExactFilter() {} bool ExactFilter::accepts(const QString& value) { return value == pattern; @@ -27,10 +23,15 @@ RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert) pattern.setPattern(regexp); pattern.optimize(); } -RegexpFilter::~RegexpFilter() {} bool RegexpFilter::accepts(const QString& value) { auto match = pattern.match(value); bool matched = match.hasMatch(); return invert ? (!matched) : (matched); } + +ExactListFilter::ExactListFilter(const QStringList& pattern) : m_pattern(pattern) {} +bool ExactListFilter::accepts(const QString& value) +{ + return m_pattern.isEmpty() || m_pattern.contains(value); +} \ No newline at end of file diff --git a/launcher/Filter.h b/launcher/Filter.h index 089c844d4..a8c9c14d8 100644 --- a/launcher/Filter.h +++ b/launcher/Filter.h @@ -5,14 +5,14 @@ class Filter { public: - virtual ~Filter(); + virtual ~Filter() = default; virtual bool accepts(const QString& value) = 0; }; class ContainsFilter : public Filter { public: ContainsFilter(const QString& pattern); - virtual ~ContainsFilter(); + virtual ~ContainsFilter() = default; bool accepts(const QString& value) override; private: @@ -22,7 +22,7 @@ class ContainsFilter : public Filter { class ExactFilter : public Filter { public: ExactFilter(const QString& pattern); - virtual ~ExactFilter(); + virtual ~ExactFilter() = default; bool accepts(const QString& value) override; private: @@ -32,7 +32,7 @@ class ExactFilter : public Filter { class ExactIfPresentFilter : public Filter { public: ExactIfPresentFilter(const QString& pattern); - ~ExactIfPresentFilter() override = default; + virtual ~ExactIfPresentFilter() override = default; bool accepts(const QString& value) override; private: @@ -42,10 +42,20 @@ class ExactIfPresentFilter : public Filter { class RegexpFilter : public Filter { public: RegexpFilter(const QString& regexp, bool invert); - virtual ~RegexpFilter(); + virtual ~RegexpFilter() = default; bool accepts(const QString& value) override; private: QRegularExpression pattern; bool invert = false; }; + +class ExactListFilter : public Filter { + public: + ExactListFilter(const QStringList& pattern = {}); + virtual ~ExactListFilter() = default; + bool accepts(const QString& value) override; + + private: + const QStringList& m_pattern; +}; diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 7af0df389..730116072 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -56,7 +56,7 @@ class MinecraftInstance : public BaseInstance { Q_OBJECT public: MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir); - virtual ~MinecraftInstance() {}; + virtual ~MinecraftInstance() = default; virtual void saveNow() override; void loadSpecificSettings() override; diff --git a/launcher/minecraft/VersionFile.h b/launcher/minecraft/VersionFile.h index 85ac55426..40f49aaa4 100644 --- a/launcher/minecraft/VersionFile.h +++ b/launcher/minecraft/VersionFile.h @@ -101,7 +101,7 @@ class VersionFile : public ProblemContainer { /// Mojang: list of compatible java majors QList compatibleJavaMajors; - /// Mojang: the name of recomended java version + /// Mojang: the name of recommended java version QString compatibleJavaName; /// Mojang: type of the Minecraft version diff --git a/launcher/ui/java/InstallJavaDialog.cpp b/launcher/ui/java/InstallJavaDialog.cpp index 1a4b4cc58..01ec56dfd 100644 --- a/launcher/ui/java/InstallJavaDialog.cpp +++ b/launcher/ui/java/InstallJavaDialog.cpp @@ -18,6 +18,7 @@ #include "InstallJavaDialog.h" +#include #include #include #include @@ -27,10 +28,13 @@ #include "Application.h" #include "BaseVersionList.h" #include "FileSystem.h" +#include "Filter.h" #include "java/download/ArchiveDownloadTask.h" #include "java/download/ManifestDownloadTask.h" #include "meta/Index.h" #include "meta/VersionList.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" #include "ui/java/VersionList.h" @@ -119,6 +123,27 @@ class InstallJavaPage : public QWidget, public BasePage { majorVersionSelect->loadList(); javaVersionSelect->loadList(); } + + public slots: + void setRecommendedMajors(const QStringList& majors) + { + m_recommended_majors = majors; + recommendedFilterChanged(); + } + void setRecomend(bool recomend) + { + m_recommend = recomend; + recommendedFilterChanged(); + } + void recommendedFilterChanged() + { + if (m_recommend) { + majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, new ExactListFilter(m_recommended_majors)); + } else { + majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, new ExactListFilter()); + } + } + signals: void selectionChanged(); @@ -131,6 +156,9 @@ class InstallJavaPage : public QWidget, public BasePage { QHBoxLayout* horizontalLayout = nullptr; VersionSelectWidget* majorVersionSelect = nullptr; VersionSelectWidget* javaVersionSelect = nullptr; + + QStringList m_recommended_majors; + bool m_recommend; }; static InstallJavaPage* pageCast(BasePage* page) @@ -140,8 +168,20 @@ static InstallJavaPage* pageCast(BasePage* page) return result; } namespace Java { +QStringList getRecommendedJavaVersionsFromVersionList(Meta::VersionList::Ptr list) +{ + QStringList recommendedJavas; + for (auto ver : list->versions()) { + auto major = ver->version(); + if (major.startsWith("java")) { + major = "Java " + major.mid(4); + } + recommendedJavas.append(major); + } + return recommendedJavas; +} -InstallDialog::InstallDialog(const QString& uid, QWidget* parent) +InstallDialog::InstallDialog(const QString& uid, BaseInstance* instance, QWidget* parent) : QDialog(parent), container(new PageContainer(this, QString(), this)), buttons(new QDialogButtonBox(this)) { auto layout = new QVBoxLayout(this); @@ -150,10 +190,22 @@ InstallDialog::InstallDialog(const QString& uid, QWidget* parent) layout->addWidget(container); auto buttonLayout = new QHBoxLayout(this); + auto refreshLayout = new QHBoxLayout(this); auto refreshButton = new QPushButton(tr("&Refresh"), this); connect(refreshButton, &QPushButton::clicked, this, [this] { pageCast(container->selectedPage())->loadList(); }); - buttonLayout->addWidget(refreshButton); + refreshLayout->addWidget(refreshButton); + + auto recommendedCheckBox = new QCheckBox("Recommended", this); + recommendedCheckBox->setCheckState(Qt::CheckState::Checked); + connect(recommendedCheckBox, &QCheckBox::stateChanged, this, [this](int state) { + for (BasePage* page : container->getPages()) { + pageCast(page)->setRecomend(state == Qt::Checked); + } + }); + + refreshLayout->addWidget(recommendedCheckBox); + buttonLayout->addLayout(refreshLayout); buttons->setOrientation(Qt::Horizontal); buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); @@ -168,11 +220,49 @@ InstallDialog::InstallDialog(const QString& uid, QWidget* parent) setWindowModality(Qt::WindowModal); resize(840, 480); + QStringList recommendedJavas; + if (auto mcInst = dynamic_cast(instance); mcInst) { + auto mc = mcInst->getPackProfile()->getComponent("net.minecraft"); + if (mc) { + auto file = mc->getVersionFile(); // no need for load as it should already be loaded + if (file) { + for (auto major : file->compatibleJavaMajors) { + recommendedJavas.append(QString("Java %1").arg(major)); + } + } + } + } else { + const auto versions = APPLICATION->metadataIndex()->get("net.minecraft.java"); + if (versions) { + if (versions->isLoaded()) { + recommendedJavas = getRecommendedJavaVersionsFromVersionList(versions); + } else { + auto newTask = versions->getLoadTask(); + if (newTask) { + connect(newTask.get(), &Task::succeeded, this, [this, versions] { + auto recommendedJavas = getRecommendedJavaVersionsFromVersionList(versions); + for (BasePage* page : container->getPages()) { + pageCast(page)->setRecommendedMajors(recommendedJavas); + } + }); + if (!newTask->isRunning()) + newTask->start(); + } else { + recommendedJavas = getRecommendedJavaVersionsFromVersionList(versions); + } + } + } + } for (BasePage* page : container->getPages()) { if (page->id() == uid) container->selectPage(page->id()); - connect(pageCast(page), &InstallJavaPage::selectionChanged, this, [this] { validate(); }); + auto cast = pageCast(page); + cast->setRecomend(true); + connect(cast, &InstallJavaPage::selectionChanged, this, [this] { validate(); }); + if (!recommendedJavas.isEmpty()) { + cast->setRecommendedMajors(recommendedJavas); + } } connect(container, &PageContainer::selectedPageChanged, this, [this] { validate(); }); pageCast(container->selectedPage())->selectSearch(); @@ -243,6 +333,7 @@ void InstallDialog::done(int result) QDialog::done(result); } + } // namespace Java #include "InstallJavaDialog.moc" \ No newline at end of file diff --git a/launcher/ui/java/InstallJavaDialog.h b/launcher/ui/java/InstallJavaDialog.h index 80d010c1a..d6f879207 100644 --- a/launcher/ui/java/InstallJavaDialog.h +++ b/launcher/ui/java/InstallJavaDialog.h @@ -19,6 +19,7 @@ #pragma once #include +#include "BaseInstance.h" #include "ui/pages/BasePageProvider.h" class MinecraftInstance; @@ -31,7 +32,7 @@ class InstallDialog final : public QDialog, private BasePageProvider { Q_OBJECT public: - explicit InstallDialog(const QString& uid = QString(), QWidget* parent = nullptr); + explicit InstallDialog(const QString& uid = QString(), BaseInstance* instance = nullptr, QWidget* parent = nullptr); QList getPages() override; QString dialogTitle() override; diff --git a/launcher/ui/pages/BasePageProvider.h b/launcher/ui/pages/BasePageProvider.h index 422891e6b..ef3c1cd08 100644 --- a/launcher/ui/pages/BasePageProvider.h +++ b/launcher/ui/pages/BasePageProvider.h @@ -16,7 +16,6 @@ #pragma once #include -#include #include "ui/pages/BasePage.h" class BasePageProvider { diff --git a/launcher/ui/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index 97ffa5d4d..6699b00c0 100644 --- a/launcher/ui/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -201,7 +201,7 @@ void JavaPage::on_javaTestBtn_clicked() void JavaPage::on_downloadJavaButton_clicked() { - auto jdialog = new Java::InstallDialog({}, this); + auto jdialog = new Java::InstallDialog({}, nullptr, this); jdialog->exec(); ui->managedJavaList->loadList(); } diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 6e6b1db57..364f64e19 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -390,7 +390,7 @@ void InstanceSettingsPage::loadSettings() void InstanceSettingsPage::on_javaDownloadBtn_clicked() { - auto jdialog = new Java::InstallDialog({}, this); + auto jdialog = new Java::InstallDialog({}, m_instance, this); jdialog->exec(); } diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index ec1ed0605..fb90afe1d 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -351,7 +351,7 @@ void JavaSettingsWidget::on_javaBrowseBtn_clicked() void JavaSettingsWidget::javaDownloadBtn_clicked() { - auto jdialog = new Java::InstallDialog({}, this); + auto jdialog = new Java::InstallDialog({}, nullptr, this); jdialog->exec(); }