From 4f0ec908ecc0c14c1ffe8e9631d031c754e3540a Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 9 May 2023 23:29:16 -0300 Subject: feat: add a close button to the main toolbar when running on gamescope Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db64..9b8db1ae 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -219,6 +219,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // disabled until we have an instance selected ui->instanceToolBar->setEnabled(false); setInstanceActionsEnabled(false); + + // add a close button at the end of the main toolbar when running on gamescope / steam deck + if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { + ui->mainToolBar->addAction(ui->actionCloseWindow); + } + } // add the toolbar toggles to the view menu -- cgit From f724059b883d584b9f1d9ecd5fe21c7e4d214889 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 7 Jun 2023 01:23:53 +0300 Subject: Added visit mod's page Signed-off-by: Trial97 --- .../ui/pages/instance/ExternalResourcesPage.ui | 11 +++++ launcher/ui/pages/instance/ModFolderPage.cpp | 48 +++++++++++++++++----- launcher/ui/pages/instance/ModFolderPage.h | 1 + 3 files changed, 49 insertions(+), 11 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 33a03336..b110dbfd 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -154,6 +154,17 @@ Try to check or update all selected resources (all resources if none are selected) + + + false + + + Visit on mod's page + + + Go to mods home page + + diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 4548af59..d1787e7d 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include "Application.h" @@ -59,6 +60,7 @@ #include "minecraft/mod/Mod.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" #include "Version.h" @@ -85,22 +87,29 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); + ui->actionVisitItemPage->setToolTip(tr("Go to mods home page")); + ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); + connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); + auto check_allow_update = [this] { - return (!m_instance || !m_instance->isRunning()) && - (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); + return (!m_instance || !m_instance->isRunning()) && (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); }; connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); - }); - connect(mods.get(), &ModFolderModel::rowsInserted, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + auto mods_list = m_model->selectedMods(selection); + auto enableView = std::any_of(mods_list.cbegin(), mods_list.cend(), + [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); + ui->actionVisitItemPage->setEnabled(enableView); }); - connect(mods.get(), &ModFolderModel::rowsRemoved, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); - }); + connect(mods.get(), &ModFolderModel::rowsInserted, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); + + connect(mods.get(), &ModFolderModel::rowsRemoved, this, + [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update, mods] { ui->actionUpdateItem->setEnabled(check_allow_update()); @@ -140,7 +149,7 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI return true; } -void ModFolderPage::removeItems(const QItemSelection &selection) +void ModFolderPage::removeItems(const QItemSelection& selection) { m_model->deleteMods(selection.indexes()); } @@ -214,8 +223,7 @@ void ModFolderPage::updateMods() message = tr("All selected mods are up-to-date! :)"); } } - CustomMessageBox::selectable(this, tr("Update checker"), message) - ->exec(); + CustomMessageBox::selectable(this, tr("Update checker"), message)->exec(); return; } @@ -282,3 +290,21 @@ bool NilModFolderPage::shouldDisplay() const { return m_model->dir().exists(); } + +void ModFolderPage::visitModPages() +{ + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + for (auto mod : m_model->selectedMods(selection)) + if (auto meta = mod->metadata(); meta != nullptr) { + auto slug = meta->slug.remove(".pw.toml"); + switch (meta->provider) { + case ModPlatform::ResourceProvider::MODRINTH: + DesktopServices::openUrl(QString("https://modrinth.com/mod/%1").arg(slug)); + break; + case ModPlatform::ResourceProvider::FLAME: + DesktopServices::openUrl(QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug)); + break; + } + } else if (mod->homeurl().size() != 0) + DesktopServices::openUrl(mod->homeurl()); +} \ No newline at end of file diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 2fc7b574..d36a7995 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -64,6 +64,7 @@ class ModFolderPage : public ExternalResourcesPage { void installMods(); void updateMods(); + void visitModPages(); protected: std::shared_ptr m_model; -- cgit From e936bc4c60b4262cd70ff1eb3291dc3ead4c53ac Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 7 Jun 2023 01:38:10 +0300 Subject: Added custom text for multiple selection Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index d1787e7d..1dbb9f47 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -87,7 +87,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); - ui->actionVisitItemPage->setToolTip(tr("Go to mods home page")); + ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); @@ -100,9 +100,16 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); auto mods_list = m_model->selectedMods(selection); - auto enableView = std::any_of(mods_list.cbegin(), mods_list.cend(), + auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(), [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); - ui->actionVisitItemPage->setEnabled(enableView); + if (selected <= 1) { + ui->actionVisitItemPage->setText(tr("Visit on mod's page")); + ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); + } else { + ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); + ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); + } + ui->actionVisitItemPage->setEnabled(selected != 0); }); connect(mods.get(), &ModFolderModel::rowsInserted, this, -- cgit From d33de2e4277dfcd090a36c96e09148ea6a5d2e55 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Jun 2023 00:54:32 +0300 Subject: Made cat scalable Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 17 ++--------------- launcher/ui/instanceview/InstanceView.cpp | 23 ++++++++++++++++++++++- launcher/ui/instanceview/InstanceView.h | 8 ++++---- 3 files changed, 28 insertions(+), 20 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 834f57dd..4b77dd1c 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -901,21 +901,8 @@ void MainWindow::onCatToggled(bool state) void MainWindow::setCatBackground(bool enabled) { - if (enabled) { - view->setStyleSheet(QString(R"( -InstanceView -{ - background-image: url(:/backgrounds/%1); - background-attachment: fixed; - background-clip: padding; - background-position: bottom right; - background-repeat: none; - background-color:palette(base); -})") - .arg(ThemeManager::getCatImage())); - } else { - view->setStyleSheet(QString()); - } + view->setCatVisible(enabled); + view->viewport()->repaint(); } void MainWindow::runModalTask(Task *task) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index fbeffe35..4c83e94a 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -48,6 +48,7 @@ #include #include "VisualGroup.h" +#include "ui/themes/ThemeManager.h" #include #include @@ -73,6 +74,7 @@ InstanceView::InstanceView(QWidget *parent) setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setAcceptDrops(true); setAutoScroll(true); + setCatVisible(APPLICATION->settings()->get("TheCat").toBool()); } InstanceView::~InstanceView() @@ -498,12 +500,31 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) } } -void InstanceView::paintEvent(QPaintEvent *event) +void InstanceView::setCatVisible(bool visible) +{ + m_catVisible = visible; + m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); +} + +void InstanceView::paintEvent(QPaintEvent* event) { executeDelayedItemsLayout(); QPainter painter(this->viewport()); + if (m_catVisible) { + int widWidth = this->viewport()->width(); + int widHeight = this->viewport()->height(); + if (m_catPixmap.width() < widWidth) + widWidth = m_catPixmap.width(); + if (m_catPixmap.height() < widHeight) + widHeight = m_catPixmap.height(); + auto pixmap = m_catPixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatio); + QRect rectOfPixmap = pixmap.rect(); + rectOfPixmap.moveBottomRight(this->viewport()->rect().bottomRight()); + painter.drawPixmap(rectOfPixmap.topLeft(), pixmap); + } + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStyleOptionViewItem option; initViewItemOption(&option); diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index ac338274..a9bd0bd7 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -85,10 +85,8 @@ public: virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; - int spacing() const - { - return m_spacing; - }; + int spacing() const { return m_spacing; }; + void setCatVisible(bool visible); public slots: virtual void updateGeometries() override; @@ -139,6 +137,8 @@ private: int m_currentItemsPerRow = -1; int m_currentCursorColumn= -1; mutable QCache geometryCache; + bool m_catVisible = false; + QPixmap m_catPixmap; // point where the currently active mouse action started in geometry coordinates QPoint m_pressedPosition; -- cgit From 318d11481d719cf537ecdc00f8d676494bab22b6 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Wed, 7 Jun 2023 19:37:54 -0400 Subject: Resolve other switch fallthrough issues --- launcher/LaunchController.cpp | 4 +- launcher/VersionProxyModel.cpp | 100 ++++++++------------- launcher/meta/Index.cpp | 2 +- launcher/minecraft/auth/AccountList.cpp | 9 +- launcher/minecraft/auth/Yggdrasil.cpp | 1 + launcher/minecraft/mod/DataPack.cpp | 2 + launcher/minecraft/mod/Mod.cpp | 3 + launcher/minecraft/mod/Resource.cpp | 3 + launcher/minecraft/mod/ResourcePack.cpp | 2 + .../flame/FlameInstanceCreationTask.cpp | 3 +- launcher/translations/TranslationsModel.cpp | 1 + .../ui/instanceview/AccessibleInstanceView.cpp | 2 +- launcher/ui/pages/instance/WorldListPage.cpp | 1 + launcher/ui/setupwizard/JavaWizardPage.cpp | 1 + 14 files changed, 60 insertions(+), 74 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 070ee283..5d84b3bf 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -187,8 +187,8 @@ void LaunchController::login() { switch(m_accountToUse->accountState()) { case AccountState::Offline: { m_session->wants_online = false; - // NOTE: fallthrough is intentional } + /* fallthrough */ case AccountState::Online: { if(!m_session->wants_online) { // we ask the user for a player name @@ -267,8 +267,8 @@ void LaunchController::login() { // This means some sort of soft error that we can fix with a refresh ... so let's refresh. case AccountState::Unchecked: { m_accountToUse->refresh(); - // NOTE: fallthrough intentional } + /* fallthrough */ case AccountState::Working: { // refresh is in progress, we need to wait for it to finish to proceed. ProgressDialog progDialog(m_parentWidget); diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 6aba268d..3c294873 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -185,80 +185,50 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const return QVariant(); } } - case Qt::ToolTipRole: - { - switch(column) - { - case Name: - { - if(hasRecommended) + case Qt::ToolTipRole: { + if (column == Name && hasRecommended) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(value.toBool()) { + return tr("Recommended"); + } + else if(hasLatest) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(value.toBool()) { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { - return tr("Recommended"); - } - else if(hasLatest) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { - return tr("Latest"); - } - } - else if(index.row() == 0) - { - return tr("Latest"); - } + return tr("Latest"); } } - default: - { - return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); + else if(index.row() == 0) { + return tr("Latest"); } } + return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole); } - case Qt::DecorationRole: - { - switch(column) - { - case Name: - { - if(hasRecommended) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); - if(value.toBool()) - { - return APPLICATION->getThemedIcon("star"); - } - else if(hasLatest) - { - auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); - if(value.toBool()) - { - return APPLICATION->getThemedIcon("bug"); - } - } - else if(index.row() == 0) - { - return APPLICATION->getThemedIcon("bug"); - } - QPixmap pixmap; - QPixmapCache::find("placeholder", &pixmap); - if(!pixmap) - { - QPixmap px(16,16); - px.fill(Qt::transparent); - QPixmapCache::insert("placeholder", px); - return px; - } - return pixmap; + case Qt::DecorationRole: { + if (column == Name && hasRecommended) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); + if(value.toBool()) { + return APPLICATION->getThemedIcon("star"); + } else if(hasLatest) { + auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); + if(value.toBool()) { + return APPLICATION->getThemedIcon("bug"); } } - default: - { - return QVariant(); + else if(index.row() == 0) { + return APPLICATION->getThemedIcon("bug"); + } + QPixmap pixmap; + QPixmapCache::find("placeholder", &pixmap); + if(!pixmap) { + QPixmap px(16,16); + px.fill(Qt::transparent); + QPixmapCache::insert("placeholder", px); + return px; } + return pixmap; + } else { + return QVariant(); } } default: diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp index 242aad9f..2902f290 100644 --- a/launcher/meta/Index.cpp +++ b/launcher/meta/Index.cpp @@ -48,8 +48,8 @@ QVariant Index::data(const QModelIndex &index, int role) const switch (index.column()) { case 0: return list->humanReadable(); - default: break; } + break; case UidRole: return list->uid(); case NameRole: return list->name(); case ListPtrRole: return QVariant::fromValue(list); diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index e454bcc4..184f8e10 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -357,11 +357,12 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return QVariant::fromValue(account); case Qt::CheckStateRole: - switch (index.column()) - { - case ProfileNameColumn: - return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; + if (index.column() == ProfileNameColumn) { + return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; + } else { + return QVariant(); } + default: return QVariant(); diff --git a/launcher/minecraft/auth/Yggdrasil.cpp b/launcher/minecraft/auth/Yggdrasil.cpp index 29978411..d3e7ccdd 100644 --- a/launcher/minecraft/auth/Yggdrasil.cpp +++ b/launcher/minecraft/auth/Yggdrasil.cpp @@ -273,6 +273,7 @@ void Yggdrasil::processReply() { AccountTaskState::STATE_FAILED_GONE, tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.") ); + return; } default: changeState( diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp index ca75cd2a..c5754638 100644 --- a/launcher/minecraft/mod/DataPack.cpp +++ b/launcher/minecraft/mod/DataPack.cpp @@ -74,6 +74,7 @@ std::pair DataPack::compare(const Resource& other, SortType type) con auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::PACK_FORMAT: { auto this_ver = packFormat(); @@ -83,6 +84,7 @@ std::pair DataPack::compare(const Resource& other, SortType type) con return { 1, type == SortType::PACK_FORMAT }; if (this_ver < other_ver) return { -1, type == SortType::PACK_FORMAT }; + break; } } return { 0, false }; diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index c495cd47..6cda6185 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -89,6 +89,7 @@ std::pair Mod::compare(const Resource& other, SortType type) const auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::VERSION: { auto this_ver = Version(version()); @@ -97,11 +98,13 @@ std::pair Mod::compare(const Resource& other, SortType type) const return { 1, type == SortType::VERSION }; if (this_ver < other_ver) return { -1, type == SortType::VERSION }; + break; } case SortType::PROVIDER: { auto compare_result = QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::PROVIDER }; + break; } } return { 0, false }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index a0b8a4bb..e5077260 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -71,6 +71,7 @@ std::pair Resource::compare(const Resource& other, SortType type) con return { 1, type == SortType::ENABLED }; if (!enabled() && other.enabled()) return { -1, type == SortType::ENABLED }; + break; case SortType::NAME: { QString this_name{ name() }; QString other_name{ other.name() }; @@ -81,12 +82,14 @@ std::pair Resource::compare(const Resource& other, SortType type) con auto compare_result = QString::compare(this_name, other_name, Qt::CaseInsensitive); if (compare_result != 0) return { compare_result, type == SortType::NAME }; + break; } case SortType::DATE: if (dateTimeChanged() > other.dateTimeChanged()) return { 1, type == SortType::DATE }; if (dateTimeChanged() < other.dateTimeChanged()) return { -1, type == SortType::DATE }; + break; } return { 0, false }; diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp index 759d2b56..32a789f5 100644 --- a/launcher/minecraft/mod/ResourcePack.cpp +++ b/launcher/minecraft/mod/ResourcePack.cpp @@ -95,6 +95,7 @@ std::pair ResourcePack::compare(const Resource& other, SortType type) auto res = Resource::compare(other, type); if (res.first != 0) return res; + break; } case SortType::PACK_FORMAT: { auto this_ver = packFormat(); @@ -104,6 +105,7 @@ std::pair ResourcePack::compare(const Resource& other, SortType type) return { 1, type == SortType::PACK_FORMAT }; if (this_ver < other_ver) return { -1, type == SortType::PACK_FORMAT }; + break; } } return { 0, false }; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index dae93d1c..11365a21 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -467,8 +467,9 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) switch (result.type) { case Flame::File::Type::Folder: { logWarning(tr("This 'Folder' may need extracting: %1").arg(relpath)); - // fall-through intentional, we treat these as plain old mods and dump them wherever. + // fallthrough intentional, we treat these as plain old mods and dump them wherever. } + /* fallthrough */ case Flame::File::Type::SingleFile: case Flame::File::Type::Mod: { if (!result.url.isEmpty()) { diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 23e55c51..489dff86 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -454,6 +454,7 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const return QString("%1%").arg(lang.percentTranslated(), 3, 'f', 1); } } + qWarning("TranslationModel::data not implemented when role is DisplayRole"); } case Qt::ToolTipRole: { diff --git a/launcher/ui/instanceview/AccessibleInstanceView.cpp b/launcher/ui/instanceview/AccessibleInstanceView.cpp index 7de3ac72..2e7b8300 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.cpp +++ b/launcher/ui/instanceview/AccessibleInstanceView.cpp @@ -248,8 +248,8 @@ bool AccessibleInstanceView::selectColumn(int column) if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) { return false; } - // fallthrough intentional } + /* fallthrough */ case QAbstractItemView::ContiguousSelection: { if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { view()->clearSelection(); diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index b6ad159e..b5dc5a17 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -338,6 +338,7 @@ void WorldListPage::mceditState(LoggedProcess::State state) case LoggedProcess::Aborted: { failed = true; + break; } case LoggedProcess::Running: case LoggedProcess::Finished: diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index 14683778..e8833535 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -69,6 +69,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::AllOK: { settings->set("JavaPath", m_java_widget->javaPath()); + break; } case JavaSettingsWidget::ValidationStatus::JavaBad: { -- cgit From be0df38453977c37ae8b6b241e82ace41149fdcc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 15 Jun 2023 11:40:39 +0300 Subject: Added tooltip for name label Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 1 + launcher/ui/pages/instance/ModFolderPage.h | 3 +- launcher/ui/widgets/InfoFrame.cpp | 111 +++++++++++++++------------ launcher/ui/widgets/InfoFrame.h | 45 +++++++---- 4 files changed, 97 insertions(+), 63 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 1dbb9f47..650bf5bd 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -4,6 +4,7 @@ * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad + * Copyright (c) 2023 Trial97 * * 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 diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index d36a7995..2c1a9c77 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -4,6 +4,7 @@ * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad + * Copyright (c) 2023 Trial97 * * 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 @@ -60,7 +61,7 @@ class ModFolderPage : public ExternalResourcesPage { private slots: void runningStateChanged(bool running); - void removeItems(const QItemSelection &selection) override; + void removeItems(const QItemSelection& selection) override; void installMods(); void updateMods(); diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index fdc581b4..d0b55c0b 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -1,37 +1,38 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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 . -* -* 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. -*/ + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln + * Copyright (c) 2023 Trial97 + * + * 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 . + * + * 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 @@ -57,34 +58,47 @@ InfoFrame::~InfoFrame() void InfoFrame::updateWithMod(Mod const& m) { - if (m.type() == ResourceType::FOLDER) - { + if (m.type() == ResourceType::FOLDER) { clear(); return; } QString text = ""; QString name = ""; + QString link = ""; + QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else name = m.name(); - if (m.homeurl().isEmpty()) + if (auto meta = m.metadata(); meta != nullptr) { + auto slug = meta->slug.remove(".pw.toml"); + switch (meta->provider) { + case ModPlatform::ResourceProvider::MODRINTH: + link = QString("https://modrinth.com/mod/%1").arg(slug); + break; + case ModPlatform::ResourceProvider::FLAME: + link = QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug); + break; + } + } else if (!m.homeurl().isEmpty()) + link = m.homeurl(); + + if (link.isEmpty()) text = name; - else - text = "" + name + ""; + else { + text = "" + name + ""; + toolTip = tr("Go to mod's home page"); + } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); - setName(text); + setName(text, toolTip); - if (m.description().isEmpty()) - { + if (m.description().isEmpty()) { setDescription(QString()); - } - else - { + } else { setDescription(m.description()); } @@ -191,16 +205,15 @@ void InfoFrame::updateHiddenState() } } -void InfoFrame::setName(QString text) +void InfoFrame::setName(QString text, QString toolTip) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->nameLabel->setHidden(true); - } - else - { + ui->nameLabel->setToolTip({}); + } else { ui->nameLabel->setText(text); ui->nameLabel->setHidden(false); + ui->nameLabel->setToolTip(toolTip); } updateHiddenState(); } diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index 84523e28..4f6adc6d 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * 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 @@ -21,8 +41,7 @@ #include "minecraft/mod/ResourcePack.h" #include "minecraft/mod/TexturePack.h" -namespace Ui -{ +namespace Ui { class InfoFrame; } @@ -33,7 +52,7 @@ class InfoFrame : public QFrame { InfoFrame(QWidget* parent = nullptr); ~InfoFrame() override; - void setName(QString text = {}); + void setName(QString text = {}, QString toolTip = {}); void setDescription(QString text = {}); void setImage(QPixmap img = {}); -- cgit From d9b24f770561e3bb139955854ac7f3ca4d92a122 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:52:57 +1200 Subject: Screenshots: remove path from watcher if it no longer exists Signed-off-by: James Beddek --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index ca368d3b..8f134efd 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -145,7 +145,6 @@ public: m_thumbnailCache = std::make_shared(); m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); - // FIXME: the watched file set is not updated when files are removed } virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); } virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const @@ -214,10 +213,12 @@ private slots: void fileChanged(QString filepath) { m_thumbnailCache->setStale(filepath); - thumbnailImage(filepath); // reinsert the path... watcher.removePath(filepath); - watcher.addPath(filepath); + if (QFile::exists(filepath)) { + watcher.addPath(filepath); + thumbnailImage(filepath); + } } private: -- cgit From f2471f0f68e436d25d27ccc750e6668c07a29070 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:54:15 +1200 Subject: Screenshots: clear the thumbnailing pool on page delete Removes pending QThreadPool jobs which linger after page delete. May help with #1201 by allowing the pool to finish earlier. Signed-off-by: James Beddek --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 8f134efd..9d1f8421 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -146,7 +146,11 @@ public: m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); } - virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); } + virtual ~FilterModel() { + m_thumbnailingPool.clear(); + if (!m_thumbnailingPool.waitForDone(500)) + qDebug() << "Thumbnail pool took longer than 500ms to finish"; + } virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const { auto model = sourceModel(); -- cgit From 75bd626f33a5182facff2ef1f9938f60553c3352 Mon Sep 17 00:00:00 2001 From: James Beddek Date: Tue, 20 Jun 2023 16:59:59 +1200 Subject: Screenshots: do not retry image thumbnailing on null result This causes the thumbnailing thread pool to spend a lot of time attempting to retry an image that failed. A null result is common where the image is too large to be allocated (>128MiB alloc). The repeated retries continue after page delete, causing hangs if a user tries to exit the application. Fixes: #1201 Signed-off-by: James Beddek --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 51 +++++++++++--------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 9d1f8421..75bb48b2 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -96,37 +96,30 @@ public: return; if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0)) return; - int tries = 5; - while (tries) - { - if (!m_cache->stale(m_path)) - return; - QImage image(m_path); - if (image.isNull()) - { - QThread::msleep(500); - tries--; - continue; - } - QImage small; - if (image.width() > image.height()) - small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); - else - small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); - QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); - QImage square(QSize(256, 256), QImage::Format_ARGB32); - square.fill(Qt::transparent); - - QPainter painter(&square); - painter.drawImage(offset, small); - painter.end(); - - QIcon icon(QPixmap::fromImage(square)); - m_cache->add(m_path, icon); - m_resultEmitter.emitResultsReady(m_path); + if (!m_cache->stale(m_path)) + return; + QImage image(m_path); + if (image.isNull()) { + m_resultEmitter.emitResultsFailed(m_path); + qDebug() << "Error loading screenshot: " + m_path + ". Perhaps too large?"; return; } - m_resultEmitter.emitResultsFailed(m_path); + QImage small; + if (image.width() > image.height()) + small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); + else + small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); + QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); + QImage square(QSize(256, 256), QImage::Format_ARGB32); + square.fill(Qt::transparent); + + QPainter painter(&square); + painter.drawImage(offset, small); + painter.end(); + + QIcon icon(QPixmap::fromImage(square)); + m_cache->add(m_path, icon); + m_resultEmitter.emitResultsReady(m_path); } QString m_path; SharedIconCachePtr m_cache; -- cgit From 480faca5598b503eb130566061f06348e4a42b8f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 21:17:17 +0300 Subject: Removed unused variable Signed-off-by: Trial97 --- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 15 --------------- launcher/ui/pages/instance/ExternalResourcesPage.h | 2 -- launcher/ui/pages/instance/ModFolderPage.cpp | 4 +--- launcher/ui/pages/instance/ResourcePackPage.cpp | 2 -- launcher/ui/pages/instance/ShaderPackPage.cpp | 3 --- launcher/ui/pages/instance/TexturePackPage.cpp | 2 -- 6 files changed, 1 insertion(+), 27 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index e50fa635..e77e4572 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -135,9 +135,6 @@ void ExternalResourcesPage::retranslate() void ExternalResourcesPage::itemActivated(const QModelIndex&) { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::TOGGLE); } @@ -182,9 +179,6 @@ bool ExternalResourcesPage::eventFilter(QObject* obj, QEvent* ev) void ExternalResourcesPage::addItem() { - if (!m_controlsEnabled) - return; - auto list = GuiUtil::BrowseForFiles( helpPage(), tr("Select %1", "Select whatever type of files the page contains. Example: 'Loader Mods'").arg(displayName()), m_fileSelectionFilter.arg(displayName()), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); @@ -198,9 +192,6 @@ void ExternalResourcesPage::addItem() void ExternalResourcesPage::removeItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); int count = 0; @@ -249,18 +240,12 @@ void ExternalResourcesPage::removeItems(const QItemSelection& selection) void ExternalResourcesPage::enableItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::ENABLE); } void ExternalResourcesPage::disableItem() { - if (!m_controlsEnabled) - return; - auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::DISABLE); } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index fd200193..acea81b5 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -72,7 +72,5 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { QString m_fileSelectionFilter; QString m_viewFilter; - bool m_controlsEnabled = true; - std::shared_ptr m_wide_bar_setting = nullptr; }; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 90e7d0d6..ef7b1f2b 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -133,15 +133,13 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI return true; } -void ModFolderPage::removeItems(const QItemSelection &selection) +void ModFolderPage::removeItems(const QItemSelection& selection) { m_model->deleteMods(selection.indexes()); } void ModFolderPage::installMods() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/ResourcePackPage.cpp b/launcher/ui/pages/instance/ResourcePackPage.cpp index 24bfb38d..12b371df 100644 --- a/launcher/ui/pages/instance/ResourcePackPage.cpp +++ b/launcher/ui/pages/instance/ResourcePackPage.cpp @@ -67,8 +67,6 @@ bool ResourcePackPage::onSelectionChanged(const QModelIndex& current, const QMod void ResourcePackPage::downloadRPs() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/ShaderPackPage.cpp b/launcher/ui/pages/instance/ShaderPackPage.cpp index 2d0c10aa..dc8b0a05 100644 --- a/launcher/ui/pages/instance/ShaderPackPage.cpp +++ b/launcher/ui/pages/instance/ShaderPackPage.cpp @@ -46,7 +46,6 @@ #include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ResourceDownloadDialog.h" - ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptr model, QWidget* parent) : ExternalResourcesPage(instance, model, parent) { @@ -61,8 +60,6 @@ ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptrtypeName() != "Minecraft") return; // this is a null instance or a legacy instance diff --git a/launcher/ui/pages/instance/TexturePackPage.cpp b/launcher/ui/pages/instance/TexturePackPage.cpp index 427aba11..e477ceda 100644 --- a/launcher/ui/pages/instance/TexturePackPage.cpp +++ b/launcher/ui/pages/instance/TexturePackPage.cpp @@ -69,8 +69,6 @@ bool TexturePackPage::onSelectionChanged(const QModelIndex& current, const QMode void TexturePackPage::downloadTPs() { - if (!m_controlsEnabled) - return; if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance -- cgit From 0d2105dec44bb1b5234e18ce6a8de5b2d26eb93a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 21:34:40 +0300 Subject: Made buttons on ModsFolderPage enabled all the time Signed-off-by: Trial97 --- launcher/minecraft/MinecraftInstance.cpp | 15 ++---- launcher/minecraft/mod/ModFolderModel.cpp | 11 ++-- launcher/minecraft/mod/ResourceFolderModel.cpp | 69 +++++++++----------------- launcher/minecraft/mod/ResourceFolderModel.h | 14 +++--- launcher/ui/pages/instance/ModFolderPage.cpp | 20 +------- launcher/ui/pages/instance/ModFolderPage.h | 3 +- 6 files changed, 39 insertions(+), 93 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index f8ed5214..e896799a 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1112,36 +1112,27 @@ JavaVersion MinecraftInstance::getJavaVersion() std::shared_ptr MinecraftInstance::loaderModList() { - if (!m_loader_mod_list) - { + if (!m_loader_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_loader_mod_list.reset(new ModFolderModel(modsRoot(), this, is_indexed)); - m_loader_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_loader_mod_list.get(), &ModFolderModel::disableInteraction); } return m_loader_mod_list; } std::shared_ptr MinecraftInstance::coreModList() { - if (!m_core_mod_list) - { + if (!m_core_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_core_mod_list.reset(new ModFolderModel(coreModsDir(), this, is_indexed)); - m_core_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_core_mod_list.get(), &ModFolderModel::disableInteraction); } return m_core_mod_list; } std::shared_ptr MinecraftInstance::nilModList() { - if (!m_nil_mod_list) - { + if (!m_nil_mod_list) { bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); m_nil_mod_list.reset(new ModFolderModel(nilModsDir(), this, is_indexed, false)); - m_nil_mod_list->disableInteraction(isRunning()); - connect(this, &BaseInstance::runningStatusChanged, m_nil_mod_list.get(), &ModFolderModel::disableInteraction); } return m_nil_mod_list; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 5e3b31e0..0089cd8b 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -213,16 +213,11 @@ bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadat bool ModFolderModel::deleteMods(const QModelIndexList& indexes) { - if(!m_can_interact) { - return false; - } - - if(indexes.isEmpty()) + if (indexes.isEmpty()) return true; - for (auto i: indexes) - { - if(i.column() != 0) { + for (auto i : indexes) { + if (i.column() != 0) { continue; } auto m = at(i.row()); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index d2d875e4..c38e97d9 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -74,10 +74,6 @@ bool ResourceFolderModel::stopWatching(const QStringList paths) bool ResourceFolderModel::installResource(QString original_path) { - if (!m_can_interact) { - return false; - } - // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName original_path = FS::NormalizePath(original_path); QFileInfo file_info(original_path); @@ -168,9 +164,6 @@ bool ResourceFolderModel::uninstallResource(QString file_name) bool ResourceFolderModel::deleteResources(const QModelIndexList& indexes) { - if (!m_can_interact) - return false; - if (indexes.isEmpty()) return true; @@ -189,11 +182,8 @@ bool ResourceFolderModel::deleteResources(const QModelIndexList& indexes) return true; } -bool ResourceFolderModel::setResourceEnabled(const QModelIndexList &indexes, EnableAction action) +bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAction action) { - if (!m_can_interact) - return false; - if (indexes.isEmpty()) return true; @@ -246,15 +236,18 @@ bool ResourceFolderModel::update() connect(m_current_update_task.get(), &Task::succeeded, this, &ResourceFolderModel::onUpdateSucceeded, Qt::ConnectionType::QueuedConnection); connect(m_current_update_task.get(), &Task::failed, this, &ResourceFolderModel::onUpdateFailed, Qt::ConnectionType::QueuedConnection); - connect(m_current_update_task.get(), &Task::finished, this, [=] { - m_current_update_task.reset(); - if (m_scheduled_update) { - m_scheduled_update = false; - update(); - } else { - emit updateFinished(); - } - }, Qt::ConnectionType::QueuedConnection); + connect( + m_current_update_task.get(), &Task::finished, this, + [=] { + m_current_update_task.reset(); + if (m_scheduled_update) { + m_scheduled_update = false; + update(); + } else { + emit updateFinished(); + } + }, + Qt::ConnectionType::QueuedConnection); QThreadPool::globalInstance()->start(m_current_update_task.get()); @@ -344,15 +337,9 @@ Qt::DropActions ResourceFolderModel::supportedDropActions() const Qt::ItemFlags ResourceFolderModel::flags(const QModelIndex& index) const { Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); - auto flags = defaultFlags; - if (!m_can_interact) { - flags &= ~Qt::ItemIsDropEnabled; - } else { - flags |= Qt::ItemIsDropEnabled; - if (index.isValid()) { - flags |= Qt::ItemIsUserCheckable; - } - } + auto flags = defaultFlags | Qt::ItemIsDropEnabled; + if (index.isValid()) + flags |= Qt::ItemIsUserCheckable; return flags; } @@ -425,16 +412,17 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const if (column == NAME_COLUMN) { if (at(row).isSymLinkUnder(instDirPath())) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." - "\nCanonical Path: %1") - .arg(at(row).fileinfo().canonicalFilePath());; + tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original." + "\nCanonical Path: %1") + .arg(at(row).fileinfo().canonicalFilePath()); + ; } if (at(row).isMoreThanOneHardLink()) { return m_resources[row]->internal_id() + - tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); + tr("\nWarning: This resource is hard linked elsewhere. Editing it will also change the original."); } } - + return m_resources[row]->internal_id(); case Qt::DecorationRole: { if (column == NAME_COLUMN && (at(row).isSymLinkUnder(instDirPath()) || at(row).isMoreThanOneHardLink())) @@ -511,16 +499,6 @@ SortType ResourceFolderModel::columnToSortKey(size_t column) const return m_column_sort_keys.at(column); } -void ResourceFolderModel::enableInteraction(bool enabled) -{ - if (m_can_interact == enabled) - return; - - m_can_interact = enabled; - if (size()) - emit dataChanged(index(0), index(size() - 1)); -} - /* Standard Proxy Model for createFilterProxyModel */ [[nodiscard]] bool ResourceFolderModel::ProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { @@ -556,6 +534,7 @@ void ResourceFolderModel::enableInteraction(bool enabled) return (compare_result.first > 0); } -QString ResourceFolderModel::instDirPath() const { +QString ResourceFolderModel::instDirPath() const +{ return QFileInfo(m_instance->instanceRoot()).absoluteFilePath(); } diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 0a35e1bc..d5ca08e8 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -11,8 +11,8 @@ #include "BaseInstance.h" -#include "tasks/Task.h" #include "tasks/ConcurrentTask.h" +#include "tasks/Task.h" class QSortFilterProxyModel; @@ -129,10 +129,6 @@ class ResourceFolderModel : public QAbstractListModel { QString instDirPath() const; - public slots: - void enableInteraction(bool enabled); - void disableInteraction(bool disabled) { enableInteraction(!disabled); } - signals: void updateFinished(); @@ -181,15 +177,17 @@ class ResourceFolderModel : public QAbstractListModel { * if the resource is complex and has more stuff to parse. */ virtual void onParseSucceeded(int ticket, QString resource_id); - virtual void onParseFailed(int ticket, QString resource_id) { Q_UNUSED(ticket); Q_UNUSED(resource_id); } + virtual void onParseFailed(int ticket, QString resource_id) + { + Q_UNUSED(ticket); + Q_UNUSED(resource_id); + } protected: // Represents the relationship between a column's index (represented by the list index), and it's sorting key. // As such, the order in with they appear is very important! QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; - bool m_can_interact = true; - QDir m_dir; BaseInstance* m_instance; QFileSystemWatcher m_watcher; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index ef7b1f2b..9812bbe9 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -86,9 +86,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); - auto check_allow_update = [this] { - return (!m_instance || !m_instance->isRunning()) && (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); - }; + auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); }; connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); @@ -101,22 +99,9 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - - connect(m_instance, &BaseInstance::runningStatusChanged, this, &ModFolderPage::runningStateChanged); - ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning()); } } -void ModFolderPage::runningStateChanged(bool running) -{ - ui->actionDownloadItem->setEnabled(!running); - ui->actionUpdateItem->setEnabled(!running); - ui->actionAddItem->setEnabled(!running); - ui->actionEnableItem->setEnabled(!running); - ui->actionDisableItem->setEnabled(!running); - ui->actionRemoveItem->setEnabled(!running); -} - bool ModFolderPage::shouldDisplay() const { return true; @@ -205,8 +190,7 @@ void ModFolderPage::updateMods() message = tr("All selected mods are up-to-date! :)"); } } - CustomMessageBox::selectable(this, tr("Update checker"), message) - ->exec(); + CustomMessageBox::selectable(this, tr("Update checker"), message)->exec(); return; } diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 2fc7b574..b5984195 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -59,8 +59,7 @@ class ModFolderPage : public ExternalResourcesPage { bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override; private slots: - void runningStateChanged(bool running); - void removeItems(const QItemSelection &selection) override; + void removeItems(const QItemSelection& selection) override; void installMods(); void updateMods(); -- cgit From 820892d7cc7864315bd73dcd877cb0a1beb2b106 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 21 Jun 2023 22:42:08 +0300 Subject: Made settings editable when instance is running Signed-off-by: Trial97 --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 13 ++----------- launcher/ui/pages/instance/InstanceSettingsPage.h | 3 +-- 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 08977841..1108d264 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -60,17 +60,13 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) m_settings = inst->settings(); ui->setupUi(this); - // As the signal will (probably) not be triggered once we click edit, let's update it manually instead. - updateRunningStatus(m_instance->isRunning()); - - connect(m_instance, &BaseInstance::runningStatusChanged, this, &InstanceSettingsPage::updateRunningStatus); connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); - connect(ui->instanceAccountSelector, QOverload::of(&QComboBox::currentIndexChanged), this, &InstanceSettingsPage::changeInstanceAccount); + connect(ui->instanceAccountSelector, QOverload::of(&QComboBox::currentIndexChanged), this, + &InstanceSettingsPage::changeInstanceAccount); loadSettings(); - updateThresholds(); } @@ -523,8 +519,3 @@ void InstanceSettingsPage::updateThresholds() ui->labelMaxMemIcon->setPixmap(pix); } } - -void InstanceSettingsPage::updateRunningStatus(bool running) -{ - setEnabled(!running); -} diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index 0438fe3b..036b4181 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -79,8 +79,7 @@ public: void updateThresholds(); -private slots: - void updateRunningStatus(bool running); + private slots: void on_javaDetectBtn_clicked(); void on_javaTestBtn_clicked(); void on_javaBrowseBtn_clicked(); -- cgit From f7d502c68c530d66b385d530c838a9a6566828d0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:05:47 +0300 Subject: Added ExportModsToStringDialog Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 3 + launcher/ui/MainWindow.cpp | 10 ++ launcher/ui/MainWindow.h | 1 + launcher/ui/MainWindow.ui | 8 ++ launcher/ui/dialogs/ExportModsToStringDialog.cpp | 119 ++++++++++++++++ launcher/ui/dialogs/ExportModsToStringDialog.h | 45 ++++++ launcher/ui/dialogs/ExportModsToStringDialog.ui | 171 +++++++++++++++++++++++ 7 files changed, 357 insertions(+) create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.cpp create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.h create mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.ui (limited to 'launcher/ui') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c7efdad8..5ef97f42 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -911,6 +911,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/ExportInstanceDialog.h ui/dialogs/ExportMrPackDialog.cpp ui/dialogs/ExportMrPackDialog.h + ui/dialogs/ExportModsToStringDialog.cpp + ui/dialogs/ExportModsToStringDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1058,6 +1060,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportMrPackDialog.ui + ui/dialogs/ExportModsToStringDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011ca..02ea30c3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,6 +43,7 @@ #include "FileSystem.h" #include "MainWindow.h" +#include "ui/dialogs/ExportModsToStringDialog.h" #include "ui_MainWindow.h" #include @@ -205,6 +206,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); + exportInstanceMenu->addAction(ui->actionExportInstanceToString); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1416,6 +1418,14 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } +void MainWindow::on_actionExportInstanceToString_triggered() +{ + if (m_selectedInstance) { + ExportModsToStringDialog dlg(m_selectedInstance, this); + dlg.exec(); + } +} + void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3bb20c4a..9b38810f 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,6 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); + void on_actionExportInstanceToString_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f67fb185..e6e52a91 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,6 +479,14 @@ Modrinth (mrpack) + + + + + + Text + + diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp new file mode 100644 index 00000000..d08a4c70 --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#include "ExportModsToStringDialog.h" +#include +#include +#include +#include "minecraft/MinecraftInstance.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportModsToStringTask.h" +#include "ui_ExportModsToStringDialog.h" + +#include +#include +#include +#include +#include + +ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget* parent) + : QDialog(parent), m_template_selected(false), ui(new Ui::ExportModsToStringDialog) +{ + ui->setupUi(this); + ui->templateGroup->setDisabled(true); + + MinecraftInstance* mcInstance = dynamic_cast(instance.get()); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { + m_allMods = mcInstance->loaderModList()->allMods(); + trigger(); + }); + } + + connect(ui->formatComboBox, &QComboBox::currentIndexChanged, this, &ExportModsToStringDialog::formatChanged); + connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::trigger); + connect(ui->copyButton, &QPushButton::clicked, this, [this]() { + this->ui->finalText->selectAll(); + this->ui->finalText->copy(); + }); +} + +ExportModsToStringDialog::~ExportModsToStringDialog() +{ + delete ui; +} + +void ExportModsToStringDialog::formatChanged(int index) +{ + switch (index) { + case 0: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + break; + } + case 1: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + break; + } + case 2: { + ui->templateGroup->setDisabled(false); + ui->optionsGroup->setDisabled(true); + break; + } + } + trigger(); +} + +void ExportModsToStringDialog::trigger() +{ + ExportToString::Formats format; + switch (ui->formatComboBox->currentIndex()) { + case 2: { + m_template_selected = true; + ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, ui->templateText->toPlainText())); + return; + } + case 0: { + format = ExportToString::HTML; + break; + } + case 1: { + format = ExportToString::MARKDOWN; + break; + } + } + auto opt = 0; + if (ui->authorsCheckBox->isChecked()) + opt |= ExportToString::Authors; + if (ui->versionCheckBox->isChecked()) + opt |= ExportToString::Version; + if (ui->urlCheckBox->isChecked()) + opt |= ExportToString::Url; + ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, format, static_cast(opt))); + if (!m_template_selected) { + auto exampleLine = format == ExportToString::HTML ? "
    {name}[{version}] by {authors}
" + : "[{name}]({url})[{version}] by {authors}"; + if (ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); + } +} diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportModsToStringDialog.h new file mode 100644 index 00000000..7fada4d5 --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#pragma once + +#include +#include +#include "BaseInstance.h" +#include "minecraft/mod/Mod.h" + +namespace Ui { +class ExportModsToStringDialog; +} + +class ExportModsToStringDialog : public QDialog { + Q_OBJECT + + public: + explicit ExportModsToStringDialog(InstancePtr instance, QWidget* parent = nullptr); + ~ExportModsToStringDialog(); + + protected slots: + void formatChanged(int index); + void trigger(); + + private: + QList m_allMods; + bool m_template_selected; + Ui::ExportModsToStringDialog* ui; +}; diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.ui b/launcher/ui/dialogs/ExportModsToStringDialog.ui new file mode 100644 index 00000000..4451a278 --- /dev/null +++ b/launcher/ui/dialogs/ExportModsToStringDialog.ui @@ -0,0 +1,171 @@ + + + ExportModsToStringDialog + + + + 0 + 0 + 650 + 446 + + + + Export Modrinth Pack + + + true + + + + + + + + Settings + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + Format + + + + + + + + HTML + + + + + Markdown + + + + + Custom + + + + + + + + Template + + + + + + + + + + + + Optional Info + + + + + + Version + + + + + + + Authors + + + + + + + URL + + + + + + + + + + + + + Result + + + + + + + 0 + 143 + + + + true + + + + + + + + + + + + + + Copy + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ExportModsToStringDialog + accept() + + + 334 + 435 + + + 324 + 206 + + + + + -- cgit From b84dc8551a13ed87d09e6f8ca8b401c57d549f95 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 16:49:19 +0300 Subject: Fixed trigger function Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportModsToStringDialog.cpp | 12 ++++++------ launcher/ui/dialogs/ExportModsToStringDialog.h | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp index d08a4c70..ae793dcb 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -42,16 +42,16 @@ ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget mcInstance->loaderModList()->update(); connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { m_allMods = mcInstance->loaderModList()->allMods(); - trigger(); + triggerImp(); }); } - connect(ui->formatComboBox, &QComboBox::currentIndexChanged, this, &ExportModsToStringDialog::formatChanged); + connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportModsToStringDialog::formatChanged); connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->copyButton, &QPushButton::clicked, this, [this]() { + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::triggerImp); + connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { this->ui->finalText->selectAll(); this->ui->finalText->copy(); }); @@ -81,10 +81,10 @@ void ExportModsToStringDialog::formatChanged(int index) break; } } - trigger(); + triggerImp(); } -void ExportModsToStringDialog::trigger() +void ExportModsToStringDialog::triggerImp() { ExportToString::Formats format; switch (ui->formatComboBox->currentIndex()) { diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportModsToStringDialog.h index 7fada4d5..d195d1ce 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.h +++ b/launcher/ui/dialogs/ExportModsToStringDialog.h @@ -36,7 +36,8 @@ class ExportModsToStringDialog : public QDialog { protected slots: void formatChanged(int index); - void trigger(); + void triggerImp(); + void trigger(int) { triggerImp(); }; private: QList m_allMods; -- cgit From 836e8d2e28b4ab63e6c4189410c38ad1a7fd2718 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 17:39:57 +0300 Subject: Fixed code quality Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportModsToStringDialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp index ae793dcb..29d69918 100644 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ b/launcher/ui/dialogs/ExportModsToStringDialog.cpp @@ -86,7 +86,7 @@ void ExportModsToStringDialog::formatChanged(int index) void ExportModsToStringDialog::triggerImp() { - ExportToString::Formats format; + auto format = ExportToString::HTML; switch (ui->formatComboBox->currentIndex()) { case 2: { m_template_selected = true; @@ -101,6 +101,9 @@ void ExportModsToStringDialog::triggerImp() format = ExportToString::MARKDOWN; break; } + default: { + return; + } } auto opt = 0; if (ui->authorsCheckBox->isChecked()) -- cgit From 58321f34915bd22ab8a2c195b64af3006d962be9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 20:03:44 +0300 Subject: Added curseforge export Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 2 + launcher/modplatform/flame/FlamePackExportTask.cpp | 223 +++++++++++++++++++++ launcher/modplatform/flame/FlamePackExportTask.h | 74 +++++++ launcher/ui/MainWindow.cpp | 9 + launcher/ui/MainWindow.h | 1 + launcher/ui/MainWindow.ui | 8 + launcher/ui/dialogs/ExportMrPackDialog.cpp | 30 ++- launcher/ui/dialogs/ExportMrPackDialog.h | 6 +- 8 files changed, 342 insertions(+), 11 deletions(-) create mode 100644 launcher/modplatform/flame/FlamePackExportTask.cpp create mode 100644 launcher/modplatform/flame/FlamePackExportTask.h (limited to 'launcher/ui') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c7efdad8..df6c9012 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -517,6 +517,8 @@ set(FLAME_SOURCES modplatform/flame/FlameCheckUpdate.h modplatform/flame/FlameInstanceCreationTask.h modplatform/flame/FlameInstanceCreationTask.cpp + modplatform/flame/FlamePackExportTask.h + modplatform/flame/FlamePackExportTask.cpp ) set(MODRINTH_SOURCES diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp new file mode 100644 index 00000000..1ae13f72 --- /dev/null +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#include "FlamePackExportTask.h" +#include +#include + +#include +#include +#include +#include +#include "Json.h" +#include "MMCZip.h" +#include "minecraft/PackProfile.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportModsToStringTask.h" + +const QStringList FlamePackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); +const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); +const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; + +FlamePackExportTask::FlamePackExportTask(const QString& name, + const QString& version, + const QVariant& projectID, + InstancePtr instance, + const QString& output, + MMCZip::FilterFunction filter) + : name(name) + , version(version) + , projectID(projectID) + , instance(instance) + , mcInstance(dynamic_cast(instance.get())) + , gameRoot(instance->gameRoot()) + , output(output) + , filter(filter) +{} + +void FlamePackExportTask::executeTask() +{ + setStatus(tr("Searching for files...")); + setProgress(0, 0); + collectFiles(); +} + +bool FlamePackExportTask::abort() +{ + if (task != nullptr) { + task->abort(); + task = nullptr; + emitAborted(); + return true; + } + + if (buildZipFuture.isRunning()) { + buildZipFuture.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur + // immediately. + return true; + } + + return false; +} + +void FlamePackExportTask::collectFiles() +{ + setAbortable(false); + QCoreApplication::processEvents(); + + files.clear(); + if (!MMCZip::collectFileListRecursively(instance->gameRoot(), nullptr, &files, filter)) { + emitFailed(tr("Could not search for files")); + return; + } + + resolvedFiles.clear(); + + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { + mods = mcInstance->loaderModList()->allMods(); + buildZip(); + }); +} + +void FlamePackExportTask::buildZip() +{ + setStatus(tr("Adding files...")); + + buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { + QuaZip zip(output); + if (!zip.open(QuaZip::mdCreate)) { + QFile::remove(output); + return BuildZipResult(tr("Could not create file")); + } + + if (buildZipFuture.isCanceled()) + return BuildZipResult(); + + QuaZipFile indexFile(&zip); + if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("manifest.json"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + indexFile.write(generateIndex()); + + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + QString content = ExportToString::ExportModsToStringTask(mods, TEMPLATE); + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); + + size_t progress = 0; + for (const QFileInfo& file : files) { + if (buildZipFuture.isCanceled()) { + QFile::remove(output); + return BuildZipResult(); + } + + setProgress(progress, files.length()); + const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); + if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { + QFile::remove(output); + return BuildZipResult(tr("Could not read and compress %1").arg(relative)); + } + progress++; + } + + zip.close(); + + if (zip.getZipError() != 0) { + QFile::remove(output); + return BuildZipResult(tr("A zip error occurred")); + } + + return BuildZipResult(); + }); + connect(&buildZipWatcher, &QFutureWatcher::finished, this, &FlamePackExportTask::finish); + buildZipWatcher.setFuture(buildZipFuture); +} + +void FlamePackExportTask::finish() +{ + if (buildZipFuture.isCanceled()) + emitAborted(); + else { + const BuildZipResult result = buildZipFuture.result(); + if (result.has_value()) + emitFailed(result.value()); + else + emitSucceeded(); + } +} + +QByteArray FlamePackExportTask::generateIndex() +{ + QJsonObject obj; + obj["manifestType"] = "minecraftModpack"; + obj["manifestVersion"] = 1; + obj["name"] = name; + obj["version"] = version; + obj["author"] = author; + obj["projectID"] = projectID.toInt(); + obj["overrides"] = "overrides"; + if (mcInstance) { + QJsonObject version; + auto profile = mcInstance->getPackProfile(); + // collect all supported components + const ComponentPtr minecraft = profile->getComponent("net.minecraft"); + const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader"); + const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader"); + const ComponentPtr forge = profile->getComponent("net.minecraftforge"); + + // convert all available components to mrpack dependencies + if (minecraft != nullptr) + version["version"] = minecraft->m_version; + + QJsonObject loader; + if (quilt != nullptr) + loader["id"] = quilt->getName(); + else if (fabric != nullptr) + loader["id"] = fabric->getName(); + else if (forge != nullptr) + loader["id"] = forge->getName(); + loader["primary"] = true; + + version["modLoaders"] = QJsonArray({ loader }); + obj["minecraft"] = version; + } + + QJsonArray files; + QMapIterator iterator(resolvedFiles); + while (iterator.hasNext()) { + iterator.next(); + + const ResolvedFile& value = iterator.value(); + + QJsonObject file; + file["projectID"] = value.projectID.toInt(); + file["fileID"] = value.fileID.toInt(); + file["required"] = value.required; + files << file; + } + obj["files"] = files; + + return QJsonDocument(obj).toJson(QJsonDocument::Compact); +} diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h new file mode 100644 index 00000000..83927099 --- /dev/null +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#pragma once + +#include +#include +#include "BaseInstance.h" +#include "MMCZip.h" +#include "minecraft/MinecraftInstance.h" +#include "tasks/Task.h" + +class FlamePackExportTask : public Task { + public: + FlamePackExportTask(const QString& name, + const QString& version, + const QVariant& projectID, + InstancePtr instance, + const QString& output, + MMCZip::FilterFunction filter); + + protected: + void executeTask() override; + bool abort() override; + + private: + struct ResolvedFile { + QVariant projectID, fileID; + bool required; + }; + + static const QStringList PREFIXES; + static const QStringList FILE_EXTENSIONS; + static const QString TEMPLATE; + + // inputs + const QString name, version, author; + const QVariant projectID; + const InstancePtr instance; + MinecraftInstance* mcInstance; + const QDir gameRoot; + const QString output; + const MMCZip::FilterFunction filter; + + typedef std::optional BuildZipResult; + + QFileInfoList files; + QMap resolvedFiles; + Task::Ptr task; + QFuture buildZipFuture; + QFutureWatcher buildZipWatcher; + QList mods; + + void collectFiles(); + void buildZip(); + void finish(); + + QByteArray generateIndex(); +}; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011ca..0027d180 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -205,6 +205,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); + exportInstanceMenu->addAction(ui->actionExportInstanceFlamePack); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1416,6 +1417,14 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } +void MainWindow::on_actionExportInstanceFlamePack_triggered() +{ + if (m_selectedInstance) { + ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + dlg.exec(); + } +} + void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3bb20c4a..5f74b501 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,6 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); + void on_actionExportInstanceFlamePack_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index f67fb185..f7e93f48 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,6 +479,14 @@ Modrinth (mrpack)
    + + + + + + Curseforge (zip) + + diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 561b92e4..16ef526a 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -18,6 +18,8 @@ #include "ExportMrPackDialog.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlamePackExportTask.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" #include "ui_ExportMrPackDialog.h" @@ -32,12 +34,15 @@ #include "MMCZip.h" #include "modplatform/modrinth/ModrinthPackExportTask.h" -ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog) +ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) + : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog), m_provider(provider) { ui->setupUi(this); ui->name->setText(instance->name()); - ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + else + ui->summaryLabel->setText("ProjectID"); // ensure a valid pack is generated // the name and version fields mustn't be empty @@ -97,20 +102,25 @@ void ExportMrPackDialog::done(int result) if (output.isEmpty()) return; - - ModrinthPackExportTask task(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); - - connect(&task, &Task::failed, + Task* task; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + else + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + + connect(task, &Task::failed, [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(&task, &Task::aborted, [this] { + connect(task, &Task::aborted, [this] { CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) ->show(); }); + connect(task, &Task::finished, [task] { task->deleteLater(); }); ProgressDialog progress(this); progress.setSkipButton(true, tr("Abort")); - if (progress.execWithTask(&task) != QDialog::Accepted) + if (progress.execWithTask(task) != QDialog::Accepted) return; } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.h b/launcher/ui/dialogs/ExportMrPackDialog.h index 1c70c4ae..858a31bf 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.h +++ b/launcher/ui/dialogs/ExportMrPackDialog.h @@ -22,6 +22,7 @@ #include "BaseInstance.h" #include "FastFileIconProvider.h" #include "FileIgnoreProxy.h" +#include "modplatform/ModIndex.h" namespace Ui { class ExportMrPackDialog; @@ -31,7 +32,9 @@ class ExportMrPackDialog : public QDialog { Q_OBJECT public: - explicit ExportMrPackDialog(InstancePtr instance, QWidget* parent = nullptr); + explicit ExportMrPackDialog(InstancePtr instance, + QWidget* parent = nullptr, + ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); ~ExportMrPackDialog(); void done(int result) override; @@ -42,4 +45,5 @@ class ExportMrPackDialog : public QDialog { Ui::ExportMrPackDialog* ui; FileIgnoreProxy* proxy; FastFileIconProvider icons; + const ModPlatform::ResourceProvider m_provider; }; -- cgit From 049b02cee46358a3d1dd13769e2c6f4ba27bc55e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 22 Jun 2023 21:06:01 +0300 Subject: finished up the curesforge export Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 28 +++++++++++----------- launcher/modplatform/flame/FlamePackExportTask.h | 10 ++------ launcher/ui/dialogs/ExportMrPackDialog.cpp | 20 +++++++++++----- launcher/ui/dialogs/ExportMrPackDialog.ui | 14 +++++++++-- 4 files changed, 42 insertions(+), 30 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 1ae13f72..4ac2c8ab 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -28,20 +28,21 @@ #include "MMCZip.h" #include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" #include "modplatform/helpers/ExportModsToStringTask.h" -const QStringList FlamePackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); -const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "zip" }); const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, + const QString& author, const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) : name(name) , version(version) + , author(author) , projectID(projectID) , instance(instance) , mcInstance(dynamic_cast(instance.get())) @@ -193,28 +194,27 @@ QByteArray FlamePackExportTask::generateIndex() QJsonObject loader; if (quilt != nullptr) - loader["id"] = quilt->getName(); + loader["id"] = "quilt-" + quilt->getVersion(); else if (fabric != nullptr) - loader["id"] = fabric->getName(); + loader["id"] = "fabric-" + fabric->getVersion(); else if (forge != nullptr) - loader["id"] = forge->getName(); + loader["id"] = "forge-" + forge->getVersion(); loader["primary"] = true; - version["modLoaders"] = QJsonArray({ loader }); obj["minecraft"] = version; } QJsonArray files; - QMapIterator iterator(resolvedFiles); - while (iterator.hasNext()) { - iterator.next(); - - const ResolvedFile& value = iterator.value(); + for (auto mod : mods) { + auto meta = mod->metadata(); + if (meta == nullptr || meta->provider != ModPlatform::ResourceProvider::FLAME) + continue; + resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = {}; QJsonObject file; - file["projectID"] = value.projectID.toInt(); - file["fileID"] = value.fileID.toInt(); - file["required"] = value.required; + file["projectID"] = meta->project_id.toInt(); + file["fileID"] = meta->file_id.toInt(); + file["required"] = true; files << file; } obj["files"] = files; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 83927099..c3cda926 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -29,6 +29,7 @@ class FlamePackExportTask : public Task { public: FlamePackExportTask(const QString& name, const QString& version, + const QString& author, const QVariant& projectID, InstancePtr instance, const QString& output, @@ -39,13 +40,6 @@ class FlamePackExportTask : public Task { bool abort() override; private: - struct ResolvedFile { - QVariant projectID, fileID; - bool required; - }; - - static const QStringList PREFIXES; - static const QStringList FILE_EXTENSIONS; static const QString TEMPLATE; // inputs @@ -60,7 +54,7 @@ class FlamePackExportTask : public Task { typedef std::optional BuildZipResult; QFileInfoList files; - QMap resolvedFiles; + QMap resolvedFiles; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 16ef526a..aaa528aa 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -39,10 +39,13 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo { ui->setupUi(this); ui->name->setText(instance->name()); - if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); - else + ui->author->hide(); + ui->authorLabel->hide(); + } else { ui->summaryLabel->setText("ProjectID"); + } // ensure a valid pack is generated // the name and version fields mustn't be empty @@ -96,9 +99,14 @@ void ExportMrPackDialog::done(int result) { if (result == Accepted) { const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text()); - const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".mrpack"), - "Modrinth pack (*.mrpack *.zip)", nullptr); + QString output; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".mrpack"), "Modrinth pack (*.mrpack *.zip)", + nullptr); + else + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".zip"), "Curseforge pack (*.zip)", nullptr); if (output.isEmpty()) return; @@ -107,7 +115,7 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 9a789737..59ecb17c 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -24,7 +24,7 @@
    - + Summary @@ -41,7 +41,7 @@ - + Version @@ -57,6 +57,16 @@ + + + + Author + + + + + + -- cgit From bf95cfb30eee52f23d0279284f70931b2c968dd3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 01:37:28 +0300 Subject: Added CatPacks Signed-off-by: Trial97 --- launcher/Application.cpp | 12 ++- launcher/Application.h | 9 +- launcher/CMakeLists.txt | 2 + launcher/ui/MainWindow.cpp | 4 +- launcher/ui/setupwizard/ThemeWizardPage.cpp | 2 +- launcher/ui/themes/CatPack.cpp | 109 +++++++++++++++++++++++ launcher/ui/themes/CatPack.h | 98 ++++++++++++++++++++ launcher/ui/themes/ThemeManager.cpp | 82 ++++++++++++++--- launcher/ui/themes/ThemeManager.h | 15 ++-- launcher/ui/widgets/ThemeCustomizationWidget.cpp | 17 ++-- launcher/ui/widgets/ThemeCustomizationWidget.h | 34 +++---- 11 files changed, 331 insertions(+), 53 deletions(-) create mode 100644 launcher/ui/themes/CatPack.cpp create mode 100644 launcher/ui/themes/CatPack.h (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 724e6e44..d8ac2168 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1173,7 +1173,17 @@ QIcon Application::getThemedIcon(const QString& name) return QIcon::fromTheme(name); } -bool Application::openJsonEditor(const QString &filename) +QList Application::getValidCatPacks() +{ + return m_themeManager->getValidCatPacks(); +} + +QString Application::getCatPack(QString catName) +{ + return m_themeManager->getCatPack(catName); +} + +bool Application::openJsonEditor(const QString& filename) { const QString file = QDir::current().absoluteFilePath(filename); if (m_settings->get("JsonEditor").toString().isEmpty()) diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17..55b01cd4 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -48,6 +48,7 @@ #include #include "minecraft/launch/MinecraftServerTarget.h" +#include "ui/themes/CatPack.h" class LaunchController; class LocalPeer; @@ -126,9 +127,11 @@ public: void setApplicationTheme(const QString& name); - shared_qobject_ptr updater() { - return m_updater; - } + QList getValidCatPacks(); + + QString getCatPack(QString catName = ""); + + shared_qobject_ptr updater() { return m_updater; } void triggerUpdateCheck(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ce2771a4..4d0f7d06 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -755,6 +755,8 @@ SET(LAUNCHER_SOURCES ui/themes/SystemTheme.h ui/themes/ThemeManager.cpp ui/themes/ThemeManager.h + ui/themes/CatPack.cpp + ui/themes/CatPack.h # Processes LaunchController.h diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e04011ca..8e1b5613 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -924,14 +924,14 @@ void MainWindow::setCatBackground(bool enabled) view->setStyleSheet(QString(R"( InstanceView { - background-image: url(:/backgrounds/%1); + background-image: url(%1); background-attachment: fixed; background-clip: padding; background-position: bottom right; background-repeat: none; background-color:palette(base); })") - .arg(ThemeManager::getCatImage())); + .arg(APPLICATION->getCatPack())); } else { view->setStyleSheet(QString()); } diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp index 42826aba..282a01ac 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.cpp +++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp @@ -61,7 +61,7 @@ void ThemeWizardPage::updateIcons() void ThemeWizardPage::updateCat() { qDebug() << "Setting Cat"; - ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(ThemeManager::getCatImage()))); + ui->catImagePreviewButton->setIcon(QIcon(QString(R"(%1)").arg(APPLICATION->getCatPack()))); } void ThemeWizardPage::retranslate() diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp new file mode 100644 index 00000000..e74b9709 --- /dev/null +++ b/launcher/ui/themes/CatPack.cpp @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + * + * 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 "ui/themes/CatPack.h" +#include +#include +#include +#include +#include +#include +#include +#include "FileSystem.h" +#include "Json.h" +#include "ui/themes/ThemeManager.h" + +QString BasicCatPack::path() +{ + const QDateTime now = QDateTime::currentDateTime(); + const QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); + const QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); + const QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); + + QString cat = QString(":/backgrounds/%1").arg(m_id); + if (std::abs(now.daysTo(xmas)) <= 4) { + cat += "-xmas"; + } else if (std::abs(now.daysTo(halloween)) <= 4) { + cat += "-spooky"; + } else if (std::abs(now.daysTo(birthday)) <= 12) { + cat += "-bday"; + } + return cat; +} + +JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) +{ + QString path = FS::PathCombine("catpacks", m_id); + + if (!FS::ensureFolderPathExists(path)) { + themeWarningLog() << "couldn't create folder for catpack!"; + return; + } + + if (manifestInfo.exists() && manifestInfo.isFile()) { + try { + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_id = Json::requireString(root, "id", "Catpack ID"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + date(Json::requireString(variant, "startTime", "Variant startTime")), + date(Json::requireString(variant, "endTime", "Variant endTime")) }; + } + + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json: " << e.cause(); + return; + } + } else { + themeDebugLog() << "No catpack json present."; + } +} + +QString JsonCatPack::path() +{ + const QDateTime now = QDateTime::currentDateTime(); + for (auto var : m_variants) { + QDateTime startDate(QDate(now.date().year(), var.startTime.mounth, var.startTime.day), QTime(0, 0)); + QDateTime endDate(QDate(now.date().year(), var.endTime.mounth, var.endTime.day), QTime(0, 0)); + if (startDate.daysTo(now) > 0 && now.daysTo(endDate) > 0) + return var.path; + } + return m_defaultPath; +} diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h new file mode 100644 index 00000000..d9010b8e --- /dev/null +++ b/launcher/ui/themes/CatPack.h @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + * + * 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 +#include +#include +#include + +class CatPack { + public: + virtual ~CatPack() {} + virtual QString id() = 0; + virtual QString name() = 0; + virtual QString path() = 0; +}; + +class BasicCatPack : public CatPack { + public: + BasicCatPack(QString id, QString name) : m_id(id), m_name(name) {} + BasicCatPack(QString id) : BasicCatPack(id, id) {} + virtual QString id() { return m_id; }; + virtual QString name() { return m_name; }; + virtual QString path(); + + protected: + QString m_id; + QString m_name; +}; + +class FileCatPack : public BasicCatPack { + public: + FileCatPack(QString id, QFileInfo& fileInfo) : BasicCatPack(id), m_path(fileInfo.absoluteFilePath()) {} + FileCatPack(QFileInfo& fileInfo) : FileCatPack(fileInfo.baseName(), fileInfo) {} + virtual QString path() { return m_path; } + + private: + QString m_path; +}; + +class JsonCatPack : public BasicCatPack { + public: + struct date { + date(QString d) + { + auto sp = d.split("-"); + day = sp[0].toInt(); + if (sp.length() >= 2) + mounth = sp[1].length(); + } + int mounth; + int day; + }; + struct Variant { + QString path; + date startTime; + date endTime; + }; + JsonCatPack(QFileInfo& manifestInfo); + virtual QString path(); + + private: + QString m_defaultPath; + QList m_variants; +}; diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 94ac8a24..bfd0550a 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -22,6 +22,7 @@ #include #include #include "ui/themes/BrightTheme.h" +#include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" #include "ui/themes/DarkTheme.h" #include "ui/themes/SystemTheme.h" @@ -32,6 +33,7 @@ ThemeManager::ThemeManager(MainWindow* mainWindow) { m_mainWindow = mainWindow; initializeThemes(); + initializeCatPacks(); } /// @brief Adds the Theme to the list of themes @@ -111,6 +113,16 @@ QList ThemeManager::getValidApplicationThemes() return ret; } +QList ThemeManager::getValidCatPacks() +{ + QList ret; + ret.reserve(m_catPacks.size()); + for (auto&& [id, theme] : m_catPacks) { + ret.append(theme.get()); + } + return ret; +} + void ThemeManager::setIconTheme(const QString& name) { QIcon::setThemeName(name); @@ -137,19 +149,63 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) } } -QString ThemeManager::getCatImage(QString catName) +QString ThemeManager::getCatPack(QString catName) +{ + auto catIter = m_catPacks.find(!catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString()); + if (catIter != m_catPacks.end()) { + auto& catPack = catIter->second; + themeDebugLog() << "applying catpack" << catPack->id(); + return catPack->path(); + } else { + themeWarningLog() << "Tried to get invalid catPack:" << catName; + } + + return m_catPacks.begin()->second->path(); +} + +QString ThemeManager::addCatPack(std::unique_ptr catPack) +{ + QString id = catPack->id(); + m_catPacks.emplace(id, std::move(catPack)); + return id; +} + +void ThemeManager::initializeCatPacks() { - QDateTime now = QDateTime::currentDateTime(); - QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); - QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); - QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); - QString cat = !catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString(); - if (std::abs(now.daysTo(xmas)) <= 4) { - cat += "-xmas"; - } else if (std::abs(now.daysTo(halloween)) <= 4) { - cat += "-spooky"; - } else if (std::abs(now.daysTo(birthday)) <= 12) { - cat += "-bday"; + QList> defaultCats{ { "kitteh", QObject::tr("Background Cat (from MultiMC)") }, + { "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") }, + { "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") }, + { "teawie", QObject::tr("Teawie (drawn by SympathyTea)") } }; + for (auto [id, name] : defaultCats) { + addCatPack(std::unique_ptr(new BasicCatPack(id, name))); + } + QDir catpacksDir("./catpacks/"); + QString catpacksFolder = catpacksDir.absoluteFilePath(""); + themeDebugLog() << "CatPacks Folder Path: " << catpacksFolder; + + auto loadFiles = [this](QDir dir) { + // Load image files directly + QDirIterator ImageFileIterator(dir.absoluteFilePath(""), { "*.png", "*.gif", "*.jpg", "*.apng", "*.jxl", "*.avif" }, QDir::Files); + while (ImageFileIterator.hasNext()) { + QFile customCatFile(ImageFileIterator.next()); + QFileInfo customCatFileInfo(customCatFile); + themeDebugLog() << "Loading QSS Theme from:" << customCatFileInfo.absoluteFilePath(); + addCatPack(std::unique_ptr(new FileCatPack(customCatFileInfo))); + } + }; + + loadFiles(catpacksDir); + + QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (directoryIterator.hasNext()) { + QDir dir(directoryIterator.next()); + QFileInfo manifest(dir.absoluteFilePath("catpack.json")); + if (manifest.exists()) { + // Load background manifest + themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); + addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + } else { + loadFiles(dir); + } } - return cat; } diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 87f36d9c..bc0d31cd 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -20,6 +20,7 @@ #include #include "ui/MainWindow.h" +#include "ui/themes/CatPack.h" #include "ui/themes/ITheme.h" inline auto themeDebugLog() @@ -40,18 +41,20 @@ class ThemeManager { void applyCurrentlySelectedTheme(bool initial = false); void setApplicationTheme(const QString& name, bool initial = false); - /// - /// Returns the cat based on selected cat and with events (Birthday, XMas, etc.) - /// - /// Optional, if you need a specific cat. - /// - static QString getCatImage(QString catName = ""); + /// @brief Returns the background based on selected and with events (Birthday, XMas, etc.) + /// @param catName Optional, if you need a specific background. + /// @return + QString getCatPack(QString catName = ""); + QList getValidCatPacks(); private: std::map> m_themes; + std::map> m_catPacks; MainWindow* m_mainWindow; void initializeThemes(); + void initializeCatPacks(); QString addTheme(std::unique_ptr theme); ITheme* getTheme(QString themeId); + QString addCatPack(std::unique_ptr catPack); }; diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index dcf13303..e2c5ce3d 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -95,9 +95,14 @@ void ThemeCustomizationWidget::applyWidgetTheme(int index) { emit currentWidgetThemeChanged(index); } -void ThemeCustomizationWidget::applyCatTheme(int index) { +void ThemeCustomizationWidget::applyCatTheme(int index) +{ auto settings = APPLICATION->settings(); - settings->set("BackgroundCat", m_catOptions[index].first); + auto originalCat = settings->get("BackgroundCat").toString(); + auto newCat = ui->backgroundCatComboBox->currentData().toString(); + if (originalCat != newCat) { + settings->set("BackgroundCat", newCat); + } emit currentCatChanged(index); } @@ -135,10 +140,10 @@ void ThemeCustomizationWidget::loadSettings() } auto cat = settings->get("BackgroundCat").toString(); - for (auto& catFromList : m_catOptions) { - QIcon catIcon = QIcon(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage(catFromList.first))); - ui->backgroundCatComboBox->addItem(catIcon, catFromList.second); - if (cat == catFromList.first) { + for (auto& catFromList : APPLICATION->getValidCatPacks()) { + QIcon catIcon = QIcon(QString("%1").arg(catFromList->path())); + ui->backgroundCatComboBox->addItem(catIcon, catFromList->name(), catFromList->id()); + if (cat == catFromList->id()) { ui->backgroundCatComboBox->setCurrentIndex(ui->backgroundCatComboBox->count() - 1); } } diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h index d955a266..be204e57 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/ThemeCustomizationWidget.h @@ -53,25 +53,17 @@ class ThemeCustomizationWidget : public QWidget { private: Ui::ThemeCustomizationWidget* ui; - //TODO finish implementing - QList> m_iconThemeOptions{ - { "pe_colored", QObject::tr("Simple (Colored Icons)") }, - { "pe_light", QObject::tr("Simple (Light Icons)") }, - { "pe_dark", QObject::tr("Simple (Dark Icons)") }, - { "pe_blue", QObject::tr("Simple (Blue Icons)") }, - { "breeze_light", QObject::tr("Breeze Light") }, - { "breeze_dark", QObject::tr("Breeze Dark") }, - { "OSX", QObject::tr("OSX") }, - { "iOS", QObject::tr("iOS") }, - { "flat", QObject::tr("Flat") }, - { "flat_white", QObject::tr("Flat (White)") }, - { "multimc", QObject::tr("Legacy") }, - { "custom", QObject::tr("Custom") } - }; - QList> m_catOptions{ - { "kitteh", QObject::tr("Background Cat (from MultiMC)") }, - { "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") }, - { "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") }, - { "teawie", QObject::tr("Teawie (drawn by SympathyTea)") } - }; + // TODO finish implementing + QList> m_iconThemeOptions{ { "pe_colored", QObject::tr("Simple (Colored Icons)") }, + { "pe_light", QObject::tr("Simple (Light Icons)") }, + { "pe_dark", QObject::tr("Simple (Dark Icons)") }, + { "pe_blue", QObject::tr("Simple (Blue Icons)") }, + { "breeze_light", QObject::tr("Breeze Light") }, + { "breeze_dark", QObject::tr("Breeze Dark") }, + { "OSX", QObject::tr("OSX") }, + { "iOS", QObject::tr("iOS") }, + { "flat", QObject::tr("Flat") }, + { "flat_white", QObject::tr("Flat (White)") }, + { "multimc", QObject::tr("Legacy") }, + { "custom", QObject::tr("Custom") } }; }; -- cgit From 718aca3d066fc24c03b7ac6d625d68829fcaa427 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 09:24:18 +0300 Subject: Fixed date constructor Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index d9010b8e..9f288d3d 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -79,7 +79,7 @@ class JsonCatPack : public BasicCatPack { auto sp = d.split("-"); day = sp[0].toInt(); if (sp.length() >= 2) - mounth = sp[1].length(); + mounth = sp[1].toInt(); } int mounth; int day; -- cgit From f8adb508ab0152af76829e0fdee92b451dcc1acf Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 11:44:40 +0300 Subject: Made catpack id optional in catpack.json Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index e74b9709..2d5653a6 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -77,7 +77,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); const auto root = doc.object(); m_name = Json::requireString(root, "name", "Catpack name"); - m_id = Json::requireString(root, "id", "Catpack ID"); + auto id = Json::ensureString(root, "id", "", "Catpack ID"); + m_id = id.isEmpty() ? m_id : id; m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); for (auto v : variants) { -- cgit From c5ea8367aaf9d61a6362427a55206d8891f40cda Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Fri, 23 Jun 2023 14:25:21 +0300 Subject: Update launcher/ui/themes/CatPack.cpp Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/themes/CatPack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 2d5653a6..bee63202 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -78,7 +78,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di const auto root = doc.object(); m_name = Json::requireString(root, "name", "Catpack name"); auto id = Json::ensureString(root, "id", "", "Catpack ID"); - m_id = id.isEmpty() ? m_id : id; + if (!id.isEmpty()) + m_id = id; m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); for (auto v : variants) { -- cgit From 0a566318315c4e1566cb4ef7c99321a025e998a2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Jun 2023 19:35:41 +0300 Subject: Added curseforge search Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 130 ++++++++++++++++++--- launcher/modplatform/flame/FlamePackExportTask.h | 13 ++- launcher/ui/dialogs/ExportMrPackDialog.cpp | 5 +- 3 files changed, 133 insertions(+), 15 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 6114f1b1..7130b502 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -24,12 +24,15 @@ #include #include #include +#include #include "Json.h" #include "MMCZip.h" #include "minecraft/PackProfile.h" +#include "minecraft/mod/ModDetails.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" #include "modplatform/helpers/ExportModsToStringTask.h" +#include "modplatform/helpers/HashUtils.h" const QString FlamePackExportTask::TEMPLATE = "
  • {name}({authors})
  • "; @@ -88,13 +91,118 @@ void FlamePackExportTask::collectFiles() return; } + pendingHashes.clear(); resolvedFiles.clear(); - mcInstance->loaderModList()->update(); - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { - mods = mcInstance->loaderModList()->allMods(); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this]() { + mods = mcInstance->loaderModList()->allMods(); + collectHashes(); + }); + } else + collectHashes(); +} + +void FlamePackExportTask::collectHashes() +{ + ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); + for (auto* mod : mods) { + if (!mod || !mod->valid() || mod->type() == ResourceType::FOLDER) + continue; + if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { + resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled() }); + continue; + } + + auto hash_task = Hashing::createFlameHasher(mod->fileinfo().absoluteFilePath()); + connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { pendingHashes.insert(hash_task->getResult(), mod); }); + connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + connect(hash_task.get(), &Task::finished, [hash_task] { hash_task->deleteLater(); }); + hashing_task->addTask(hash_task); + } + connect(hashing_task.get(), &Task::succeeded, this, &FlamePackExportTask::makeApiRequest); + connect(hashing_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); + connect(hashing_task.get(), &Task::finished, [hashing_task] { hashing_task->deleteLater(); }); + hashing_task->start(); +} + +void FlamePackExportTask::makeApiRequest() +{ + setAbortable(true); + if (pendingHashes.isEmpty()) { + buildZip(); + return; + } + + auto response = std::make_shared(); + + QList fingerprints; + for (auto& murmur : pendingHashes.keys()) { + fingerprints.push_back(murmur.toUInt()); + } + + auto task = api.matchFingerprints(fingerprints, response.get()); + + connect(task.get(), &Task::succeeded, this, [this, response] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + + failed(parse_error.errorString()); + return; + } + + try { + auto doc_obj = Json::requireObject(doc); + auto data_obj = Json::requireObject(doc_obj, "data"); + auto data_arr = Json::requireArray(data_obj, "exactMatches"); + + if (data_arr.isEmpty()) { + qWarning() << "No matches found for fingerprint search!"; + + return; + } + + for (auto match : data_arr) { + auto match_obj = Json::ensureObject(match, {}); + auto file_obj = Json::ensureObject(match_obj, "file", {}); + + if (match_obj.isEmpty() || file_obj.isEmpty()) { + qWarning() << "Fingerprint match is empty!"; + + return; + } + + auto fingerprint = QString::number(Json::ensureVariant(file_obj, "fileFingerprint").toUInt()); + auto mod = pendingHashes.find(fingerprint); + if (mod == pendingHashes.end()) { + qWarning() << "Invalid fingerprint from the API response."; + continue; + } + + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); + + resolvedFiles.insert( + mod.value()->fileinfo().absoluteFilePath(), + { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "modId"), mod.value()->enabled() }); + } + + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << doc; + } + pendingHashes.clear(); buildZip(); }); + + connect(task.get(), &NetJob::finished, [task]() { task->deleteLater(); }); + connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); + task->start(); } void FlamePackExportTask::buildZip() @@ -177,7 +285,8 @@ QByteArray FlamePackExportTask::generateIndex() obj["name"] = name; obj["version"] = version; obj["author"] = author; - obj["projectID"] = projectID.toInt(); + if (projectID.toInt() != 0) + obj["projectID"] = projectID.toInt(); obj["overrides"] = "overrides"; if (mcInstance) { QJsonObject version; @@ -205,16 +314,11 @@ QByteArray FlamePackExportTask::generateIndex() } QJsonArray files; - for (auto mod : mods) { - auto meta = mod->metadata(); - if (meta == nullptr || meta->provider != ModPlatform::ResourceProvider::FLAME) - continue; - resolvedFiles[gameRoot.relativeFilePath(mod->fileinfo().absoluteFilePath())] = true; - + for (auto mod : resolvedFiles) { QJsonObject file; - file["projectID"] = meta->project_id.toInt(); - file["fileID"] = meta->file_id.toInt(); - file["required"] = true; + file["projectID"] = mod.addonId; + file["fileID"] = mod.version; + file["required"] = mod.enabled; files << file; } obj["files"] = files; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 370cd67e..58f66cc5 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -23,6 +23,7 @@ #include "BaseInstance.h" #include "MMCZip.h" #include "minecraft/MinecraftInstance.h" +#include "modplatform/flame/FlameAPI.h" #include "tasks/Task.h" class FlamePackExportTask : public Task { @@ -52,15 +53,25 @@ class FlamePackExportTask : public Task { const MMCZip::FilterFunction filter; typedef std::optional BuildZipResult; + struct ResolvedFile { + int addonId; + int version; + bool enabled; + }; + + FlameAPI api; QFileInfoList files; - QMap resolvedFiles; + QMap pendingHashes; + QMap resolvedFiles; Task::Ptr task; QFuture buildZipFuture; QFutureWatcher buildZipWatcher; QList mods; void collectFiles(); + void collectHashes(); + void makeApiRequest(); void buildZip(); void finish(); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index aaa528aa..3711bb8f 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -44,6 +44,8 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->author->hide(); ui->authorLabel->hide(); } else { + setWindowTitle("Export CurseForge Pack"); + ui->version->setText(""); ui->summaryLabel->setText("ProjectID"); } @@ -137,6 +139,7 @@ void ExportMrPackDialog::done(int result) void ExportMrPackDialog::validate() { - const bool invalid = ui->name->text().isEmpty() || ui->version->text().isEmpty(); + const bool invalid = + ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty()); ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid); } -- cgit From cf94adb363c1ae791ebd6f0149899f63c78bfb1b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 01:05:49 +0300 Subject: Added some warnings Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 7 ++ launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 9 +- launcher/modplatform/ModIndex.h | 1 + launcher/modplatform/flame/FlamePackExportTask.cpp | 124 ++++++++++++++++++--- launcher/modplatform/flame/FlamePackExportTask.h | 7 ++ .../modplatform/helpers/ExportModsToStringTask.cpp | 22 +--- launcher/ui/MainWindow.cpp | 13 ++- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 +- launcher/ui/dialogs/ExportMrPackDialog.ui | 7 ++ 10 files changed, 158 insertions(+), 37 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb..e93ff8bc 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->slug); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4..d6272f4d 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf..c68333c5 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,18 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + if (!hash.addData(device)) qCritical() << "Failed to read JAR to create hash!"; Q_ASSERT(hash.result().length() == hash.hashLength(algo)); return { hash.result().toHex() }; } +QString getMetaURL(ResourceProvider provider, QString slug) +{ + return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/minecraft/mc-mods/" + : "https://modrinth.com/mod/") + + slug.remove(".pw.toml"); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 82da2ab2..7d8199b3 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -118,6 +118,7 @@ struct IndexedPack { return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); } }; +QString getMetaURL(ResourceProvider provider, QString slug); } // namespace ModPlatform diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 880d4324..2f1201e1 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -24,13 +24,14 @@ #include #include #include +#include #include #include "Json.h" #include "MMCZip.h" #include "minecraft/PackProfile.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/ModIndex.h" -#include "modplatform/helpers/ExportModsToStringTask.h" +#include "modplatform/flame/FlameModIndex.h" #include "modplatform/helpers/HashUtils.h" #include "tasks/Task.h" @@ -40,6 +41,7 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, const QVariant& projectID, + const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) @@ -52,6 +54,7 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, , gameRoot(instance->gameRoot()) , output(output) , filter(filter) + , generateModList(generateModList) {} void FlamePackExportTask::executeTask() @@ -116,7 +119,8 @@ void FlamePackExportTask::collectHashes() } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), - { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled() }); + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), + mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); setProgress(m_progress + 1, mods.count()); continue; } @@ -195,10 +199,10 @@ void FlamePackExportTask::makeApiRequest() } setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*mod)->name())); - - resolvedFiles.insert( - mod.value()->fileinfo().absoluteFilePath(), - { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "modId"), mod.value()->enabled() }); + if (Json::ensureBoolean(file_obj, "isAvailable", false)) + resolvedFiles.insert( + mod.value()->fileinfo().absoluteFilePath(), + { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod.value()->enabled() }); } } catch (Json::JsonException& e) { @@ -206,13 +210,94 @@ void FlamePackExportTask::makeApiRequest() qDebug() << doc; } pendingHashes.clear(); - buildZip(); }); - + connect(task.get(), &Task::finished, this, &FlamePackExportTask::getProjectsInfo); connect(task.get(), &NetJob::failed, this, &FlamePackExportTask::emitFailed); task->start(); } +void FlamePackExportTask::getProjectsInfo() +{ + if (!generateModList) { + buildZip(); + return; + } + setStatus(tr("Find project info from curseforge...")); + QList addonIds; + for (auto resolved : resolvedFiles) { + if (resolved.slug.isEmpty()) { + addonIds << QString::number(resolved.addonId); + } + } + + auto response = std::make_shared(); + Task::Ptr proj_task; + + if (addonIds.isEmpty()) { + buildZip(); + return; + } else if (addonIds.size() == 1) { + proj_task = api.getProject(*addonIds.begin(), response); + } else { + proj_task = api.getProjects(addonIds, response); + } + + connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { + QJsonParseError parse_error{}; + auto doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth projects task at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + try { + QJsonArray entries; + if (addonIds.size() == 1) + entries = { Json::requireObject(Json::requireObject(doc), "data") }; + else + entries = Json::requireArray(Json::requireObject(doc), "data"); + + size_t progress = 0; + for (auto entry : entries) { + setProgress(progress++, entries.count()); + auto entry_obj = Json::requireObject(entry); + + try { + setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(Json::requireString(entry_obj, "name"))); + + ModPlatform::IndexedPack pack; + FlameMod::loadIndexedPack(pack, entry_obj); + for (auto key : resolvedFiles.keys()) { + auto val = resolvedFiles.value(key); + if (val.addonId == pack.addonId) { + val.name = pack.name; + val.slug = pack.slug; + QStringList authors; + for (auto author : pack.authors) + authors << author.name; + + val.authors = authors.join(", "); + resolvedFiles[key] = val; + } + } + + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << entries; + } + } + } catch (Json::JsonException& e) { + qDebug() << e.cause(); + qDebug() << doc; + } + buildZip(); + }); + task.reset(proj_task); + task->start(); +} + void FlamePackExportTask::buildZip() { setStatus(tr("Adding files...")); @@ -234,14 +319,23 @@ void FlamePackExportTask::buildZip() } indexFile.write(generateIndex()); - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); + if (generateModList) { + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + QString content = ""; + for (auto mod : resolvedFiles) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; + } + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); } - QString content = ExportToString::ExportModsToStringTask(mcInstance->loaderModList()->allMods(), TEMPLATE); - content = "
      " + content + "
    "; - modlist.write(content.toUtf8()); size_t progress = 0; for (const QFileInfo& file : files) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index f0069678..7f27e0d0 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,6 +32,7 @@ class FlamePackExportTask : public Task { const QString& version, const QString& author, const QVariant& projectID, + const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -51,12 +52,17 @@ class FlamePackExportTask : public Task { const QDir gameRoot; const QString output; const MMCZip::FilterFunction filter; + const bool generateModList; typedef std::optional BuildZipResult; struct ResolvedFile { int addonId; int version; bool enabled; + + QString name; + QString slug; + QString authors; }; FlameAPI api; @@ -71,6 +77,7 @@ class FlamePackExportTask : public Task { void collectFiles(); void collectHashes(); void makeApiRequest(); + void getProjectsInfo(); void buildZip(); void finish(); diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp index e7be5ce1..03e1f4ba 100644 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ b/launcher/modplatform/helpers/ExportModsToStringTask.cpp @@ -19,6 +19,7 @@ #include "modplatform/ModIndex.h" namespace ExportToString { + QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) { switch (format) { @@ -28,12 +29,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("%2").arg(url, modName); } @@ -57,12 +53,7 @@ QString ExportModsToStringTask(QList mods, Formats format, OptionalData ex auto meta = mod->metadata(); auto modName = mod->name(); if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); } @@ -93,12 +84,7 @@ QString ExportModsToStringTask(QList mods, QString lineTemplate) auto meta = mod->metadata(); auto modName = mod->name(); - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } + auto url = mod->metaurl(); auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 0027d180..eb09efbc 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1420,8 +1420,17 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() void MainWindow::on_actionExportInstanceFlamePack_triggered() { if (m_selectedInstance) { - ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); - dlg.exec(); + auto instance = dynamic_cast(m_selectedInstance.get()); + if (instance) { + if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { + QMessageBox msgBox; + msgBox.setText(tr("Quilt is not yet supported by curseforge.")); + msgBox.exec(); + return; + } + ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + dlg.exec(); + } } } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 3711bb8f..edd2148a 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -43,6 +43,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); ui->author->hide(); ui->authorLabel->hide(); + ui->gnerateModlist->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); @@ -117,7 +118,8 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), + ui->gnerateModlist->isChecked(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 59ecb17c..1b137eb4 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -67,6 +67,13 @@ + + + + Generate modlist + + + -- cgit From 42bc04a0d2af26e97829e6b1afd87d550b9b44da Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 24 Jun 2023 11:01:23 +0300 Subject: Update launcher/ui/MainWindow.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index eb09efbc..89c78539 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1424,7 +1424,7 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (instance) { if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { QMessageBox msgBox; - msgBox.setText(tr("Quilt is not yet supported by curseforge.")); + msgBox.setText(tr("Quilt is currently not supported by CurseForge modpacks.")); msgBox.exec(); return; } -- cgit From cd1e8dc8cc87acf905ab3140efc48ef482973c7e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 11:12:23 +0300 Subject: Removed modlist checkbox Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 36 +++++++++------------- launcher/modplatform/flame/FlamePackExportTask.h | 2 -- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 +-- launcher/ui/dialogs/ExportMrPackDialog.ui | 7 ----- 4 files changed, 15 insertions(+), 34 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 2f1201e1..927b2e46 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -41,7 +41,6 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, const QVariant& projectID, - const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) @@ -54,7 +53,6 @@ FlamePackExportTask::FlamePackExportTask(const QString& name, , gameRoot(instance->gameRoot()) , output(output) , filter(filter) - , generateModList(generateModList) {} void FlamePackExportTask::executeTask() @@ -218,10 +216,6 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - if (!generateModList) { - buildZip(); - return; - } setStatus(tr("Find project info from curseforge...")); QList addonIds; for (auto resolved : resolvedFiles) { @@ -319,23 +313,21 @@ void FlamePackExportTask::buildZip() } indexFile.write(generateIndex()); - if (generateModList) { - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - QString content = ""; - for (auto mod : resolvedFiles) { - content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) - .replace("{authors}", mod.authors) + - "\n"; - } - content = "
      " + content + "
    "; - modlist.write(content.toUtf8()); + QuaZipFile modlist(&zip); + if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { + QFile::remove(output); + return BuildZipResult(tr("Could not create index")); + } + QString content = ""; + for (auto mod : resolvedFiles) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; } + content = "
      " + content + "
    "; + modlist.write(content.toUtf8()); size_t progress = 0; for (const QFileInfo& file : files) { diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 7f27e0d0..9ec9a230 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,7 +32,6 @@ class FlamePackExportTask : public Task { const QString& version, const QString& author, const QVariant& projectID, - const bool generateModList, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -52,7 +51,6 @@ class FlamePackExportTask : public Task { const QDir gameRoot; const QString output; const MMCZip::FilterFunction filter; - const bool generateModList; typedef std::optional BuildZipResult; struct ResolvedFile { diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 3c593d20..8a95997b 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -43,7 +43,6 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, Mo ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); ui->author->hide(); ui->authorLabel->hide(); - ui->gnerateModlist->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); @@ -118,8 +117,7 @@ void ExportMrPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), - ui->gnerateModlist->isChecked(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui index 1b137eb4..59ecb17c 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ b/launcher/ui/dialogs/ExportMrPackDialog.ui @@ -67,13 +67,6 @@ - - - - Generate modlist - - - -- cgit From 30ef5475c75514c08a4d1b2c8e4c6ec5abba41ea Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:50:05 +0300 Subject: Made sure CurseForge string is corect Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/ui/MainWindow.ui | 2 +- launcher/ui/dialogs/ExportMrPackDialog.cpp | 2 +- launcher/ui/pages/global/LauncherPage.ui | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 45fc2e63..fb5bcc0b 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -232,7 +232,7 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - setStatus(tr("Find project info from curseforge...")); + setStatus(tr("Find project info from CurseForge...")); QList addonIds; for (auto resolved : resolvedFiles) { if (resolved.slug.isEmpty()) { diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 1cfb59cd..190219b9 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -484,7 +484,7 @@ - Curseforge (zip) + CurseForge (zip)
    diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 8a95997b..94987c7e 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -108,7 +108,7 @@ void ExportMrPackDialog::done(int result) nullptr); else output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".zip"), "Curseforge pack (*.zip)", nullptr); + FS::PathCombine(QDir::homePath(), filename + ".zip"), "CurseForge pack (*.zip)", nullptr); if (output.isEmpty()) return; diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index d9116bfc..26408f44 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -169,7 +169,7 @@ - Disable using metadata provided by mod providers (like Modrinth or Curseforge) for mods. + Disable using metadata provided by mod providers (like Modrinth or CurseForge) for mods. Disable using metadata for mods -- cgit From 25579fbedcfac6b36c6b30ad2447d702b601e1d6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 14:54:39 +0300 Subject: Renamed ExportMrPackDialog to ExportPackDialog Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 6 +- launcher/ui/MainWindow.cpp | 6 +- launcher/ui/dialogs/ExportMrPackDialog.cpp | 145 ---------------------------- launcher/ui/dialogs/ExportMrPackDialog.h | 49 ---------- launcher/ui/dialogs/ExportMrPackDialog.ui | 146 ----------------------------- launcher/ui/dialogs/ExportPackDialog.cpp | 145 ++++++++++++++++++++++++++++ launcher/ui/dialogs/ExportPackDialog.h | 49 ++++++++++ launcher/ui/dialogs/ExportPackDialog.ui | 146 +++++++++++++++++++++++++++++ 8 files changed, 346 insertions(+), 346 deletions(-) delete mode 100644 launcher/ui/dialogs/ExportMrPackDialog.cpp delete mode 100644 launcher/ui/dialogs/ExportMrPackDialog.h delete mode 100644 launcher/ui/dialogs/ExportMrPackDialog.ui create mode 100644 launcher/ui/dialogs/ExportPackDialog.cpp create mode 100644 launcher/ui/dialogs/ExportPackDialog.h create mode 100644 launcher/ui/dialogs/ExportPackDialog.ui (limited to 'launcher/ui') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 8de616a6..0dc2b80a 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -908,8 +908,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/EditAccountDialog.h ui/dialogs/ExportInstanceDialog.cpp ui/dialogs/ExportInstanceDialog.h - ui/dialogs/ExportMrPackDialog.cpp - ui/dialogs/ExportMrPackDialog.h + ui/dialogs/ExportPackDialog.cpp + ui/dialogs/ExportPackDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1056,7 +1056,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ProfileSelectDialog.ui ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui - ui/dialogs/ExportMrPackDialog.ui + ui/dialogs/ExportPackDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 89c78539..91809c7b 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -107,7 +107,7 @@ #include "ui/dialogs/CopyInstanceDialog.h" #include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/ExportInstanceDialog.h" -#include "ui/dialogs/ExportMrPackDialog.h" +#include "ui/dialogs/ExportPackDialog.h" #include "ui/dialogs/ImportResourceDialog.h" #include "ui/themes/ITheme.h" #include "ui/themes/ThemeManager.h" @@ -1412,7 +1412,7 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() { if (m_selectedInstance) { - ExportMrPackDialog dlg(m_selectedInstance, this); + ExportPackDialog dlg(m_selectedInstance, this); dlg.exec(); } } @@ -1428,7 +1428,7 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() msgBox.exec(); return; } - ExportMrPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); + ExportPackDialog dlg(m_selectedInstance, this, ModPlatform::ResourceProvider::FLAME); dlg.exec(); } } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp deleted file mode 100644 index 94987c7e..00000000 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (C) 2023 TheKodeToad - * - * 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 . - */ - -#include "ExportMrPackDialog.h" -#include "minecraft/mod/ModFolderModel.h" -#include "modplatform/ModIndex.h" -#include "modplatform/flame/FlamePackExportTask.h" -#include "ui/dialogs/CustomMessageBox.h" -#include "ui/dialogs/ProgressDialog.h" -#include "ui_ExportMrPackDialog.h" - -#include -#include -#include -#include -#include -#include "FastFileIconProvider.h" -#include "FileSystem.h" -#include "MMCZip.h" -#include "modplatform/modrinth/ModrinthPackExportTask.h" - -ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) - : QDialog(parent), instance(instance), ui(new Ui::ExportMrPackDialog), m_provider(provider) -{ - ui->setupUi(this); - ui->name->setText(instance->name()); - if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { - ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); - ui->author->hide(); - ui->authorLabel->hide(); - } else { - setWindowTitle("Export CurseForge Pack"); - ui->version->setText(""); - ui->summaryLabel->setText("ProjectID"); - } - - // ensure a valid pack is generated - // the name and version fields mustn't be empty - connect(ui->name, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); - connect(ui->version, &QLineEdit::textEdited, this, &ExportMrPackDialog::validate); - // the instance name can technically be empty - validate(); - - QFileSystemModel* model = new QFileSystemModel(this); - model->setIconProvider(&icons); - - // use the game root - everything outside cannot be exported - const QDir root(instance->gameRoot()); - proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->setSourceModel(model); - proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); - - const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); - - for (const QString& file : root.entryList(filter)) { - if (!(file == "mods" || file == "coremods" || file == "datapacks" || file == "config" || file == "options.txt" || - file == "servers.dat")) - proxy->blockedPaths().insert(file); - } - - MinecraftInstance* mcInstance = dynamic_cast(instance.get()); - if (mcInstance) { - const QDir index = mcInstance->loaderModList()->indexDir(); - if (index.exists()) - proxy->blockedPaths().insert(root.relativeFilePath(index.absolutePath())); - } - - ui->treeView->setModel(proxy); - ui->treeView->setRootIndex(proxy->mapFromSource(model->index(instance->gameRoot()))); - ui->treeView->sortByColumn(0, Qt::AscendingOrder); - - model->setFilter(filter); - model->setRootPath(instance->gameRoot()); - - QHeaderView* headerView = ui->treeView->header(); - headerView->setSectionResizeMode(QHeaderView::ResizeToContents); - headerView->setSectionResizeMode(0, QHeaderView::Stretch); -} - -ExportMrPackDialog::~ExportMrPackDialog() -{ - delete ui; -} - -void ExportMrPackDialog::done(int result) -{ - if (result == Accepted) { - const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text()); - QString output; - if (m_provider == ModPlatform::ResourceProvider::MODRINTH) - output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".mrpack"), "Modrinth pack (*.mrpack *.zip)", - nullptr); - else - output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), - FS::PathCombine(QDir::homePath(), filename + ".zip"), "CurseForge pack (*.zip)", nullptr); - - if (output.isEmpty()) - return; - Task* task; - if (m_provider == ModPlatform::ResourceProvider::MODRINTH) - task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); - else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); - - connect(task, &Task::failed, - [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(task, &Task::aborted, [this] { - CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) - ->show(); - }); - connect(task, &Task::finished, [task] { task->deleteLater(); }); - - ProgressDialog progress(this); - progress.setSkipButton(true, tr("Abort")); - if (progress.execWithTask(task) != QDialog::Accepted) - return; - } - - QDialog::done(result); -} - -void ExportMrPackDialog::validate() -{ - const bool invalid = - ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty()); - ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid); -} diff --git a/launcher/ui/dialogs/ExportMrPackDialog.h b/launcher/ui/dialogs/ExportMrPackDialog.h deleted file mode 100644 index 858a31bf..00000000 --- a/launcher/ui/dialogs/ExportMrPackDialog.h +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (C) 2023 TheKodeToad - * - * 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 . - */ - -#pragma once - -#include -#include "BaseInstance.h" -#include "FastFileIconProvider.h" -#include "FileIgnoreProxy.h" -#include "modplatform/ModIndex.h" - -namespace Ui { -class ExportMrPackDialog; -} - -class ExportMrPackDialog : public QDialog { - Q_OBJECT - - public: - explicit ExportMrPackDialog(InstancePtr instance, - QWidget* parent = nullptr, - ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); - ~ExportMrPackDialog(); - - void done(int result) override; - void validate(); - - private: - const InstancePtr instance; - Ui::ExportMrPackDialog* ui; - FileIgnoreProxy* proxy; - FastFileIconProvider icons; - const ModPlatform::ResourceProvider m_provider; -}; diff --git a/launcher/ui/dialogs/ExportMrPackDialog.ui b/launcher/ui/dialogs/ExportMrPackDialog.ui deleted file mode 100644 index 59ecb17c..00000000 --- a/launcher/ui/dialogs/ExportMrPackDialog.ui +++ /dev/null @@ -1,146 +0,0 @@ - - - ExportMrPackDialog - - - - 0 - 0 - 650 - 413 - - - - Export Modrinth Pack - - - true - - - - - - Information - - - - - - Summary - - - - - - - - - - Name - - - - - - - Version - - - - - - - - - - 1.0.0 - - - - - - - Author - - - - - - - - - - - - - Files - - - - - - - true - - - QAbstractItemView::ExtendedSelection - - - true - - - false - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - name - version - summary - treeView - - - - - buttonBox - accepted() - ExportMrPackDialog - accept() - - - 324 - 390 - - - 324 - 206 - - - - - buttonBox - rejected() - ExportMrPackDialog - reject() - - - 324 - 390 - - - 324 - 206 - - - - - diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp new file mode 100644 index 00000000..8e921f89 --- /dev/null +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad + * + * 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 . + */ + +#include "ExportPackDialog.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlamePackExportTask.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui_ExportMrPackDialog.h" + +#include +#include +#include +#include +#include +#include "FastFileIconProvider.h" +#include "FileSystem.h" +#include "MMCZip.h" +#include "modplatform/modrinth/ModrinthPackExportTask.h" + +ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider) + : QDialog(parent), instance(instance), ui(new Ui::ExportPackDialog), m_provider(provider) +{ + ui->setupUi(this); + ui->name->setText(instance->name()); + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { + ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + ui->author->hide(); + ui->authorLabel->hide(); + } else { + setWindowTitle("Export CurseForge Pack"); + ui->version->setText(""); + ui->summaryLabel->setText("ProjectID"); + } + + // ensure a valid pack is generated + // the name and version fields mustn't be empty + connect(ui->name, &QLineEdit::textEdited, this, &ExportPackDialog::validate); + connect(ui->version, &QLineEdit::textEdited, this, &ExportPackDialog::validate); + // the instance name can technically be empty + validate(); + + QFileSystemModel* model = new QFileSystemModel(this); + model->setIconProvider(&icons); + + // use the game root - everything outside cannot be exported + const QDir root(instance->gameRoot()); + proxy = new FileIgnoreProxy(instance->gameRoot(), this); + proxy->setSourceModel(model); + proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); + + const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); + + for (const QString& file : root.entryList(filter)) { + if (!(file == "mods" || file == "coremods" || file == "datapacks" || file == "config" || file == "options.txt" || + file == "servers.dat")) + proxy->blockedPaths().insert(file); + } + + MinecraftInstance* mcInstance = dynamic_cast(instance.get()); + if (mcInstance) { + const QDir index = mcInstance->loaderModList()->indexDir(); + if (index.exists()) + proxy->blockedPaths().insert(root.relativeFilePath(index.absolutePath())); + } + + ui->treeView->setModel(proxy); + ui->treeView->setRootIndex(proxy->mapFromSource(model->index(instance->gameRoot()))); + ui->treeView->sortByColumn(0, Qt::AscendingOrder); + + model->setFilter(filter); + model->setRootPath(instance->gameRoot()); + + QHeaderView* headerView = ui->treeView->header(); + headerView->setSectionResizeMode(QHeaderView::ResizeToContents); + headerView->setSectionResizeMode(0, QHeaderView::Stretch); +} + +ExportPackDialog::~ExportPackDialog() +{ + delete ui; +} + +void ExportPackDialog::done(int result) +{ + if (result == Accepted) { + const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text()); + QString output; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".mrpack"), "Modrinth pack (*.mrpack *.zip)", + nullptr); + else + output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()), + FS::PathCombine(QDir::homePath(), filename + ".zip"), "CurseForge pack (*.zip)", nullptr); + + if (output.isEmpty()) + return; + Task* task; + if (m_provider == ModPlatform::ResourceProvider::MODRINTH) + task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + else + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, + [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + + connect(task, &Task::failed, + [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); + connect(task, &Task::aborted, [this] { + CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) + ->show(); + }); + connect(task, &Task::finished, [task] { task->deleteLater(); }); + + ProgressDialog progress(this); + progress.setSkipButton(true, tr("Abort")); + if (progress.execWithTask(task) != QDialog::Accepted) + return; + } + + QDialog::done(result); +} + +void ExportPackDialog::validate() +{ + const bool invalid = + ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid); +} diff --git a/launcher/ui/dialogs/ExportPackDialog.h b/launcher/ui/dialogs/ExportPackDialog.h new file mode 100644 index 00000000..830c24d2 --- /dev/null +++ b/launcher/ui/dialogs/ExportPackDialog.h @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 TheKodeToad + * + * 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 . + */ + +#pragma once + +#include +#include "BaseInstance.h" +#include "FastFileIconProvider.h" +#include "FileIgnoreProxy.h" +#include "modplatform/ModIndex.h" + +namespace Ui { +class ExportPackDialog; +} + +class ExportPackDialog : public QDialog { + Q_OBJECT + + public: + explicit ExportPackDialog(InstancePtr instance, + QWidget* parent = nullptr, + ModPlatform::ResourceProvider provider = ModPlatform::ResourceProvider::MODRINTH); + ~ExportPackDialog(); + + void done(int result) override; + void validate(); + + private: + const InstancePtr instance; + Ui::ExportPackDialog* ui; + FileIgnoreProxy* proxy; + FastFileIconProvider icons; + const ModPlatform::ResourceProvider m_provider; +}; diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui new file mode 100644 index 00000000..5762508a --- /dev/null +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -0,0 +1,146 @@ + + + ExportPackDialog + + + + 0 + 0 + 650 + 413 + + + + Export Modrinth Pack + + + true + + + + + + Information + + + + + + Summary + + + + + + + + + + Name + + + + + + + Version + + + + + + + + + + 1.0.0 + + + + + + + Author + + + + + + + + + + + + + Files + + + + + + + true + + + QAbstractItemView::ExtendedSelection + + + true + + + false + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + name + version + summary + treeView + + + + + buttonBox + accepted() + ExportPackDialog + accept() + + + 324 + 390 + + + 324 + 206 + + + + + buttonBox + rejected() + ExportPackDialog + reject() + + + 324 + 390 + + + 324 + 206 + + + + + -- cgit From 4a84084d9d605ae4fa9a8063f36bfdbcdc4c5c3d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 15:02:00 +0300 Subject: Added condition for modlist Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 20 +++++++++++--------- launcher/modplatform/flame/FlamePackExportTask.h | 2 ++ launcher/ui/dialogs/ExportPackDialog.cpp | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index fb5bcc0b..dc407653 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -118,7 +118,7 @@ void FlamePackExportTask::collectHashes() } if (mod->metadata() && mod->metadata()->provider == ModPlatform::ResourceProvider::FLAME) { resolvedFiles.insert(mod->fileinfo().absoluteFilePath(), - { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), + { mod->metadata()->project_id.toInt(), mod->metadata()->file_id.toInt(), mod->enabled(), true, mod->metadata()->name, mod->metadata()->slug, mod->authors().join(", ") }); setProgress(m_progress + 1, totalProgres); continue; @@ -128,7 +128,7 @@ void FlamePackExportTask::collectHashes() connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod, totalProgres](QString hash) { if (m_state == Task::State::Running) { setProgress(m_progress + 1, totalProgres); - pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled() }); + pendingHashes.insert(hash, { mod->name(), mod->fileinfo().absoluteFilePath(), mod->enabled(), true }); } }); connect(hash_task.get(), &Task::failed, this, &FlamePackExportTask::emitFailed); @@ -215,8 +215,8 @@ void FlamePackExportTask::makeApiRequest() setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(mod->name)); if (Json::ensureBoolean(file_obj, "isAvailable", false, "isAvailable")) - resolvedFiles.insert(mod->path, - { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), mod->enabled }); + resolvedFiles.insert(mod->path, { Json::requireInteger(file_obj, "modId"), Json::requireInteger(file_obj, "id"), + mod->enabled, mod->isMod }); } } catch (Json::JsonException& e) { @@ -336,11 +336,13 @@ void FlamePackExportTask::buildZip() } QString content = ""; for (auto mod : resolvedFiles) { - content += QString(TEMPLATE) - .replace("{name}", mod.name) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) - .replace("{authors}", mod.authors) + - "\n"; + if (mod.isMod) { + content += QString(TEMPLATE) + .replace("{name}", mod.name) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.slug)) + .replace("{authors}", mod.authors) + + "\n"; + } } content = "
      " + content + "
    "; modlist.write(content.toUtf8()); diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 629493d8..ee1f4e8d 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -57,6 +57,7 @@ class FlamePackExportTask : public Task { int addonId; int version; bool enabled; + bool isMod; QString name; QString slug; @@ -66,6 +67,7 @@ class FlamePackExportTask : public Task { QString name; QString path; bool enabled; + bool isMod; }; FlameAPI api; diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index 8e921f89..fb71f4a5 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -22,7 +22,7 @@ #include "modplatform/flame/FlamePackExportTask.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/ProgressDialog.h" -#include "ui_ExportMrPackDialog.h" +#include "ui_ExportPackDialog.h" #include #include -- cgit From 69c21454ecf683b1794aec55ddad66d53d3afc7c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 22:15:18 +0300 Subject: removed projectID Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 6 +----- launcher/modplatform/flame/FlamePackExportTask.h | 2 -- launcher/ui/dialogs/ExportPackDialog.cpp | 6 ++---- launcher/ui/dialogs/ExportPackDialog.ui | 11 +---------- 4 files changed, 4 insertions(+), 21 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index d729e977..ac85a628 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -41,14 +41,12 @@ const QString FlamePackExportTask::TEMPLATE = "
  • {name}{authors} FlamePackExportTask::FlamePackExportTask(const QString& name, const QString& version, const QString& author, - const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter) : name(name) , version(version) , author(author) - , projectID(projectID) , instance(instance) , mcInstance(dynamic_cast(instance.get())) , gameRoot(instance->gameRoot()) @@ -341,7 +339,7 @@ void FlamePackExportTask::buildZip() content += QString(TEMPLATE) .replace("{name}", mod.name) .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId)) - .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by {%1})").arg(mod.authors) : ""); + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors) : ""); } } content = "
      " + content + "
    "; @@ -398,8 +396,6 @@ QByteArray FlamePackExportTask::generateIndex() obj["name"] = name; obj["version"] = version; obj["author"] = author; - if (projectID.toInt() != 0) - obj["projectID"] = projectID.toInt(); obj["overrides"] = "overrides"; if (mcInstance) { QJsonObject version; diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index cf67ed5f..5c8caa45 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -32,7 +32,6 @@ class FlamePackExportTask : public Task { FlamePackExportTask(const QString& name, const QString& version, const QString& author, - const QVariant& projectID, InstancePtr instance, const QString& output, MMCZip::FilterFunction filter); @@ -46,7 +45,6 @@ class FlamePackExportTask : public Task { // inputs const QString name, version, author; - const QVariant projectID; const InstancePtr instance; MinecraftInstance* mcInstance; const QDir gameRoot; diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index fb71f4a5..ea364939 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -41,12 +41,10 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla ui->name->setText(instance->name()); if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); - ui->author->hide(); - ui->authorLabel->hide(); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); - ui->summaryLabel->setText("ProjectID"); + ui->summaryLabel->setText("Author"); } // ensure a valid pack is generated @@ -117,7 +115,7 @@ void ExportPackDialog::done(int result) task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); else - task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->author->text(), ui->summary->text(), instance, output, + task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, [this](const QString& path) { return proxy->blockedPaths().covers(path); }); connect(task, &Task::failed, diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui index 5762508a..658e2199 100644 --- a/launcher/ui/dialogs/ExportPackDialog.ui +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -57,16 +57,7 @@ - - - - Author - - - - - - + -- cgit From 932531c8ba1197e38dcd66c1ad146aeebc9ca177 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 23:48:18 +0300 Subject: fixed authors Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 2 +- launcher/ui/dialogs/ExportPackDialog.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index ac85a628..e73f3de5 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -95,8 +95,8 @@ void FlamePackExportTask::collectFiles() resolvedFiles.clear(); if (mcInstance != nullptr) { - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes); mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, &FlamePackExportTask::collectHashes); } else collectHashes(); } diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index ea364939..fd374246 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -73,6 +73,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { + mcInstance->loaderModList()->update(); const QDir index = mcInstance->loaderModList()->indexDir(); if (index.exists()) proxy->blockedPaths().insert(root.relativeFilePath(index.absolutePath())); -- cgit From 529e2054eadf4c97231a51d7bd2d25cb75bd74c9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 22:54:05 +0100 Subject: A few tweaks, with inspiration from Zeke :3 Signed-off-by: TheKodeToad --- launcher/CMakeLists.txt | 6 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 4 +- launcher/ui/pages/instance/VersionPage.cpp | 1 - launcher/ui/pages/instance/VersionPage.ui | 10 - launcher/ui/pages/modplatform/CustomPage.cpp | 241 +++++++++++++++++++++ launcher/ui/pages/modplatform/CustomPage.h | 104 +++++++++ launcher/ui/pages/modplatform/CustomPage.ui | 290 ++++++++++++++++++++++++++ launcher/ui/pages/modplatform/VanillaPage.cpp | 241 --------------------- launcher/ui/pages/modplatform/VanillaPage.h | 104 --------- launcher/ui/pages/modplatform/VanillaPage.ui | 290 -------------------------- 10 files changed, 640 insertions(+), 651 deletions(-) create mode 100644 launcher/ui/pages/modplatform/CustomPage.cpp create mode 100644 launcher/ui/pages/modplatform/CustomPage.h create mode 100644 launcher/ui/pages/modplatform/CustomPage.ui delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.cpp delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.h delete mode 100644 launcher/ui/pages/modplatform/VanillaPage.ui (limited to 'launcher/ui') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9bad2a67..c10064c0 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -827,8 +827,8 @@ SET(LAUNCHER_SOURCES ui/pages/global/APIPage.h # GUI - platform pages - ui/pages/modplatform/VanillaPage.cpp - ui/pages/modplatform/VanillaPage.h + ui/pages/modplatform/CustomPage.cpp + ui/pages/modplatform/CustomPage.h ui/pages/modplatform/ResourcePage.cpp ui/pages/modplatform/ResourcePage.h @@ -1034,7 +1034,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/instance/ScreenshotsPage.ui ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui ui/pages/modplatform/atlauncher/AtlPage.ui - ui/pages/modplatform/VanillaPage.ui + ui/pages/modplatform/CustomPage.ui ui/pages/modplatform/ResourcePage.ui ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/legacy_ftb/Page.ui diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index aafaf220..7b9bb944 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -54,7 +54,7 @@ #include #include "ui/widgets/PageContainer.h" -#include "ui/pages/modplatform/VanillaPage.h" +#include "ui/pages/modplatform/CustomPage.h" #include "ui/pages/modplatform/atlauncher/AtlPage.h" #include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/flame/FlamePage.h" @@ -162,7 +162,7 @@ QList NewInstanceDialog::getPages() importPage = new ImportPage(this); - pages.append(new VanillaPage(this)); + pages.append(new CustomPage(this)); pages.append(importPage); pages.append(new AtlPage(this)); if (APPLICATION->capabilities() & Application::SupportsFlame) diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 74b7ec7c..59107c53 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -287,7 +287,6 @@ void VersionPage::updateButtons(int row) ui->actionAdd_Empty->setEnabled(controlsEnabled); ui->actionImport_Components->setEnabled(controlsEnabled); ui->actionReload->setEnabled(controlsEnabled); - ui->actionInstall_mods->setEnabled(controlsEnabled); ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled); ui->actionAdd_Agents->setEnabled(controlsEnabled); diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index 4777eafe..a73c42d6 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -102,7 +102,6 @@ - @@ -112,7 +111,6 @@ - @@ -204,14 +202,6 @@ Install the LiteLoader package. - - - Install mods - - - Install normal mods. - - Add to Minecraft.jar diff --git a/launcher/ui/pages/modplatform/CustomPage.cpp b/launcher/ui/pages/modplatform/CustomPage.cpp new file mode 100644 index 00000000..e164171a --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.cpp @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield + * + * 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 . + * + * 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 "CustomPage.h" +#include "ui_CustomPage.h" + +#include + +#include "Application.h" +#include "Filter.h" +#include "Version.h" +#include "meta/Index.h" +#include "meta/VersionList.h" +#include "minecraft/VanillaInstanceCreationTask.h" +#include "ui/dialogs/NewInstanceDialog.h" + +CustomPage::CustomPage(NewInstanceDialog *dialog, QWidget *parent) + : QWidget(parent), dialog(dialog), ui(new Ui::CustomPage) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedVersion); + filterChanged(); + connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->betaFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &CustomPage::filterChanged); + connect(ui->refreshBtn, &QPushButton::clicked, this, &CustomPage::refresh); + + connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &CustomPage::setSelectedLoaderVersion); + connect(ui->noneFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->forgeFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->fabricFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->quiltFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &CustomPage::loaderFilterChanged); + connect(ui->loaderRefreshBtn, &QPushButton::clicked, this, &CustomPage::loaderRefresh); + +} + +void CustomPage::openedImpl() +{ + if(!initialized) + { + auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); + ui->versionList->initialize(vlist.get()); + initialized = true; + } + else + { + suggestCurrent(); + } +} + +void CustomPage::refresh() +{ + ui->versionList->loadList(); +} + +void CustomPage::loaderRefresh() +{ + if(ui->noneFilter->isChecked()) + return; + ui->loaderVersionList->loadList(); +} + +void CustomPage::filterChanged() +{ + QStringList out; + if(ui->alphaFilter->isChecked()) + out << "(old_alpha)"; + if(ui->betaFilter->isChecked()) + out << "(old_beta)"; + if(ui->snapshotFilter->isChecked()) + out << "(snapshot)"; + if(ui->oldSnapshotFilter->isChecked()) + out << "(old_snapshot)"; + if(ui->releaseFilter->isChecked()) + out << "(release)"; + if(ui->experimentsFilter->isChecked()) + out << "(experiment)"; + auto regexp = out.join('|'); + ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); +} + +void CustomPage::loaderFilterChanged() +{ + QString minecraftVersion; + if (m_selectedVersion) + { + minecraftVersion = m_selectedVersion->descriptor(); + } + else + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list + ui->loaderVersionList->setEmptyString(tr("No Minecraft version is selected.")); + ui->loaderVersionList->setEmptyMode(VersionListView::String); + return; + } + 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(); + ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); +} + +CustomPage::~CustomPage() +{ + delete ui; +} + +bool CustomPage::shouldDisplay() const +{ + return true; +} + +void CustomPage::retranslate() +{ + ui->retranslateUi(this); +} + +BaseVersion::Ptr CustomPage::selectedVersion() const +{ + return m_selectedVersion; +} + +BaseVersion::Ptr CustomPage::selectedLoaderVersion() const +{ + return m_selectedLoaderVersion; +} + +QString CustomPage::selectedLoader() const +{ + return m_selectedLoader; +} + +void CustomPage::suggestCurrent() +{ + if (!isOpened) + { + return; + } + + if(!m_selectedVersion) + { + dialog->setSuggestedPack(); + return; + } + + // There isn't a selected version if the version list is empty + if(ui->loaderVersionList->selectedVersion() == nullptr) + dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion)); + else + { + dialog->setSuggestedPack(m_selectedVersion->descriptor(), + new VanillaCreationTask(m_selectedVersion, m_selectedLoader, + m_selectedLoaderVersion)); + } + dialog->setSuggestedIcon("default"); +} + +void CustomPage::setSelectedVersion(BaseVersion::Ptr version) +{ + m_selectedVersion = version; + suggestCurrent(); + loaderFilterChanged(); +} + +void CustomPage::setSelectedLoaderVersion(BaseVersion::Ptr version) +{ + m_selectedLoaderVersion = version; + suggestCurrent(); +} diff --git a/launcher/ui/pages/modplatform/CustomPage.h b/launcher/ui/pages/modplatform/CustomPage.h new file mode 100644 index 00000000..8b5a5011 --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.h @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield + * + * 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 . + * + * 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 + +#include "ui/pages/BasePage.h" +#include +#include "tasks/Task.h" + +namespace Ui +{ +class CustomPage; +} + +class NewInstanceDialog; + +class CustomPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit CustomPage(NewInstanceDialog *dialog, QWidget *parent = 0); + virtual ~CustomPage(); + virtual QString displayName() const override + { + return tr("Custom"); + } + virtual QIcon icon() const override + { + return APPLICATION->getThemedIcon("minecraft"); + } + virtual QString id() const override + { + return "vanilla"; + } + virtual QString helpPage() const override + { + return "Vanilla-platform"; + } + virtual bool shouldDisplay() const override; + void retranslate() override; + + void openedImpl() override; + + BaseVersion::Ptr selectedVersion() const; + BaseVersion::Ptr selectedLoaderVersion() const; + QString selectedLoader() const; + +public slots: + void setSelectedVersion(BaseVersion::Ptr version); + void setSelectedLoaderVersion(BaseVersion::Ptr version); + +private slots: + void filterChanged(); + void loaderFilterChanged(); + +private: + void refresh(); + void loaderRefresh(); + void suggestCurrent(); + +private: + bool initialized = false; + NewInstanceDialog *dialog = nullptr; + Ui::CustomPage *ui = nullptr; + bool m_versionSetByUser = false; + BaseVersion::Ptr m_selectedVersion; + BaseVersion::Ptr m_selectedLoaderVersion; + QString m_selectedLoader; +}; diff --git a/launcher/ui/pages/modplatform/CustomPage.ui b/launcher/ui/pages/modplatform/CustomPage.ui new file mode 100644 index 00000000..0d89b595 --- /dev/null +++ b/launcher/ui/pages/modplatform/CustomPage.ui @@ -0,0 +1,290 @@ + + + CustomPage + + + + 0 + 0 + 815 + 607 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + + + + + + Filter + + + Qt::AlignCenter + + + + + + + Releases + + + true + + + true + + + + + + + Snapshots + + + true + + + + + + + Old Snapshots + + + true + + + + + + + Betas + + + true + + + + + + + Alphas + + + true + + + + + + + Experiments + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Refresh + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + Mod Loader + + + Qt::AlignCenter + + + + + + + None + + + true + + + loaderBtnGroup + + + + + + + Forge + + + loaderBtnGroup + + + + + + + Fabric + + + loaderBtnGroup + + + + + + + Quilt + + + loaderBtnGroup + + + + + + + LiteLoader + + + loaderBtnGroup + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Refresh + + + + + + + + + + + + + + + + VersionSelectWidget + QWidget +
    ui/widgets/VersionSelectWidget.h
    + 1 +
    +
    + + tabWidget + releaseFilter + snapshotFilter + oldSnapshotFilter + betaFilter + alphaFilter + experimentsFilter + refreshBtn + + + + + + +
    diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp deleted file mode 100644 index 29fecb85..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 Jamie Mansfield - * - * 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 . - * - * 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 "VanillaPage.h" -#include "ui_VanillaPage.h" - -#include - -#include "Application.h" -#include "Filter.h" -#include "Version.h" -#include "meta/Index.h" -#include "meta/VersionList.h" -#include "minecraft/VanillaInstanceCreationTask.h" -#include "ui/dialogs/NewInstanceDialog.h" - -VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent) - : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage) -{ - ui->setupUi(this); - ui->tabWidget->tabBar()->hide(); - connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion); - filterChanged(); - connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged); - 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() -{ - if(!initialized) - { - auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); - ui->versionList->initialize(vlist.get()); - initialized = true; - } - else - { - suggestCurrent(); - } -} - -void VanillaPage::refresh() -{ - ui->versionList->loadList(); -} - -void VanillaPage::loaderRefresh() -{ - if(ui->noneFilter->isChecked()) - return; - ui->loaderVersionList->loadList(); -} - -void VanillaPage::filterChanged() -{ - QStringList out; - if(ui->alphaFilter->isChecked()) - out << "(old_alpha)"; - if(ui->betaFilter->isChecked()) - out << "(old_beta)"; - if(ui->snapshotFilter->isChecked()) - out << "(snapshot)"; - if(ui->oldSnapshotFilter->isChecked()) - out << "(old_snapshot)"; - if(ui->releaseFilter->isChecked()) - out << "(release)"; - if(ui->experimentsFilter->isChecked()) - out << "(experiment)"; - auto regexp = out.join('|'); - ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); -} - -void VanillaPage::loaderFilterChanged() -{ - QString minecraftVersion; - if (m_selectedVersion) - { - minecraftVersion = m_selectedVersion->descriptor(); - } - else - { - ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, "AAA"); // empty list - ui->loaderVersionList->setEmptyString(tr("No Minecraft version is selected.")); - ui->loaderVersionList->setEmptyMode(VersionListView::String); - return; - } - 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(); - ui->loaderVersionList->setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); -} - -VanillaPage::~VanillaPage() -{ - delete ui; -} - -bool VanillaPage::shouldDisplay() const -{ - return true; -} - -void VanillaPage::retranslate() -{ - ui->retranslateUi(this); -} - -BaseVersion::Ptr VanillaPage::selectedVersion() const -{ - return m_selectedVersion; -} - -BaseVersion::Ptr VanillaPage::selectedLoaderVersion() const -{ - return m_selectedLoaderVersion; -} - -QString VanillaPage::selectedLoader() const -{ - return m_selectedLoader; -} - -void VanillaPage::suggestCurrent() -{ - if (!isOpened) - { - return; - } - - if(!m_selectedVersion) - { - dialog->setSuggestedPack(); - return; - } - - // There isn't a selected version if the version list is empty - if(ui->loaderVersionList->selectedVersion() == nullptr) - dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion)); - else - { - dialog->setSuggestedPack(m_selectedVersion->descriptor(), - new VanillaCreationTask(m_selectedVersion, m_selectedLoader, - m_selectedLoaderVersion)); - } - dialog->setSuggestedIcon("default"); -} - -void VanillaPage::setSelectedVersion(BaseVersion::Ptr version) -{ - m_selectedVersion = version; - suggestCurrent(); - loaderFilterChanged(); -} - -void VanillaPage::setSelectedLoaderVersion(BaseVersion::Ptr version) -{ - m_selectedLoaderVersion = version; - suggestCurrent(); -} diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h deleted file mode 100644 index 39aba760..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.h +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * PolyMC - Minecraft Launcher - * Copyright (c) 2022 Jamie Mansfield - * - * 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 . - * - * 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 - -#include "ui/pages/BasePage.h" -#include -#include "tasks/Task.h" - -namespace Ui -{ -class VanillaPage; -} - -class NewInstanceDialog; - -class VanillaPage : public QWidget, public BasePage -{ - Q_OBJECT - -public: - explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0); - virtual ~VanillaPage(); - virtual QString displayName() const override - { - return tr("Vanilla"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("minecraft"); - } - virtual QString id() const override - { - return "vanilla"; - } - virtual QString helpPage() const override - { - return "Vanilla-platform"; - } - virtual bool shouldDisplay() const override; - void retranslate() override; - - void openedImpl() override; - - BaseVersion::Ptr selectedVersion() const; - BaseVersion::Ptr selectedLoaderVersion() const; - QString selectedLoader() const; - -public slots: - void setSelectedVersion(BaseVersion::Ptr version); - void setSelectedLoaderVersion(BaseVersion::Ptr version); - -private slots: - void filterChanged(); - void loaderFilterChanged(); - -private: - void refresh(); - void loaderRefresh(); - void suggestCurrent(); - -private: - bool initialized = false; - NewInstanceDialog *dialog = nullptr; - Ui::VanillaPage *ui = nullptr; - bool m_versionSetByUser = false; - BaseVersion::Ptr m_selectedVersion; - BaseVersion::Ptr m_selectedLoaderVersion; - QString m_selectedLoader; -}; diff --git a/launcher/ui/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/VanillaPage.ui deleted file mode 100644 index 43110927..00000000 --- a/launcher/ui/pages/modplatform/VanillaPage.ui +++ /dev/null @@ -1,290 +0,0 @@ - - - VanillaPage - - - - 0 - 0 - 815 - 607 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - - - - - - - Filter - - - Qt::AlignCenter - - - - - - - Releases - - - true - - - true - - - - - - - Snapshots - - - true - - - - - - - Old Snapshots - - - true - - - - - - - Betas - - - true - - - - - - - Alphas - - - true - - - - - - - Experiments - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Refresh - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - Mod Loader - - - Qt::AlignCenter - - - - - - - None - - - true - - - loaderBtnGroup - - - - - - - Forge - - - loaderBtnGroup - - - - - - - Fabric - - - loaderBtnGroup - - - - - - - Quilt - - - loaderBtnGroup - - - - - - - LiteLoader - - - loaderBtnGroup - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Refresh - - - - - - - - - - - - - - - - VersionSelectWidget - QWidget -
    ui/widgets/VersionSelectWidget.h
    - 1 -
    -
    - - tabWidget - releaseFilter - snapshotFilter - oldSnapshotFilter - betaFilter - alphaFilter - experimentsFilter - refreshBtn - - - - - - -
    -- cgit From 8a3aba1634ca9f8b86c995687c7e2f99740d9111 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:30:51 +0100 Subject: Fix Open Global Settings, why not Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 08977841..893fe2a5 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -86,11 +86,11 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) APPLICATION->ShowGlobalSettings(this, "java-settings"); return; case 1: - APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); - return; - case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; + default: + APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); + return; } } -- cgit From 5eb71fc6a96690e3d9a658f383b0937446ec3f9e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 24 Jun 2023 23:34:37 +0100 Subject: Revert "feat(Mods): hide 'Provider' column when no mods have providers" With Ryex's change, this causes issues. Apparently you need to sign off reverts! That's just weird... Signed-off-by: TheKodeToad --- launcher/ui/widgets/ModListView.cpp | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index 893cd120..80a918b6 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -14,9 +14,6 @@ */ #include "ModListView.h" - -#include "minecraft/mod/ModFolderModel.h" - #include #include #include @@ -65,19 +62,6 @@ void ModListView::setModel ( QAbstractItemModel* model ) for(int i = 1; i < head->count(); i++) head->setSectionResizeMode(i, QHeaderView::ResizeToContents); } - - auto real_model = model; - if (auto proxy_model = dynamic_cast(model); proxy_model) - real_model = proxy_model->sourceModel(); - - if (auto mod_model = dynamic_cast(real_model); mod_model) { - connect(mod_model, &ModFolderModel::updateFinished, this, [this, mod_model]{ - auto mods = mod_model->allMods(); - // Hide the 'Provider' column if no mod has a defined provider! - setColumnHidden(ModFolderModel::Columns::ProviderColumn, - std::none_of(mods.constBegin(), mods.constEnd(), [](auto const mod){ return mod->provider().has_value(); })); - }); - } } void ModListView::setResizeModes(const QList &modes) -- cgit From ce4a86fbcd0c891472b842e76066d285de3aef7b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 10:41:29 +0300 Subject: Made custom url function Signed-off-by: Trial97 --- launcher/minecraft/mod/Mod.cpp | 7 +++++++ launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 8 +++++++- launcher/modplatform/ModIndex.h | 1 + launcher/ui/pages/instance/ModFolderPage.cpp | 18 +++++------------- launcher/ui/widgets/InfoFrame.cpp | 21 +++------------------ 6 files changed, 24 insertions(+), 32 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb..d5b96bad 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4..d6272f4d 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf..a1c4d891 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,17 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + if (!hash.addData(device)) qCritical() << "Failed to read JAR to create hash!"; Q_ASSERT(hash.result().length() == hash.hashLength(algo)); return { hash.result().toHex() }; } +QString getMetaURL(ResourceProvider provider, QVariant projectID) +{ + return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/projects/" : "https://modrinth.com/mod/") + + projectID.toString(); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 3b0a03a1..3f51e700 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -144,6 +144,7 @@ inline auto getOverrideDeps() -> QList { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH }, { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } }; }; +QString getMetaURL(ResourceProvider provider, QVariant projectID); } // namespace ModPlatform diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 9722d483..1d31a292 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -298,17 +298,9 @@ bool NilModFolderPage::shouldDisplay() const void ModFolderPage::visitModPages() { auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); - for (auto mod : m_model->selectedMods(selection)) - if (auto meta = mod->metadata(); meta != nullptr) { - auto slug = meta->slug.remove(".pw.toml"); - switch (meta->provider) { - case ModPlatform::ResourceProvider::MODRINTH: - DesktopServices::openUrl(QString("https://modrinth.com/mod/%1").arg(slug)); - break; - case ModPlatform::ResourceProvider::FLAME: - DesktopServices::openUrl(QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug)); - break; - } - } else if (mod->homeurl().size() != 0) - DesktopServices::openUrl(mod->homeurl()); + for (auto mod : m_model->selectedMods(selection)) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + DesktopServices::openUrl(url); + } } \ No newline at end of file diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 52e79dc0..57562a93 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -41,9 +41,7 @@ #include "ui/dialogs/CustomMessageBox.h" -InfoFrame::InfoFrame(QWidget *parent) : - QFrame(parent), - ui(new Ui::InfoFrame) +InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) { ui->setupUi(this); ui->descriptionLabel->setHidden(true); @@ -67,31 +65,18 @@ void InfoFrame::updateWithMod(Mod const& m) QString text = ""; QString name = ""; - QString link = ""; + QString link = m.metaurl(); QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else name = m.name(); - if (auto meta = m.metadata(); meta != nullptr) { - auto slug = meta->slug.remove(".pw.toml"); - switch (meta->provider) { - case ModPlatform::ResourceProvider::MODRINTH: - link = QString("https://modrinth.com/mod/%1").arg(slug); - break; - case ModPlatform::ResourceProvider::FLAME: - link = QString("https://www.curseforge.com/minecraft/mc-mods/%1").arg(slug); - break; - } - } else if (!m.homeurl().isEmpty()) - link = m.homeurl(); - if (link.isEmpty()) text = name; else { text = "
    " + name + ""; - toolTip = tr("Go to mod's home page"); + toolTip = link; } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); -- cgit From 40fbae8ff684b6613ff073ec1992587b38dcdf8c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 11:36:37 +0300 Subject: Fixed links tooltip Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 36 +++++++++++++++++++++++------------- launcher/ui/widgets/InfoFrame.h | 2 +- 2 files changed, 24 insertions(+), 14 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 57562a93..24349014 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -34,13 +34,24 @@ * limitations under the License. */ +#include #include +#include #include "InfoFrame.h" #include "ui_InfoFrame.h" #include "ui/dialogs/CustomMessageBox.h" +void setupLinkTooTip(QLabel* label) +{ + QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { + if (!link.isEmpty() && !link.startsWith("http")) + return; + label->setToolTip(link); + }); +} + InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) { ui->setupUi(this); @@ -48,6 +59,12 @@ InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) ui->nameLabel->setHidden(true); ui->licenseLabel->setHidden(true); ui->issueTrackerLabel->setHidden(true); + + setupLinkTooTip(ui->iconLabel); + setupLinkTooTip(ui->descriptionLabel); + setupLinkTooTip(ui->nameLabel); + setupLinkTooTip(ui->licenseLabel); + setupLinkTooTip(ui->issueTrackerLabel); updateHiddenState(); } @@ -66,7 +83,6 @@ void InfoFrame::updateWithMod(Mod const& m) QString text = ""; QString name = ""; QString link = m.metaurl(); - QString toolTip = ""; if (m.name().isEmpty()) name = m.internal_id(); else @@ -76,12 +92,11 @@ void InfoFrame::updateWithMod(Mod const& m) text = name; else { text = "" + name + ""; - toolTip = link; } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); - setName(text, toolTip); + setName(text); if (m.description().isEmpty()) { setDescription(QString()); @@ -89,14 +104,14 @@ void InfoFrame::updateWithMod(Mod const& m) setDescription(m.description()); } - setImage(m.icon({64,64})); + setImage(m.icon({ 64, 64 })); auto licenses = m.licenses(); QString licenseText = ""; if (!licenses.empty()) { for (auto l : licenses) { if (!licenseText.isEmpty()) { - licenseText += "\n"; // add newline between licenses + licenseText += "\n"; // add newline between licenses } if (!l.name.isEmpty()) { if (l.url.isEmpty()) { @@ -226,29 +241,24 @@ void InfoFrame::updateHiddenState() } } -void InfoFrame::setName(QString text, QString toolTip) +void InfoFrame::setName(QString text) { if (text.isEmpty()) { ui->nameLabel->setHidden(true); - ui->nameLabel->setToolTip({}); } else { ui->nameLabel->setText(text); ui->nameLabel->setHidden(false); - ui->nameLabel->setToolTip(toolTip); } updateHiddenState(); } void InfoFrame::setDescription(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->descriptionLabel->setHidden(true); updateHiddenState(); return; - } - else - { + } else { ui->descriptionLabel->setHidden(false); updateHiddenState(); } diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index b8c7e9a0..d6764baa 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -52,7 +52,7 @@ class InfoFrame : public QFrame { InfoFrame(QWidget* parent = nullptr); ~InfoFrame() override; - void setName(QString text = {}, QString toolTip = {}); + void setName(QString text = {}); void setDescription(QString text = {}); void setImage(QPixmap img = {}); void setLicense(QString text = {}); -- cgit From fd5b155ee7d796015c84c8b348f384bf21d8328d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 12:24:59 +0300 Subject: Added error message when exporting snapshots with curseforge Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 18 +++++++++++------- launcher/ui/MainWindow.cpp | 9 ++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index e73f3de5..e5eeb098 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -409,16 +409,20 @@ QByteArray FlamePackExportTask::generateIndex() // convert all available components to mrpack dependencies if (minecraft != nullptr) version["version"] = minecraft->m_version; - - QJsonObject loader; + QString id; if (quilt != nullptr) - loader["id"] = "quilt-" + quilt->getVersion(); + id = "quilt-" + quilt->getVersion(); else if (fabric != nullptr) - loader["id"] = "fabric-" + fabric->getVersion(); + id = "fabric-" + fabric->getVersion(); else if (forge != nullptr) - loader["id"] = "forge-" + forge->getVersion(); - loader["primary"] = true; - version["modLoaders"] = QJsonArray({ loader }); + id = "forge-" + forge->getVersion(); + version["modLoaders"] = QJsonArray(); + if (!id.isEmpty()) { + QJsonObject loader; + loader["id"] = id; + loader["primary"] = true; + version["modLoaders"] = QJsonArray({ loader }); + } obj["minecraft"] = version; } diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 91809c7b..50eb9e64 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1422,9 +1422,16 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() if (m_selectedInstance) { auto instance = dynamic_cast(m_selectedInstance.get()); if (instance) { + QString errorMsg; if (instance->getPackProfile()->getComponent("org.quiltmc.quilt-loader")) { + errorMsg = tr("Quilt is currently not supported by CurseForge modpacks."); + } else if (auto cmp = instance->getPackProfile()->getComponent("net.minecraft"); + cmp && cmp->getVersionFile() && cmp->getVersionFile()->type == "snapshot") { + errorMsg = tr("Snapshots are currently not supported by CurseForge modpacks."); + } + if (!errorMsg.isEmpty()) { QMessageBox msgBox; - msgBox.setText(tr("Quilt is currently not supported by CurseForge modpacks.")); + msgBox.setText(errorMsg); msgBox.exec(); return; } -- cgit From 603ed220151345f44a43e14538ea449bae843958 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 10:36:54 +0100 Subject: Replace accidental usages of QAbstractButton::pressed This signal is not usually what you want, and creates an inconsistent experience. Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ManagedPackPage.cpp | 4 ++-- launcher/ui/pages/modplatform/legacy_ftb/Page.cpp | 4 ++-- launcher/ui/setupwizard/SetupWizard.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index e0a7314f..d89c5bfc 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -205,7 +205,7 @@ ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWin { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &ModrinthManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &ModrinthManagedPackPage::update); } // MODRINTH @@ -332,7 +332,7 @@ FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* i { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); - connect(ui->updateButton, &QPushButton::pressed, this, &FlameManagedPackPage::update); + connect(ui->updateButton, &QPushButton::clicked, this, &FlameManagedPackPage::update); } void FlameManagedPackPage::parseManagedPack() diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index 98ab8799..b3f6261f 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -116,8 +116,8 @@ Page::Page(NewInstanceDialog* dialog, QWidget *parent) connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onThirdPartyPackSelectionChanged); connect(ui->privatePackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onPrivatePackSelectionChanged); - connect(ui->addPackBtn, &QPushButton::pressed, this, &Page::onAddPackClicked); - connect(ui->removePackBtn, &QPushButton::pressed, this, &Page::onRemovePackClicked); + connect(ui->addPackBtn, &QPushButton::clicked, this, &Page::onAddPackClicked); + connect(ui->removePackBtn, &QPushButton::clicked, this, &Page::onRemovePackClicked); connect(ui->tabWidget, &QTabWidget::currentChanged, this, &Page::onTabChanged); diff --git a/launcher/ui/setupwizard/SetupWizard.cpp b/launcher/ui/setupwizard/SetupWizard.cpp index 3fd9bb23..0a47334f 100644 --- a/launcher/ui/setupwizard/SetupWizard.cpp +++ b/launcher/ui/setupwizard/SetupWizard.cpp @@ -59,7 +59,7 @@ void SetupWizard::pageChanged(int id) { setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton}); auto customButton = button(QWizard::CustomButton1); - connect(customButton, &QAbstractButton::pressed, [&](){ + connect(customButton, &QAbstractButton::clicked, [&](){ auto basePagePtr = getCurrentBasePage(); if(basePagePtr) { -- cgit From 84c63f4f017324b42c2470fb2e7a1ac5858fcaa0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 14:11:41 +0300 Subject: Added plantxt export Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 10 +- launcher/minecraft/mod/Mod.cpp | 7 + launcher/minecraft/mod/Mod.h | 1 + launcher/modplatform/ModIndex.cpp | 8 +- launcher/modplatform/ModIndex.h | 1 + .../modplatform/helpers/ExportModsToStringTask.cpp | 114 ------------ .../modplatform/helpers/ExportModsToStringTask.h | 33 ---- launcher/modplatform/helpers/ExportToModList.cpp | 122 +++++++++++++ launcher/modplatform/helpers/ExportToModList.h | 33 ++++ launcher/ui/MainWindow.cpp | 8 +- launcher/ui/MainWindow.h | 2 +- launcher/ui/MainWindow.ui | 4 +- launcher/ui/dialogs/ExportModsToStringDialog.cpp | 122 ------------- launcher/ui/dialogs/ExportModsToStringDialog.h | 46 ----- launcher/ui/dialogs/ExportModsToStringDialog.ui | 171 ------------------ launcher/ui/dialogs/ExportToModListDialog.cpp | 171 ++++++++++++++++++ launcher/ui/dialogs/ExportToModListDialog.h | 52 ++++++ launcher/ui/dialogs/ExportToModListDialog.ui | 199 +++++++++++++++++++++ 18 files changed, 605 insertions(+), 499 deletions(-) delete mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.cpp delete mode 100644 launcher/modplatform/helpers/ExportModsToStringTask.h create mode 100644 launcher/modplatform/helpers/ExportToModList.cpp create mode 100644 launcher/modplatform/helpers/ExportToModList.h delete mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.cpp delete mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.h delete mode 100644 launcher/ui/dialogs/ExportModsToStringDialog.ui create mode 100644 launcher/ui/dialogs/ExportToModListDialog.cpp create mode 100644 launcher/ui/dialogs/ExportToModListDialog.h create mode 100644 launcher/ui/dialogs/ExportToModListDialog.ui (limited to 'launcher/ui') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index aab7e90d..a4e82576 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -490,8 +490,8 @@ set(API_SOURCES modplatform/helpers/OverrideUtils.h modplatform/helpers/OverrideUtils.cpp - modplatform/helpers/ExportModsToStringTask.h - modplatform/helpers/ExportModsToStringTask.cpp + modplatform/helpers/ExportToModList.h + modplatform/helpers/ExportToModList.cpp ) set(FTB_SOURCES @@ -913,8 +913,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/ExportInstanceDialog.h ui/dialogs/ExportMrPackDialog.cpp ui/dialogs/ExportMrPackDialog.h - ui/dialogs/ExportModsToStringDialog.cpp - ui/dialogs/ExportModsToStringDialog.h + ui/dialogs/ExportToModListDialog.cpp + ui/dialogs/ExportToModListDialog.h ui/dialogs/IconPickerDialog.cpp ui/dialogs/IconPickerDialog.h ui/dialogs/ImportResourceDialog.cpp @@ -1062,7 +1062,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/SkinUploadDialog.ui ui/dialogs/ExportInstanceDialog.ui ui/dialogs/ExportMrPackDialog.ui - ui/dialogs/ExportModsToStringDialog.ui + ui/dialogs/ExportToModListDialog.ui ui/dialogs/IconPickerDialog.ui ui/dialogs/ImportResourceDialog.ui ui/dialogs/MSALoginDialog.ui diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index e613ddeb..d5b96bad 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -166,6 +166,13 @@ auto Mod::homeurl() const -> QString return details().homeurl; } +auto Mod::metaurl() const -> QString +{ + if (metadata() == nullptr) + return homeurl(); + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); +} + auto Mod::description() const -> QString { return details().description; diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index d4e419f4..d6272f4d 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -70,6 +70,7 @@ public: auto provider() const -> std::optional; auto licenses() const -> const QList&; auto issueTracker() const -> QString; + auto metaurl() const -> QString; /** Get the intneral path to the mod's icon file*/ QString iconPath() const { return m_local_details.icon_file; }; diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 6a507caf..a1c4d891 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -70,11 +70,17 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t } QCryptographicHash hash(algo); - if(!hash.addData(device)) + if (!hash.addData(device)) qCritical() << "Failed to read JAR to create hash!"; Q_ASSERT(hash.result().length() == hash.hashLength(algo)); return { hash.result().toHex() }; } +QString getMetaURL(ResourceProvider provider, QVariant projectID) +{ + return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/projects/" : "https://modrinth.com/mod/") + + projectID.toString(); +} + } // namespace ModPlatform diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index 3b0a03a1..3f51e700 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -144,6 +144,7 @@ inline auto getOverrideDeps() -> QList { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH }, { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } }; }; +QString getMetaURL(ResourceProvider provider, QVariant projectID); } // namespace ModPlatform diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.cpp b/launcher/modplatform/helpers/ExportModsToStringTask.cpp deleted file mode 100644 index e7be5ce1..00000000 --- a/launcher/modplatform/helpers/ExportModsToStringTask.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 . - */ -#include "ExportModsToStringTask.h" -#include "modplatform/ModIndex.h" - -namespace ExportToString { -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData) -{ - switch (format) { - case HTML: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } - if (!url.isEmpty()) - modName = QString("%2").arg(url, modName); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines.append(QString("
      %1
    ").arg(line)); - } - return QString("\n\t%1\n").arg(lines.join("\n\t")); - } - case MARKDOWN: { - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - if (extraData & Url) { - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } - if (!url.isEmpty()) - modName = QString("[%1](%2)").arg(modName, url); - } - auto line = modName; - if (extraData & Version) { - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); - } - if (extraData & Authors && !mod->authors().isEmpty()) - line += " by " + mod->authors().join(", "); - lines << line; - } - return lines.join("\n"); - } - default: { - return QString("unknown format:%1").arg(format); - } - } -} - -QString ExportModsToStringTask(QList mods, QString lineTemplate) -{ - QStringList lines; - for (auto mod : mods) { - auto meta = mod->metadata(); - auto modName = mod->name(); - - auto url = mod->homeurl(); - if (meta != nullptr) { - url = (meta->provider == ModPlatform::ResourceProvider::FLAME ? "https://www.curseforge.com/minecraft/mc-mods/" - : "https://modrinth.com/mod/") + - meta->slug.remove(".pw.toml"); - } - auto ver = mod->version(); - if (ver.isEmpty() && meta != nullptr) - ver = meta->version().toString(); - auto authors = mod->authors().join(", "); - lines << QString(lineTemplate) - .replace("{name}", modName) - .replace("{url}", url) - .replace("{version}", ver) - .replace("{authors}", authors); - } - return lines.join("\n"); -} -} // namespace ExportToString \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportModsToStringTask.h b/launcher/modplatform/helpers/ExportModsToStringTask.h deleted file mode 100644 index 756c69f7..00000000 --- a/launcher/modplatform/helpers/ExportModsToStringTask.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 . - */ -#pragma once -#include -#include -#include "minecraft/mod/Mod.h" - -namespace ExportToString { - -enum Formats { HTML, MARKDOWN }; -enum OptionalData { - Authors = 1 << 0, - Url = 1 << 1, - Version = 1 << 2, -}; -QString ExportModsToStringTask(QList mods, Formats format, OptionalData extraData); -QString ExportModsToStringTask(QList mods, QString lineTemplate); -} // namespace ExportToString diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp new file mode 100644 index 00000000..5e01367f --- /dev/null +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ +#include "ExportToModList.h" + +namespace ExportToModList { +QString ExportToModList(QList mods, Formats format, OptionalData extraData) +{ + switch (format) { + case HTML: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + modName = QString("%2").arg(url, modName); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines.append(QString("
      %1
    ").arg(line)); + } + return QString("
  • \n\t%1\n
  • ").arg(lines.join("\n\t")); + } + case MARKDOWN: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + modName = QString("[%1](%2)").arg(modName, url); + } + auto line = modName; + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += QString("[%1]").arg(ver); + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " by " + mod->authors().join(", "); + lines << "- " + line; + } + return lines.join("\n"); + } + case PLAINTXT: { + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + + auto line = "name: " + modName + ";"; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line += " url: " + url + ";"; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line += " version: " + QString("[%1]").arg(ver) + ";"; + } + if (extraData & Authors && !mod->authors().isEmpty()) + line += " authors " + mod->authors().join(", ") + ";"; + lines << line; + } + return lines.join("\n"); + } + default: { + return QString("unknown format:%1").arg(format); + } + } +} + +QString ExportToModList(QList mods, QString lineTemplate) +{ + QStringList lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + auto url = mod->metaurl(); + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + auto authors = mod->authors().join(", "); + lines << QString(lineTemplate) + .replace("{name}", modName) + .replace("{url}", url) + .replace("{version}", ver) + .replace("{authors}", authors); + } + return lines.join("\n"); +} +} // namespace ExportToModList \ No newline at end of file diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h new file mode 100644 index 00000000..9ff8d25a --- /dev/null +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ +#pragma once +#include +#include +#include "minecraft/mod/Mod.h" + +namespace ExportToModList { + +enum Formats { HTML, MARKDOWN, PLAINTXT, CUSTOM }; +enum OptionalData { + Authors = 1 << 0, + Url = 1 << 1, + Version = 1 << 2, +}; +QString ExportToModList(QList mods, Formats format, OptionalData extraData); +QString ExportToModList(QList mods, QString lineTemplate); +} // namespace ExportToModList diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 02ea30c3..37f4d4ed 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,7 +43,7 @@ #include "FileSystem.h" #include "MainWindow.h" -#include "ui/dialogs/ExportModsToStringDialog.h" +#include "ui/dialogs/ExportToModListDialog.h" #include "ui_MainWindow.h" #include @@ -206,7 +206,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi auto exportInstanceMenu = new QMenu(this); exportInstanceMenu->addAction(ui->actionExportInstanceZip); exportInstanceMenu->addAction(ui->actionExportInstanceMrPack); - exportInstanceMenu->addAction(ui->actionExportInstanceToString); + exportInstanceMenu->addAction(ui->actionExportInstanceToModList); ui->actionExportInstance->setMenu(exportInstanceMenu); } @@ -1418,10 +1418,10 @@ void MainWindow::on_actionExportInstanceMrPack_triggered() } } -void MainWindow::on_actionExportInstanceToString_triggered() +void MainWindow::on_actionExportInstanceToModList_triggered() { if (m_selectedInstance) { - ExportModsToStringDialog dlg(m_selectedInstance, this); + ExportToModListDialog dlg(m_selectedInstance, this); dlg.exec(); } } diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 9b38810f..f62e39e1 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -157,7 +157,7 @@ private slots: inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); } void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceMrPack_triggered(); - void on_actionExportInstanceToString_triggered(); + void on_actionExportInstanceToModList_triggered(); void on_actionRenameInstance_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index ecc7e236..027742ba 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -479,12 +479,12 @@ Modrinth (mrpack)
    - + - Text + ModList (txt) diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.cpp b/launcher/ui/dialogs/ExportModsToStringDialog.cpp deleted file mode 100644 index 29d69918..00000000 --- a/launcher/ui/dialogs/ExportModsToStringDialog.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 . - */ - -#include "ExportModsToStringDialog.h" -#include -#include -#include -#include "minecraft/MinecraftInstance.h" -#include "minecraft/mod/ModFolderModel.h" -#include "modplatform/helpers/ExportModsToStringTask.h" -#include "ui_ExportModsToStringDialog.h" - -#include -#include -#include -#include -#include - -ExportModsToStringDialog::ExportModsToStringDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), m_template_selected(false), ui(new Ui::ExportModsToStringDialog) -{ - ui->setupUi(this); - ui->templateGroup->setDisabled(true); - - MinecraftInstance* mcInstance = dynamic_cast(instance.get()); - if (mcInstance) { - mcInstance->loaderModList()->update(); - connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { - m_allMods = mcInstance->loaderModList()->allMods(); - triggerImp(); - }); - } - - connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportModsToStringDialog::formatChanged); - connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportModsToStringDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportModsToStringDialog::triggerImp); - connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { - this->ui->finalText->selectAll(); - this->ui->finalText->copy(); - }); -} - -ExportModsToStringDialog::~ExportModsToStringDialog() -{ - delete ui; -} - -void ExportModsToStringDialog::formatChanged(int index) -{ - switch (index) { - case 0: { - ui->templateGroup->setDisabled(true); - ui->optionsGroup->setDisabled(false); - break; - } - case 1: { - ui->templateGroup->setDisabled(true); - ui->optionsGroup->setDisabled(false); - break; - } - case 2: { - ui->templateGroup->setDisabled(false); - ui->optionsGroup->setDisabled(true); - break; - } - } - triggerImp(); -} - -void ExportModsToStringDialog::triggerImp() -{ - auto format = ExportToString::HTML; - switch (ui->formatComboBox->currentIndex()) { - case 2: { - m_template_selected = true; - ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, ui->templateText->toPlainText())); - return; - } - case 0: { - format = ExportToString::HTML; - break; - } - case 1: { - format = ExportToString::MARKDOWN; - break; - } - default: { - return; - } - } - auto opt = 0; - if (ui->authorsCheckBox->isChecked()) - opt |= ExportToString::Authors; - if (ui->versionCheckBox->isChecked()) - opt |= ExportToString::Version; - if (ui->urlCheckBox->isChecked()) - opt |= ExportToString::Url; - ui->finalText->setPlainText(ExportToString::ExportModsToStringTask(m_allMods, format, static_cast(opt))); - if (!m_template_selected) { - auto exampleLine = format == ExportToString::HTML ? "
      {name}[{version}] by {authors}
    " - : "[{name}]({url})[{version}] by {authors}"; - if (ui->templateText->toPlainText() != exampleLine) - ui->templateText->setPlainText(exampleLine); - } -} diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.h b/launcher/ui/dialogs/ExportModsToStringDialog.h deleted file mode 100644 index d195d1ce..00000000 --- a/launcher/ui/dialogs/ExportModsToStringDialog.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -/* - * Prism Launcher - Minecraft Launcher - * Copyright (c) 2023 Trial97 - * - * 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 . - */ - -#pragma once - -#include -#include -#include "BaseInstance.h" -#include "minecraft/mod/Mod.h" - -namespace Ui { -class ExportModsToStringDialog; -} - -class ExportModsToStringDialog : public QDialog { - Q_OBJECT - - public: - explicit ExportModsToStringDialog(InstancePtr instance, QWidget* parent = nullptr); - ~ExportModsToStringDialog(); - - protected slots: - void formatChanged(int index); - void triggerImp(); - void trigger(int) { triggerImp(); }; - - private: - QList m_allMods; - bool m_template_selected; - Ui::ExportModsToStringDialog* ui; -}; diff --git a/launcher/ui/dialogs/ExportModsToStringDialog.ui b/launcher/ui/dialogs/ExportModsToStringDialog.ui deleted file mode 100644 index 4451a278..00000000 --- a/launcher/ui/dialogs/ExportModsToStringDialog.ui +++ /dev/null @@ -1,171 +0,0 @@ - - - ExportModsToStringDialog - - - - 0 - 0 - 650 - 446 - - - - Export Modrinth Pack - - - true - - - - - - - - Settings - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - Format - - - - - - - - HTML - - - - - Markdown - - - - - Custom - - - - - - - - Template - - - - - - - - - - - - Optional Info - - - - - - Version - - - - - - - Authors - - - - - - - URL - - - - - - - - - - - - - Result - - - - - - - 0 - 143 - - - - true - - - - - - - - - - - - - - Copy - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - ExportModsToStringDialog - accept() - - - 334 - 435 - - - 324 - 206 - - - - - diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp new file mode 100644 index 00000000..0550725f --- /dev/null +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#include "ExportToModListDialog.h" +#include +#include +#include +#include "FileSystem.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/mod/ModFolderModel.h" +#include "modplatform/helpers/ExportToModList.h" +#include "ui_ExportToModListDialog.h" + +#include +#include +#include +#include +#include + +ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* parent) + : QDialog(parent), m_template_selected(false), name(instance->name()), ui(new Ui::ExportToModListDialog) +{ + ui->setupUi(this); + ui->templateGroup->setDisabled(true); + + MinecraftInstance* mcInstance = dynamic_cast(instance.get()); + if (mcInstance) { + mcInstance->loaderModList()->update(); + connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() { + m_allMods = mcInstance->loaderModList()->allMods(); + triggerImp(); + }); + } + + connect(ui->formatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ExportToModListDialog::formatChanged); + connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->templateText, &QTextEdit::textChanged, this, &ExportToModListDialog::triggerImp); + connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { + this->ui->finalText->selectAll(); + this->ui->finalText->copy(); + }); +} + +ExportToModListDialog::~ExportToModListDialog() +{ + delete ui; +} + +void ExportToModListDialog::formatChanged(int index) +{ + switch (index) { + case 0: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->show(); + format = ExportToModList::HTML; + break; + } + case 1: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->show(); + format = ExportToModList::MARKDOWN; + break; + } + case 2: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::PLAINTXT; + break; + } + case 3: { + ui->templateGroup->setDisabled(false); + ui->optionsGroup->setDisabled(true); + ui->resultText->hide(); + format = ExportToModList::CUSTOM; + break; + } + } + triggerImp(); +} + +void ExportToModListDialog::triggerImp() +{ + if (format == ExportToModList::CUSTOM) { + m_template_selected = true; + ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); + return; + } + auto opt = 0; + if (ui->authorsCheckBox->isChecked()) + opt |= ExportToModList::Authors; + if (ui->versionCheckBox->isChecked()) + opt |= ExportToModList::Version; + if (ui->urlCheckBox->isChecked()) + opt |= ExportToModList::Url; + auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); + ui->finalText->setPlainText(txt); + QString exampleLine; + switch (format) { + case ExportToModList::HTML: { + exampleLine = "
      {name}[{version}] by {authors}
    "; + ui->resultText->setHtml(txt); + break; + } + case ExportToModList::MARKDOWN: { + exampleLine = "[{name}]({url})[{version}] by {authors}"; + ui->resultText->setMarkdown(txt); + break; + } + case ExportToModList::PLAINTXT: { + exampleLine = "name: {name}; url: {url}; version: {version}; authors: {authors};"; + break; + } + case ExportToModList::CUSTOM: + return; + } + if (!m_template_selected) { + if (ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); + } +} + +void ExportToModListDialog::done(int result) +{ + if (result == Accepted) { + const QString filename = FS::RemoveInvalidFilenameChars(name); + const QString output = + QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + extension()), + "File (*.txt *.html *.md)", nullptr); + + if (output.isEmpty()) + return; + FS::write(output, ui->finalText->toPlainText().toUtf8()); + } + + QDialog::done(result); +} + +QString ExportToModListDialog::extension() +{ + switch (format) { + case ExportToModList::HTML: + return ".html"; + case ExportToModList::MARKDOWN: + return ".md"; + case ExportToModList::PLAINTXT: + return ".txt"; + case ExportToModList::CUSTOM: + return ".txt"; + } + return ".txt"; +} diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h new file mode 100644 index 00000000..a7a6bcdc --- /dev/null +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 + * + * 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 . + */ + +#pragma once + +#include +#include +#include "BaseInstance.h" +#include "minecraft/mod/Mod.h" +#include "modplatform/helpers/ExportToModList.h" + +namespace Ui { +class ExportToModListDialog; +} + +class ExportToModListDialog : public QDialog { + Q_OBJECT + + public: + explicit ExportToModListDialog(InstancePtr instance, QWidget* parent = nullptr); + ~ExportToModListDialog(); + + void done(int result) override; + + protected slots: + void formatChanged(int index); + void triggerImp(); + void trigger(int) { triggerImp(); }; + + private: + QString extension(); + QList m_allMods; + bool m_template_selected; + QString name; + ExportToModList::Formats format = ExportToModList::Formats::HTML; + Ui::ExportToModListDialog* ui; +}; diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui new file mode 100644 index 00000000..640b1766 --- /dev/null +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -0,0 +1,199 @@ + + + ExportToModListDialog + + + + 0 + 0 + 650 + 446 + + + + Export Pack to ModList + + + true + + + + + + + + Settings + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + Format + + + + + + + + HTML + + + + + Markdown + + + + + Plaintext + + + + + Custom + + + + + + + + Template + + + + + + + + + + + + Optional Info + + + + + + Version + + + + + + + Authors + + + + + + + URL + + + + + + + + + + + + + Result + + + + + + + 0 + 143 + + + + true + + + + + + + true + + + + + + + + + + + + + + Copy + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Save + + + + + + + + + + + buttonBox + accepted() + ExportToModListDialog + accept() + + + 334 + 435 + + + 324 + 206 + + + + + buttonBox + rejected() + ExportToModListDialog + reject() + + + 324 + 390 + + + 324 + 206 + + + + + -- cgit From c75ba0f8551e911b72152ebdd8b2fe1f8bd8f64f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 25 Jun 2023 12:46:07 +0100 Subject: Fix big mistake :iea: Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/InstanceSettingsPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 893fe2a5..2a7c5b27 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -85,7 +85,7 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) case 0: APPLICATION->ShowGlobalSettings(this, "java-settings"); return; - case 1: + case 2: APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; default: -- cgit From 8d3bc6b6b94ff5fb2dba0c06bf6d108794af7d8f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 14:58:54 +0300 Subject: Added markdown QT version check Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 0550725f..715a62c3 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -76,7 +76,11 @@ void ExportToModListDialog::formatChanged(int index) case 1: { ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->show(); +#else + ui->resultText->hide(); +#endif format = ExportToModList::MARKDOWN; break; } @@ -123,7 +127,9 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::MARKDOWN: { exampleLine = "[{name}]({url})[{version}] by {authors}"; +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->setMarkdown(txt); +#endif break; } case ExportToModList::PLAINTXT: { -- cgit From 3546f57a42eb23053772eb5b84cb864f9c83b166 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 15:17:09 +0300 Subject: Use internal markdown implementation Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 715a62c3..57ee4453 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -21,6 +21,7 @@ #include #include #include "FileSystem.h" +#include "Markdown.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/mod/ModFolderModel.h" #include "modplatform/helpers/ExportToModList.h" @@ -76,11 +77,7 @@ void ExportToModListDialog::formatChanged(int index) case 1: { ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) ui->resultText->show(); -#else - ui->resultText->hide(); -#endif format = ExportToModList::MARKDOWN; break; } @@ -127,9 +124,7 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::MARKDOWN: { exampleLine = "[{name}]({url})[{version}] by {authors}"; -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) - ui->resultText->setMarkdown(txt); -#endif + ui->resultText->setHtml(markdownToHTML(txt)); break; } case ExportToModList::PLAINTXT: { -- cgit From 953a2590e27954a3b1d163224bd343bb75a62b69 Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 25 Jun 2023 10:11:58 -0300 Subject: Add fixme comment for no SSD detection Co-authored-by: Sefa Eyeoglu Signed-off-by: Leo --- launcher/ui/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 9b8db1ae..7e2c4acf 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -221,6 +221,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi setInstanceActionsEnabled(false); // add a close button at the end of the main toolbar when running on gamescope / steam deck + // FIXME: detect if we don't have server side decorations instead if (qgetenv("XDG_CURRENT_DESKTOP") == "gamescope") { ui->mainToolBar->addAction(ui->actionCloseWindow); } -- cgit From 6d0e255ca18b1934d6eb514b6324cde67bb87d60 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 22:00:33 +0300 Subject: fix: Page container extra info set on logs page Signed-off-by: Trial97 --- launcher/ui/pages/BasePage.h | 2 +- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 2 +- launcher/ui/widgets/PageContainer.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/BasePage.h b/launcher/ui/pages/BasePage.h index 5537c28f..dc2bde99 100644 --- a/launcher/ui/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h @@ -44,7 +44,7 @@ class BasePage { public: - using updateExtraInfoFunc = std::function; + using updateExtraInfoFunc = std::function; virtual ~BasePage() {} virtual QString id() const = 0; virtual QString displayName() const = 0; diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 8e5226ef..173bcb66 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -83,7 +83,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current); auto updateExtra = [this]() { if (updateExtraInfo) - updateExtraInfo(extraHeaderInfoString()); + updateExtraInfo(id(), extraHeaderInfoString()); }; connect(selection_model, &QItemSelectionModel::selectionChanged, this, updateExtra); connect(model.get(), &ResourceFolderModel::updateFinished, this, updateExtra); diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 34df42ec..b98c9796 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -93,8 +93,8 @@ PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId, page->listIndex = counter; page->setParentContainer(this); counter++; - page->updateExtraInfo = [this](QString info) { - if (m_currentPage) + page->updateExtraInfo = [this](QString id, QString info) { + if (m_currentPage && id == m_currentPage->id()) m_header->setText(m_currentPage->displayName() + info); }; } -- cgit From f2015eee8059fa68af4ca9415cc8a11f13b65922 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:44:47 +0300 Subject: Update launcher/ui/MainWindow.ui Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/MainWindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 027742ba..22721fcd 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -484,7 +484,7 @@ - ModList (txt) + Mod List
    -- cgit From cf5c01a5b1a9a91d41fb343d2d2abc9bac07f1ec Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:44:55 +0300 Subject: Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 57ee4453..d53e8db3 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -118,7 +118,7 @@ void ExportToModListDialog::triggerImp() QString exampleLine; switch (format) { case ExportToModList::HTML: { - exampleLine = "
      {name}[{version}] by {authors}
    "; + exampleLine = "
      {name} [{version}] by {authors}
    "; ui->resultText->setHtml(txt); break; } -- cgit From d82ae31fc1dc75693e3a6270f0b733fcf7bdaadd Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:45:05 +0300 Subject: Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index d53e8db3..b399dc17 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -123,7 +123,7 @@ void ExportToModListDialog::triggerImp() break; } case ExportToModList::MARKDOWN: { - exampleLine = "[{name}]({url})[{version}] by {authors}"; + exampleLine = "[{name}]({url}) [{version}] by {authors}"; ui->resultText->setHtml(markdownToHTML(txt)); break; } -- cgit From 22bb260ae3ccdc17840047cbef49f0af09b809bd Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Mon, 26 Jun 2023 11:45:26 +0300 Subject: Update launcher/ui/dialogs/ExportToModListDialog.cpp Co-authored-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index b399dc17..149f6b35 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -128,7 +128,7 @@ void ExportToModListDialog::triggerImp() break; } case ExportToModList::PLAINTXT: { - exampleLine = "name: {name}; url: {url}; version: {version}; authors: {authors};"; + exampleLine = "{name} ({url}) [{version}] by {authors}"; break; } case ExportToModList::CUSTOM: -- cgit From 0aaec9ae4fb8a2f9e00d81acf85ab66e60ad2639 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 26 Jun 2023 11:53:14 +0200 Subject: chore: remove obsolete macOS warning We don't support that macOS version. This check also never worked, as we never set the platform to that value. Signed-off-by: Sefa Eyeoglu --- buildconfig/BuildConfig.cpp.in | 2 +- buildconfig/BuildConfig.h | 2 +- launcher/ui/pages/global/AccountListPage.cpp | 13 ------------- 3 files changed, 2 insertions(+), 15 deletions(-) (limited to 'launcher/ui') diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 8a412b7f..140731fe 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -65,7 +65,7 @@ Config::Config() MAC_SPARKLE_PUB_KEY = "@MACOSX_SPARKLE_UPDATE_PUBLIC_KEY@"; MAC_SPARKLE_APPCAST_URL = "@MACOSX_SPARKLE_UPDATE_FEED_URL@"; - if (BUILD_PLATFORM == "macOS" && !MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty()) + if (!MAC_SPARKLE_PUB_KEY.isEmpty() && !MAC_SPARKLE_APPCAST_URL.isEmpty()) { UPDATER_ENABLED = true; } diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 8543d724..11773d88 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -68,7 +68,7 @@ class Config { bool UPDATER_ENABLED = false; - /// A short string identifying this build's platform. For example, "lin64" or "win32". + /// A short string identifying this build's platform or distribution. QString BUILD_PLATFORM; /// A string containing the build timestamp diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 278f45c4..fced5ff4 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -159,19 +159,6 @@ void AccountListPage::on_actionAddMojang_triggered() void AccountListPage::on_actionAddMicrosoft_triggered() { - if(BuildConfig.BUILD_PLATFORM == "osx64") { - CustomMessageBox::selectable( - this, - tr("Microsoft Accounts not available"), - //: %1 refers to the launcher itself - tr( - "Microsoft accounts are only usable on macOS 10.13 or newer, with fully updated %1.\n\n" - "Please update both your operating system and %1." - ).arg(BuildConfig.LAUNCHER_DISPLAYNAME), - QMessageBox::Warning - )->exec(); - return; - } MinecraftAccountPtr account = MSALoginDialog::newAccount( this, tr("Please enter your Mojang account email and password to add your account.") -- cgit From 6e5716f097d89b4b7b4c48ae18e37474ef23b3e8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:05:32 +0300 Subject: Fixed illegal characters in shortcuts name Signed-off-by: Trial97 --- launcher/FileSystem.cpp | 11 ++- launcher/ui/MainWindow.cpp | 203 +++++++++++++++++++-------------------------- 2 files changed, 95 insertions(+), 119 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 835ad925..1ea9f755 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -372,7 +372,7 @@ void create_link::make_link_list(const QString& offset) auto src_path = source_it.next(); auto relative_path = src_dir.relativeFilePath(src_path); - if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth){ + if (m_max_depth >= 0 && pathDepth(relative_path) > m_max_depth) { relative_path = pathTruncate(relative_path, m_max_depth); src_path = src_dir.filePath(relative_path); if (linkedPaths.contains(src_path)) { @@ -663,7 +663,7 @@ QString pathTruncate(const QString& path, int depth) QString trunc = QFileInfo(path).path(); - if (pathDepth(trunc) > depth ) { + if (pathDepth(trunc) > depth) { return pathTruncate(trunc, depth); } @@ -769,6 +769,9 @@ QString getDesktopDir() // Cross-platform Shortcut creation bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon) { + if (destination.isEmpty()) { + destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); + } #if defined(Q_OS_MACOS) destination += ".command"; @@ -791,6 +794,8 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated + destination += ".desktop"; QFile f(destination); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); @@ -974,7 +979,7 @@ FilesystemType getFilesystemType(const QString& name) { for (auto iter = s_filesystem_type_names.constBegin(); iter != s_filesystem_type_names.constEnd(); ++iter) { auto fs_names = iter.value(); - if(fs_names.contains(name.toUpper())) + if (fs_names.contains(name.toUpper())) return iter.key(); } return FilesystemType::UNKNOWN; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index eeb78c53..7407483f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1510,140 +1510,111 @@ void MainWindow::on_actionKillInstance_triggered() void MainWindow::on_actionCreateInstanceShortcut_triggered() { - if (m_selectedInstance) - { - auto desktopPath = FS::getDesktopDir(); - if (desktopPath.isEmpty()) { - // TODO come up with an alternative solution (open "save file" dialog) - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); - return; - } + if (!m_selectedInstance) + return; + auto desktopPath = FS::getDesktopDir(); + if (desktopPath.isEmpty()) { + // TODO come up with an alternative solution (open "save file" dialog) + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!")); + return; + } + QString desktopFilePath; + QString appPath = QApplication::applicationFilePath(); + QString iconPath; + QStringList args; #if defined(Q_OS_MACOS) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/private/var/")) { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; - } - - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - appPath, { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), "")) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } + if (appPath.startsWith("/private/var/")) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); + return; + } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - QString appPath = QApplication::applicationFilePath(); - if (appPath.startsWith("/tmp/.mount_")) { - // AppImage! - appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); - if (appPath.isEmpty()) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); - } - else if (appPath.endsWith("/")) - { - appPath.chop(1); - } + if (appPath.startsWith("/tmp/.mount_")) { + // AppImage! + appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE")); + if (appPath.isEmpty()) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)")); + } else if (appPath.endsWith("/")) { + appPath.chop(1); } + } - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG"); + iconFile.close(); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + + if (DesktopServices::isFlatpak()) { + desktopFilePath = FS::PathCombine(desktopPath, FS::RemoveInvalidFilenameChars(m_selectedInstance->name()) + ".desktop"); + 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 }); + } - 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 - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #elif defined(Q_OS_WIN) - auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); - if (icon == nullptr) - { - icon = APPLICATION->icons()->icon("grass"); - } + auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (icon == nullptr) { + icon = APPLICATION->icons()->icon("grass"); + } - QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico"); - // part of fix for weird bug involving the window icon being replaced - // dunno why it happens, but this 2-line fix seems to be enough, so w/e - auto appIcon = APPLICATION->getThemedIcon("logo"); + // part of fix for weird bug involving the window icon being replaced + // dunno why it happens, but this 2-line fix seems to be enough, so w/e + auto appIcon = APPLICATION->getThemedIcon("logo"); - QFile iconFile(iconPath); - if (!iconFile.open(QFile::WriteOnly)) - { - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } - bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); - iconFile.close(); + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } + bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO"); + iconFile.close(); - // restore original window icon - QGuiApplication::setWindowIcon(appIcon); + // restore original window icon + QGuiApplication::setWindowIcon(appIcon); - if (!success) - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); - return; - } + if (!success) { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut.")); + return; + } - if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()), - QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() }, - m_selectedInstance->name(), iconPath)) { - QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); - } - else - { - iconFile.remove(); - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); - } #else - QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!")); + return; #endif + 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 { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } -- cgit From 92847b977409f4f4b4daa1e34196596e40becc05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:15:20 +0300 Subject: omit icon remove on macos Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7407483f..496738e3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1613,7 +1613,9 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() 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 { +#if not defined(Q_OS_MACOS) iconFile.remove(); +#endif QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!")); } } -- cgit From 54cb077b40b1785174a9bd111d055a399b725e52 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 19:31:36 +0300 Subject: Added more information to the screenshot upload warning Signed-off-by: Trial97 --- launcher/ui/pages/instance/ScreenshotsPage.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index ca368d3b..35237594 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -36,6 +36,7 @@ */ #include "ScreenshotsPage.h" +#include "BuildConfig.h" #include "ui_ScreenshotsPage.h" #include @@ -380,16 +381,18 @@ void ScreenshotsPage::on_actionUpload_triggered() if (selection.isEmpty()) return; - QString text; + QUrl baseUrl(BuildConfig.IMGUR_BASE_URL); if (selection.size() > 1) - text = tr("You are about to upload %1 screenshots.\n\n" + text = tr("You are about to upload %1 screenshots to %2.\n" + "You should double-check for personal information.\n\n" "Are you sure?") - .arg(selection.size()); + .arg(QString::number(selection.size()), baseUrl.host()); else - text = - tr("You are about to upload the selected screenshot.\n\n" - "Are you sure?"); + text = tr("You are about to upload the selected screenshot to %1.\n" + "You should double-check for personal information.\n\n" + "Are you sure?") + .arg(baseUrl.host()); auto response = CustomMessageBox::selectable(this, "Confirm Upload", text, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) -- cgit From 0f64ee6a5f6d157e493d474b74004a4ebd0dae43 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 28 Jun 2023 18:28:25 +0300 Subject: Added warnings for running instances Signed-off-by: Trial97 --- launcher/minecraft/mod/ResourceFolderModel.cpp | 18 ++++++++++++++++-- launcher/ui/pages/instance/ExternalResourcesPage.cpp | 20 ++++++++++++++++++++ launcher/ui/pages/instance/ModFolderPage.cpp | 10 ++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 1a56b679..c2c0d178 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -1,14 +1,15 @@ #include "ResourceFolderModel.h" +#include #include #include #include #include +#include #include #include #include #include -#include #include "Application.h" #include "FileSystem.h" @@ -18,6 +19,7 @@ #include "settings/Setting.h" #include "tasks/Task.h" +#include "ui/dialogs/CustomMessageBox.h" ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObject* parent, bool create_dir) : QAbstractListModel(parent), m_dir(dir), m_instance(instance), m_watcher(this) @@ -451,8 +453,20 @@ bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& valu if (row < 0 || row >= rowCount(index.parent()) || !index.isValid()) return false; - if (role == Qt::CheckStateRole) + if (role == Qt::CheckStateRole) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = + CustomMessageBox::selectable(nullptr, "Confirm toggle", + "If you enable/disable this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return false; + } return setResourceEnabled({ index }, EnableAction::TOGGLE); + } return false; } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index 87a3df10..12038f88 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -250,6 +250,16 @@ void ExternalResourcesPage::removeItem() void ExternalResourcesPage::removeItems(const QItemSelection& selection) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm Delete", + "If you remove this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } m_model->deleteResources(selection.indexes()); } @@ -261,6 +271,16 @@ void ExternalResourcesPage::enableItem() void ExternalResourcesPage::disableItem() { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm disable", + "If you disable this resource while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); m_model->setResourceEnabled(selection.indexes(), EnableAction::DISABLE); } diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 9812bbe9..3176396f 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -120,6 +120,16 @@ bool ModFolderPage::onSelectionChanged(const QModelIndex& current, const QModelI void ModFolderPage::removeItems(const QItemSelection& selection) { + if (m_instance != nullptr && m_instance->isRunning()) { + auto response = CustomMessageBox::selectable(this, "Confirm Delete", + "If you remove mods while the game is running it may crash your game.\n" + "Are you sure you want to do this?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); + + if (response != QMessageBox::Yes) + return; + } m_model->deleteMods(selection.indexes()); } -- cgit From 0008b22d8b352e3591ee7ba7c6d9313ed23cbd4a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 28 Jun 2023 18:41:47 +0300 Subject: Renamed function Signed-off-by: Trial97 --- launcher/ui/MainWindow.cpp | 2 +- launcher/ui/instanceview/InstanceView.cpp | 9 ++++++--- launcher/ui/instanceview/InstanceView.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 26fcb3a3..515abf07 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -927,7 +927,7 @@ void MainWindow::onCatToggled(bool state) void MainWindow::setCatBackground(bool enabled) { - view->setCatVisible(enabled); + view->setPaintCat(enabled); view->viewport()->repaint(); } diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 4c83e94a..1911dd59 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -74,7 +74,7 @@ InstanceView::InstanceView(QWidget *parent) setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setAcceptDrops(true); setAutoScroll(true); - setCatVisible(APPLICATION->settings()->get("TheCat").toBool()); + setPaintCat(APPLICATION->settings()->get("TheCat").toBool()); } InstanceView::~InstanceView() @@ -500,10 +500,13 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent *event) } } -void InstanceView::setCatVisible(bool visible) +void InstanceView::setPaintCat(bool visible) { m_catVisible = visible; - m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); + if (visible) + m_catPixmap.load(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage())); + else + m_catPixmap = QPixmap(); } void InstanceView::paintEvent(QPaintEvent* event) diff --git a/launcher/ui/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index a9bd0bd7..36405675 100644 --- a/launcher/ui/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h @@ -86,7 +86,7 @@ public: virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; int spacing() const { return m_spacing; }; - void setCatVisible(bool visible); + void setPaintCat(bool visible); public slots: virtual void updateGeometries() override; -- cgit From 7033e2857268a314971ea9a29a5dbc83d3b2d978 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:00:40 +0200 Subject: update instance group header to more modern style Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 138 ++++++++----------------------- 1 file changed, 35 insertions(+), 103 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index e6bca17d..f2d1ca14 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -157,133 +157,65 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) { - painter->setRenderHint(QPainter::Antialiasing); - const QRect optRect = option.rect; QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - QColor outlineColor = option.palette.text().color(); - outlineColor.setAlphaF(0.35); + int centerHeight = option.rect.top() + fontMetrics.height()/2; - //BEGIN: top left corner - { - painter->save(); - painter->setPen(outlineColor); - const QPointF topLeft(optRect.topLeft()); - QRectF arc(topLeft, QSizeF(4, 4)); - arc.translate(0.5, 0.5); - painter->drawArc(arc, 1440, 1440); - painter->restore(); - } - //END: top left corner + QPen pen; + pen.setWidth(2); + QColor penColor = option.palette.text().color(); + penColor.setAlphaF(0.6); + pen.setColor(penColor); + painter->setPen(pen); - //BEGIN: left vertical line + //BEGIN: arrow { - QPoint start(optRect.topLeft()); - start.ry() += 3; - QPoint verticalGradBottom(optRect.topLeft()); - verticalGradBottom.ry() += fontMetrics.height() + 5; - QLinearGradient gradient(start, verticalGradBottom); - gradient.setColorAt(0, outlineColor); - gradient.setColorAt(1, Qt::transparent); - painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); - } - //END: left vertical line - - //BEGIN: horizontal line - { - QPoint start(optRect.topLeft()); - start.rx() += 3; - QPoint horizontalGradTop(optRect.topLeft()); - horizontalGradTop.rx() += optRect.width() - 6; - painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor); - } - //END: horizontal line - - //BEGIN: top right corner - { - painter->save(); - painter->setPen(outlineColor); - QPointF topRight(optRect.topRight()); - topRight.rx() -= 4; - QRectF arc(topRight, QSizeF(4, 4)); - arc.translate(0.5, 0.5); - painter->drawArc(arc, 0, 1440); - painter->restore(); - } - //END: top right corner - - //BEGIN: right vertical line - { - QPoint start(optRect.topRight()); - start.ry() += 3; - QPoint verticalGradBottom(optRect.topRight()); - verticalGradBottom.ry() += fontMetrics.height() + 5; - QLinearGradient gradient(start, verticalGradBottom); - gradient.setColorAt(0, outlineColor); - gradient.setColorAt(1, Qt::transparent); - painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); - } - //END: right vertical line - - //BEGIN: checkboxy thing - { - painter->save(); painter->setRenderHint(QPainter::Antialiasing, false); - painter->setFont(font); - QColor penColor(option.palette.text().color()); - penColor.setAlphaF(0.6); - painter->setPen(penColor); - QRect iconSubRect(option.rect); - iconSubRect.setTop(iconSubRect.top() + 7); - iconSubRect.setLeft(iconSubRect.left() + 7); - - int sizing = fontMetrics.height(); - int even = ( (sizing - 1) % 2 ); - - iconSubRect.setHeight(sizing - even); - iconSubRect.setWidth(sizing - even); - painter->drawRect(iconSubRect); - + painter->save(); - /* - if(collapsed) - painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "+"); - else - painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "-"); - */ - painter->setBrush(option.palette.text()); - painter->fillRect(iconSubRect.x(), iconSubRect.y() + iconSubRect.height() / 2, - iconSubRect.width(), 2, penColor); - if (collapsed) - { - painter->fillRect(iconSubRect.x() + iconSubRect.width() / 2, iconSubRect.y(), 2, - iconSubRect.height(), penColor); + int offsetLeft = fontMetrics.height()/2; + int offsetTop = centerHeight; + int arrowSize = 6; + + QPolygon polygon; + if (collapsed) { + polygon << QPoint(offsetLeft - arrowSize/2, offsetTop - arrowSize) << QPoint(offsetLeft + arrowSize/2, offsetTop) << QPoint(offsetLeft - arrowSize/2, offsetTop + arrowSize); + painter->drawPolyline(polygon); + } else { + polygon << QPoint(offsetLeft - arrowSize, offsetTop - arrowSize/2) << QPoint(offsetLeft, offsetTop + arrowSize/2) << QPoint(offsetLeft + arrowSize, offsetTop - arrowSize/2); + painter->drawPolyline(polygon); } - - painter->restore(); } - //END: checkboxy thing + //END: arrow //BEGIN: text { + painter->setRenderHint(QPainter::Antialiasing); QRect textRect(option.rect); - textRect.setTop(textRect.top() + 7); - textRect.setLeft(textRect.left() + 7 + fontMetrics.height() + 7); + textRect.setTop(textRect.top()); + textRect.setLeft(textRect.left() + fontMetrics.height()); textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); painter->save(); painter->setFont(font); - QColor penColor(option.palette.text().color()); - penColor.setAlphaF(0.6); - painter->setPen(penColor); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); - painter->restore(); } //END: text + + //BEGIN: horizontal line + { + // startPoint is left + arrow + text + space + int startPoint = optRect.left() + fontMetrics.height() + fontMetrics.size(Qt::AlignLeft | Qt::AlignVCenter, text).width() + 7; + painter->setRenderHint(QPainter::Antialiasing, false); + QPolygon polygon; + polygon << QPoint(startPoint, centerHeight) << QPoint(optRect.right() - 3, centerHeight); + painter->drawPolyline(polygon); + } + //END: horizontal line } int VisualGroup::totalHeight() const -- cgit From 66461ac500ded75d1d3f4df580296936b85e08b2 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:42:49 +0200 Subject: some positioning adjustments, deleted the line Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 34 +++++++++++--------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index f2d1ca14..f544c3dc 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -157,12 +157,13 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) { - const QRect optRect = option.rect; + QRect optRect = option.rect; + optRect.setTop(optRect.top() + 7); QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - int centerHeight = option.rect.top() + fontMetrics.height()/2; + int centerHeight = optRect.top() + fontMetrics.height()/2; QPen pen; pen.setWidth(2); @@ -171,21 +172,21 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti pen.setColor(penColor); painter->setPen(pen); + int arrowOffsetLeft = fontMetrics.height()/2 + 7; + int textOffsetLeft = arrowOffsetLeft *2; + int arrowSize = 6; + //BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); painter->save(); - int offsetLeft = fontMetrics.height()/2; - int offsetTop = centerHeight; - int arrowSize = 6; - QPolygon polygon; if (collapsed) { - polygon << QPoint(offsetLeft - arrowSize/2, offsetTop - arrowSize) << QPoint(offsetLeft + arrowSize/2, offsetTop) << QPoint(offsetLeft - arrowSize/2, offsetTop + arrowSize); + polygon << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight - arrowSize) << QPoint(arrowOffsetLeft + arrowSize/2, centerHeight) << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight + arrowSize); painter->drawPolyline(polygon); } else { - polygon << QPoint(offsetLeft - arrowSize, offsetTop - arrowSize/2) << QPoint(offsetLeft, offsetTop + arrowSize/2) << QPoint(offsetLeft + arrowSize, offsetTop - arrowSize/2); + polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); painter->drawPolyline(polygon); } } @@ -194,9 +195,9 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti //BEGIN: text { painter->setRenderHint(QPainter::Antialiasing); - QRect textRect(option.rect); + QRect textRect(optRect); textRect.setTop(textRect.top()); - textRect.setLeft(textRect.left() + fontMetrics.height()); + textRect.setLeft(textOffsetLeft); textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); @@ -205,22 +206,11 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); } //END: text - - //BEGIN: horizontal line - { - // startPoint is left + arrow + text + space - int startPoint = optRect.left() + fontMetrics.height() + fontMetrics.size(Qt::AlignLeft | Qt::AlignVCenter, text).width() + 7; - painter->setRenderHint(QPainter::Antialiasing, false); - QPolygon polygon; - polygon << QPoint(startPoint, centerHeight) << QPoint(optRect.right() - 3, centerHeight); - painter->drawPolyline(polygon); - } - //END: horizontal line } int VisualGroup::totalHeight() const { - return headerHeight() + 5 + contentHeight(); // FIXME: wtf is that '5'? + return headerHeight() + contentHeight(); } int VisualGroup::headerHeight() const -- cgit From 6b3b119db07b229e22e33313a92a0c81a530f45c Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:50:44 +0200 Subject: give ungrouped instances a group header Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index f544c3dc..9d8dd2b9 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -189,6 +189,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); painter->drawPolyline(polygon); } + painter->restore(); } //END: arrow @@ -203,7 +204,8 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->save(); painter->setFont(font); - painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); + painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text != "" ? text : QObject::tr("Ungrouped")); + painter->restore(); } //END: text } -- cgit From 54d88e4dbf058fe32e92becb5af7eab8c1eb051c Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 18:57:10 +0200 Subject: use QString.isEmpty() oops Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 9d8dd2b9..edf487f1 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -204,7 +204,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->save(); painter->setFont(font); - painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text != "" ? text : QObject::tr("Ungrouped")); + painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); painter->restore(); } //END: text -- cgit From 534d156b1239aed19c9d36a88ff23d84127ac002 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 20:06:17 +0200 Subject: format VisualGroup.cpp file Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 94 +++++++++++++------------------- 1 file changed, 39 insertions(+), 55 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index edf487f1..9b2189b8 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -35,22 +35,17 @@ #include "VisualGroup.h" +#include +#include #include #include #include -#include -#include #include "InstanceView.h" -VisualGroup::VisualGroup(const QString &text, InstanceView *view) : view(view), text(text), collapsed(false) -{ -} +VisualGroup::VisualGroup(const QString& text, InstanceView* view) : view(view), text(text), collapsed(false) {} -VisualGroup::VisualGroup(const VisualGroup *other) - : view(other->view), text(other->text), collapsed(other->collapsed) -{ -} +VisualGroup::VisualGroup(const VisualGroup* other) : view(other->view), text(other->text), collapsed(other->collapsed) {} void VisualGroup::update() { @@ -64,13 +59,11 @@ void VisualGroup::update() int positionInRow = 0; int currentRow = 0; int offsetFromTop = 0; - for (auto item: temp_items) - { - if(positionInRow == itemsPerRow) - { + for (auto item : temp_items) { + if (positionInRow == itemsPerRow) { rows[currentRow].height = maxRowHeight; rows[currentRow].top = offsetFromTop; - currentRow ++; + currentRow++; offsetFromTop += maxRowHeight + 5; positionInRow = 0; maxRowHeight = 0; @@ -83,8 +76,7 @@ void VisualGroup::update() #endif auto itemHeight = view->itemDelegate()->sizeHint(viewItemOption, item).height(); - if(itemHeight > maxRowHeight) - { + if (itemHeight > maxRowHeight) { maxRowHeight = itemHeight; } rows[currentRow].items.append(item); @@ -94,16 +86,13 @@ void VisualGroup::update() rows[currentRow].top = offsetFromTop; } -QPair VisualGroup::positionOf(const QModelIndex &index) const +QPair VisualGroup::positionOf(const QModelIndex& index) const { int y = 0; - for (auto & row: rows) - { - for(auto x = 0; x < row.items.size(); x++) - { - if(row.items[x] == index) - { - return qMakePair(x,y); + for (auto& row : rows) { + for (auto x = 0; x < row.items.size(); x++) { + if (row.items[x] == index) { + return qMakePair(x, y); } } y++; @@ -112,50 +101,44 @@ QPair VisualGroup::positionOf(const QModelIndex &index) const return qMakePair(0, 0); } -int VisualGroup::rowTopOf(const QModelIndex &index) const +int VisualGroup::rowTopOf(const QModelIndex& index) const { auto position = positionOf(index); return rows[position.second].top; } -int VisualGroup::rowHeightOf(const QModelIndex &index) const +int VisualGroup::rowHeightOf(const QModelIndex& index) const { auto position = positionOf(index); return rows[position.second].height; } -VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const +VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const { VisualGroup::HitResults results = VisualGroup::NoHit; int y_start = verticalPosition(); int body_start = y_start + headerHeight(); - int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? + int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? int y = pos.y(); // int x = pos.x(); - if (y < y_start) - { + if (y < y_start) { results = VisualGroup::NoHit; - } - else if (y < body_start) - { + } else if (y < body_start) { results = VisualGroup::HeaderHit; int collapseSize = headerHeight() - 4; // the icon QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize); - if (iconRect.contains(pos)) - { + if (iconRect.contains(pos)) { results |= VisualGroup::CheckboxHit; } - } - else if (y < body_end) - { + } else if (y < body_end) { results |= VisualGroup::BodyHit; } return results; } -void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option) +void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) { QRect optRect = option.rect; optRect.setTop(optRect.top() + 7); @@ -163,7 +146,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - int centerHeight = optRect.top() + fontMetrics.height()/2; + int centerHeight = optRect.top() + fontMetrics.height() / 2; QPen pen; pen.setWidth(2); @@ -172,28 +155,32 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti pen.setColor(penColor); painter->setPen(pen); - int arrowOffsetLeft = fontMetrics.height()/2 + 7; - int textOffsetLeft = arrowOffsetLeft *2; + int arrowOffsetLeft = fontMetrics.height() / 2 + 7; + int textOffsetLeft = arrowOffsetLeft * 2; int arrowSize = 6; - //BEGIN: arrow + // BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); painter->save(); QPolygon polygon; if (collapsed) { - polygon << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight - arrowSize) << QPoint(arrowOffsetLeft + arrowSize/2, centerHeight) << QPoint(arrowOffsetLeft - arrowSize/2, centerHeight + arrowSize); + polygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) + << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) + << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); painter->drawPolyline(polygon); } else { - polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize/2) << QPoint(arrowOffsetLeft, centerHeight + arrowSize/2) << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize/2); + polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) + << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) + << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); painter->drawPolyline(polygon); } painter->restore(); } - //END: arrow + // END: arrow - //BEGIN: text + // BEGIN: text { painter->setRenderHint(QPainter::Antialiasing); QRect textRect(optRect); @@ -207,7 +194,7 @@ void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &opti painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); painter->restore(); } - //END: text + // END: text } int VisualGroup::totalHeight() const @@ -222,7 +209,7 @@ int VisualGroup::headerHeight() const QFontMetrics fontMetrics(font); const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient */ - + 11 /* top and bottom separation */; + + 11 /* top and bottom separation */; return height; /* int raw = view->viewport()->fontMetrics().height() + 4; @@ -235,8 +222,7 @@ int VisualGroup::headerHeight() const int VisualGroup::contentHeight() const { - if (collapsed) - { + if (collapsed) { return 0; } auto last = rows[numRows() - 1]; @@ -256,11 +242,9 @@ int VisualGroup::verticalPosition() const QList VisualGroup::items() const { QList indices; - for (int i = 0; i < view->model()->rowCount(); ++i) - { + for (int i = 0; i < view->model()->rowCount(); ++i) { const QModelIndex index = view->model()->index(i, 0); - if (index.data(InstanceViewRoles::GroupRole).toString() == text) - { + if (index.data(InstanceViewRoles::GroupRole).toString() == text) { indices.append(index); } } -- cgit From 1dc7f800347d6b4e179a12de14af7f4ad87b7f27 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 23:02:34 +0200 Subject: 4 clang-tidy changes, update copyright info while already at it I updated all my emails to use one from my domain Signed-off-by: Tayou --- launcher/Application.cpp | 2 +- launcher/Application.h | 2 +- launcher/ui/instanceview/VisualGroup.cpp | 12 +++--- launcher/ui/instanceview/VisualGroup.h | 48 +++++++++++++++++------- launcher/ui/pages/global/LauncherPage.cpp | 2 +- launcher/ui/setupwizard/ThemeWizardPage.cpp | 2 +- launcher/ui/setupwizard/ThemeWizardPage.h | 2 +- launcher/ui/themes/CustomTheme.cpp | 2 +- launcher/ui/themes/CustomTheme.h | 2 +- launcher/ui/themes/ITheme.cpp | 2 +- launcher/ui/themes/ITheme.h | 2 +- launcher/ui/themes/SystemTheme.cpp | 2 +- launcher/ui/themes/SystemTheme.h | 2 +- launcher/ui/themes/ThemeManager.cpp | 2 +- launcher/ui/themes/ThemeManager.h | 2 +- launcher/ui/widgets/ThemeCustomizationWidget.cpp | 2 +- launcher/ui/widgets/ThemeCustomizationWidget.h | 2 +- 17 files changed, 56 insertions(+), 34 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2..8e1d0cbd 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -6,7 +6,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Lenny McLennington - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> * diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17..527c536b 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 9b2189b8..8663633b 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 Tayou * * 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 @@ -40,10 +41,11 @@ #include #include #include +#include #include "InstanceView.h" -VisualGroup::VisualGroup(const QString& text, InstanceView* view) : view(view), text(text), collapsed(false) {} +VisualGroup::VisualGroup(QString text, InstanceView* view) : view(view), text(std::move(text)), collapsed(false) {} VisualGroup::VisualGroup(const VisualGroup* other) : view(other->view), text(other->text), collapsed(other->collapsed) {} @@ -138,7 +140,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const return results; } -void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) +void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& option) const { QRect optRect = option.rect; optRect.setTop(optRect.top() + 7); @@ -202,7 +204,7 @@ int VisualGroup::totalHeight() const return headerHeight() + contentHeight(); } -int VisualGroup::headerHeight() const +int VisualGroup::headerHeight() { QFont font(QApplication::font()); font.setBold(true); @@ -231,7 +233,7 @@ int VisualGroup::contentHeight() const int VisualGroup::numRows() const { - return rows.size(); + return (int)rows.size(); } int VisualGroup::verticalPosition() const diff --git a/launcher/ui/instanceview/VisualGroup.h b/launcher/ui/instanceview/VisualGroup.h index 5a743aa1..697298c2 100644 --- a/launcher/ui/instanceview/VisualGroup.h +++ b/launcher/ui/instanceview/VisualGroup.h @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 Tayou * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * 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 @@ -42,8 +62,8 @@ struct VisualRow struct VisualGroup { /* constructors */ - VisualGroup(const QString &text, InstanceView *view); - VisualGroup(const VisualGroup *other); + VisualGroup(QString text, InstanceView *view); + explicit VisualGroup(const VisualGroup *other); /* data */ InstanceView *view = nullptr; @@ -58,13 +78,13 @@ struct VisualGroup void update(); /// draw the header at y-position. - void drawHeader(QPainter *painter, const QStyleOptionViewItem &option); + void drawHeader(QPainter *painter, const QStyleOptionViewItem &option) const; /// height of the group, in total. includes a small bit of padding. int totalHeight() const; /// height of the group header, in pixels - int headerHeight() const; + static int headerHeight() ; /// height of the group content, in pixels int contentHeight() const; diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 816dde72..2080b56f 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (c) 2022 dada513 - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp index 42826aba..c3e0a524 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.cpp +++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h index 61a3d0c0..f3d40b6d 100644 --- a/launcher/ui/setupwizard/ThemeWizardPage.h +++ b/launcher/ui/setupwizard/ThemeWizardPage.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 198e76ba..177edefa 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index f2b1b06e..3ec4cafa 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp index 8f0757e1..42d63b11 100644 --- a/launcher/ui/themes/ITheme.cpp +++ b/launcher/ui/themes/ITheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/ITheme.h b/launcher/ui/themes/ITheme.h index a0a638bd..d85e7f98 100644 --- a/launcher/ui/themes/ITheme.h +++ b/launcher/ui/themes/ITheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 3a746d02..3b8cb24a 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h index 05f31233..4f7d83e5 100644 --- a/launcher/ui/themes/SystemTheme.h +++ b/launcher/ui/themes/SystemTheme.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 94ac8a24..b50c6157 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 87f36d9c..d2a6fb70 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp index dcf13303..3bfcd821 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp +++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h index d955a266..6c33c3c5 100644 --- a/launcher/ui/widgets/ThemeCustomizationWidget.h +++ b/launcher/ui/widgets/ThemeCustomizationWidget.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher - * Copyright (C) 2022 Tayou + * Copyright (C) 2022 Tayou * * 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 -- cgit From 8211befc29a4a5b05e1ff1bdd3e7fc2dfb90fc82 Mon Sep 17 00:00:00 2001 From: Tayou Date: Wed, 28 Jun 2023 23:24:57 +0200 Subject: removed magic 5, removed unnecessary QPainter function calls Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 8663633b..7d52e4ad 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -120,7 +120,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const VisualGroup::HitResults results = VisualGroup::NoHit; int y_start = verticalPosition(); int body_start = y_start + headerHeight(); - int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5? + int body_end = body_start + contentHeight(); int y = pos.y(); // int x = pos.x(); if (y < y_start) { @@ -147,8 +147,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); - - int centerHeight = optRect.top() + fontMetrics.height() / 2; + painter->setFont(font); QPen pen; pen.setWidth(2); @@ -157,14 +156,15 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti pen.setColor(penColor); painter->setPen(pen); + // sizes and offsets, to keep things consistent below int arrowOffsetLeft = fontMetrics.height() / 2 + 7; int textOffsetLeft = arrowOffsetLeft * 2; int arrowSize = 6; + int centerHeight = optRect.top() + fontMetrics.height() / 2; // BEGIN: arrow { painter->setRenderHint(QPainter::Antialiasing, false); - painter->save(); QPolygon polygon; if (collapsed) { @@ -178,7 +178,6 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); painter->drawPolyline(polygon); } - painter->restore(); } // END: arrow @@ -191,10 +190,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); - painter->save(); - painter->setFont(font); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, !text.isEmpty() ? text : QObject::tr("Ungrouped")); - painter->restore(); } // END: text } -- cgit From 87efa700ab53148f0555605fa21c683f3a9c3d15 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 00:01:36 +0300 Subject: Removed logs from instance export Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 14 ++++++++++++++ launcher/FileIgnoreProxy.h | 8 ++++++++ launcher/ui/dialogs/ExportInstanceDialog.cpp | 22 +++++++++++++--------- launcher/ui/dialogs/ExportMrPackDialog.cpp | 3 ++- 4 files changed, 37 insertions(+), 10 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index a3b7d505..1f6b664c 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "FileSystem.h" #include "SeparatorPrefixTree.h" #include "StringUtils.h" @@ -254,3 +255,16 @@ bool FileIgnoreProxy::filterAcceptsColumn(int source_column, const QModelIndex& return true; } + +bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + QFileSystemModel* fsm = qobject_cast(sourceModel()); + + auto fileInfo = fsm->fileInfo(index); + auto fileName = fileInfo.fileName(); + auto path = relPath(fileInfo.absoluteFilePath()); + return !(path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); +} diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index a5a1153d..dbd353e0 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -63,10 +63,18 @@ class FileIgnoreProxy : public QSortFilterProxyModel { inline const SeparatorPrefixTree<'/'>& blockedPaths() const { return blocked; } inline SeparatorPrefixTree<'/'>& blockedPaths() { return blocked; } + // list of file names that need to be removed completely from model + inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } + // list of relative paths that need to be removed completely from model + inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; private: const QString root; SeparatorPrefixTree<'/'> blocked; + QStringList m_ignoreFiles; + QStringList m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8ecd91a9..8d0e05a2 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -35,24 +35,24 @@ */ #include "ExportInstanceDialog.h" -#include "ui_ExportInstanceDialog.h" #include #include #include -#include #include +#include +#include "ui_ExportInstanceDialog.h" -#include +#include +#include #include +#include #include +#include #include -#include -#include "SeparatorPrefixTree.h" #include "Application.h" -#include -#include +#include "SeparatorPrefixTree.h" -ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent) +ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent) : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance) { ui->setupUi(this); @@ -60,8 +60,12 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent model->setIconProvider(&icons); auto root = instance->instanceRoot(); proxyModel = new FileIgnoreProxy(root, this); - loadPackIgnore(); proxyModel->setSourceModel(model); + auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); + proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); + loadPackIgnore(); + ui->treeView->setModel(proxyModel); ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); ui->treeView->sortByColumn(0, Qt::AscendingOrder); diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index 60ecefd5..f1d2610a 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,8 +52,9 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); + proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); - proxy->setFilterRegularExpression("^(?!(\\.DS_Store)|([tT]humbs\\.db)).+$"); const QDir::Filters filter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); -- cgit From 81207c65027a35d37394abe3ba6e3ef43777910a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 30 Jun 2023 10:52:10 +0300 Subject: Made sure the logs are ignored when collecting files Signed-off-by: Trial97 --- launcher/FileIgnoreProxy.cpp | 16 +++++++++++++--- launcher/FileIgnoreProxy.h | 9 +++++++-- launcher/ui/dialogs/ExportInstanceDialog.cpp | 8 ++++---- launcher/ui/dialogs/ExportMrPackDialog.cpp | 4 ++-- 4 files changed, 26 insertions(+), 11 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/FileIgnoreProxy.cpp b/launcher/FileIgnoreProxy.cpp index 1f6b664c..556e992c 100644 --- a/launcher/FileIgnoreProxy.cpp +++ b/launcher/FileIgnoreProxy.cpp @@ -262,9 +262,19 @@ bool FileIgnoreProxy::filterAcceptsRow(int sourceRow, const QModelIndex& sourceP QFileSystemModel* fsm = qobject_cast(sourceModel()); auto fileInfo = fsm->fileInfo(index); + return !ignoreFile(fileInfo); +} + +bool FileIgnoreProxy::ignoreFile(QFileInfo fileInfo) const +{ auto fileName = fileInfo.fileName(); auto path = relPath(fileInfo.absoluteFilePath()); - return !(path.startsWith("..") || // just in case ignore files outside the gameroot - std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || - std::any_of(m_ignoreFilePaths.cbegin(), m_ignoreFilePaths.cend(), [path](auto iPath) { return path == iPath; })); + return (path.startsWith("..") || // just in case ignore files outside the gameroot + std::any_of(m_ignoreFiles.cbegin(), m_ignoreFiles.cend(), [fileName](auto iFileName) { return fileName == iFileName; }) || + m_ignoreFilePaths.covers(path)); +} + +bool FileIgnoreProxy::filterFile(const QString& fileName) const +{ + return blocked.covers(fileName) || ignoreFile(QFileInfo(QDir(root), fileName)); } diff --git a/launcher/FileIgnoreProxy.h b/launcher/FileIgnoreProxy.h index dbd353e0..e01a2651 100644 --- a/launcher/FileIgnoreProxy.h +++ b/launcher/FileIgnoreProxy.h @@ -36,6 +36,7 @@ #pragma once +#include #include #include "SeparatorPrefixTree.h" @@ -66,15 +67,19 @@ class FileIgnoreProxy : public QSortFilterProxyModel { // list of file names that need to be removed completely from model inline QStringList& ignoreFilesWithName() { return m_ignoreFiles; } // list of relative paths that need to be removed completely from model - inline QStringList& ignoreFilesWithPath() { return m_ignoreFilePaths; } + inline SeparatorPrefixTree<'/'>& ignoreFilesWithPath() { return m_ignoreFilePaths; } + + bool filterFile(const QString& fileName) const; protected: bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; + bool ignoreFile(QFileInfo file) const; + private: const QString root; SeparatorPrefixTree<'/'> blocked; QStringList m_ignoreFiles; - QStringList m_ignoreFilePaths; + SeparatorPrefixTree<'/'> m_ignoreFilePaths; }; diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 8d0e05a2..cc41c394 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -40,6 +40,7 @@ #include #include #include +#include "FileIgnoreProxy.h" #include "ui_ExportInstanceDialog.h" #include @@ -49,6 +50,7 @@ #include #include #include +#include #include "Application.h" #include "SeparatorPrefixTree.h" @@ -62,7 +64,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent proxyModel = new FileIgnoreProxy(root, this); proxyModel->setSourceModel(model); auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); - proxyModel->ignoreFilesWithPath().append({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); + proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); loadPackIgnore(); @@ -137,11 +139,9 @@ bool ExportInstanceDialog::doExport() SaveIcon(m_instance); - auto & blocked = proxyModel->blockedPaths(); - using std::placeholders::_1; auto files = QFileInfoList(); if (!MMCZip::collectFileListRecursively(m_instance->instanceRoot(), nullptr, &files, - std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1))) { + std::bind(&FileIgnoreProxy::filterFile, proxyModel, std::placeholders::_1))) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } diff --git a/launcher/ui/dialogs/ExportMrPackDialog.cpp b/launcher/ui/dialogs/ExportMrPackDialog.cpp index f1d2610a..b302f7ba 100644 --- a/launcher/ui/dialogs/ExportMrPackDialog.cpp +++ b/launcher/ui/dialogs/ExportMrPackDialog.cpp @@ -52,7 +52,7 @@ ExportMrPackDialog::ExportMrPackDialog(InstancePtr instance, QWidget* parent) // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->ignoreFilesWithPath().append({ "logs", "crash-reports" }); + proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" }); proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); @@ -100,7 +100,7 @@ void ExportMrPackDialog::done(int result) return; ModrinthPackExportTask task(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output, - [this](const QString& path) { return proxy->blockedPaths().covers(path); }); + std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1)); connect(&task, &Task::failed, [this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); -- cgit From 7579fff532629643384d9b8011e885028ca9a8f0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 2 Jul 2023 13:34:04 +0300 Subject: Added more options for variants planing Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 10 ++++++---- launcher/ui/themes/CatPack.h | 4 ++-- launcher/ui/themes/ThemeManager.cpp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 2d5653a6..a0b06a60 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -99,11 +99,13 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di QString JsonCatPack::path() { - const QDateTime now = QDateTime::currentDateTime(); + const QDate now = QDate::currentDate(); for (auto var : m_variants) { - QDateTime startDate(QDate(now.date().year(), var.startTime.mounth, var.startTime.day), QTime(0, 0)); - QDateTime endDate(QDate(now.date().year(), var.endTime.mounth, var.endTime.day), QTime(0, 0)); - if (startDate.daysTo(now) > 0 && now.daysTo(endDate) > 0) + QDate startDate(now.year(), var.startTime.month, var.startTime.day); + QDate endDate(now.year(), var.endTime.month, var.endTime.day); + if (startDate.daysTo(endDate) < 0) // in this case end date should be next year + endDate = endDate.addYears(1); + if (startDate.daysTo(now) >= 0 && now.daysTo(endDate) >= 0) return var.path; } return m_defaultPath; diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index 9f288d3d..e22df1f4 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -79,9 +79,9 @@ class JsonCatPack : public BasicCatPack { auto sp = d.split("-"); day = sp[0].toInt(); if (sp.length() >= 2) - mounth = sp[1].toInt(); + month = sp[1].toInt(); } - int mounth; + int month; int day; }; struct Variant { diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index bfd0550a..d00b3a99 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -189,7 +189,7 @@ void ThemeManager::initializeCatPacks() while (ImageFileIterator.hasNext()) { QFile customCatFile(ImageFileIterator.next()); QFileInfo customCatFileInfo(customCatFile); - themeDebugLog() << "Loading QSS Theme from:" << customCatFileInfo.absoluteFilePath(); + themeDebugLog() << "Loading CatPack from:" << customCatFileInfo.absoluteFilePath(); addCatPack(std::unique_ptr(new FileCatPack(customCatFileInfo))); } }; -- cgit From 81c0a1c4bd3b26c24a506e6d84c878b0786cf14a Mon Sep 17 00:00:00 2001 From: Tayou Date: Sun, 2 Jul 2023 14:01:56 +0200 Subject: antialiasing for all painting, make hitbox fullwidth Signed-off-by: Tayou --- launcher/ui/instanceview/VisualGroup.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 7d52e4ad..aaf31941 100644 --- a/launcher/ui/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp @@ -130,7 +130,7 @@ VisualGroup::HitResults VisualGroup::hitScan(const QPoint& pos) const int collapseSize = headerHeight() - 4; // the icon - QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize); + QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, view->width() - 4, collapseSize); if (iconRect.contains(pos)) { results |= VisualGroup::CheckboxHit; } @@ -155,6 +155,7 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti penColor.setAlphaF(0.6); pen.setColor(penColor); painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing); // sizes and offsets, to keep things consistent below int arrowOffsetLeft = fontMetrics.height() / 2 + 7; @@ -164,26 +165,23 @@ void VisualGroup::drawHeader(QPainter* painter, const QStyleOptionViewItem& opti // BEGIN: arrow { - painter->setRenderHint(QPainter::Antialiasing, false); - - QPolygon polygon; + QPolygon arrowPolygon; if (collapsed) { - polygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) - << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) - << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); - painter->drawPolyline(polygon); + arrowPolygon << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight - arrowSize) + << QPoint(arrowOffsetLeft + arrowSize / 2, centerHeight) + << QPoint(arrowOffsetLeft - arrowSize / 2, centerHeight + arrowSize); + painter->drawPolyline(arrowPolygon); } else { - polygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) - << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) - << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); - painter->drawPolyline(polygon); + arrowPolygon << QPoint(arrowOffsetLeft - arrowSize, centerHeight - arrowSize / 2) + << QPoint(arrowOffsetLeft, centerHeight + arrowSize / 2) + << QPoint(arrowOffsetLeft + arrowSize, centerHeight - arrowSize / 2); + painter->drawPolyline(arrowPolygon); } } // END: arrow // BEGIN: text { - painter->setRenderHint(QPainter::Antialiasing); QRect textRect(optRect); textRect.setTop(textRect.top()); textRect.setLeft(textOffsetLeft); -- cgit From aad5ca5474ff015da30809260fe0f9d6cb503d61 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 2 Jul 2023 16:45:15 +0300 Subject: fixed typos Signed-off-by: Trial97 --- launcher/modplatform/flame/FlamePackExportTask.cpp | 10 +++++----- launcher/ui/dialogs/ExportPackDialog.cpp | 1 + launcher/ui/dialogs/ExportPackDialog.ui | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index 13308b50..927146e1 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -105,7 +105,7 @@ void FlamePackExportTask::collectFiles() void FlamePackExportTask::collectHashes() { setAbortable(true); - setStatus(tr("Find file hashes...")); + setStatus(tr("Finding file hashes...")); setProgress(1, 5); auto allMods = mcInstance->loaderModList()->allMods(); ConcurrentTask::Ptr hashing_task(new ConcurrentTask(this, "MakeHashesTask", 10)); @@ -186,7 +186,7 @@ void FlamePackExportTask::makeApiRequest() return; } - setStatus(tr("Find versions for hashes...")); + setStatus(tr("Finding versions for hashes...")); setProgress(2, 5); auto response = std::make_shared(); @@ -255,10 +255,10 @@ void FlamePackExportTask::makeApiRequest() void FlamePackExportTask::getProjectsInfo() { - setStatus(tr("Find project info from CurseForge...")); + setStatus(tr("Finding project info from CurseForge...")); setProgress(3, 5); - QList addonIds; - for (auto resolved : resolvedFiles) { + QStringList addonIds; + for (const auto& resolved : resolvedFiles) { if (resolved.slug.isEmpty()) { addonIds << QString::number(resolved.addonId); } diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index a54a3c86..2abe2805 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -41,6 +41,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla ui->name->setText(instance->name()); if (m_provider == ModPlatform::ResourceProvider::MODRINTH) { ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]); + setWindowTitle("Export Modrinth Pack"); } else { setWindowTitle("Export CurseForge Pack"); ui->version->setText(""); diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui index 658e2199..3976e28f 100644 --- a/launcher/ui/dialogs/ExportPackDialog.ui +++ b/launcher/ui/dialogs/ExportPackDialog.ui @@ -11,7 +11,7 @@ - Export Modrinth Pack + Export Pack true -- cgit From 4004e0faeed99b3deb0ffb0b0f469594843ca14b Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 20:22:25 -0700 Subject: fix: segfault in progress dialog - dialog tries to resize after unhiding the subtask scroll area - after resize attempts to recenter on parent - `calls parentWidget()->{x|y}()` - what if there is no parent? nullptr->() = segfault - recenter on last pos, don't access parent Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 246a0fd4..84f9db7e 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -34,6 +34,7 @@ */ #include "ProgressDialog.h" +#include #include "ui_ProgressDialog.h" #include @@ -96,21 +97,30 @@ ProgressDialog::~ProgressDialog() void ProgressDialog::updateSize() { QSize lastSize = this->size(); - QSize qSize = QSize(480, minimumSizeHint().height()); + QPoint lastPos = this->pos(); + int minHeight = minimumSizeHint().height(); + if (ui->taskProgressScrollArea->isHidden()) + minHeight -= ui->taskProgressScrollArea->minimumSizeHint().height(); + QSize labelMinSize = ui->globalStatusLabel->minimumSize(); + int labelHeight = ui->globalStatusLabel->height(); + if (labelHeight > labelMinSize.height()) + minHeight += labelHeight - labelMinSize.height(); // account for multiline label + minHeight = std::max(minHeight, 0); + QSize minSize = QSize(480, minHeight); // if the current window is too small - if ((lastSize != qSize) && (lastSize.height() < qSize.height())) + if ((lastSize != minSize) && (lastSize.height() < minSize.height())) { - resize(qSize); - - // keep the dialog in the center after a resize - this->move( - this->parentWidget()->x() + (this->parentWidget()->width() - this->width()) / 2, - this->parentWidget()->y() + (this->parentWidget()->height() - this->height()) / 2 - ); + resize(minSize); + + QSize newSize = this->size(); + QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative + // center on old position after resize + QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); + this->move(newPos); } - setMinimumSize(qSize); + setMinimumSize(minSize); } -- cgit From 3960eb7d32af6ea776634b9f94e12f8df2397627 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 21:24:43 -0700 Subject: fix: properly calculate min size for progress dialog, apply it at creation Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 84f9db7e..f70eee49 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -69,6 +69,7 @@ ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Pr setAttribute(Qt::WidgetAttribute::WA_QuitOnClose, true); setSkipButton(false); changeProgress(0, 100); + updateSize(); } void ProgressDialog::setSkipButton(bool present, QString label) @@ -98,30 +99,28 @@ void ProgressDialog::updateSize() { QSize lastSize = this->size(); QPoint lastPos = this->pos(); - int minHeight = minimumSizeHint().height(); - if (ui->taskProgressScrollArea->isHidden()) - minHeight -= ui->taskProgressScrollArea->minimumSizeHint().height(); - QSize labelMinSize = ui->globalStatusLabel->minimumSize(); - int labelHeight = ui->globalStatusLabel->height(); - if (labelHeight > labelMinSize.height()) - minHeight += labelHeight - labelMinSize.height(); // account for multiline label - minHeight = std::max(minHeight, 0); + int minHeight = ui->globalStatusDetailsLabel->minimumSize().height() + (ui->verticalLayout->spacing() * 2); + minHeight += ui->globalProgressBar->minimumSize().height() + ui->verticalLayout->spacing(); + if (!ui->taskProgressScrollArea->isHidden()) + minHeight += ui->taskProgressScrollArea->minimumSizeHint().height() + ui->verticalLayout->spacing(); + if (ui->skipButton->isVisible()) + minHeight += ui->skipButton->height() + ui->verticalLayout->spacing(); + minHeight = std::max(minHeight, 60); QSize minSize = QSize(480, minHeight); + setMinimumSize(minSize); + adjustSize(); + + QSize newSize = this->size(); // if the current window is too small if ((lastSize != minSize) && (lastSize.height() < minSize.height())) { - resize(minSize); - - QSize newSize = this->size(); QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); this->move(newPos); } - setMinimumSize(minSize); - } int ProgressDialog::execWithTask(Task* task) @@ -211,7 +210,9 @@ void ProgressDialog::onTaskSucceeded() void ProgressDialog::changeStatus(const QString& status) { ui->globalStatusLabel->setText(task->getStatus()); + ui->globalStatusLabel->adjustSize(); ui->globalStatusDetailsLabel->setText(task->getDetails()); + ui->globalStatusDetailsLabel->adjustSize(); updateSize(); } -- cgit From 73d83439140377a7ece34e262ca4efab1608a03d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:27:24 -0700 Subject: fix: header `` -> `` Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index f70eee49..c6d8e573 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -34,7 +34,7 @@ */ #include "ProgressDialog.h" -#include +#include #include "ui_ProgressDialog.h" #include -- cgit From 8cb8273e67d4770300fdb7c3ce61feb19b1a899b Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:29:45 -0700 Subject: fix: update if new size is larger Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index c6d8e573..f422d91e 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -113,7 +113,7 @@ void ProgressDialog::updateSize() QSize newSize = this->size(); // if the current window is too small - if ((lastSize != minSize) && (lastSize.height() < minSize.height())) + if ((lastSize != minSize) && (lastSize.height() < newSize.height())) { QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize -- cgit From e5b9bfb2e78ca86917d91fd41de1e797e570cf83 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:30:25 -0700 Subject: fix: update if new size is larger Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index f422d91e..3368a8c4 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -113,7 +113,7 @@ void ProgressDialog::updateSize() QSize newSize = this->size(); // if the current window is too small - if ((lastSize != minSize) && (lastSize.height() < newSize.height())) + if ((lastSize != newSize) && (lastSize.height() < newSize.height())) { QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize -- cgit From 5d5f1b86fdaa865bf8627acd86163469389ebb83 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 09:21:25 +0300 Subject: fixed logic regarding range over multiple years Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 29 +++++++++++++++-------------- launcher/ui/themes/CatPack.h | 10 +++++----- 2 files changed, 20 insertions(+), 19 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 4170febd..435ccdb8 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -34,11 +34,7 @@ */ #include "ui/themes/CatPack.h" -#include -#include -#include -#include -#include +#include #include #include #include "FileSystem.h" @@ -47,10 +43,10 @@ QString BasicCatPack::path() { - const QDateTime now = QDateTime::currentDateTime(); - const QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0)); - const QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); - const QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0)); + const auto now = QDate::currentDate(); + const auto birthday = QDate(now.year(), 11, 30); + const auto xmas = QDate(now.year(), 12, 25); + const auto halloween = QDate(now.year(), 10, 31); QString cat = QString(":/backgrounds/%1").arg(m_id); if (std::abs(now.daysTo(xmas)) <= 4) { @@ -85,8 +81,8 @@ JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.di for (auto v : variants) { auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - date(Json::requireString(variant, "startTime", "Variant startTime")), - date(Json::requireString(variant, "endTime", "Variant endTime")) }; + PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), + PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; } } catch (const Exception& e) { @@ -104,9 +100,14 @@ QString JsonCatPack::path() for (auto var : m_variants) { QDate startDate(now.year(), var.startTime.month, var.startTime.day); QDate endDate(now.year(), var.endTime.month, var.endTime.day); - if (startDate.daysTo(endDate) < 0) // in this case end date should be next year - endDate = endDate.addYears(1); - if (startDate.daysTo(now) >= 0 && now.daysTo(endDate) >= 0) + if (startDate > endDate) { // it's spans over multiple years + if (endDate <= now) // end date is in the past so jump one year into the future for endDate + endDate = endDate.addYears(1); + else // end date is in the future so jump one year into the past for startDate + startDate = startDate.addYears(-1); + } + + if (startDate >= now && now >= endDate) return var.path; } return m_defaultPath; diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index e22df1f4..20cb8f61 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -35,7 +35,7 @@ #pragma once -#include +#include #include #include #include @@ -73,8 +73,8 @@ class FileCatPack : public BasicCatPack { class JsonCatPack : public BasicCatPack { public: - struct date { - date(QString d) + struct PartialDate { + PartialDate(QString d) { auto sp = d.split("-"); day = sp[0].toInt(); @@ -86,8 +86,8 @@ class JsonCatPack : public BasicCatPack { }; struct Variant { QString path; - date startTime; - date endTime; + PartialDate startTime; + PartialDate endTime; }; JsonCatPack(QFileInfo& manifestInfo); virtual QString path(); -- cgit From 026293f7731181b1198c3c5a9552dd340d13b4b5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 14:17:39 +0300 Subject: updated option text Signed-off-by: Trial97 --- launcher/ui/pages/instance/ExternalResourcesPage.ui | 2 +- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 351aaf75..3c836691 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -162,7 +162,7 @@ false - Visit on mod's page + Visit mod's page Go to mods home page diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 1d31a292..ce6968f5 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -104,7 +104,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(), [](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; }); if (selected <= 1) { - ui->actionVisitItemPage->setText(tr("Visit on mod's page")); + ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); } else { ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); -- cgit From f0aab541f817347a932c65d3b06d2d4c1e7b90c1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 3 Jul 2023 15:09:35 +0300 Subject: fixed typo Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 91 +++++++++++++++------------------------ 1 file changed, 34 insertions(+), 57 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 24349014..b16bc097 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -43,7 +43,7 @@ #include "ui/dialogs/CustomMessageBox.h" -void setupLinkTooTip(QLabel* label) +void setupLinkToolTip(QLabel* label) { QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { if (!link.isEmpty() && !link.startsWith("http")) @@ -60,11 +60,11 @@ InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) ui->licenseLabel->setHidden(true); ui->issueTrackerLabel->setHidden(true); - setupLinkTooTip(ui->iconLabel); - setupLinkTooTip(ui->descriptionLabel); - setupLinkTooTip(ui->nameLabel); - setupLinkTooTip(ui->licenseLabel); - setupLinkTooTip(ui->issueTrackerLabel); + setupLinkToolTip(ui->iconLabel); + setupLinkToolTip(ui->descriptionLabel); + setupLinkToolTip(ui->nameLabel); + setupLinkToolTip(ui->licenseLabel); + setupLinkToolTip(ui->issueTrackerLabel); updateHiddenState(); } @@ -123,9 +123,9 @@ void InfoFrame::updateWithMod(Mod const& m) licenseText += "" + l.url + ""; } if (!l.description.isEmpty() && l.description != l.name) { - licenseText += " " + l.description; + licenseText += " " + l.description; } - } + } } if (!licenseText.isEmpty()) { setLicense(tr("License: %1").arg(licenseText)); @@ -137,7 +137,7 @@ void InfoFrame::updateWithMod(Mod const& m) if (!m.issueTracker().isEmpty()) { issueTracker += tr("Report issues to: "); issueTracker += "" + m.issueTracker() + ""; - } + } setIssueTracker(issueTracker); } @@ -147,7 +147,8 @@ void InfoFrame::updateWithResource(const Resource& resource) setImage(); } -QString InfoFrame::renderColorCodes(QString input) { +QString InfoFrame::renderColorCodes(QString input) +{ // We have to manually set the colors for use. // // A color is set using §x, with x = a hex number from 0 to f. @@ -158,16 +159,12 @@ QString InfoFrame::renderColorCodes(QString input) { // TODO: Wrap links inside tags // https://minecraft.fandom.com/wiki/Formatting_codes#Color_codes - const QMap color_codes_map = { - {'0', "#000000"}, {'1', "#0000AA"}, {'2', "#00AA00"}, {'3', "#00AAAA"}, {'4', "#AA0000"}, - {'5', "#AA00AA"}, {'6', "#FFAA00"}, {'7', "#AAAAAA"}, {'8', "#555555"}, {'9', "#5555FF"}, - {'a', "#55FF55"}, {'b', "#55FFFF"}, {'c', "#FF5555"}, {'d', "#FF55FF"}, {'e', "#FFFF55"}, - {'f', "#FFFFFF"} - }; + const QMap color_codes_map = { { '0', "#000000" }, { '1', "#0000AA" }, { '2', "#00AA00" }, { '3', "#00AAAA" }, + { '4', "#AA0000" }, { '5', "#AA00AA" }, { '6', "#FFAA00" }, { '7', "#AAAAAA" }, + { '8', "#555555" }, { '9', "#5555FF" }, { 'a', "#55FF55" }, { 'b', "#55FFFF" }, + { 'c', "#FF5555" }, { 'd', "#FF55FF" }, { 'e', "#FFFF55" }, { 'f', "#FFFFFF" } }; // https://minecraft.fandom.com/wiki/Formatting_codes#Formatting_codes - const QMap formatting_codes_map = { - {'l', "b"}, {'m', "s"}, {'n', "u"}, {'o', "i"} - }; + const QMap formatting_codes_map = { { 'l', "b" }, { 'm', "s" }, { 'n', "u" }, { 'o', "i" } }; QString html(""); QList tags{}; @@ -212,14 +209,14 @@ void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack) { setName(renderColorCodes(resource_pack.name())); setDescription(renderColorCodes(resource_pack.description())); - setImage(resource_pack.image({64, 64})); + setImage(resource_pack.image({ 64, 64 })); } void InfoFrame::updateWithTexturePack(TexturePack& texture_pack) { setName(renderColorCodes(texture_pack.name())); setDescription(renderColorCodes(texture_pack.description())); - setImage(texture_pack.image({64, 64})); + setImage(texture_pack.image({ 64, 64 })); } void InfoFrame::clear() @@ -268,9 +265,8 @@ void InfoFrame::setDescription(QString text) QChar rem('\n'); QString finaltext; finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ + foreach (const QChar& c, intermediatetext) { + if (c == rem && prev) { continue; } prev = c == rem; @@ -278,17 +274,14 @@ void InfoFrame::setDescription(QString text) } QString labeltext; labeltext.reserve(300); - if(finaltext.length() > 290) - { + if (finaltext.length() > 290) { ui->descriptionLabel->setOpenExternalLinks(false); ui->descriptionLabel->setTextFormat(Qt::TextFormat::RichText); m_description = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); QObject::connect(ui->descriptionLabel, &QLabel::linkActivated, this, &InfoFrame::descriptionEllipsisHandler); - } - else - { + } else { ui->descriptionLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } @@ -297,14 +290,11 @@ void InfoFrame::setDescription(QString text) void InfoFrame::setLicense(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->licenseLabel->setHidden(true); updateHiddenState(); return; - } - else - { + } else { ui->licenseLabel->setHidden(false); updateHiddenState(); } @@ -314,9 +304,8 @@ void InfoFrame::setLicense(QString text) QChar rem('\n'); QString finaltext; finaltext.reserve(intermediatetext.size()); - foreach(const QChar& c, intermediatetext) - { - if(c == rem && prev){ + foreach (const QChar& c, intermediatetext) { + if (c == rem && prev) { continue; } prev = c == rem; @@ -324,17 +313,14 @@ void InfoFrame::setLicense(QString text) } QString labeltext; labeltext.reserve(300); - if(finaltext.length() > 290) - { + if (finaltext.length() > 290) { ui->licenseLabel->setOpenExternalLinks(false); ui->licenseLabel->setTextFormat(Qt::TextFormat::RichText); m_description = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); QObject::connect(ui->licenseLabel, &QLabel::linkActivated, this, &InfoFrame::licenseEllipsisHandler); - } - else - { + } else { ui->licenseLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } @@ -343,12 +329,9 @@ void InfoFrame::setLicense(QString text) void InfoFrame::setIssueTracker(QString text) { - if(text.isEmpty()) - { + if (text.isEmpty()) { ui->issueTrackerLabel->setHidden(true); - } - else - { + } else { ui->issueTrackerLabel->setText(text); ui->issueTrackerLabel->setHidden(false); } @@ -367,28 +350,22 @@ void InfoFrame::setImage(QPixmap img) void InfoFrame::descriptionEllipsisHandler(QString link) { - if(!m_current_box) - { + if (!m_current_box) { m_current_box = CustomMessageBox::selectable(this, "", m_description); connect(m_current_box, &QMessageBox::finished, this, &InfoFrame::boxClosed); m_current_box->show(); - } - else - { + } else { m_current_box->setText(m_description); } } void InfoFrame::licenseEllipsisHandler(QString link) { - if(!m_current_box) - { + if (!m_current_box) { m_current_box = CustomMessageBox::selectable(this, "", m_license); connect(m_current_box, &QMessageBox::finished, this, &InfoFrame::boxClosed); m_current_box->show(); - } - else - { + } else { m_current_box->setText(m_license); } } -- cgit From 1fbc17d275b99d194906302f98412f78fbb77538 Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Tue, 4 Jul 2023 16:38:04 -0400 Subject: Remove break and add fallthrough comment in WorldListPage.cpp Signed-off-by: PandaNinjas --- launcher/ui/pages/instance/WorldListPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index b5dc5a17..b2200b1a 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -338,8 +338,8 @@ void WorldListPage::mceditState(LoggedProcess::State state) case LoggedProcess::Aborted: { failed = true; - break; } + /* fallthrough */ case LoggedProcess::Running: case LoggedProcess::Finished: { -- cgit From 34cf28712c254ba378bdbf728471d0dfbb4ab58f Mon Sep 17 00:00:00 2001 From: PandaNinjas Date: Tue, 4 Jul 2023 16:39:24 -0400 Subject: Replace break with return true; Signed-off-by: PandaNinjas --- launcher/ui/setupwizard/JavaWizardPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index e8833535..2b70c47c 100644 --- a/launcher/ui/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -69,7 +69,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::AllOK: { settings->set("JavaPath", m_java_widget->javaPath()); - break; + return true; } case JavaSettingsWidget::ValidationStatus::JavaBad: { -- cgit From 93870c315f84d2bb599d669be8205990ee48907d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 6 Jul 2023 18:46:59 +0300 Subject: better url handling Signed-off-by: Trial97 --- launcher/ui/widgets/InfoFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index b16bc097..a0fda952 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -46,7 +46,7 @@ void setupLinkToolTip(QLabel* label) { QObject::connect(label, &QLabel::linkHovered, [label](const QString& link) { - if (!link.isEmpty() && !link.startsWith("http")) + if (auto url = QUrl(link); !url.isValid() || (url.scheme() != "http" && url.scheme() != "https")) return; label->setToolTip(link); }); -- cgit From 073cb91f885b780ae04b6d9a4b94702307f07321 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 7 Jul 2023 15:56:04 +0200 Subject: fix(ui): validate meta override url Signed-off-by: Sefa Eyeoglu --- launcher/ui/pages/global/APIPage.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index dca1b3a6..fab31dbd 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -81,6 +81,8 @@ APIPage::APIPage(QWidget *parent) : connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLPlaceholder); // This function needs to be called even when the ComboBox's index is still in its default state. updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); + // NOTE: this allows http://, but we replace that with https later anyway + ui->metaURL->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->metaURL)); ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry)); ui->msaClientID->setValidator(new QRegularExpressionValidator(validMSAClientID, ui->msaClientID)); ui->flameKey->setValidator(new QRegularExpressionValidator(validFlameKey, ui->flameKey)); -- cgit From 3139af8487ae8ea20468023e477be02cf0b96a4d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 7 Jul 2023 17:12:10 +0300 Subject: Made action text simpler Signed-off-by: Trial97 --- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index ce6968f5..fe2f21c9 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -107,7 +107,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); } else { - ui->actionVisitItemPage->setText(tr("Visit the pages of the selected mods")); + ui->actionVisitItemPage->setText(tr("Visit mods pages")); ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); } ui->actionVisitItemPage->setEnabled(selected != 0); -- cgit From b8482a5d89b4044482e7b55aa1c2e2547b41f4fd Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 7 Jul 2023 15:53:50 +0100 Subject: Update ModFolderPage.cpp Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ModFolderPage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index fe2f21c9..041d1bfd 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -107,7 +107,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr ui->actionVisitItemPage->setText(tr("Visit mod's page")); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); } else { - ui->actionVisitItemPage->setText(tr("Visit mods pages")); + ui->actionVisitItemPage->setText(tr("Visit mods' pages")); ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); } ui->actionVisitItemPage->setEnabled(selected != 0); @@ -303,4 +303,4 @@ void ModFolderPage::visitModPages() if (!url.isEmpty()) DesktopServices::openUrl(url); } -} \ No newline at end of file +} -- cgit From 51e62761ee8e8cd868c5f2a7eb63d54de5b71d6a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 7 Jul 2023 19:25:12 +0200 Subject: fix: improve QUrl construction Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 2 +- launcher/ui/pages/global/APIPage.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 34e1320a..7858d713 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -691,7 +691,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Meta URL m_settings->registerSetting("MetaURLOverride", ""); - QUrl metaUrl = m_settings->get("MetaURLOverride").toString(); + QUrl metaUrl(m_settings->get("MetaURLOverride").toString()); // get rid of invalid meta urls if (!metaUrl.isValid() || metaUrl.scheme() != "http" || metaUrl.scheme() != "https") diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index fab31dbd..668aa007 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -165,7 +165,7 @@ void APIPage::applySettings() QString msaClientID = ui->msaClientID->text(); s->set("MSAClientIDOverride", msaClientID); - QUrl metaURL = ui->metaURL->text(); + QUrl metaURL(ui->metaURL->text()); // Add required trailing slash if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) { -- cgit From 20c781b23b0d2bd2be8bed0c015eb6c82312c29a Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 02:28:37 -0700 Subject: fix(progress dialog): if there is a parent center on creation Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/ProgressDialog.cpp | 23 +++++++++++++++-------- launcher/ui/dialogs/ProgressDialog.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 3368a8c4..4243e291 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -67,9 +67,9 @@ ProgressDialog::ProgressDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Pr ui->taskProgressScrollArea->setHidden(true); this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); setAttribute(Qt::WidgetAttribute::WA_QuitOnClose, true); - setSkipButton(false); changeProgress(0, 100); - updateSize(); + updateSize(true); + setSkipButton(false); } void ProgressDialog::setSkipButton(bool present, QString label) @@ -95,7 +95,7 @@ ProgressDialog::~ProgressDialog() delete ui; } -void ProgressDialog::updateSize() +void ProgressDialog::updateSize(bool recenterParent) { QSize lastSize = this->size(); QPoint lastPos = this->pos(); @@ -112,13 +112,20 @@ void ProgressDialog::updateSize() adjustSize(); QSize newSize = this->size(); - // if the current window is too small - if ((lastSize != newSize) && (lastSize.height() < newSize.height())) + // if the current window is a different size + auto parent = this->parentWidget(); + if (recenterParent && parent) { + auto newX = std::max(0, parent->x() + ((parent->width() - newSize.width()) / 2)); + auto newY = std::max(0, parent->y() + ((parent->height() - newSize.height()) / 2)); + this->move(newX, newY); + } + else if (lastSize != newSize) { - QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative // center on old position after resize - QPoint newPos(lastPos.x() + (sizeDiff.width() / 2), lastPos.y() + (sizeDiff.height() / 2)); - this->move(newPos); + QSize sizeDiff = lastSize - newSize; // last size was smaller, the results should be negative + auto newX = std::max(0, lastPos.x() + (sizeDiff.width() / 2)); + auto newY = std::max(0, lastPos.y() + (sizeDiff.height() / 2)); + this->move(newX, newY); } } diff --git a/launcher/ui/dialogs/ProgressDialog.h b/launcher/ui/dialogs/ProgressDialog.h index fc9a0fbc..f062be08 100644 --- a/launcher/ui/dialogs/ProgressDialog.h +++ b/launcher/ui/dialogs/ProgressDialog.h @@ -62,7 +62,7 @@ public: explicit ProgressDialog(QWidget *parent = 0); ~ProgressDialog(); - void updateSize(); + void updateSize(bool recenterParent = false); int execWithTask(Task* task); int execWithTask(std::unique_ptr &&task); -- cgit From 08c140b9b45b1a8afd134793acedf867526d6432 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 8 Jul 2023 20:51:27 +0100 Subject: Fix actionVisitItemPage insersion, and prevent widebar segfault Signed-off-by: TheKodeToad --- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- launcher/ui/widgets/WideBar.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 041d1bfd..9f077618 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -89,7 +89,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page")); - ui->actionsToolbar->insertActionAfter(ui->actionViewFolder, ui->actionVisitItemPage); + ui->actionsToolbar->addAction(ui->actionVisitItemPage); connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages); auto check_allow_update = [this] { diff --git a/launcher/ui/widgets/WideBar.cpp b/launcher/ui/widgets/WideBar.cpp index ac34e3aa..a77c45fe 100644 --- a/launcher/ui/widgets/WideBar.cpp +++ b/launcher/ui/widgets/WideBar.cpp @@ -116,12 +116,21 @@ void WideBar::insertActionAfter(QAction* after, QAction* action) if (iter == m_entries.end()) return; + iter++; + // the action to insert after is present + // however, the element after it isn't valid + if (iter == m_entries.end()) { + // append the action instead of inserting it + addAction(action); + return; + } + BarEntry entry; - entry.bar_action = insertWidget((iter + 1)->bar_action, new ActionButton(action, this, m_use_default_action)); + entry.bar_action = insertWidget(iter->bar_action, new ActionButton(action, this, m_use_default_action)); entry.menu_action = action; entry.type = BarEntry::Type::Action; - m_entries.insert(iter + 1, entry); + m_entries.insert(iter, entry); m_menu_state = MenuState::Dirty; } -- cgit From a54bbae62282e8adce76df9626c58b6bb3e12967 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 8 Jul 2023 12:59:55 -0700 Subject: fix(instance edit): don't allow editing if no selected instance or instance doesn't support editing Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 515abf07..254f229d 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1279,7 +1279,17 @@ void MainWindow::globalSettingsClosed() void MainWindow::on_actionEditInstance_triggered() { - APPLICATION->showInstanceWindow(m_selectedInstance); + + if (!m_selectedInstance) + return; + + if (m_selectedInstance->canEdit()) { + APPLICATION->showInstanceWindow(m_selectedInstance); + } else { + CustomMessageBox::selectable(this, tr("Instance not editable"), + tr("This instance is not editable. it may be broken, invalid, or too old. Check logs for details,"), + QMessageBox::Critical)->show(); + } } void MainWindow::on_actionManageAccounts_triggered() -- cgit From d53d58a5d42684c5151680016f38a0f4bd1c0298 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 8 Jul 2023 22:03:47 +0100 Subject: LiteMod downloading Signed-off-by: TheKodeToad --- launcher/minecraft/PackProfile.cpp | 3 ++- launcher/modplatform/flame/FlameAPI.h | 2 ++ launcher/modplatform/modrinth/ModrinthAPI.h | 6 +++--- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 9 +++++++-- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index aff05dbc..e8fd2157 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -65,7 +65,8 @@ static const QMap modloaderMapping{ {"net.minecraftforge", ResourceAPI::Forge}, {"net.fabricmc.fabric-loader", ResourceAPI::Fabric}, - {"org.quiltmc.quilt-loader", ResourceAPI::Quilt} + {"org.quiltmc.quilt-loader", ResourceAPI::Quilt}, + {"com.mumfrey.liteloader", ResourceAPI::LiteLoader} }; PackProfile::PackProfile(MinecraftInstance * instance) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 0a6dc78f..49bc316f 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -23,6 +23,8 @@ class FlameAPI : public NetworkResourceAPI { [[nodiscard]] auto getSortingMethods() const -> QList override; + static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt); } + private: static int getClassId(ModPlatform::ResourceType type) { diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index e83ed2bf..58af14cc 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -38,7 +38,7 @@ class ModrinthAPI : public NetworkResourceAPI { static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList { QStringList l; - for (auto loader : { Forge, Fabric, Quilt }) { + for (auto loader : { Forge, Fabric, Quilt, LiteLoader }) { if (types & loader) { l << getModLoaderString(loader); } @@ -92,7 +92,7 @@ class ModrinthAPI : public NetworkResourceAPI { { if (args.loaders.has_value()) { if (!validateModLoaders(args.loaders.value())) { - qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; + qWarning() << "Modrinth - or our interface - does not support any the provided mod loaders!"; return {}; } } @@ -141,7 +141,7 @@ class ModrinthAPI : public NetworkResourceAPI { return s.isEmpty() ? QString() : s; } - inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool { return loaders & (Forge | Fabric | Quilt); } + static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt | LiteLoader); } [[nodiscard]] std::optional getDependencyURL(DependencySearchArgs const& args) const override { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 4f59f560..b17eced3 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -43,6 +43,8 @@ #include "ui/pages/modplatform/flame/FlameResourcePages.h" #include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h" +#include "modplatform/flame/FlameAPI.h" +#include "modplatform/modrinth/ModrinthAPI.h" #include "ui/widgets/PageContainer.h" namespace ResourceDownload { @@ -281,8 +283,11 @@ QList ModDownloadDialog::getPages() { QList pages; - pages.append(ModrinthModPage::create(this, *m_instance)); - if (APPLICATION->capabilities() & Application::SupportsFlame) + auto loaders = static_cast(m_instance)->getPackProfile()->getModLoaders().value(); + + if (ModrinthAPI::validateModLoaders(loaders)) + pages.append(ModrinthModPage::create(this, *m_instance)); + if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders)) pages.append(FlameModPage::create(this, *m_instance)); m_selectedPage = dynamic_cast(pages[0]); -- cgit From 159f14c0768a1cd8ab99b8a46f2021d163e6740c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 9 Jul 2023 22:47:38 +0300 Subject: feat:unlocked versions page Signed-off-by: Trial97 --- launcher/ui/pages/instance/VersionPage.cpp | 313 +++++++++++------------------ launcher/ui/pages/instance/VersionPage.h | 55 ++--- 2 files changed, 138 insertions(+), 230 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 59107c53..7db1b19f 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -40,14 +40,13 @@ #include "Application.h" -#include -#include +#include #include #include +#include +#include #include -#include #include -#include #include #include @@ -55,49 +54,42 @@ #include "ui_VersionPage.h" #include "ui/dialogs/CustomMessageBox.h" -#include "ui/dialogs/VersionSelectDialog.h" #include "ui/dialogs/NewComponentDialog.h" #include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" #include "ui/GuiUtil.h" +#include "DesktopServices.h" +#include "Exception.h" +#include "Version.h" +#include "icons/IconList.h" #include "minecraft/PackProfile.h" #include "minecraft/auth/AccountList.h" #include "minecraft/mod/Mod.h" -#include "icons/IconList.h" -#include "Exception.h" -#include "Version.h" -#include "DesktopServices.h" #include "meta/Index.h" #include "meta/VersionList.h" -class IconProxy : public QIdentityProxyModel -{ +class IconProxy : public QIdentityProxyModel { Q_OBJECT -public: - - IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget) + public: + IconProxy(QWidget* parentWidget) : QIdentityProxyModel(parentWidget) { connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone); m_parentWidget = parentWidget; } - virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override + virtual QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const override { QVariant var = QIdentityProxyModel::data(proxyIndex, role); int column = proxyIndex.column(); - if(column == 0 && role == Qt::DecorationRole && m_parentWidget) - { - if(!var.isNull()) - { + if (column == 0 && role == Qt::DecorationRole && m_parentWidget) { + if (!var.isNull()) { auto string = var.toString(); - if(string == "warning") - { + if (string == "warning") { return APPLICATION->getThemedIcon("status-yellow"); - } - else if(string == "error") - { + } else if (string == "error") { return APPLICATION->getThemedIcon("status-bad"); } } @@ -105,14 +97,11 @@ public: } return var; } -private slots: - void widgetGone() - { - m_parentWidget = nullptr; - } + private slots: + void widgetGone() { m_parentWidget = nullptr; } -private: - QWidget *m_parentWidget = nullptr; + private: + QWidget* m_parentWidget = nullptr; }; QIcon VersionPage::icon() const @@ -144,15 +133,14 @@ void VersionPage::closedImpl() m_wide_bar_setting->set(ui->toolBar->getVisibilityState()); } -QMenu * VersionPage::createPopupMenu() +QMenu* VersionPage::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); - filteredMenu->removeAction( ui->toolBar->toggleViewAction() ); + filteredMenu->removeAction(ui->toolBar->toggleViewAction()); return filteredMenu; } -VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent) - : QMainWindow(parent), ui(new Ui::VersionPage), m_inst(inst) +VersionPage::VersionPage(MinecraftInstance* inst, QWidget* parent) : QMainWindow(parent), ui(new Ui::VersionPage), m_inst(inst) { ui->setupUi(this); @@ -182,10 +170,8 @@ VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent) connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent); connect(m_profile.get(), &PackProfile::minecraftChanged, this, &VersionPage::updateVersionControls); - controlsEnabled = !m_inst->isRunning(); updateVersionControls(); preselect(0); - connect(m_inst, &BaseInstance::runningStatusChanged, this, &VersionPage::updateRunningStatus); connect(ui->packageView, &ModListView::customContextMenuRequested, this, &VersionPage::showContextMenu); connect(ui->filterEdit, &QLineEdit::textChanged, this, &VersionPage::onFilterTextChanged); } @@ -202,18 +188,16 @@ void VersionPage::showContextMenu(const QPoint& pos) delete menu; } -void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex &previous) +void VersionPage::packageCurrent(const QModelIndex& current, const QModelIndex& previous) { - if (!current.isValid()) - { + if (!current.isValid()) { ui->frame->clear(); return; } int row = current.row(); auto patch = m_profile->getComponent(row); auto severity = patch->getProblemSeverity(); - switch(severity) - { + switch (severity) { case ProblemSeverity::Warning: ui->frame->setName(tr("%1 possibly has issues.").arg(patch->getName())); break; @@ -226,16 +210,12 @@ void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex & return; } - auto &problems = patch->getProblems(); + auto& problems = patch->getProblems(); QString problemOut; - for (auto &problem: problems) - { - if(problem.m_severity == ProblemSeverity::Error) - { + for (auto& problem : problems) { + if (problem.m_severity == ProblemSeverity::Error) { problemOut += tr("Error: "); - } - else if(problem.m_severity == ProblemSeverity::Warning) - { + } else if (problem.m_severity == ProblemSeverity::Warning) { problemOut += tr("Warning: "); } problemOut += problem.m_description; @@ -244,71 +224,56 @@ void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex & ui->frame->setDescription(problemOut); } -void VersionPage::updateRunningStatus(bool running) -{ - if(controlsEnabled == running) { - controlsEnabled = !running; - updateVersionControls(); - } -} - void VersionPage::updateVersionControls() { // FIXME: this is a dirty hack auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft")); - ui->actionInstall_Forge->setEnabled(controlsEnabled); + ui->actionInstall_Forge->setEnabled(true); bool supportsFabric = minecraftVersion >= Version("1.14"); - ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric); + ui->actionInstall_Fabric->setEnabled(supportsFabric); bool supportsQuilt = minecraftVersion >= Version("1.14"); - ui->actionInstall_Quilt->setEnabled(controlsEnabled && supportsQuilt); + ui->actionInstall_Quilt->setEnabled(supportsQuilt); bool supportsLiteLoader = minecraftVersion <= Version("1.12.2"); - ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && supportsLiteLoader); + ui->actionInstall_LiteLoader->setEnabled(supportsLiteLoader); updateButtons(); } void VersionPage::updateButtons(int row) { - if(row == -1) + if (row == -1) row = currentRow(); auto patch = m_profile->getComponent(row); - ui->actionRemove->setEnabled(controlsEnabled && patch && patch->isRemovable()); - ui->actionMove_down->setEnabled(controlsEnabled && patch && patch->isMoveable()); - ui->actionMove_up->setEnabled(controlsEnabled && patch && patch->isMoveable()); - ui->actionChange_version->setEnabled(controlsEnabled && patch && patch->isVersionChangeable()); - ui->actionEdit->setEnabled(controlsEnabled && patch && patch->isCustom()); - ui->actionCustomize->setEnabled(controlsEnabled && patch && patch->isCustomizable()); - ui->actionRevert->setEnabled(controlsEnabled && patch && patch->isRevertible()); - ui->actionDownload_All->setEnabled(controlsEnabled); - ui->actionAdd_Empty->setEnabled(controlsEnabled); - ui->actionImport_Components->setEnabled(controlsEnabled); - ui->actionReload->setEnabled(controlsEnabled); - ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled); - ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled); - ui->actionAdd_Agents->setEnabled(controlsEnabled); + ui->actionRemove->setEnabled(patch && patch->isRemovable()); + ui->actionMove_down->setEnabled(patch && patch->isMoveable()); + ui->actionMove_up->setEnabled(patch && patch->isMoveable()); + ui->actionChange_version->setEnabled(patch && patch->isVersionChangeable()); + ui->actionEdit->setEnabled(patch && patch->isCustom()); + ui->actionCustomize->setEnabled(patch && patch->isCustomizable()); + ui->actionRevert->setEnabled(patch && patch->isRevertible()); + ui->actionDownload_All->setEnabled(true); + ui->actionAdd_Empty->setEnabled(true); + ui->actionImport_Components->setEnabled(true); + ui->actionReload->setEnabled(true); + ui->actionReplace_Minecraft_jar->setEnabled(true); + ui->actionAdd_to_Minecraft_jar->setEnabled(true); + ui->actionAdd_Agents->setEnabled(true); } bool VersionPage::reloadPackProfile() { - try - { + try { m_profile->reload(Net::Mode::Online); return true; - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); return false; - } - catch (...) - { - QMessageBox::critical( - this, tr("Error"), - tr("Couldn't load the instance profile.")); + } catch (...) { + QMessageBox::critical(this, tr("Error"), tr("Couldn't load the instance profile.")); return false; } } @@ -321,14 +286,12 @@ void VersionPage::on_actionReload_triggered() void VersionPage::on_actionRemove_triggered() { - if (!ui->packageView->currentIndex().isValid()) - { + if (!ui->packageView->currentIndex().isValid()) { return; } int index = ui->packageView->currentIndex().row(); auto component = m_profile->getComponent(index); - if (component->isCustom()) - { + if (component->isCustom()) { auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"), tr("You are about to remove \"%1\".\n" "This is permanent and will completely remove the custom component.\n\n" @@ -341,8 +304,7 @@ void VersionPage::on_actionRemove_triggered() return; } // FIXME: use actual model, not reloading. - if (!m_profile->remove(index)) - { + if (!m_profile->remove(index)) { QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file")); } updateButtons(); @@ -352,17 +314,16 @@ void VersionPage::on_actionRemove_triggered() void VersionPage::on_actionInstall_mods_triggered() { - if(m_container) - { + if (m_container) { m_container->selectPage("mods"); } } void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() { - auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); - if(!list.empty()) - { + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), + APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); + if (!list.empty()) { m_profile->installJarMods(list); } updateButtons(); @@ -370,9 +331,9 @@ void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() void VersionPage::on_actionReplace_Minecraft_jar_triggered() { - auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); - if(!jarPath.isEmpty()) - { + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), + APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); + if (!jarPath.isEmpty()) { m_profile->installCustomJar(jarPath); } updateButtons(); @@ -406,12 +367,9 @@ void VersionPage::on_actionAdd_Agents_triggered() void VersionPage::on_actionMove_up_triggered() { - try - { + try { m_profile->move(currentRow(), PackProfile::MoveUp); - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); } updateButtons(); @@ -419,12 +377,9 @@ void VersionPage::on_actionMove_up_triggered() void VersionPage::on_actionMove_down_triggered() { - try - { + try { m_profile->move(currentRow(), PackProfile::MoveDown); - } - catch (const Exception &e) - { + } catch (const Exception& e) { QMessageBox::critical(this, tr("Error"), e.cause()); } updateButtons(); @@ -433,39 +388,32 @@ void VersionPage::on_actionMove_down_triggered() void VersionPage::on_actionChange_version_triggered() { auto versionRow = currentRow(); - if(versionRow == -1) - { + if (versionRow == -1) { return; } auto patch = m_profile->getComponent(versionRow); auto name = patch->getName(); auto list = patch->getVersionList(); - if(!list) - { + if (!list) { return; } auto uid = list->uid(); // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata... - if(uid == "net.minecraftforge") - { + if (uid == "net.minecraftforge") { on_actionInstall_Forge_triggered(); return; - } - else if (uid == "com.mumfrey.liteloader") - { + } else if (uid == "com.mumfrey.liteloader") { on_actionInstall_LiteLoader_triggered(); return; } VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this); - if (uid == "net.fabricmc.intermediary" || uid == "org.quiltmc.hashed") - { + if (uid == "net.fabricmc.intermediary" || uid == "org.quiltmc.hashed") { vselect.setEmptyString(tr("No intermediary mappings versions are currently available.")); vselect.setEmptyErrorString(tr("Couldn't load or download the intermediary mappings version lists!")); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); } auto currentVersion = patch->getVersion(); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } if (!vselect.exec() || !vselect.selectedVersion()) @@ -473,8 +421,7 @@ void VersionPage::on_actionChange_version_triggered() qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor(); bool important = false; - if(uid == "net.minecraft") - { + if (uid == "net.minecraft") { important = true; } m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important); @@ -484,19 +431,17 @@ void VersionPage::on_actionChange_version_triggered() void VersionPage::on_actionDownload_All_triggered() { - if (!APPLICATION->accounts()->anyAccountIsValid()) - { - CustomMessageBox::selectable( - this, tr("Error"), - tr("Cannot download Minecraft or update instances unless you have at least " - "one account added.\nPlease add your Mojang or Minecraft account."), - QMessageBox::Warning)->show(); + if (!APPLICATION->accounts()->anyAccountIsValid()) { + CustomMessageBox::selectable(this, tr("Error"), + tr("Cannot download Minecraft or update instances unless you have at least " + "one account added.\nPlease add your Mojang or Minecraft account."), + QMessageBox::Warning) + ->show(); return; } auto updateTask = m_inst->createUpdateTask(Net::Mode::Online); - if (!updateTask) - { + if (!updateTask) { return; } ProgressDialog tDialog(this); @@ -510,28 +455,26 @@ void VersionPage::on_actionDownload_All_triggered() void VersionPage::on_actionInstall_Forge_triggered() { auto vlist = APPLICATION->metadataIndex()->get("net.minecraftforge"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); - vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + + m_profile->getComponentVersion("net.minecraft")); vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!")); auto currentVersion = m_profile->getComponentVersion("net.minecraftforge"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); // m_profile->installVersion(); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -539,8 +482,7 @@ void VersionPage::on_actionInstall_Forge_triggered() void VersionPage::on_actionInstall_Fabric_triggered() { auto vlist = APPLICATION->metadataIndex()->get("net.fabricmc.fabric-loader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Fabric Loader version"), this); @@ -548,17 +490,15 @@ void VersionPage::on_actionInstall_Fabric_triggered() vselect.setEmptyErrorString(tr("Couldn't load or download the Fabric Loader version lists!")); auto currentVersion = m_profile->getComponentVersion("net.fabricmc.fabric-loader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("net.fabricmc.fabric-loader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -566,8 +506,7 @@ void VersionPage::on_actionInstall_Fabric_triggered() void VersionPage::on_actionInstall_Quilt_triggered() { auto vlist = APPLICATION->metadataIndex()->get("org.quiltmc.quilt-loader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select Quilt Loader version"), this); @@ -575,17 +514,15 @@ void VersionPage::on_actionInstall_Quilt_triggered() vselect.setEmptyErrorString(tr("Couldn't load or download the Quilt Loader version lists!")); auto currentVersion = m_profile->getComponentVersion("org.quiltmc.quilt-loader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("org.quiltmc.quilt-loader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -594,14 +531,12 @@ void VersionPage::on_actionAdd_Empty_triggered() { NewComponentDialog compdialog(QString(), QString(), this); QStringList blacklist; - for(int i = 0; i < m_profile->rowCount(); i++) - { + for (int i = 0; i < m_profile->rowCount(); i++) { auto comp = m_profile->getComponent(i); blacklist.push_back(comp->getID()); } compdialog.setBlacklist(blacklist); - if (compdialog.exec()) - { + if (compdialog.exec()) { qDebug() << "name:" << compdialog.name(); qDebug() << "uid:" << compdialog.uid(); m_profile->installEmpty(compdialog.uid(), compdialog.name()); @@ -611,28 +546,26 @@ void VersionPage::on_actionAdd_Empty_triggered() void VersionPage::on_actionInstall_LiteLoader_triggered() { auto vlist = APPLICATION->metadataIndex()->get("com.mumfrey.liteloader"); - if(!vlist) - { + if (!vlist) { return; } VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this); vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); - vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + + m_profile->getComponentVersion("net.minecraft")); vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!")); auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader"); - if(!currentVersion.isEmpty()) - { + if (!currentVersion.isEmpty()) { vselect.setCurrentVersion(currentVersion); } - if (vselect.exec() && vselect.selectedVersion()) - { + if (vselect.exec() && vselect.selectedVersion()) { auto vsn = vselect.selectedVersion(); m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor()); m_profile->resolve(Net::Mode::Online); // m_profile->installVersion(vselect.selectedVersion()); - preselect(m_profile->rowCount(QModelIndex())-1); + preselect(m_profile->rowCount(QModelIndex()) - 1); m_container->refreshContainer(); } } @@ -647,7 +580,7 @@ void VersionPage::on_actionMinecraftFolder_triggered() DesktopServices::openDirectory(m_inst->gameRoot(), true); } -void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous) +void VersionPage::versionCurrent(const QModelIndex& current, const QModelIndex& previous) { currentIdx = current.row(); updateButtons(currentIdx); @@ -655,16 +588,13 @@ void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex & void VersionPage::preselect(int row) { - if(row < 0) - { + if (row < 0) { row = 0; } - if(row >= m_profile->rowCount(QModelIndex())) - { + if (row >= m_profile->rowCount(QModelIndex())) { row = m_profile->rowCount(QModelIndex()) - 1; } - if(row < 0) - { + if (row < 0) { return; } auto model_index = m_profile->index(row); @@ -680,8 +610,7 @@ void VersionPage::onGameUpdateError(QString error) ComponentPtr VersionPage::current() { auto row = currentRow(); - if(row < 0) - { + if (row < 0) { return nullptr; } return m_profile->getComponent(row); @@ -689,8 +618,7 @@ ComponentPtr VersionPage::current() int VersionPage::currentRow() { - if (ui->packageView->selectionModel()->selectedRows().isEmpty()) - { + if (ui->packageView->selectionModel()->selectedRows().isEmpty()) { return -1; } return ui->packageView->selectionModel()->selectedRows().first().row(); @@ -699,18 +627,15 @@ int VersionPage::currentRow() void VersionPage::on_actionCustomize_triggered() { auto version = currentRow(); - if(version == -1) - { + if (version == -1) { return; } auto patch = m_profile->getComponent(version); - if(!patch->getVersionFile()) - { + if (!patch->getVersionFile()) { // TODO: wait for the update task to finish here... return; } - if(!m_profile->customize(version)) - { + if (!m_profile->customize(version)) { // TODO: some error box here } updateButtons(); @@ -720,13 +645,11 @@ void VersionPage::on_actionCustomize_triggered() void VersionPage::on_actionEdit_triggered() { auto version = current(); - if(!version) - { + if (!version) { return; } auto filename = version->getFilename(); - if(!QFileInfo::exists(filename)) - { + if (!QFileInfo::exists(filename)) { qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; return; } @@ -736,8 +659,7 @@ void VersionPage::on_actionEdit_triggered() void VersionPage::on_actionRevert_triggered() { auto version = currentRow(); - if(version == -1) - { + if (version == -1) { return; } auto component = m_profile->getComponent(version); @@ -753,8 +675,7 @@ void VersionPage::on_actionRevert_triggered() if (response != QMessageBox::Yes) return; - if(!m_profile->revertToBase(version)) - { + if (!m_profile->revertToBase(version)) { // TODO: some error box here } updateButtons(); @@ -762,7 +683,7 @@ void VersionPage::on_actionRevert_triggered() m_container->refreshContainer(); } -void VersionPage::onFilterTextChanged(const QString &newContents) +void VersionPage::onFilterTextChanged(const QString& newContents) { m_filterModel->setFilterFixedString(newContents); } diff --git a/launcher/ui/pages/instance/VersionPage.h b/launcher/ui/pages/instance/VersionPage.h index d0087714..45d383f4 100644 --- a/launcher/ui/pages/instance/VersionPage.h +++ b/launcher/ui/pages/instance/VersionPage.h @@ -46,38 +46,27 @@ #include "minecraft/PackProfile.h" #include "ui/pages/BasePage.h" -namespace Ui -{ +namespace Ui { class VersionPage; } -class VersionPage : public QMainWindow, public BasePage -{ +class VersionPage : public QMainWindow, public BasePage { Q_OBJECT -public: - explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0); + public: + explicit VersionPage(MinecraftInstance* inst, QWidget* parent = 0); virtual ~VersionPage(); - virtual QString displayName() const override - { - return tr("Version"); - } + virtual QString displayName() const override { return tr("Version"); } virtual QIcon icon() const override; - virtual QString id() const override - { - return "version"; - } - virtual QString helpPage() const override - { - return "Instance-Version"; - } + virtual QString id() const override { return "version"; } + virtual QString helpPage() const override { return "Instance-Version"; } virtual bool shouldDisplay() const override; void retranslate() override; void openedImpl() override; void closedImpl() override; -private slots: + private slots: void on_actionChange_version_triggered(); void on_actionInstall_Forge_triggered(); void on_actionInstall_Fabric_triggered(); @@ -103,36 +92,34 @@ private slots: void updateVersionControls(); -private: + private: ComponentPtr current(); int currentRow(); void updateButtons(int row = -1); void preselect(int row = 0); int doUpdate(); -protected: - QMenu * createPopupMenu() override; + protected: + QMenu* createPopupMenu() override; /// FIXME: this shouldn't be necessary! bool reloadPackProfile(); -private: - Ui::VersionPage *ui; - QSortFilterProxyModel *m_filterModel; + private: + Ui::VersionPage* ui; + QSortFilterProxyModel* m_filterModel; std::shared_ptr m_profile; - MinecraftInstance *m_inst; + MinecraftInstance* m_inst; int currentIdx = 0; - bool controlsEnabled = false; std::shared_ptr m_wide_bar_setting = nullptr; -public slots: - void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous); + public slots: + void versionCurrent(const QModelIndex& current, const QModelIndex& previous); -private slots: - void updateRunningStatus(bool running); + private slots: void onGameUpdateError(QString error); - void packageCurrent(const QModelIndex ¤t, const QModelIndex &previous); - void showContextMenu(const QPoint &pos); - void onFilterTextChanged(const QString & newContents); + void packageCurrent(const QModelIndex& current, const QModelIndex& previous); + void showContextMenu(const QPoint& pos); + void onFilterTextChanged(const QString& newContents); }; -- cgit From 308877aa8f105de408c4c8fe87d3476116b23cf4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 9 Jul 2023 23:18:38 +0300 Subject: removed redundant code Signed-off-by: Trial97 --- launcher/ui/pages/instance/VersionPage.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 7db1b19f..a180c804 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -229,8 +229,6 @@ void VersionPage::updateVersionControls() // FIXME: this is a dirty hack auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft")); - ui->actionInstall_Forge->setEnabled(true); - bool supportsFabric = minecraftVersion >= Version("1.14"); ui->actionInstall_Fabric->setEnabled(supportsFabric); @@ -255,13 +253,6 @@ void VersionPage::updateButtons(int row) ui->actionEdit->setEnabled(patch && patch->isCustom()); ui->actionCustomize->setEnabled(patch && patch->isCustomizable()); ui->actionRevert->setEnabled(patch && patch->isRevertible()); - ui->actionDownload_All->setEnabled(true); - ui->actionAdd_Empty->setEnabled(true); - ui->actionImport_Components->setEnabled(true); - ui->actionReload->setEnabled(true); - ui->actionReplace_Minecraft_jar->setEnabled(true); - ui->actionAdd_to_Minecraft_jar->setEnabled(true); - ui->actionAdd_Agents->setEnabled(true); } bool VersionPage::reloadPackProfile() -- cgit From 99ba02afb6a7af1bc0800552338ab811b027eb9e Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 10 Jul 2023 11:26:25 -0700 Subject: Shortcuts on macOS (#1081) Co-authored-by: TheKodeToad --- launcher/FileSystem.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++-- launcher/ui/MainWindow.cpp | 44 +++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 8 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 812d45eb..4538702f 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -778,9 +778,43 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri destination = PathCombine(getDesktopDir(), RemoveInvalidFilenameChars(name)); } #if defined(Q_OS_MACOS) - destination += ".command"; + // Create the Application + QDir applicationDirectory = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + BuildConfig.LAUNCHER_NAME + " Instances/"; - QFile f(destination); + if (!applicationDirectory.mkpath(".")) { + qWarning() << "Couldn't create application directory"; + return false; + } + + QDir application = applicationDirectory.path() + "/" + name + ".app/"; + + if (application.exists()) { + qWarning() << "Application already exists!"; + return false; + } + + if (!application.mkpath(".")) { + qWarning() << "Couldn't create application"; + return false; + } + + QDir content = application.path() + "/Contents/"; + QDir resources = content.path() + "/Resources/"; + QDir binaryDir = content.path() + "/MacOS/"; + QFile info = content.path() + "/Info.plist"; + + if (!(content.mkpath(".") && resources.mkpath(".") && binaryDir.mkpath("."))) { + qWarning() << "Couldn't create directories within application"; + return false; + } + info.open(QIODevice::WriteOnly | QIODevice::Text); + + QFile(icon).rename(resources.path() + "/Icon.icns"); + + // Create the Command file + QString exec = binaryDir.path() + "/Run.command"; + + QFile f(exec); f.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&f); @@ -797,6 +831,28 @@ bool createShortcut(QString destination, QString target, QStringList args, QStri f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); + // Generate the Info.plist + QTextStream infoStream(&info); + infoStream << " \n" + "" + "\n" + "\n" + " CFBundleExecutable\n" + " Run.command\n" // The path to the executable + " CFBundleIconFile\n" + " Icon.icns\n" + " CFBundleName\n" + " " << name << "\n" // Name of the application + " CFBundlePackageType\n" + " APPL\n" + " CFBundleShortVersionString\n" + " 1.0\n" + " CFBundleVersion\n" + " 1.0\n" + "\n" + ""; + return true; #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (!destination.endsWith(".desktop")) // in case of isFlatpak destination is already populated diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 2f944472..fe364937 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1536,11 +1536,39 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() QString iconPath; QStringList args; #if defined(Q_OS_MACOS) - if (appPath.startsWith("/private/var/")) { - QMessageBox::critical(this, tr("Create instance shortcut"), - tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); - return; - } + appPath = QApplication::applicationFilePath(); + if (appPath.startsWith("/private/var/")) { + QMessageBox::critical(this, tr("Create instance shortcut"), + tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts.")); + return; + } + + auto pIcon = APPLICATION->icons()->icon(m_selectedInstance->iconKey()); + if (pIcon == nullptr) + { + pIcon = APPLICATION->icons()->icon("grass"); + } + + iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "Icon.icns"); + + QFile iconFile(iconPath); + if (!iconFile.open(QFile::WriteOnly)) + { + QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application.")); + return; + } + + QIcon icon = pIcon->icon(); + + bool success = icon.pixmap(1024, 1024).save(iconPath, "ICNS"); + iconFile.close(); + + if (!success) + { + iconFile.remove(); + QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application.")); + return; + } #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) if (appPath.startsWith("/tmp/.mount_")) { // AppImage! @@ -1623,7 +1651,11 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered() #endif 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!")); +#if not defined(Q_OS_MACOS) + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!")); +#else + QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!")); +#endif } else { #if not defined(Q_OS_MACOS) iconFile.remove(); -- cgit From 1aa5fa03f94438ce53899e4660f12e794fd8bc35 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 10 Jul 2023 12:05:01 -0700 Subject: Update launcher/ui/MainWindow.cpp Co-authored-by: TheKodeToad Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 254f229d..5a8fcc78 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1287,7 +1287,7 @@ void MainWindow::on_actionEditInstance_triggered() APPLICATION->showInstanceWindow(m_selectedInstance); } else { CustomMessageBox::selectable(this, tr("Instance not editable"), - tr("This instance is not editable. it may be broken, invalid, or too old. Check logs for details,"), + tr("This instance is not editable. It may be broken, invalid, or too old. Check logs for details."), QMessageBox::Critical)->show(); } } -- cgit From f0d2aab784fd0ff0fc495d5f0c44715887741eb1 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Jul 2023 18:05:43 +0300 Subject: feat:Added option to use system locale Signed-off-by: Trial97 --- launcher/Application.cpp | 8 ++----- launcher/translations/TranslationsModel.cpp | 29 +++++++++++++------------ launcher/translations/TranslationsModel.h | 29 ++++++++++++------------- launcher/ui/widgets/LanguageSelectionWidget.cpp | 28 ++++++++++++++---------- launcher/ui/widgets/LanguageSelectionWidget.h | 25 +++++++++++---------- 5 files changed, 61 insertions(+), 58 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 7858d713..86005ef7 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -568,6 +568,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Language m_settings->registerSetting("Language", QString()); + m_settings->registerSetting("UseSystemLocales", false); // Console m_settings->registerSetting("ShowConsole", false); @@ -918,12 +919,7 @@ bool Application::createSetupWizard() } return false; }(); - bool languageRequired = [&]() - { - if (settings()->get("Language").toString().isEmpty()) - return true; - return false; - }(); + bool languageRequired = settings()->get("Language").toString().isEmpty(); bool pasteInterventionRequired = settings()->get("PastebinURL") != ""; bool themeInterventionRequired = settings()->get("ApplicationTheme") == ""; bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired; diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 489dff86..838155a4 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -527,34 +527,34 @@ Language * TranslationsModel::findLanguage(const QString& key) } } +void TranslationsModel::setUseSystemLocale(bool useSystemLocale) +{ + APPLICATION->settings()->set("UseSystemLocales", useSystemLocale); + QLocale::setDefault(QLocale(useSystemLocale ? QString::fromStdString(std::locale().name()) : defaultLangCode)); +} + bool TranslationsModel::selectLanguage(QString key) { - QString &langCode = key; + QString& langCode = key; auto langPtr = findLanguage(key); - if (langCode.isEmpty()) - { + if (langCode.isEmpty()) { d->no_language_set = true; } - if(!langPtr) - { + if (!langPtr) { qWarning() << "Selected invalid language" << key << ", defaulting to" << defaultLangCode; langCode = defaultLangCode; - } - else - { + } else { langCode = langPtr->key; } // uninstall existing translators if there are any - if (d->m_app_translator) - { + if (d->m_app_translator) { QCoreApplication::removeTranslator(d->m_app_translator.get()); d->m_app_translator.reset(); } - if (d->m_qt_translator) - { + if (d->m_qt_translator) { QCoreApplication::removeTranslator(d->m_qt_translator.get()); d->m_qt_translator.reset(); } @@ -564,8 +564,9 @@ bool TranslationsModel::selectLanguage(QString key) * In a multithreaded application, the default locale should be set at application startup, before any non-GUI threads are created. * This function is not reentrant. */ - QLocale locale = QLocale(langCode); - QLocale::setDefault(locale); + QLocale::setDefault( + QLocale(APPLICATION->settings()->get("UseSystemLocales").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); + // if it's the default UI language, finish if(langCode == defaultLangCode) diff --git a/launcher/translations/TranslationsModel.h b/launcher/translations/TranslationsModel.h index 3abf84e6..cff23ce7 100644 --- a/launcher/translations/TranslationsModel.h +++ b/launcher/translations/TranslationsModel.h @@ -20,17 +20,16 @@ struct Language; -class TranslationsModel : public QAbstractListModel -{ +class TranslationsModel : public QAbstractListModel { Q_OBJECT -public: - explicit TranslationsModel(QString path, QObject *parent = 0); + public: + explicit TranslationsModel(QString path, QObject* parent = 0); virtual ~TranslationsModel(); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex & parent) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent) const override; bool selectLanguage(QString key); void updateLanguage(QString key); @@ -38,27 +37,27 @@ public: QString selectedLanguage(); void downloadIndex(); + void setUseSystemLocale(bool useSystemLocale); -private: - Language *findLanguage(const QString & key); + private: + Language* findLanguage(const QString& key); void reloadLocalFiles(); void downloadTranslation(QString key); void downloadNext(); // hide copy constructor - TranslationsModel(const TranslationsModel &) = delete; + TranslationsModel(const TranslationsModel&) = delete; // hide assign op - TranslationsModel &operator=(const TranslationsModel &) = delete; + TranslationsModel& operator=(const TranslationsModel&) = delete; -private slots: + private slots: void indexReceived(); void indexFailed(QString reason); void dlFailed(QString reason); void dlGood(); - void translationDirChanged(const QString &path); + void translationDirChanged(const QString& path); - -private: /* data */ + private: /* data */ struct Private; std::unique_ptr d; }; diff --git a/launcher/ui/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp index 256b09da..8b95999d 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.cpp +++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp @@ -1,16 +1,16 @@ #include "LanguageSelectionWidget.h" -#include -#include +#include #include #include +#include +#include #include "Application.h" #include "BuildConfig.h" -#include "translations/TranslationsModel.h" #include "settings/Setting.h" +#include "translations/TranslationsModel.h" -LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : - QWidget(parent) +LanguageSelectionWidget::LanguageSelectionWidget(QWidget* parent) : QWidget(parent) { verticalLayout = new QVBoxLayout(this); verticalLayout->setObjectName(QStringLiteral("verticalLayout")); @@ -31,6 +31,13 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : helpUsLabel->setWordWrap(true); verticalLayout->addWidget(helpUsLabel); + formatCheckbox = new QCheckBox(this); + formatCheckbox->setObjectName(QStringLiteral("formatCheckbox")); + formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocales").toBool() ? Qt::Checked : Qt::Unchecked); + connect(formatCheckbox, &QCheckBox::stateChanged, + [this]() { APPLICATION->translations()->setUseSystemLocale(formatCheckbox->isChecked()); }); + verticalLayout->addWidget(formatCheckbox); + auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); languageView->setModel(translations.get()); @@ -38,7 +45,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : languageView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); languageView->header()->setSectionResizeMode(0, QHeaderView::Stretch); connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageSelectionWidget::languageRowChanged); - verticalLayout->setContentsMargins(0,0,0,0); + verticalLayout->setContentsMargins(0, 0, 0, 0); auto language_setting = APPLICATION->settings()->getSetting("Language"); connect(language_setting.get(), &Setting::SettingChanged, this, &LanguageSelectionWidget::languageSettingChanged); @@ -53,15 +60,14 @@ QString LanguageSelectionWidget::getSelectedLanguageKey() const void LanguageSelectionWidget::retranslate() { QString text = tr("Don't see your language or the quality is poor?
    Help us with translations!") - .arg(BuildConfig.TRANSLATIONS_URL); + .arg(BuildConfig.TRANSLATIONS_URL); helpUsLabel->setText(text); - + formatCheckbox->setText(tr("Use system locales")); } void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, const QModelIndex& previous) { - if (current == previous) - { + if (current == previous) { return; } auto translations = APPLICATION->translations(); @@ -70,7 +76,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con translations->updateLanguage(key); } -void LanguageSelectionWidget::languageSettingChanged(const Setting &, const QVariant) +void LanguageSelectionWidget::languageSettingChanged(const Setting&, const QVariant) { auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); diff --git a/launcher/ui/widgets/LanguageSelectionWidget.h b/launcher/ui/widgets/LanguageSelectionWidget.h index 4a88924c..5e86a288 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.h +++ b/launcher/ui/widgets/LanguageSelectionWidget.h @@ -21,23 +21,24 @@ class QVBoxLayout; class QTreeView; class QLabel; class Setting; +class QCheckBox; -class LanguageSelectionWidget: public QWidget -{ +class LanguageSelectionWidget : public QWidget { Q_OBJECT -public: - explicit LanguageSelectionWidget(QWidget *parent = 0); - virtual ~LanguageSelectionWidget() { }; + public: + explicit LanguageSelectionWidget(QWidget* parent = 0); + virtual ~LanguageSelectionWidget(){}; QString getSelectedLanguageKey() const; void retranslate(); -protected slots: - void languageRowChanged(const QModelIndex ¤t, const QModelIndex &previous); - void languageSettingChanged(const Setting &, const QVariant); + protected slots: + void languageRowChanged(const QModelIndex& current, const QModelIndex& previous); + void languageSettingChanged(const Setting&, const QVariant); -private: - QVBoxLayout *verticalLayout = nullptr; - QTreeView *languageView = nullptr; - QLabel *helpUsLabel = nullptr; + private: + QVBoxLayout* verticalLayout = nullptr; + QTreeView* languageView = nullptr; + QLabel* helpUsLabel = nullptr; + QCheckBox* formatCheckbox = nullptr; }; -- cgit From 766e833a7386c9b027c02687ce345b985b4a256d Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 16:25:05 +0300 Subject: fixed crash if no version is loaded Signed-off-by: Trial97 --- launcher/ui/pages/instance/ManagedPackPage.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index d89c5bfc..0fc0c986 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -69,7 +69,6 @@ class NoBigComboBoxStyle : public QProxyStyle { private: NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {} - }; ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent) @@ -91,13 +90,13 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi // NOTE: GTK2 themes crash with the proxy style. // This seems like an upstream bug, so there's not much else that can be done. - if (!QStyleFactory::keys().contains("gtk2")){ + if (!QStyleFactory::keys().contains("gtk2")) { auto comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style()); ui->versionsComboBox->setStyle(comboStyle); } ui->reloadButton->setVisible(false); - connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool){ + connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool) { ui->reloadButton->setVisible(false); m_loaded = false; @@ -226,7 +225,8 @@ void ModrinthManagedPackPage::parseManagedPack() QString id = m_inst->getManagedPackID(); - m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); + m_fetch_job->addNetAction( + Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); QObject::connect(m_fetch_job.get(), &NetJob::succeeded, this, [this, response, id] { QJsonParseError parse_error{}; @@ -267,7 +267,6 @@ void ModrinthManagedPackPage::parseManagedPack() if (version.version == m_inst->getManagedPackVersionName()) name = tr("%1 (Current)").arg(name); - ui->versionsComboBox->addItem(name, QVariant(version.id)); } @@ -291,6 +290,10 @@ QString ModrinthManagedPackPage::url() const void ModrinthManagedPackPage::suggestVersion() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); ui->changelogTextBrowser->setHtml(markdownToHTML(version.changelog.toUtf8())); @@ -301,6 +304,10 @@ void ModrinthManagedPackPage::suggestVersion() void ModrinthManagedPackPage::update() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); QMap extra_info; @@ -429,6 +436,10 @@ QString FlameManagedPackPage::url() const void FlameManagedPackPage::suggestVersion() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); ui->changelogTextBrowser->setHtml(m_api.getModFileChangelog(m_inst->getManagedPackID().toInt(), version.fileId)); @@ -439,6 +450,10 @@ void FlameManagedPackPage::suggestVersion() void FlameManagedPackPage::update() { auto index = ui->versionsComboBox->currentIndex(); + if (m_pack.versions.length() == 0) { + setFailState(); + return; + } auto version = m_pack.versions.at(index); QMap extra_info; -- cgit From 76cc8ce0437b7047ee984993daab57b2605f52a6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jul 2023 21:05:13 +0300 Subject: renamed setting Signed-off-by: Trial97 --- launcher/Application.cpp | 2 +- launcher/translations/TranslationsModel.cpp | 4 ++-- launcher/ui/widgets/LanguageSelectionWidget.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 86005ef7..5aa9efc4 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -568,7 +568,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Language m_settings->registerSetting("Language", QString()); - m_settings->registerSetting("UseSystemLocales", false); + m_settings->registerSetting("UseSystemLocale", false); // Console m_settings->registerSetting("ShowConsole", false); diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index e6bc06a6..2763cca2 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -530,7 +530,7 @@ Language * TranslationsModel::findLanguage(const QString& key) void TranslationsModel::setUseSystemLocale(bool useSystemLocale) { - APPLICATION->settings()->set("UseSystemLocales", useSystemLocale); + APPLICATION->settings()->set("UseSystemLocale", useSystemLocale); QLocale::setDefault(QLocale(useSystemLocale ? QString::fromStdString(std::locale().name()) : defaultLangCode)); } @@ -566,7 +566,7 @@ bool TranslationsModel::selectLanguage(QString key) * This function is not reentrant. */ QLocale::setDefault( - QLocale(APPLICATION->settings()->get("UseSystemLocales").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); + QLocale(APPLICATION->settings()->get("UseSystemLocale").toBool() ? QString::fromStdString(std::locale().name()) : langCode)); // if it's the default UI language, finish diff --git a/launcher/ui/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp index 8b95999d..37d05347 100644 --- a/launcher/ui/widgets/LanguageSelectionWidget.cpp +++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp @@ -33,7 +33,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget* parent) : QWidget(pare formatCheckbox = new QCheckBox(this); formatCheckbox->setObjectName(QStringLiteral("formatCheckbox")); - formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocales").toBool() ? Qt::Checked : Qt::Unchecked); + formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocale").toBool() ? Qt::Checked : Qt::Unchecked); connect(formatCheckbox, &QCheckBox::stateChanged, [this]() { APPLICATION->translations()->setUseSystemLocale(formatCheckbox->isChecked()); }); verticalLayout->addWidget(formatCheckbox); -- cgit From 89aaedc06c3eb7a035d8be593a7bbe417cb2f712 Mon Sep 17 00:00:00 2001 From: seth Date: Wed, 12 Jul 2023 21:10:48 -0400 Subject: feat: add toggle for quilt beacon Signed-off-by: seth --- launcher/Application.cpp | 4 ++++ launcher/minecraft/MinecraftInstance.cpp | 10 +++++++++- launcher/ui/pages/global/MinecraftPage.cpp | 6 ++++++ launcher/ui/pages/global/MinecraftPage.ui | 16 ++++++++++++++++ .../ui/pages/instance/InstanceSettingsPage.cpp | 15 ++++++++++++++- launcher/ui/pages/instance/InstanceSettingsPage.ui | 22 ++++++++++++++++++++++ 6 files changed, 71 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5aa9efc4..f9859429 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -9,6 +9,7 @@ * Copyright (C) 2022 Tayou * Copyright (C) 2023 TheKodeToad * Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * Copyright (C) 2023 seth * * 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 @@ -605,6 +606,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("IgnoreJavaCompatibility", false); m_settings->registerSetting("IgnoreJavaWizard", false); + // Mod loader settings + m_settings->registerSetting("DisableQuiltBeacon", false); + // Native library workarounds m_settings->registerSetting("UseNativeOpenAL", false); m_settings->registerSetting("UseNativeGLFW", false); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 4867cc7a..180838ad 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -3,7 +3,8 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield - * Copyright (C) 2022 TheKodeToad + * Copyright (C) 2022 TheKodeToad \ + * Copyright (c) 2023 seth * * 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 @@ -186,6 +187,10 @@ void MinecraftInstance::loadSpecificSettings() m_settings->registerOverride(global_settings->getSetting("CloseAfterLaunch"), miscellaneousOverride); m_settings->registerOverride(global_settings->getSetting("QuitAfterGameStop"), miscellaneousOverride); + // Mod loader specific options + auto modLoaderSettings = m_settings->registerSetting("OverrideModLoaderSettings", false); + m_settings->registerOverride(global_settings->getSetting("DisableQuiltBeacon"), modLoaderSettings); + m_settings->set("InstanceType", "OneSix"); } @@ -391,6 +396,9 @@ QStringList MinecraftInstance::extraArguments() agent->library()->getApplicableFiles(runtimeContext(), jar, temp1, temp2, temp3, getLocalLibraryPath()); list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument())); } + if (version->getModLoaders().value() & ResourceAPI::Quilt && settings()->get("DisableQuiltBeacon").toBool()) { + list.append("-Dloader.disable_beacon=true"); + } return list; } diff --git a/launcher/ui/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index eca3e865..95482356 100644 --- a/launcher/ui/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield + * Copyright (C) 2023 seth * * 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 @@ -99,6 +100,9 @@ void MinecraftPage::applySettings() // Miscellaneous s->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked()); s->set("QuitAfterGameStop", ui->quitAfterGameStopCheck->isChecked()); + + // Mod loader settings + s->set("DisableQuiltBeacon", ui->disableQuiltBeaconCheckBox->isChecked()); } void MinecraftPage::loadSettings() @@ -137,6 +141,8 @@ void MinecraftPage::loadSettings() ui->closeAfterLaunchCheck->setChecked(s->get("CloseAfterLaunch").toBool()); ui->quitAfterGameStopCheck->setChecked(s->get("QuitAfterGameStop").toBool()); + + ui->disableQuiltBeaconCheckBox->setChecked(s->get("DisableQuiltBeacon").toBool()); } void MinecraftPage::retranslate() diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 8f5de725..7a8f107b 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -190,6 +190,22 @@ Tweaks + + + + Mod loader settings + + + + + + Disable Quilt's Beacon + + + + + + diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 943ff17f..25cc1a0d 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -3,6 +3,7 @@ * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 seth * * 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 @@ -50,9 +51,9 @@ #include "Application.h" #include "minecraft/auth/AccountList.h" +#include "FileSystem.h" #include "java/JavaInstallList.h" #include "java/JavaUtils.h" -#include "FileSystem.h" InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) @@ -280,6 +281,14 @@ void InstanceSettingsPage::applySettings() m_settings->reset("InstanceAccountId"); } + bool overrideModLoaderSettings = ui->modLoaderSettingsGroupBox->isChecked(); + m_settings->set("OverrideModLoaderSettings", overrideModLoaderSettings); + if (overrideModLoaderSettings) { + m_settings->set("DisableQuiltBeacon", ui->disableQuiltBeaconCheckBox->isChecked()); + } else { + m_settings->reset("DisableQuiltBeacon"); + } + // FIXME: This should probably be called by a signal instead m_instance->updateRuntimeContext(); } @@ -380,6 +389,10 @@ void InstanceSettingsPage::loadSettings() ui->instanceAccountGroupBox->setChecked(m_settings->get("UseAccountForInstance").toBool()); updateAccountsMenu(); + + // Mod loader specific settings + ui->modLoaderSettingsGroupBox->setChecked(m_settings->get("OverrideModLoaderSettings").toBool()); + ui->disableQuiltBeaconCheckBox->setChecked(m_settings->get("DisableQuiltBeacon").toBool()); } void InstanceSettingsPage::on_javaDetectBtn_clicked() diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 8427965d..5c6f74d4 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -541,6 +541,28 @@ Miscellaneous + + + + true + + + false + + + Mod loader settings + + + + + + Disable Quilt's Beacon + + + + + + -- cgit From 515197fba2da1d674dbe7bd17dae4e0f22f64097 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 26 Jun 2023 11:57:21 +0300 Subject: fix: html sintax for modlist export Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 16 ++++++++-------- launcher/ui/dialogs/ExportToModListDialog.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index 5e01367f..d837fb0b 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -37,13 +37,13 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) line += " by " + mod->authors().join(", "); - lines.append(QString("
      %1
    ").arg(line)); + lines.append(QString("
  • %1
  • ").arg(line)); } - return QString("
  • \n\t%1\n
  • ").arg(lines.join("\n\t")); + return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); } case MARKDOWN: { QStringList lines; @@ -61,7 +61,7 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += QString("[%1]").arg(ver); + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) line += " by " + mod->authors().join(", "); @@ -75,21 +75,21 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData auto meta = mod->metadata(); auto modName = mod->name(); - auto line = "name: " + modName + ";"; + auto line = modName; if (extraData & Url) { auto url = mod->metaurl(); if (!url.isEmpty()) - line += " url: " + url + ";"; + line += QString(" (%1)").arg(url); } if (extraData & Version) { auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); if (!ver.isEmpty()) - line += " version: " + QString("[%1]").arg(ver) + ";"; + line += QString(" [%1]").arg(ver); } if (extraData & Authors && !mod->authors().isEmpty()) - line += " authors " + mod->authors().join(", ") + ";"; + line += " by " + mod->authors().join(", "); lines << line; } return lines.join("\n"); diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 149f6b35..700e7178 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -118,7 +118,7 @@ void ExportToModListDialog::triggerImp() QString exampleLine; switch (format) { case ExportToModList::HTML: { - exampleLine = "
      {name} [{version}] by {authors}
    "; + exampleLine = "
  • {name} [{version}] by {authors}
  • "; ui->resultText->setHtml(txt); break; } -- cgit From 9a3931dac6e75a79989f13b10604a142dbafcfbb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 27 Jun 2023 16:57:30 +0300 Subject: Added json and csv format Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 56 ++++++++++++++++++++++++ launcher/modplatform/helpers/ExportToModList.h | 2 +- launcher/ui/dialogs/ExportToModListDialog.cpp | 26 ++++++++++- launcher/ui/dialogs/ExportToModListDialog.ui | 10 +++++ 4 files changed, 92 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index d837fb0b..86bb9c41 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -16,6 +16,9 @@ * along with this program. If not, see . */ #include "ExportToModList.h" +#include +#include +#include namespace ExportToModList { QString ExportToModList(QList mods, Formats format, OptionalData extraData) @@ -94,6 +97,59 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData } return lines.join("\n"); } + case JSON: { + QJsonArray lines; + for (auto mod : mods) { + auto meta = mod->metadata(); + auto modName = mod->name(); + QJsonObject line; + line["name"] = modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + line["url"] = url; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + line["version"] = ver; + } + if (extraData & Authors && !mod->authors().isEmpty()) + line["authors"] = QJsonArray::fromStringList(mod->authors()); + lines << line; + } + QJsonDocument doc; + doc.setArray(lines); + return doc.toJson(); + } + case CSV: { + QStringList lines; + for (auto mod : mods) { + QStringList data; + auto meta = mod->metadata(); + auto modName = mod->name(); + + data << modName; + if (extraData & Url) { + auto url = mod->metaurl(); + if (!url.isEmpty()) + data << url; + } + if (extraData & Version) { + auto ver = mod->version(); + if (ver.isEmpty() && meta != nullptr) + ver = meta->version().toString(); + if (!ver.isEmpty()) + data << ver; + } + if (extraData & Authors && !mod->authors().isEmpty()) + data << QString("\"%1\"").arg(mod->authors().join(",")); + lines << data.join(","); + } + return lines.join("\n"); + } default: { return QString("unknown format:%1").arg(format); } diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index 9ff8d25a..abd6e9bc 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -22,7 +22,7 @@ namespace ExportToModList { -enum Formats { HTML, MARKDOWN, PLAINTXT, CUSTOM }; +enum Formats { HTML, MARKDOWN, PLAINTXT, JSON, CSV, CUSTOM }; enum OptionalData { Authors = 1 << 0, Url = 1 << 1, diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index 700e7178..cfd28cf8 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -89,6 +89,20 @@ void ExportToModListDialog::formatChanged(int index) break; } case 3: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::JSON; + break; + } + case 4: { + ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); + ui->resultText->hide(); + format = ExportToModList::CSV; + break; + } + case 5: { ui->templateGroup->setDisabled(false); ui->optionsGroup->setDisabled(true); ui->resultText->hide(); @@ -133,6 +147,12 @@ void ExportToModListDialog::triggerImp() } case ExportToModList::CUSTOM: return; + case ExportToModList::JSON: + exampleLine = "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"},"; + break; + case ExportToModList::CSV: + exampleLine = "{name},{url},{version},\"{authors}\""; + break; } if (!m_template_selected) { if (ui->templateText->toPlainText() != exampleLine) @@ -146,7 +166,7 @@ void ExportToModListDialog::done(int result) const QString filename = FS::RemoveInvalidFilenameChars(name); const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + extension()), - "File (*.txt *.html *.md)", nullptr); + "File (*.txt *.html *.md *.json *.csv)", nullptr); if (output.isEmpty()) return; @@ -167,6 +187,10 @@ QString ExportToModListDialog::extension() return ".txt"; case ExportToModList::CUSTOM: return ".txt"; + case ExportToModList::JSON: + return ".json"; + case ExportToModList::CSV: + return ".csv"; } return ".txt"; } diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index 640b1766..e0f138f9 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -58,6 +58,16 @@ Plaintext
    + + + JSON + + + + + CSV + + Custom -- cgit From 1495bfb73ead50b45942e94a8e3b18e111820b4b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 11 Jul 2023 22:43:27 +0300 Subject: Made custom template enabled all time Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.h | 2 +- launcher/ui/dialogs/ExportToModListDialog.cpp | 53 ++++++++++++-------------- launcher/ui/dialogs/ExportToModListDialog.h | 3 +- launcher/ui/dialogs/ExportToModListDialog.ui | 14 ++++++- 4 files changed, 40 insertions(+), 32 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index abd6e9bc..49252fc4 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ #pragma once -#include +#include #include #include "minecraft/mod/Mod.h" diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index cfd28cf8..b86b1056 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -33,11 +33,19 @@ #include #include +const QHash ExportToModListDialog::exampleLines = { + { ExportToModList::HTML, "
  • {name} [{version}] by {authors}
  • " }, + { ExportToModList::MARKDOWN, "[{name}]({url}) [{version}] by {authors}" }, + { ExportToModList::PLAINTXT, "{name} ({url}) [{version}] by {authors}" }, + { ExportToModList::JSON, "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"}," }, + { ExportToModList::CSV, "{name},{url},{version},\"{authors}\"" }, +}; + ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* parent) - : QDialog(parent), m_template_selected(false), name(instance->name()), ui(new Ui::ExportToModListDialog) + : QDialog(parent), m_template_changed(false), name(instance->name()), ui(new Ui::ExportToModListDialog) { ui->setupUi(this); - ui->templateGroup->setDisabled(true); + ui->optionsGroup->setDisabled(false); MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { @@ -52,7 +60,12 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); - connect(ui->templateText, &QTextEdit::textChanged, this, &ExportToModListDialog::triggerImp); + connect(ui->templateText, &QTextEdit::textChanged, this, [this] { + if (ui->templateText->toPlainText() != exampleLines[format]) + ui->formatComboBox->setCurrentIndex(5); + else + triggerImp(); + }); connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) { this->ui->finalText->selectAll(); this->ui->finalText->copy(); @@ -68,42 +81,37 @@ void ExportToModListDialog::formatChanged(int index) { switch (index) { case 0: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->show(); format = ExportToModList::HTML; break; } case 1: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->show(); format = ExportToModList::MARKDOWN; break; } case 2: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::PLAINTXT; break; } case 3: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::JSON; break; } case 4: { - ui->templateGroup->setDisabled(true); ui->optionsGroup->setDisabled(false); ui->resultText->hide(); format = ExportToModList::CSV; break; } case 5: { - ui->templateGroup->setDisabled(false); + m_template_changed = true; ui->optionsGroup->setDisabled(true); ui->resultText->hide(); format = ExportToModList::CUSTOM; @@ -116,7 +124,6 @@ void ExportToModListDialog::formatChanged(int index) void ExportToModListDialog::triggerImp() { if (format == ExportToModList::CUSTOM) { - m_template_selected = true; ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); return; } @@ -129,35 +136,25 @@ void ExportToModListDialog::triggerImp() opt |= ExportToModList::Url; auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); ui->finalText->setPlainText(txt); - QString exampleLine; switch (format) { - case ExportToModList::HTML: { - exampleLine = "
  • {name} [{version}] by {authors}
  • "; + case ExportToModList::CUSTOM: + return; + case ExportToModList::HTML: ui->resultText->setHtml(txt); break; - } - case ExportToModList::MARKDOWN: { - exampleLine = "[{name}]({url}) [{version}] by {authors}"; + case ExportToModList::MARKDOWN: ui->resultText->setHtml(markdownToHTML(txt)); break; - } - case ExportToModList::PLAINTXT: { - exampleLine = "{name} ({url}) [{version}] by {authors}"; + case ExportToModList::PLAINTXT: break; - } - case ExportToModList::CUSTOM: - return; case ExportToModList::JSON: - exampleLine = "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"},"; break; case ExportToModList::CSV: - exampleLine = "{name},{url},{version},\"{authors}\""; break; } - if (!m_template_selected) { - if (ui->templateText->toPlainText() != exampleLine) - ui->templateText->setPlainText(exampleLine); - } + auto exampleLine = exampleLines[format]; + if (!m_template_changed && ui->templateText->toPlainText() != exampleLine) + ui->templateText->setPlainText(exampleLine); } void ExportToModListDialog::done(int result) diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h index a7a6bcdc..b8a83d83 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.h +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -45,8 +45,9 @@ class ExportToModListDialog : public QDialog { private: QString extension(); QList m_allMods; - bool m_template_selected; + bool m_template_changed; QString name; ExportToModList::Formats format = ExportToModList::Formats::HTML; Ui::ExportToModListDialog* ui; + static const QHash exampleLines; }; diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index e0f138f9..90f179a6 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -18,7 +18,7 @@
    - + @@ -149,6 +149,16 @@
    + + + + This depends on the mods meta data. To ensure the meta data run at least one time the mods update on the selected instance(no need to update the mods). + + + true + + +
    @@ -189,7 +199,7 @@ - + buttonBox rejected() ExportToModListDialog -- cgit From b9ed8283b7e22fff5920dcd81ae347822d31353a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jul 2023 20:38:08 +0300 Subject: Added buttons Signed-off-by: Trial97 --- launcher/ui/dialogs/ExportToModListDialog.cpp | 44 ++++++++++++++++++---- launcher/ui/dialogs/ExportToModListDialog.h | 2 + launcher/ui/dialogs/ExportToModListDialog.ui | 53 +++++++++++++++++++-------- 3 files changed, 76 insertions(+), 23 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index b86b1056..a0f8ee7b 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -45,7 +45,7 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare : QDialog(parent), m_template_changed(false), name(instance->name()), ui(new Ui::ExportToModListDialog) { ui->setupUi(this); - ui->optionsGroup->setDisabled(false); + enableCustom(false); MinecraftInstance* mcInstance = dynamic_cast(instance.get()); if (mcInstance) { @@ -60,6 +60,9 @@ ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* pare connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger); + connect(ui->authorsButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Authors); }); + connect(ui->versionButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Version); }); + connect(ui->urlButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Url); }); connect(ui->templateText, &QTextEdit::textChanged, this, [this] { if (ui->templateText->toPlainText() != exampleLines[format]) ui->formatComboBox->setCurrentIndex(5); @@ -81,38 +84,38 @@ void ExportToModListDialog::formatChanged(int index) { switch (index) { case 0: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->show(); format = ExportToModList::HTML; break; } case 1: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->show(); format = ExportToModList::MARKDOWN; break; } case 2: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::PLAINTXT; break; } case 3: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::JSON; break; } case 4: { - ui->optionsGroup->setDisabled(false); + enableCustom(false); ui->resultText->hide(); format = ExportToModList::CSV; break; } case 5: { m_template_changed = true; - ui->optionsGroup->setDisabled(true); + enableCustom(true); ui->resultText->hide(); format = ExportToModList::CUSTOM; break; @@ -191,3 +194,30 @@ QString ExportToModListDialog::extension() } return ".txt"; } + +void ExportToModListDialog::addExtra(ExportToModList::OptionalData option) +{ + if (format != ExportToModList::CUSTOM) + return; + switch (option) { + case ExportToModList::Authors: + ui->templateText->insertPlainText("{authors}"); + break; + case ExportToModList::Url: + ui->templateText->insertPlainText("{url}"); + break; + case ExportToModList::Version: + ui->templateText->insertPlainText("{version}"); + break; + } +} +void ExportToModListDialog::enableCustom(bool enabled) +{ + ui->authorsCheckBox->setHidden(enabled); + ui->versionCheckBox->setHidden(enabled); + ui->urlCheckBox->setHidden(enabled); + + ui->authorsButton->setHidden(!enabled); + ui->versionButton->setHidden(!enabled); + ui->urlButton->setHidden(!enabled); +} diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h index b8a83d83..9886ae5a 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.h +++ b/launcher/ui/dialogs/ExportToModListDialog.h @@ -41,9 +41,11 @@ class ExportToModListDialog : public QDialog { void formatChanged(int index); void triggerImp(); void trigger(int) { triggerImp(); }; + void addExtra(ExportToModList::OptionalData option); private: QString extension(); + void enableCustom(bool enabled); QList m_allMods; bool m_template_changed; QString name; diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index 90f179a6..fc72f9a9 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -25,22 +25,6 @@ Settings
    - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - Format - - - @@ -114,9 +98,46 @@ + + + + Version + + + + + + + Authors + + + + + + + URL + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + Format + + + -- cgit From 1ccfba13ebe11a1d6ea2897db45b47c2452931f5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 14 Jul 2023 23:39:54 +0300 Subject: renames Signed-off-by: Trial97 --- launcher/modplatform/helpers/ExportToModList.cpp | 12 ++++++------ launcher/modplatform/helpers/ExportToModList.h | 4 ++-- launcher/ui/dialogs/ExportToModListDialog.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index e7bafac4..1f01c4a8 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -47,7 +47,7 @@ QString toHTML(QList mods, OptionalData extraData) return QString("
      \n\t%1\n
    ").arg(lines.join("\n\t")); } -QString toMARKDOWN(QList mods, OptionalData extraData) +QString toMarkdown(QList mods, OptionalData extraData) { QStringList lines; for (auto mod : mods) { @@ -73,7 +73,7 @@ QString toMARKDOWN(QList mods, OptionalData extraData) return lines.join("\n"); } -QString toPLAINTXT(QList mods, OptionalData extraData) +QString toPlainTXT(QList mods, OptionalData extraData) { QStringList lines; for (auto mod : mods) { @@ -159,15 +159,15 @@ QString toCSV(QList mods, OptionalData extraData) return lines.join("\n"); } -QString ExportToModList(QList mods, Formats format, OptionalData extraData) +QString exportToModList(QList mods, Formats format, OptionalData extraData) { switch (format) { case HTML: return toHTML(mods, extraData); case MARKDOWN: - return toMARKDOWN(mods, extraData); + return toMarkdown(mods, extraData); case PLAINTXT: - return toPLAINTXT(mods, extraData); + return toPlainTXT(mods, extraData); case JSON: return toJSON(mods, extraData); case CSV: @@ -178,7 +178,7 @@ QString ExportToModList(QList mods, Formats format, OptionalData extraData } } -QString ExportToModList(QList mods, QString lineTemplate) +QString exportToModList(QList mods, QString lineTemplate) { QStringList lines; for (auto mod : mods) { diff --git a/launcher/modplatform/helpers/ExportToModList.h b/launcher/modplatform/helpers/ExportToModList.h index 49252fc4..7ea4ba9c 100644 --- a/launcher/modplatform/helpers/ExportToModList.h +++ b/launcher/modplatform/helpers/ExportToModList.h @@ -28,6 +28,6 @@ enum OptionalData { Url = 1 << 1, Version = 1 << 2, }; -QString ExportToModList(QList mods, Formats format, OptionalData extraData); -QString ExportToModList(QList mods, QString lineTemplate); +QString exportToModList(QList mods, Formats format, OptionalData extraData); +QString exportToModList(QList mods, QString lineTemplate); } // namespace ExportToModList diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp index a0f8ee7b..c811bfe6 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.cpp +++ b/launcher/ui/dialogs/ExportToModListDialog.cpp @@ -127,7 +127,7 @@ void ExportToModListDialog::formatChanged(int index) void ExportToModListDialog::triggerImp() { if (format == ExportToModList::CUSTOM) { - ui->finalText->setPlainText(ExportToModList::ExportToModList(m_allMods, ui->templateText->toPlainText())); + ui->finalText->setPlainText(ExportToModList::exportToModList(m_allMods, ui->templateText->toPlainText())); return; } auto opt = 0; @@ -137,7 +137,7 @@ void ExportToModListDialog::triggerImp() opt |= ExportToModList::Version; if (ui->urlCheckBox->isChecked()) opt |= ExportToModList::Url; - auto txt = ExportToModList::ExportToModList(m_allMods, format, static_cast(opt)); + auto txt = ExportToModList::exportToModList(m_allMods, format, static_cast(opt)); ui->finalText->setPlainText(txt); switch (format) { case ExportToModList::CUSTOM: -- cgit From da87e825a154bc87a6017270d80e4afc1b3c2e64 Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Sat, 15 Jul 2023 15:59:19 +0300 Subject: Update launcher/ui/dialogs/ExportToModListDialog.ui Co-authored-by: TheKodeToad Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/dialogs/ExportToModListDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui index fc72f9a9..25eb4342 100644 --- a/launcher/ui/dialogs/ExportToModListDialog.ui +++ b/launcher/ui/dialogs/ExportToModListDialog.ui @@ -173,7 +173,7 @@ - This depends on the mods meta data. To ensure the meta data run at least one time the mods update on the selected instance(no need to update the mods). + This depends on the mods' metadata. To ensure it is available, run an update on the instance. Installing the updates isn't necessary. true -- cgit From a2a09ffe01fe8eb6cd1f557b0feb98ed0271151e Mon Sep 17 00:00:00 2001 From: seth Date: Thu, 13 Jul 2023 20:57:38 -0400 Subject: chore: better explain quilt loader beacon Signed-off-by: seth --- launcher/minecraft/MinecraftInstance.cpp | 2 +- launcher/ui/pages/global/MinecraftPage.ui | 5 ++++- launcher/ui/pages/instance/InstanceSettingsPage.ui | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 180838ad..0833d591 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield - * Copyright (C) 2022 TheKodeToad \ + * Copyright (C) 2022 TheKodeToad * Copyright (c) 2023 seth * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 7a8f107b..a3188dcc 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -199,7 +199,10 @@ - Disable Quilt's Beacon + Disable Quilt Loader Beacon + + + Disable Quilt loader's beacon for counting monthly active users diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 5c6f74d4..323890b9 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -556,7 +556,10 @@ - Disable Quilt's Beacon + Disable Quilt Loader Beacon + + + Disable Quilt loader's beacon for counting monthly active users -- cgit From 06fc8358d9836a203cd31580fa57f055c9bcef05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 15 Jul 2023 23:57:32 +0300 Subject: auto focus search line on resource download Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourcePage.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index aab2ee89..48afbd90 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -104,6 +104,7 @@ void ResourcePage::openedImpl() updateSelectionButton(); triggerSearch(); + m_ui->searchEdit->setFocus(); } auto ResourcePage::eventFilter(QObject* watched, QEvent* event) -> bool -- cgit From 1e9a596908ba85dea974e6d041b53c675f8d7b78 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 14:18:17 +0300 Subject: simplified code in cat packs Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 43 +++++++++++++------------------------ launcher/ui/themes/ThemeManager.cpp | 15 ++++++++----- 2 files changed, 25 insertions(+), 33 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index 435ccdb8..e1f2caf3 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -61,37 +61,24 @@ QString BasicCatPack::path() JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) { - QString path = FS::PathCombine("catpacks", m_id); + QString path = manifestInfo.path(); + try { + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), + PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; + } - if (!FS::ensureFolderPathExists(path)) { - themeWarningLog() << "couldn't create folder for catpack!"; + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json:" << e.cause(); return; } - - if (manifestInfo.exists() && manifestInfo.isFile()) { - try { - auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); - const auto root = doc.object(); - m_name = Json::requireString(root, "name", "Catpack name"); - auto id = Json::ensureString(root, "id", "", "Catpack ID"); - if (!id.isEmpty()) - m_id = id; - m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Deafult Cat")); - auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); - for (auto v : variants) { - auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); - m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), - PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; - } - - } catch (const Exception& e) { - themeWarningLog() << "Couldn't load catpack json: " << e.cause(); - return; - } - } else { - themeDebugLog() << "No catpack json present."; - } } QString JsonCatPack::path() diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index d00b3a99..ba09f627 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "ui/themes/BrightTheme.h" #include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" @@ -179,13 +180,17 @@ void ThemeManager::initializeCatPacks() for (auto [id, name] : defaultCats) { addCatPack(std::unique_ptr(new BasicCatPack(id, name))); } - QDir catpacksDir("./catpacks/"); + QDir catpacksDir("catpacks"); QString catpacksFolder = catpacksDir.absoluteFilePath(""); - themeDebugLog() << "CatPacks Folder Path: " << catpacksFolder; + themeDebugLog() << "CatPacks Folder Path:" << catpacksFolder; - auto loadFiles = [this](QDir dir) { + QStringList supportedImageFormats; + for (auto format : QImageReader::supportedImageFormats()) { + supportedImageFormats.append("*." + format); + } + auto loadFiles = [this, supportedImageFormats](QDir dir) { // Load image files directly - QDirIterator ImageFileIterator(dir.absoluteFilePath(""), { "*.png", "*.gif", "*.jpg", "*.apng", "*.jxl", "*.avif" }, QDir::Files); + QDirIterator ImageFileIterator(dir.absoluteFilePath(""), supportedImageFormats, QDir::Files); while (ImageFileIterator.hasNext()) { QFile customCatFile(ImageFileIterator.next()); QFileInfo customCatFileInfo(customCatFile); @@ -200,7 +205,7 @@ void ThemeManager::initializeCatPacks() while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); - if (manifest.exists()) { + if (manifest.isFile()) { // Load background manifest themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); addCatPack(std::unique_ptr(new JsonCatPack(manifest))); -- cgit From de30a72c4e1f051eef2a0bd389fc51e6a64d54c3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 15:16:16 +0300 Subject: made the date a object Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 58 +++++++++++++++++++++++-------------- launcher/ui/themes/CatPack.h | 7 ----- launcher/ui/themes/ThemeManager.cpp | 21 ++++++++++---- 3 files changed, 53 insertions(+), 33 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index e1f2caf3..ebb100a4 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -39,7 +39,6 @@ #include #include "FileSystem.h" #include "Json.h" -#include "ui/themes/ThemeManager.h" QString BasicCatPack::path() { @@ -59,39 +58,56 @@ QString BasicCatPack::path() return cat; } +JsonCatPack::PartialDate partialDate(QJsonObject date) +{ + auto month = Json::ensureInteger(date, "month", 1); + if (month > 12) + month = 12; + else if (month <= 0) + month = 1; + auto day = Json::ensureInteger(date, "day", 1); + if (day > 31) + day = 31; + else if (day <= 0) + day = 1; + return { month, day }; +}; + JsonCatPack::JsonCatPack(QFileInfo& manifestInfo) : BasicCatPack(manifestInfo.dir().dirName()) { QString path = manifestInfo.path(); - try { - auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); - const auto root = doc.object(); - m_name = Json::requireString(root, "name", "Catpack name"); - m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); - auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); - for (auto v : variants) { - auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); - m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), - PartialDate(Json::requireString(variant, "startTime", "Variant startTime")), - PartialDate(Json::requireString(variant, "endTime", "Variant endTime")) }; - } - - } catch (const Exception& e) { - themeWarningLog() << "Couldn't load catpack json:" << e.cause(); - return; + auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "CatPack JSON file"); + const auto root = doc.object(); + m_name = Json::requireString(root, "name", "Catpack name"); + m_defaultPath = FS::PathCombine(path, Json::requireString(root, "default", "Default Cat")); + auto variants = Json::ensureArray(root, "variants", QJsonArray(), "Catpack Variants"); + for (auto v : variants) { + auto variant = Json::ensureObject(v, QJsonObject(), "Cat variant"); + m_variants << Variant{ FS::PathCombine(path, Json::requireString(variant, "path", "Variant path")), + partialDate(Json::requireObject(variant, "startTime", "Variant startTime")), + partialDate(Json::requireObject(variant, "endTime", "Variant endTime")) }; } } +QDate ensureDay(int year, int month, int day) +{ + QDate date(year, month, 1); + if (day > date.daysInMonth()) + day = date.daysInMonth(); + return QDate(year, month, day); +} + QString JsonCatPack::path() { const QDate now = QDate::currentDate(); for (auto var : m_variants) { - QDate startDate(now.year(), var.startTime.month, var.startTime.day); - QDate endDate(now.year(), var.endTime.month, var.endTime.day); + QDate startDate = ensureDay(now.year(), var.startTime.month, var.startTime.day); + QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day); if (startDate > endDate) { // it's spans over multiple years if (endDate <= now) // end date is in the past so jump one year into the future for endDate - endDate = endDate.addYears(1); + endDate = ensureDay(now.year() + 1, var.endTime.month, var.endTime.day); else // end date is in the future so jump one year into the past for startDate - startDate = startDate.addYears(-1); + startDate = ensureDay(now.year() - 1, var.startTime.month, var.startTime.day); } if (startDate >= now && now >= endDate) diff --git a/launcher/ui/themes/CatPack.h b/launcher/ui/themes/CatPack.h index 20cb8f61..b03a19f0 100644 --- a/launcher/ui/themes/CatPack.h +++ b/launcher/ui/themes/CatPack.h @@ -74,13 +74,6 @@ class FileCatPack : public BasicCatPack { class JsonCatPack : public BasicCatPack { public: struct PartialDate { - PartialDate(QString d) - { - auto sp = d.split("-"); - day = sp[0].toInt(); - if (sp.length() >= 2) - month = sp[1].toInt(); - } int month; int day; }; diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index ba09f627..683642d7 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "Exception.h" #include "ui/themes/BrightTheme.h" #include "ui/themes/CatPack.h" #include "ui/themes/CustomTheme.h" @@ -43,7 +44,10 @@ ThemeManager::ThemeManager(MainWindow* mainWindow) QString ThemeManager::addTheme(std::unique_ptr theme) { QString id = theme->id(); - m_themes.emplace(id, std::move(theme)); + if (m_themes.find(id) == m_themes.end()) + m_themes.emplace(id, std::move(theme)); + else + themeWarningLog() << "Theme(" << id << ") not added to prevent id duplication"; return id; } @@ -167,7 +171,10 @@ QString ThemeManager::getCatPack(QString catName) QString ThemeManager::addCatPack(std::unique_ptr catPack) { QString id = catPack->id(); - m_catPacks.emplace(id, std::move(catPack)); + if (m_catPacks.find(id) == m_catPacks.end()) + m_catPacks.emplace(id, std::move(catPack)); + else + themeWarningLog() << "CatPack(" << id << ") not added to prevent id duplication"; return id; } @@ -206,9 +213,13 @@ void ThemeManager::initializeCatPacks() QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); if (manifest.isFile()) { - // Load background manifest - themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); - addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + try { + // Load background manifest + themeDebugLog() << "Loading background manifest from:" << manifest.absoluteFilePath(); + addCatPack(std::unique_ptr(new JsonCatPack(manifest))); + } catch (const Exception& e) { + themeWarningLog() << "Couldn't load catpack json:" << e.cause(); + } } else { loadFiles(dir); } -- cgit From 251055302eec0232a89f0466efe3e7e7f3fa7de3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 20:53:58 +0300 Subject: format Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 148 +++++++++----------- launcher/MMCZip.h | 198 +++++++++++++-------------- launcher/ui/dialogs/ExportInstanceDialog.cpp | 70 ++++------ launcher/ui/dialogs/ExportInstanceDialog.h | 22 ++- 4 files changed, 196 insertions(+), 242 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 1a336375..4e932a76 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -33,56 +33,48 @@ * limitations under the License. */ +#include "MMCZip.h" #include #include #include -#include "MMCZip.h" #include "FileSystem.h" #include #include // ours -bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, const FilterFunction filter) +bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) { QuaZip modZip(from.filePath()); modZip.open(QuaZip::mdUnzip); QuaZipFile fileInsideMod(&modZip); QuaZipFile zipOutFile(into); - for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) - { + for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) { QString filename = modZip.getCurrentFileName(); - if (filter && !filter(filename)) - { - qDebug() << "Skipping file " << filename << " from " - << from.fileName() << " - filtered"; + if (filter && !filter(filename)) { + qDebug() << "Skipping file " << filename << " from " << from.fileName() << " - filtered"; continue; } - if (contained.contains(filename)) - { - qDebug() << "Skipping already contained file " << filename << " from " - << from.fileName(); + if (contained.contains(filename)) { + qDebug() << "Skipping already contained file " << filename << " from " << from.fileName(); continue; } contained.insert(filename); - if (!fileInsideMod.open(QIODevice::ReadOnly)) - { + if (!fileInsideMod.open(QIODevice::ReadOnly)) { qCritical() << "Failed to open " << filename << " from " << from.fileName(); return false; } QuaZipNewInfo info_out(fileInsideMod.getActualFileName()); - if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) - { + if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) { qCritical() << "Failed to open " << filename << " in the jar"; fileInsideMod.close(); return false; } - if (!JlCompress::copyData(fileInsideMod, zipOutFile)) - { + if (!JlCompress::copyData(fileInsideMod, zipOutFile)) { zipOutFile.close(); fileInsideMod.close(); qCritical() << "Failed to copy data of " << filename << " into the jar"; @@ -94,10 +86,11 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet &containe return true; } -bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks) +bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) { QDir directory(dir); - if (!directory.exists()) return false; + if (!directory.exists()) + return false; for (auto e : files) { auto filePath = directory.relativeFilePath(e.absoluteFilePath()); @@ -109,7 +102,8 @@ bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, boo srcPath = e.canonicalFilePath(); } } - if( !JlCompress::compressFile(zip, srcPath, filePath)) return false; + if (!JlCompress::compressFile(zip, srcPath, filePath)) + return false; } return true; @@ -119,7 +113,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList { QuaZip zip(fileCompressed); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); - if(!zip.open(QuaZip::mdCreate)) { + if (!zip.open(QuaZip::mdCreate)) { QFile::remove(fileCompressed); return false; } @@ -127,7 +121,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList auto result = compressDirFiles(&zip, dir, files, followSymlinks); zip.close(); - if(zip.getZipError()!=0) { + if (zip.getZipError() != 0) { QFile::remove(fileCompressed); return false; } @@ -139,8 +133,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) { QuaZip zipOut(targetJarPath); - if (!zipOut.open(QuaZip::mdCreate)) - { + if (!zipOut.open(QuaZip::mdCreate)) { QFile::remove(targetJarPath); qCritical() << "Failed to open the minecraft.jar for modding"; return false; @@ -151,37 +144,29 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const // Modify the jar // This needs to be done in reverse-order to ensure we respect the loading order of components - for (auto i = mods.crbegin(); i != mods.crend(); i++) - { + for (auto i = mods.crbegin(); i != mods.crend(); i++) { const auto* mod = *i; // do not merge disabled mods. if (!mod->enabled()) continue; - if (mod->type() == ResourceType::ZIPFILE) - { - if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles)) - { + if (mod->type() == ResourceType::ZIPFILE) { + if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } - } - else if (mod->type() == ResourceType::SINGLEFILE) - { + } else if (mod->type() == ResourceType::SINGLEFILE) { // FIXME: buggy - does not work with addedFiles auto filename = mod->fileinfo(); - if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) - { + if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } addedFiles.insert(filename.fileName()); - } - else if (mod->type() == ResourceType::FOLDER) - { + } else if (mod->type() == ResourceType::FOLDER) { // untested, but seems to be unused / not possible to reach // FIXME: buggy - does not work with addedFiles auto filename = mod->fileinfo(); @@ -197,18 +182,14 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const files.removeAll(e); } - if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) - { + if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; return false; } - qDebug() << "Adding folder " << filename.fileName() << " from " - << filename.absoluteFilePath(); - } - else - { + qDebug() << "Adding folder " << filename.fileName() << " from " << filename.absoluteFilePath(); + } else { // Make sure we do not continue launching when something is missing or undefined... zipOut.close(); QFile::remove(targetJarPath); @@ -217,8 +198,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const } } - if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key){return !key.contains("META-INF");})) - { + if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key) { return !key.contains("META-INF"); })) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to insert minecraft.jar contents."; @@ -227,8 +207,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const // Recompress the jar zipOut.close(); - if (zipOut.getZipError() != 0) - { + if (zipOut.getZipError() != 0) { QFile::remove(targetJarPath); qCritical() << "Failed to finalize minecraft.jar!"; return false; @@ -261,27 +240,23 @@ QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QS } // ours -bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root) +bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) { QuaZipDir rootDir(zip, root); - for(auto fileName: rootDir.entryList(QDir::Files)) - { - if(fileName == what) - { + for (auto fileName : rootDir.entryList(QDir::Files)) { + if (fileName == what) { result.append(root); return true; } } - for(auto fileName: rootDir.entryList(QDir::Dirs)) - { + for (auto fileName : rootDir.entryList(QDir::Dirs)) { findFilesInZip(zip, what, result, root + fileName); } return !result.isEmpty(); } - // ours -std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target) +std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) { auto target_top_dir = QUrl::fromLocalFile(target); @@ -289,16 +264,13 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target; auto numEntries = zip->getEntriesCount(); - if(numEntries < 0) { + if (numEntries < 0) { qWarning() << "Failed to enumerate files in archive"; return std::nullopt; - } - else if(numEntries == 0) { + } else if (numEntries == 0) { qDebug() << "Extracting empty archives seems odd..."; return extracted; - } - else if (!zip->goToFirstFile()) - { + } else if (!zip->goToFirstFile()) { qWarning() << "Failed to seek to first file in zip"; return std::nullopt; } @@ -334,7 +306,8 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) { - qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" << target; + qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" + << target; return std::nullopt; } @@ -345,7 +318,8 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } extracted.append(target_file_path); - QFile::setPermissions(target_file_path, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); + QFile::setPermissions(target_file_path, + QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path; } while (zip->goToNextFile()); @@ -354,7 +328,7 @@ std::optional MMCZip::extractSubDir(QuaZip *zip, const QString & su } // ours -bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &target) +bool MMCZip::extractRelFile(QuaZip* zip, const QString& file, const QString& target) { return JlCompress::extractFile(zip, file, target); } @@ -363,14 +337,14 @@ bool MMCZip::extractRelFile(QuaZip *zip, const QString &file, const QString &tar std::optional MMCZip::extractDir(QString fileCompressed, QString dir) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return QStringList(); } - qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; + qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); + ; return std::nullopt; } return MMCZip::extractSubDir(&zip, "", dir); @@ -380,14 +354,14 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString di std::optional MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return QStringList(); } - qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError();; + qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); + ; return std::nullopt; } return MMCZip::extractSubDir(&zip, subdir, dir); @@ -397,11 +371,10 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString su bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) { QuaZip zip(fileCompressed); - if (!zip.open(QuaZip::mdUnzip)) - { + if (!zip.open(QuaZip::mdUnzip)) { // check if this is a minimum size empty zip file... QFileInfo fileInfo(fileCompressed); - if(fileInfo.size() == 22) { + if (fileInfo.size() == 22) { return true; } qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); @@ -410,10 +383,14 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) return MMCZip::extractRelFile(&zip, file, target); } -bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList *files, - MMCZip::FilterFunction excludeFilter) { +bool MMCZip::collectFileListRecursively(const QString& rootDir, + const QString& subDir, + QFileInfoList* files, + MMCZip::FilterFunction excludeFilter) +{ QDir rootDirectory(rootDir); - if (!rootDirectory.exists()) return false; + if (!rootDirectory.exists()) + return false; QDir directory; if (subDir == nullptr) @@ -421,18 +398,19 @@ bool MMCZip::collectFileListRecursively(const QString& rootDir, const QString& s else directory = QDir(subDir); - if (!directory.exists()) return false; // shouldn't ever happen + if (!directory.exists()) + return false; // shouldn't ever happen // recurse directories QFileInfoList entries = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); - for (const auto& e: entries) { + for (const auto& e : entries) { if (!collectFileListRecursively(rootDir, e.filePath(), files, excludeFilter)) return false; } // collect files entries = directory.entryInfoList(QDir::Files); - for (const auto& e: entries) { + for (const auto& e : entries) { QString relativeFilePath = rootDirectory.relativeFilePath(e.absoluteFilePath()); if (excludeFilter && excludeFilter(relativeFilePath)) { qDebug() << "Skipping file " << relativeFilePath; diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 2a78f830..c7cabdc5 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -35,110 +35,108 @@ #pragma once -#include #include #include -#include "minecraft/mod/Mod.h" +#include #include +#include "minecraft/mod/Mod.h" #include #include -namespace MMCZip -{ - using FilterFunction = std::function; - - /** - * Merge two zip files, using a filter function - */ - bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, - const FilterFunction filter = nullptr); - - /** - * Compress directory, by providing a list of files to compress - * \param zip target archive - * \param dir directory that will be compressed (to compress with relative paths) - * \param files list of files to compress - * \param followSymlinks should follow symlinks when compressing file data - * \return true for success or false for failure - */ - bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks = false); - - /** - * Compress directory, by providing a list of files to compress - * \param fileCompressed target archive file - * \param dir directory that will be compressed (to compress with relative paths) - * \param files list of files to compress - * \param followSymlinks should follow symlinks when compressing file data - * \return true for success or false for failure - */ - bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); - - /** - * take a source jar, add mods to it, resulting in target jar - */ - bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods); - - /** - * Find a single file in archive by file name (not path) - * - * \param ignore_paths paths to skip when recursing the search - * - * \return the path prefix where the file is - */ - QString findFolderOfFileInZip(QuaZip * zip, const QString & what, const QStringList& ignore_paths = {}, const QString &root = QString("")); - - /** - * Find a multiple files of the same name in archive by file name - * If a file is found in a path, no deeper paths are searched - * - * \return true if anything was found - */ - bool findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString()); - - /** - * Extract a subdirectory from an archive - */ - std::optional extractSubDir(QuaZip *zip, const QString & subdir, const QString &target); - - bool extractRelFile(QuaZip *zip, const QString & file, const QString &target); - - /** - * Extract a whole archive. - * - * \param fileCompressed The name of the archive. - * \param dir The directory to extract to, the current directory if left empty. - * \return The list of the full paths of the files extracted, empty on failure. - */ - std::optional extractDir(QString fileCompressed, QString dir); - - /** - * Extract a subdirectory from an archive - * - * \param fileCompressed The name of the archive. - * \param subdir The directory within the archive to extract - * \param dir The directory to extract to, the current directory if left empty. - * \return The list of the full paths of the files extracted, empty on failure. - */ - std::optional extractDir(QString fileCompressed, QString subdir, QString dir); - - /** - * Extract a single file from an archive into a directory - * - * \param fileCompressed The name of the archive. - * \param file The file within the archive to extract - * \param dir The directory to extract to, the current directory if left empty. - * \return true for success or false for failure - */ - bool extractFile(QString fileCompressed, QString file, QString dir); - - /** - * Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included. - * \param rootDir directory to start off - * \param subDir subdirectory, should be nullptr for first invocation - * \param files resulting list of QFileInfo - * \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude) - * \return true for success or false for failure - */ - bool collectFileListRecursively(const QString &rootDir, const QString &subDir, QFileInfoList *files, FilterFunction excludeFilter); -} +namespace MMCZip { +using FilterFunction = std::function; + +/** + * Merge two zip files, using a filter function + */ +bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter = nullptr); + +/** + * Compress directory, by providing a list of files to compress + * \param zip target archive + * \param dir directory that will be compressed (to compress with relative paths) + * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data + * \return true for success or false for failure + */ +bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks = false); + +/** + * Compress directory, by providing a list of files to compress + * \param fileCompressed target archive file + * \param dir directory that will be compressed (to compress with relative paths) + * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data + * \return true for success or false for failure + */ +bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); + +/** + * take a source jar, add mods to it, resulting in target jar + */ +bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods); + +/** + * Find a single file in archive by file name (not path) + * + * \param ignore_paths paths to skip when recursing the search + * + * \return the path prefix where the file is + */ +QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths = {}, const QString& root = QString("")); + +/** + * Find a multiple files of the same name in archive by file name + * If a file is found in a path, no deeper paths are searched + * + * \return true if anything was found + */ +bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root = QString()); + +/** + * Extract a subdirectory from an archive + */ +std::optional extractSubDir(QuaZip* zip, const QString& subdir, const QString& target); + +bool extractRelFile(QuaZip* zip, const QString& file, const QString& target); + +/** + * Extract a whole archive. + * + * \param fileCompressed The name of the archive. + * \param dir The directory to extract to, the current directory if left empty. + * \return The list of the full paths of the files extracted, empty on failure. + */ +std::optional extractDir(QString fileCompressed, QString dir); + +/** + * Extract a subdirectory from an archive + * + * \param fileCompressed The name of the archive. + * \param subdir The directory within the archive to extract + * \param dir The directory to extract to, the current directory if left empty. + * \return The list of the full paths of the files extracted, empty on failure. + */ +std::optional extractDir(QString fileCompressed, QString subdir, QString dir); + +/** + * Extract a single file from an archive into a directory + * + * \param fileCompressed The name of the archive. + * \param file The file within the archive to extract + * \param dir The directory to extract to, the current directory if left empty. + * \return true for success or false for failure + */ +bool extractFile(QString fileCompressed, QString file, QString dir); + +/** + * Populate a QFileInfoList with a directory tree recursively, while allowing to excludeFilter what shouldn't be included. + * \param rootDir directory to start off + * \param subDir subdirectory, should be nullptr for first invocation + * \param files resulting list of QFileInfo + * \param excludeFilter function to excludeFilter which files shouldn't be included (returning true means to excude) + * \return true for success or false for failure + */ +bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter); +} // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index cc41c394..379ec79f 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -72,7 +72,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); ui->treeView->sortByColumn(0, Qt::AscendingOrder); - connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int))); + connect(proxyModel, SIGNAL(rowsInserted(QModelIndex, int, int)), SLOT(rowsInserted(QModelIndex, int, int))); model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); model->setRootPath(root); @@ -92,32 +92,26 @@ void SaveIcon(InstancePtr m_instance) auto iconKey = m_instance->iconKey(); auto iconList = APPLICATION->icons(); auto mmcIcon = iconList->icon(iconKey); - if(!mmcIcon || mmcIcon->isBuiltIn()) { + if (!mmcIcon || mmcIcon->isBuiltIn()) { return; } auto path = mmcIcon->getFilePath(); - if(!path.isNull()) { - QFileInfo inInfo (path); - FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName())) (); + if (!path.isNull()) { + QFileInfo inInfo(path); + FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName()))(); return; } - auto & image = mmcIcon->m_images[mmcIcon->type()]; - auto & icon = image.icon; + auto& image = mmcIcon->m_images[mmcIcon->type()]; + auto& icon = image.icon; auto sizes = icon.availableSizes(); - if(sizes.size() == 0) - { + if (sizes.size() == 0) { return; } - auto areaOf = [](QSize size) - { - return size.width() * size.height(); - }; + auto areaOf = [](QSize size) { return size.width() * size.height(); }; QSize largest = sizes[0]; // find variant with largest area - for(auto size: sizes) - { - if(areaOf(largest) < areaOf(size)) - { + for (auto size : sizes) { + if (areaOf(largest) < areaOf(size)) { largest = size; } } @@ -129,11 +123,9 @@ bool ExportInstanceDialog::doExport() { auto name = FS::RemoveInvalidFilenameChars(m_instance->name()); - const QString output = QFileDialog::getSaveFileName( - this, tr("Export %1").arg(m_instance->name()), - FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); - if (output.isEmpty()) - { + const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_instance->name()), + FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); + if (output.isEmpty()) { return false; } @@ -146,8 +138,7 @@ bool ExportInstanceDialog::doExport() return false; } - if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) - { + if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } @@ -157,15 +148,11 @@ bool ExportInstanceDialog::doExport() void ExportInstanceDialog::done(int result) { savePackIgnore(); - if (result == QDialog::Accepted) - { - if (doExport()) - { + if (result == QDialog::Accepted) { + if (doExport()) { QDialog::done(QDialog::Accepted); return; - } - else - { + } else { return; } } @@ -174,15 +161,12 @@ void ExportInstanceDialog::done(int result) void ExportInstanceDialog::rowsInserted(QModelIndex parent, int top, int bottom) { - //WARNING: possible off-by-one? - for(int i = top; i < bottom; i++) - { + // WARNING: possible off-by-one? + for (int i = top; i < bottom; i++) { auto node = proxyModel->index(i, 0, parent); - if(proxyModel->shouldExpand(node)) - { + if (proxyModel->shouldExpand(node)) { auto expNode = node.parent(); - if(!expNode.isValid()) - { + if (!expNode.isValid()) { continue; } ui->treeView->expand(node); @@ -199,8 +183,7 @@ void ExportInstanceDialog::loadPackIgnore() { auto filename = ignoreFileName(); QFile ignoreFile(filename); - if(!ignoreFile.open(QIODevice::ReadOnly)) - { + if (!ignoreFile.open(QIODevice::ReadOnly)) { return; } auto data = ignoreFile.readAll(); @@ -216,12 +199,9 @@ void ExportInstanceDialog::savePackIgnore() { auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8(); auto filename = ignoreFileName(); - try - { + try { FS::write(filename, data); - } - catch (const Exception &e) - { + } catch (const Exception& e) { qWarning() << e.cause(); } } diff --git a/launcher/ui/dialogs/ExportInstanceDialog.h b/launcher/ui/dialogs/ExportInstanceDialog.h index 5e801875..20a92807 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.h +++ b/launcher/ui/dialogs/ExportInstanceDialog.h @@ -38,39 +38,37 @@ #include #include #include -#include "FileIgnoreProxy.h" #include "FastFileIconProvider.h" +#include "FileIgnoreProxy.h" class BaseInstance; typedef std::shared_ptr InstancePtr; -namespace Ui -{ +namespace Ui { class ExportInstanceDialog; } -class ExportInstanceDialog : public QDialog -{ +class ExportInstanceDialog : public QDialog { Q_OBJECT -public: - explicit ExportInstanceDialog(InstancePtr instance, QWidget *parent = 0); + public: + explicit ExportInstanceDialog(InstancePtr instance, QWidget* parent = 0); ~ExportInstanceDialog(); virtual void done(int result); -private: + private: bool doExport(); void loadPackIgnore(); void savePackIgnore(); QString ignoreFileName(); -private: - Ui::ExportInstanceDialog *ui; + private: + Ui::ExportInstanceDialog* ui; InstancePtr m_instance; - FileIgnoreProxy * proxyModel; + FileIgnoreProxy* proxyModel; FastFileIconProvider icons; -private slots: + private slots: void rowsInserted(QModelIndex parent, int top, int bottom); }; -- cgit From cadb7142f0fe5eab16198ca8079d544456a977cc Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 20:57:57 +0300 Subject: Added progress bar to Prism instance export Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 87 +++++++++++++++++++++------- launcher/MMCZip.h | 47 ++++++++++++++- launcher/ui/dialogs/ExportInstanceDialog.cpp | 38 +++++++----- launcher/ui/dialogs/ExportInstanceDialog.h | 3 +- 4 files changed, 136 insertions(+), 39 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 4e932a76..f272bc03 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * 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 @@ -41,9 +42,11 @@ #include #include +#include +namespace MMCZip { // ours -bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) +bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet& contained, const FilterFunction filter) { QuaZip modZip(from.filePath()); modZip.open(QuaZip::mdUnzip); @@ -86,7 +89,7 @@ bool MMCZip::mergeZipFiles(QuaZip* into, QFileInfo from, QSet& containe return true; } -bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) +bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool followSymlinks) { QDir directory(dir); if (!directory.exists()) @@ -109,7 +112,7 @@ bool MMCZip::compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, boo return true; } -bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) +bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) { QuaZip zip(fileCompressed); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); @@ -130,7 +133,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList } // ours -bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) +bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods) { QuaZip zipOut(targetJarPath); if (!zipOut.open(QuaZip::mdCreate)) { @@ -175,14 +178,14 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const dir.cdUp(); QString parent_dir = dir.absolutePath(); auto files = QFileInfoList(); - MMCZip::collectFileListRecursively(what_to_zip, nullptr, &files, nullptr); + collectFileListRecursively(what_to_zip, nullptr, &files, nullptr); for (auto e : files) { if (addedFiles.contains(e.filePath())) files.removeAll(e); } - if (!MMCZip::compressDirFiles(&zipOut, parent_dir, files)) { + if (!compressDirFiles(&zipOut, parent_dir, files)) { zipOut.close(); QFile::remove(targetJarPath); qCritical() << "Failed to add" << mod->fileinfo().fileName() << "to the jar."; @@ -216,7 +219,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const } // ours -QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) +QString findFolderOfFileInZip(QuaZip* zip, const QString& what, const QStringList& ignore_paths, const QString& root) { QuaZipDir rootDir(zip, root); for (auto&& fileName : rootDir.entryList(QDir::Files)) { @@ -240,7 +243,7 @@ QString MMCZip::findFolderOfFileInZip(QuaZip* zip, const QString& what, const QS } // ours -bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) +bool findFilesInZip(QuaZip* zip, const QString& what, QStringList& result, const QString& root) { QuaZipDir rootDir(zip, root); for (auto fileName : rootDir.entryList(QDir::Files)) { @@ -256,7 +259,7 @@ bool MMCZip::findFilesInZip(QuaZip* zip, const QString& what, QStringList& resul } // ours -std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) +std::optional extractSubDir(QuaZip* zip, const QString& subdir, const QString& target) { auto target_top_dir = QUrl::fromLocalFile(target); @@ -328,13 +331,13 @@ std::optional MMCZip::extractSubDir(QuaZip* zip, const QString& sub } // ours -bool MMCZip::extractRelFile(QuaZip* zip, const QString& file, const QString& target) +bool extractRelFile(QuaZip* zip, const QString& file, const QString& target) { return JlCompress::extractFile(zip, file, target); } // ours -std::optional MMCZip::extractDir(QString fileCompressed, QString dir) +std::optional extractDir(QString fileCompressed, QString dir) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -347,11 +350,11 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString di ; return std::nullopt; } - return MMCZip::extractSubDir(&zip, "", dir); + return extractSubDir(&zip, "", dir); } // ours -std::optional MMCZip::extractDir(QString fileCompressed, QString subdir, QString dir) +std::optional extractDir(QString fileCompressed, QString subdir, QString dir) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -364,11 +367,11 @@ std::optional MMCZip::extractDir(QString fileCompressed, QString su ; return std::nullopt; } - return MMCZip::extractSubDir(&zip, subdir, dir); + return extractSubDir(&zip, subdir, dir); } // ours -bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) +bool extractFile(QString fileCompressed, QString file, QString target) { QuaZip zip(fileCompressed); if (!zip.open(QuaZip::mdUnzip)) { @@ -380,13 +383,10 @@ bool MMCZip::extractFile(QString fileCompressed, QString file, QString target) qWarning() << "Could not open archive for unzipping:" << fileCompressed << "Error:" << zip.getZipError(); return false; } - return MMCZip::extractRelFile(&zip, file, target); + return extractRelFile(&zip, file, target); } -bool MMCZip::collectFileListRecursively(const QString& rootDir, - const QString& subDir, - QFileInfoList* files, - MMCZip::FilterFunction excludeFilter) +bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter) { QDir rootDirectory(rootDir); if (!rootDirectory.exists()) @@ -417,7 +417,52 @@ bool MMCZip::collectFileListRecursively(const QString& rootDir, continue; } - files->append(e); // we want the original paths for MMCZip::compressDirFiles + files->append(e); // we want the original paths for compressDirFiles } return true; } + +void ExportToZipTask::executeTask() +{ + (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { + setStatus("Adding files..."); + setProgress(0, m_files.length()); + if (!m_dir.exists()) { + emitFailed(tr("Folder doesn't exist")); + return; + } + if (!m_output->isOpen() && !m_output->open(QuaZip::mdCreate)) { + emitFailed(tr("Could not create file")); + return; + } + + for (const QFileInfo& file : m_files) { + if (!isRunning()) + return; + + auto absolute = file.absoluteFilePath(); + auto relative = m_dir.relativeFilePath(absolute); + setStatus("Compresing: " + relative); + setProgress(m_progress + 1, m_progressTotal); + if (m_followSymlinks) { + if (file.isSymLink()) + absolute = file.symLinkTarget(); + else + absolute = file.canonicalFilePath(); + } + + if (!JlCompress::compressFile(m_output, absolute, m_destinationPrefix + relative)) { + emitFailed(tr("Could not read and compress %1").arg(relative)); + return; + } + } + + m_output->close(); + if (m_output->getZipError() != 0) { + emitFailed(tr("A zip error occurred")); + return; + } + emitSucceeded(); + }); +} +} // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index c7cabdc5..728dd3c8 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (c) 2023 Trial97 * * 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 @@ -35,14 +36,16 @@ #pragma once +#include +#include +#include #include #include #include #include -#include "minecraft/mod/Mod.h" - -#include #include +#include "minecraft/mod/Mod.h" +#include "tasks/Task.h" namespace MMCZip { using FilterFunction = std::function; @@ -139,4 +142,42 @@ bool extractFile(QString fileCompressed, QString file, QString dir); * \return true for success or false for failure */ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, QFileInfoList* files, FilterFunction excludeFilter); + +class ExportToZipTask : public Task { + public: + ExportToZipTask(QuaZip* output, + QDir dir, + QFileInfoList files, + QString destinationPrefix = "", + bool followSymlinks = false, + bool cleanUp = false) + : m_output(output) + , m_dir(dir) + , m_files(files) + , m_destinationPrefix(destinationPrefix) + , m_followSymlinks(followSymlinks) + , m_cleanUp(cleanUp) + { + setAbortable(true); + }; + ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) + : ExportToZipTask(new QuaZip(outputPath), QDir(dir), files, destinationPrefix, followSymlinks, true){}; + + virtual ~ExportToZipTask() + { + if (m_cleanUp) + delete m_output; + } + + protected: + virtual void executeTask() override; + + private: + QuaZip* m_output; + QDir m_dir; + QFileInfoList m_files; + QString m_destinationPrefix; + bool m_followSymlinks; + bool m_cleanUp; +}; } // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 379ec79f..1a3f8cd4 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -3,6 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2023 TheKodeToad + * Copyright (c) 2023 Trial97 * * 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 @@ -41,6 +42,9 @@ #include #include #include "FileIgnoreProxy.h" +#include "QObjectPtr.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui_ExportInstanceDialog.h" #include @@ -119,14 +123,15 @@ void SaveIcon(InstancePtr m_instance) pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png")); } -bool ExportInstanceDialog::doExport() +void ExportInstanceDialog::doExport() { auto name = FS::RemoveInvalidFilenameChars(m_instance->name()); const QString output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_instance->name()), FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr); if (output.isEmpty()) { - return false; + QDialog::done(QDialog::Rejected); + return; } SaveIcon(m_instance); @@ -135,26 +140,31 @@ bool ExportInstanceDialog::doExport() if (!MMCZip::collectFileListRecursively(m_instance->instanceRoot(), nullptr, &files, std::bind(&FileIgnoreProxy::filterFile, proxyModel, std::placeholders::_1))) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); - return false; + QDialog::done(QDialog::Rejected); + return; } - if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) { - QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); - return false; - } - return true; + auto task = makeShared(output, m_instance->instanceRoot(), files, "", true); + + connect(task.get(), &Task::failed, this, [this, output](QString reason) { + CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); + QFile::remove(output); + }); + connect(task.get(), &Task::aborted, this, [output] { QFile::remove(output); }); + connect(task.get(), &Task::finished, this, [task] { task->deleteLater(); }); + + ProgressDialog progress(this); + progress.setSkipButton(true, tr("Abort")); + auto result = progress.execWithTask(task.get()); + QDialog::done(result); } void ExportInstanceDialog::done(int result) { savePackIgnore(); if (result == QDialog::Accepted) { - if (doExport()) { - QDialog::done(QDialog::Accepted); - return; - } else { - return; - } + doExport(); + return; } QDialog::done(result); } diff --git a/launcher/ui/dialogs/ExportInstanceDialog.h b/launcher/ui/dialogs/ExportInstanceDialog.h index 20a92807..02f38f63 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.h +++ b/launcher/ui/dialogs/ExportInstanceDialog.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2023 TheKodeToad + * Copyright (c) 2023 Trial97 * * 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 @@ -58,7 +59,7 @@ class ExportInstanceDialog : public QDialog { virtual void done(int result); private: - bool doExport(); + void doExport(); void loadPackIgnore(); void savePackIgnore(); QString ignoreFileName(); -- cgit From ec32618e1158beba1cf5b4c91c3835a233eceeeb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 10:20:22 +0300 Subject: reveted back to add years Signed-off-by: Trial97 --- launcher/ui/themes/CatPack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/CatPack.cpp b/launcher/ui/themes/CatPack.cpp index ebb100a4..f0d8ddd5 100644 --- a/launcher/ui/themes/CatPack.cpp +++ b/launcher/ui/themes/CatPack.cpp @@ -105,9 +105,9 @@ QString JsonCatPack::path() QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day); if (startDate > endDate) { // it's spans over multiple years if (endDate <= now) // end date is in the past so jump one year into the future for endDate - endDate = ensureDay(now.year() + 1, var.endTime.month, var.endTime.day); + endDate = endDate.addYears(1); else // end date is in the future so jump one year into the past for startDate - startDate = ensureDay(now.year() - 1, var.startTime.month, var.startTime.day); + startDate = startDate.addYears(-1); } if (startDate >= now && now >= endDate) -- cgit From b0940d696baa24ddcf29a5d3393196c1047dcd3f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 17:42:15 +0300 Subject: Added QFutureWatcher Signed-off-by: Trial97 abort forgot Signed-off-by: Trial97 --- launcher/MMCZip.cpp | 59 +++++++++++++++++++--------- launcher/MMCZip.h | 20 +++++++++- launcher/ui/dialogs/ExportInstanceDialog.cpp | 7 +--- 3 files changed, 60 insertions(+), 26 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index cc749197..acd6bf7e 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -424,36 +424,35 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q void ExportToZipTask::executeTask() { - (void)QtConcurrent::run(QThreadPool::globalInstance(), [this]() { exportZip(); }); + setStatus("Adding files..."); + setProgress(0, m_files.length()); + m_build_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return exportZip(); }); + connect(&m_build_zip_watcher, &QFutureWatcher::finished, this, &ExportToZipTask::finish); + m_build_zip_watcher.setFuture(m_build_zip_future); } -void ExportToZipTask::exportZip() +auto ExportToZipTask::exportZip() -> ZipResult { - setStatus("Adding files..."); - setProgress(0, m_files.length()); if (!m_dir.exists()) { - emitFailed(tr("Folder doesn't exist")); - return; + return ZipResult(tr("Folder doesn't exist")); } if (!m_output.isOpen() && !m_output.open(QuaZip::mdCreate)) { - emitFailed(tr("Could not create file")); - return; + return ZipResult(tr("Could not create file")); } for (auto fileName : m_extra_files.keys()) { - if (!isRunning()) - return; + if (m_build_zip_future.isCanceled()) + return ZipResult(); QuaZipFile indexFile(&m_output); if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))) { - emitFailed(tr("Could not create:") + fileName); - return; + return ZipResult(tr("Could not create:") + fileName); } indexFile.write(m_extra_files[fileName]); } for (const QFileInfo& file : m_files) { - if (!isRunning()) - return; + if (m_build_zip_future.isCanceled()) + return ZipResult(); auto absolute = file.absoluteFilePath(); auto relative = m_dir.relativeFilePath(absolute); @@ -467,17 +466,39 @@ void ExportToZipTask::exportZip() } if (!m_exclude_files.contains(relative) && !JlCompress::compressFile(&m_output, absolute, m_destination_prefix + relative)) { - emitFailed(tr("Could not read and compress %1").arg(relative)); - return; + return ZipResult(tr("Could not read and compress %1").arg(relative)); } } m_output.close(); if (m_output.getZipError() != 0) { - emitFailed(tr("A zip error occurred")); - return; + return ZipResult(tr("A zip error occurred")); + } + return ZipResult(); +} + +void ExportToZipTask::finish() +{ + if (m_build_zip_future.isCanceled()) { + QFile::remove(m_output_path); + emitAborted(); + } else if (auto result = m_build_zip_future.result(); result.has_value()) { + QFile::remove(m_output_path); + emitFailed(result.value()); + } else { + emitSucceeded(); + } +} + +bool ExportToZipTask::abort() +{ + if (m_build_zip_future.isRunning()) { + m_build_zip_future.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not occur + // immediately. + return true; } - emitSucceeded(); + return false; } } // namespace MMCZip \ No newline at end of file diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index ce76bc77..bc527ad1 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include @@ -148,7 +150,12 @@ bool collectFileListRecursively(const QString& rootDir, const QString& subDir, Q class ExportToZipTask : public Task { public: ExportToZipTask(QString outputPath, QDir dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false) - : m_output(outputPath), m_dir(dir), m_files(files), m_destination_prefix(destinationPrefix), m_follow_symlinks(followSymlinks) + : m_output_path(outputPath) + , m_output(outputPath) + , m_dir(dir) + , m_files(files) + , m_destination_prefix(destinationPrefix) + , m_follow_symlinks(followSymlinks) { setAbortable(true); }; @@ -160,11 +167,17 @@ class ExportToZipTask : public Task { void setExcludeFiles(QStringList excludeFiles) { m_exclude_files = excludeFiles; } void addExtraFile(QString fileName, QByteArray data) { m_extra_files.insert(fileName, data); } + typedef std::optional ZipResult; + protected: virtual void executeTask() override; - void exportZip(); + bool abort() override; + + ZipResult exportZip(); + void finish(); private: + QString m_output_path; QuaZip m_output; QDir m_dir; QFileInfoList m_files; @@ -172,5 +185,8 @@ class ExportToZipTask : public Task { bool m_follow_symlinks; QStringList m_exclude_files; QHash m_extra_files; + + QFuture m_build_zip_future; + QFutureWatcher m_build_zip_watcher; }; } // namespace MMCZip diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 1a3f8cd4..d1a69b93 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -146,11 +146,8 @@ void ExportInstanceDialog::doExport() auto task = makeShared(output, m_instance->instanceRoot(), files, "", true); - connect(task.get(), &Task::failed, this, [this, output](QString reason) { - CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); - QFile::remove(output); - }); - connect(task.get(), &Task::aborted, this, [output] { QFile::remove(output); }); + connect(task.get(), &Task::failed, this, + [this, output](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); connect(task.get(), &Task::finished, this, [task] { task->deleteLater(); }); ProgressDialog progress(this); -- cgit From b7bccb905829eebea039a32edf93606f5fc5defa Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 19 Jul 2023 12:27:02 +0300 Subject: removed subdirectory flag Signed-off-by: Trial97 --- launcher/ui/themes/ThemeManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 9ed8e129..321f7db4 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -84,7 +84,7 @@ void ThemeManager::initializeThemes() QString themeFolder = QDir("./themes/").absoluteFilePath(""); themeDebugLog() << "Theme Folder Path: " << themeFolder; - QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot); while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo themeJson(dir.absoluteFilePath("theme.json")); @@ -208,7 +208,7 @@ void ThemeManager::initializeCatPacks() loadFiles(catpacksDir); - QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDirIterator directoryIterator(catpacksFolder, QDir::Dirs | QDir::NoDotAndDotDot); while (directoryIterator.hasNext()) { QDir dir(directoryIterator.next()); QFileInfo manifest(dir.absoluteFilePath("catpack.json")); -- cgit From 6a01c277e8f98797e3325a2b249e59ee95f43c7e Mon Sep 17 00:00:00 2001 From: tjw123hh Date: Mon, 24 Jul 2023 20:41:22 +0800 Subject: Delete some incorrect tags --- launcher/ui/pages/global/APIPage.ui | 2 +- launcher/ui/pages/global/JavaPage.ui | 2 +- launcher/ui/pages/global/MinecraftPage.ui | 2 +- launcher/ui/pages/instance/InstanceSettingsPage.ui | 2 +- program_info/org.prismlauncher.PrismLauncher.desktop.in | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) mode change 100644 => 100755 program_info/org.prismlauncher.PrismLauncher.desktop.in (limited to 'launcher/ui') diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 40b89d91..492741ba 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -30,7 +30,7 @@ - Services + Services diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 6749cbe4..561cf79b 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -58,7 +58,7 @@ - &PermGen: + &PermGen: permGenSpinBox diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index a3188dcc..393b0f35 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -39,7 +39,7 @@ - General + General diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 323890b9..245433fe 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -116,7 +116,7 @@ - PermGen: + PermGen: diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in old mode 100644 new mode 100755 index 20fabe9d..c85c2573 --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -1,3 +1,4 @@ +#!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=Prism Launcher -- cgit From 280f041acb449d8eafc138c48339b258a6e99c64 Mon Sep 17 00:00:00 2001 From: tjw123hh Date: Tue, 25 Jul 2023 17:35:31 +0800 Subject: Delete some incorrect `notr="true"` tags Signed-off-by: tjw123hh --- launcher/ui/pages/global/LauncherPage.h | 2 +- program_info/org.prismlauncher.PrismLauncher.desktop.in | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index 33f66f1b..e06d9897 100644 --- a/launcher/ui/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -62,7 +62,7 @@ public: QString displayName() const override { - return "Launcher"; + return tr("Launcher"); } QIcon icon() const override { diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in index c85c2573..20fabe9d 100755 --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -1,4 +1,3 @@ -#!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=Prism Launcher -- cgit From 361583edfcf7e647b7bdf6ba9b82dd810a50b845 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Wed, 26 Jul 2023 03:08:38 +0200 Subject: Ignore cache files when exporting instances Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index d1a69b93..f17a5779 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,6 +70,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); + proxyModel->blockedPaths().insert({ FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric") }); loadPackIgnore(); ui->treeView->setModel(proxyModel); -- cgit From a9fefb2eebf8ded7322b778d9a3f36bfc65cf113 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Wed, 26 Jul 2023 15:22:22 +0200 Subject: Address review comments Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index f17a5779..7b64467a 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,7 +70,8 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); - proxyModel->blockedPaths().insert({ FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric") }); + proxyModel->blockedPaths().insert( + { FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric"), FS::PathCombine(prefix, ".quilt") }); loadPackIgnore(); ui->treeView->setModel(proxyModel); -- cgit From 4a9ea832ff63a3f1f6f779b35b8a7a3e705fc6a3 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Thu, 27 Jul 2023 01:42:14 +0200 Subject: Ignore cache files entirely, also apply to modpack export Signed-off-by: LostLuma --- launcher/ui/dialogs/ExportInstanceDialog.cpp | 2 +- launcher/ui/dialogs/ExportPackDialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'launcher/ui') diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 7b64467a..d6a503cc 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -70,7 +70,7 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget* parent auto prefix = QDir(instance->instanceRoot()).relativeFilePath(instance->gameRoot()); proxyModel->ignoreFilesWithPath().insert({ FS::PathCombine(prefix, "logs"), FS::PathCombine(prefix, "crash-reports") }); proxyModel->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); - proxyModel->blockedPaths().insert( + proxyModel->ignoreFilesWithPath().insert( { FS::PathCombine(prefix, ".cache"), FS::PathCombine(prefix, ".fabric"), FS::PathCombine(prefix, ".quilt") }); loadPackIgnore(); diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp index 2abe2805..ad8db5ff 100644 --- a/launcher/ui/dialogs/ExportPackDialog.cpp +++ b/launcher/ui/dialogs/ExportPackDialog.cpp @@ -61,7 +61,7 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla // use the game root - everything outside cannot be exported const QDir root(instance->gameRoot()); proxy = new FileIgnoreProxy(instance->gameRoot(), this); - proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports" }); + proxy->ignoreFilesWithPath().insert({ "logs", "crash-reports", ".cache", ".fabric", ".quilt" }); proxy->ignoreFilesWithName().append({ ".DS_Store", "thumbs.db", "Thumbs.db" }); proxy->setSourceModel(model); -- cgit