diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index c5b13ddd3..8d998f586 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -141,16 +141,14 @@ auto Mod::version() const -> QString return details().version; } -auto Mod::homeurl() const -> QString +auto Mod::homepage() const -> QString { - return details().homeurl; -} + QString metaUrl = Resource::homepage(); -auto Mod::metaurl() const -> QString -{ - if (metadata() == nullptr) - return homeurl(); - return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); + if (metaUrl.isEmpty()) + return details().homeurl; + else + return metaUrl; } auto Mod::loaders() const -> QString diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h index a86a2fad0..228686bec 100644 --- a/launcher/minecraft/mod/Mod.h +++ b/launcher/minecraft/mod/Mod.h @@ -61,12 +61,11 @@ class Mod : public Resource { auto details() const -> const ModDetails&; auto name() const -> QString override; auto version() const -> QString; - auto homeurl() const -> QString; + auto homepage() const -> QString override; auto description() const -> QString; auto authors() const -> QStringList; auto licenses() const -> const QList&; auto issueTracker() const -> QString; - auto metaurl() const -> QString; auto side() const -> QString; auto loaders() const -> QString; auto mcVersions() const -> QString; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index c7ef145b6..d1a7b8f9c 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -95,6 +95,14 @@ auto Resource::provider() const -> QString return tr("Unknown"); } +auto Resource::homepage() const -> QString +{ + if (metadata()) + return ModPlatform::getMetaURL(metadata()->provider, metadata()->project_id); + + return {}; +} + void Resource::setMetadata(std::shared_ptr&& metadata) { if (status() == ResourceStatus::NO_METADATA) diff --git a/launcher/minecraft/mod/Resource.h b/launcher/minecraft/mod/Resource.h index f6667871a..269f65859 100644 --- a/launcher/minecraft/mod/Resource.h +++ b/launcher/minecraft/mod/Resource.h @@ -100,6 +100,7 @@ class Resource : public QObject { [[nodiscard]] auto metadata() -> std::shared_ptr { return m_metadata; } [[nodiscard]] auto metadata() const -> std::shared_ptr { return m_metadata; } [[nodiscard]] auto provider() const -> QString; + [[nodiscard]] virtual auto homepage() const -> QString; void setStatus(ResourceStatus status) { m_status = status; } void setMetadata(std::shared_ptr&& metadata); diff --git a/launcher/modplatform/helpers/ExportToModList.cpp b/launcher/modplatform/helpers/ExportToModList.cpp index aea16ab50..bddc7e320 100644 --- a/launcher/modplatform/helpers/ExportToModList.cpp +++ b/launcher/modplatform/helpers/ExportToModList.cpp @@ -28,7 +28,7 @@ QString toHTML(QList mods, OptionalData extraData) auto meta = mod->metadata(); auto modName = mod->name().toHtmlEscaped(); if (extraData & Url) { - auto url = mod->metaurl().toHtmlEscaped(); + auto url = mod->homepage().toHtmlEscaped(); if (!url.isEmpty()) modName = QString("%2").arg(url, modName); } @@ -65,7 +65,7 @@ QString toMarkdown(QList mods, OptionalData extraData) auto meta = mod->metadata(); auto modName = toMarkdownEscaped(mod->name()); if (extraData & Url) { - auto url = mod->metaurl(); + auto url = mod->homepage(); if (!url.isEmpty()) modName = QString("[%1](%2)").arg(modName, url); } @@ -95,7 +95,7 @@ QString toPlainTXT(QList mods, OptionalData extraData) auto line = modName; if (extraData & Url) { - auto url = mod->metaurl(); + auto url = mod->homepage(); if (!url.isEmpty()) line += QString(" (%1)").arg(url); } @@ -124,7 +124,7 @@ QString toJSON(QList mods, OptionalData extraData) QJsonObject line; line["name"] = modName; if (extraData & Url) { - auto url = mod->metaurl(); + auto url = mod->homepage(); if (!url.isEmpty()) line["url"] = url; } @@ -156,7 +156,7 @@ QString toCSV(QList mods, OptionalData extraData) data << modName; if (extraData & Url) - data << mod->metaurl(); + data << mod->homepage(); if (extraData & Version) { auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) @@ -203,7 +203,7 @@ QString exportToModList(QList mods, QString lineTemplate) for (auto mod : mods) { auto meta = mod->metadata(); auto modName = mod->name(); - auto url = mod->metaurl(); + auto url = mod->homepage(); auto ver = mod->version(); if (ver.isEmpty() && meta != nullptr) ver = meta->version().toString(); diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index c455045b5..0e6c5131b 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -74,6 +74,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared connect(ui->actionRemoveItem, &QAction::triggered, this, &ExternalResourcesPage::removeItem); connect(ui->actionEnableItem, &QAction::triggered, this, &ExternalResourcesPage::enableItem); connect(ui->actionDisableItem, &QAction::triggered, this, &ExternalResourcesPage::disableItem); + connect(ui->actionViewHomepage, &QAction::triggered, this, &ExternalResourcesPage::viewHomepage); connect(ui->actionViewConfigs, &QAction::triggered, this, &ExternalResourcesPage::viewConfigs); connect(ui->actionViewFolder, &QAction::triggered, this, &ExternalResourcesPage::viewFolder); @@ -301,6 +302,27 @@ void ExternalResourcesPage::disableItem() m_model->setResourceEnabled(selection.indexes(), EnableAction::DISABLE); } +void ExternalResourcesPage::viewHomepage() +{ + auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes(); + bool openedAny = false; + for (auto resource : m_model->selectedResources(selection)) { + auto url = resource->homepage(); + if (!url.isEmpty()) { + DesktopServices::openUrl(url); + openedAny = true; + } + } + + // TODO: just disable button + // just doing this for now to prevent race conditions which may be worse with implementation changes + if (!openedAny) { + CustomMessageBox::selectable(this, tr("No homepages found"), tr("None of the selected resources had an available homepage."), + QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Ok) + ->exec(); + } +} + void ExternalResourcesPage::viewConfigs() { DesktopServices::openPath(m_instance->instanceConfigFolder(), true); @@ -314,16 +336,18 @@ void ExternalResourcesPage::viewFolder() void ExternalResourcesPage::updateActions() { const bool hasSelection = ui->treeView->selectionModel()->hasSelection(); + const QModelIndexList rows = ui->treeView->selectionModel()->selectedRows(); + ui->actionUpdateItem->setEnabled(!m_model->empty()); ui->actionResetItemMetadata->setEnabled(hasSelection); - const QModelIndexList rows = ui->treeView->selectionModel()->selectedRows(); ui->actionChangeVersion->setEnabled(rows.count() == 1 && m_model->at(m_filterModel->mapToSource(rows[0]).row()).metadata() != nullptr); ui->actionRemoveItem->setEnabled(hasSelection); ui->actionEnableItem->setEnabled(hasSelection); ui->actionDisableItem->setEnabled(hasSelection); + ui->actionViewHomepage->setEnabled(hasSelection); ui->actionExportMetadata->setEnabled(!m_model->empty()); } diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index 9bbd13984..00bb5d17d 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -56,6 +56,8 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { virtual void enableItem(); virtual void disableItem(); + virtual void viewHomepage(); + virtual void viewFolder(); virtual void viewConfigs(); diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 22ab556b9..9c41f3a71 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -90,6 +90,8 @@ + + @@ -213,6 +215,17 @@ QAction::NoRole + + + false + + + View Homepage + + + View the homepages of all selected items. + + diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 17bbb3bbc..b9e0cfeef 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -107,11 +107,11 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(ui->actionChangeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion); ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, ui->actionChangeVersion); + ui->actionViewHomepage->setToolTip(tr("View the homepages of all selected mods.")); + ui->actionExportMetadata->setToolTip(tr("Export mod's metadata to text.")); connect(ui->actionExportMetadata, &QAction::triggered, this, &ModFolderPage::exportModMetadata); - ui->actionsToolbar->insertActionAfter(ui->actionDisableItem, ui->actionExportMetadata); - - ui->actionsToolbar->insertSeparator(ui->actionExportMetadata); + ui->actionsToolbar->insertActionAfter(ui->actionViewHomepage, ui->actionExportMetadata); } bool ModFolderPage::shouldDisplay() const diff --git a/launcher/ui/pages/instance/TexturePackPage.cpp b/launcher/ui/pages/instance/TexturePackPage.cpp index 648cd2ec7..990ee2b2e 100644 --- a/launcher/ui/pages/instance/TexturePackPage.cpp +++ b/launcher/ui/pages/instance/TexturePackPage.cpp @@ -74,6 +74,7 @@ TexturePackPage::TexturePackPage(MinecraftInstance* instance, std::shared_ptractionChangeVersion, &QAction::triggered, this, &TexturePackPage::changeTexturePackVersion); ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, ui->actionChangeVersion); + ui->actionViewHomepage->setToolTip(tr("View the homepages of all selected texture packs.")); } void TexturePackPage::updateFrame(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous) diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index 44f702659..2ae5d939b 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -84,7 +84,7 @@ void InfoFrame::updateWithMod(Mod const& m) QString text = ""; QString name = ""; - QString link = m.metaurl(); + QString link = m.homepage(); if (m.name().isEmpty()) name = m.internal_id(); else @@ -93,7 +93,7 @@ void InfoFrame::updateWithMod(Mod const& m) if (link.isEmpty()) text = name; else { - text = "" + name + ""; + text = "" + name + ""; } if (!m.authors().isEmpty()) text += " by " + m.authors().join(", "); @@ -145,6 +145,12 @@ void InfoFrame::updateWithMod(Mod const& m) void InfoFrame::updateWithResource(const Resource& resource) { + const QString homepage = resource.homepage(); + + if (!homepage.isEmpty()) { + + } + setName(resource.name()); setImage(); } @@ -209,14 +215,28 @@ QString InfoFrame::renderColorCodes(QString input) void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack) { - setName(renderColorCodes(resource_pack.name())); + QString name = renderColorCodes(resource_pack.name()); + + const QString homepage = resource_pack.homepage(); + if (!homepage.isEmpty()) { + name = "" + name + ""; + } + + setName(name); setDescription(renderColorCodes(resource_pack.description())); setImage(resource_pack.image({ 64, 64 })); } void InfoFrame::updateWithTexturePack(TexturePack& texture_pack) { - setName(renderColorCodes(texture_pack.name())); + QString name = renderColorCodes(texture_pack.name()); + + const QString homepage = texture_pack.homepage(); + if (!homepage.isEmpty()) { + name = "" + name + ""; + } + + setName(name); setDescription(renderColorCodes(texture_pack.description())); setImage(texture_pack.image({ 64, 64 })); }