Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feature/java-downloader
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
@@ -1560,7 +1560,7 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
|
||||
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)"));
|
||||
desktopFilePath = fileDialog.getSaveFileName(this, tr("Create Shortcut"), desktopFilePath, tr("Desktop Entries") + " (*.desktop)");
|
||||
if (desktopFilePath.isEmpty())
|
||||
return; // file dialog canceled by user
|
||||
appPath = "flatpak";
|
||||
|
||||
@@ -266,7 +266,7 @@ void BlockedModsDialog::addHashTask(QString path)
|
||||
/// @param path the path to the local file being hashed
|
||||
void BlockedModsDialog::buildHashTask(QString path)
|
||||
{
|
||||
auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::ResourceProvider::FLAME, m_hash_type);
|
||||
auto hash_task = Hashing::createHasher(path, m_hash_type);
|
||||
|
||||
qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path;
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
static ModPlatform::ProviderCapabilities ProviderCaps;
|
||||
|
||||
ChooseProviderDialog::ChooseProviderDialog(QWidget* parent, bool single_choice, bool allow_skipping)
|
||||
: QDialog(parent), ui(new Ui::ChooseProviderDialog)
|
||||
{
|
||||
@@ -78,7 +76,7 @@ void ChooseProviderDialog::addProviders()
|
||||
QRadioButton* btn;
|
||||
|
||||
for (auto& provider : { ModPlatform::ResourceProvider::MODRINTH, ModPlatform::ResourceProvider::FLAME }) {
|
||||
btn = new QRadioButton(ProviderCaps.readableName(provider), this);
|
||||
btn = new QRadioButton(ModPlatform::ProviderCapabilities::readableName(provider), this);
|
||||
m_providers.addButton(btn, btn_index++);
|
||||
ui->providersLayout->addWidget(btn);
|
||||
}
|
||||
|
||||
@@ -129,14 +129,14 @@ void ExportPackDialog::done(int result)
|
||||
QString output;
|
||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
||||
output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".mrpack"),
|
||||
"Modrinth pack (*.mrpack *.zip)", nullptr);
|
||||
tr("Modrinth pack") + " (*.mrpack *.zip)", nullptr);
|
||||
if (output.isEmpty())
|
||||
return;
|
||||
if (!(output.endsWith(".zip") || output.endsWith(".mrpack")))
|
||||
output.append(".mrpack");
|
||||
} else {
|
||||
output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".zip"),
|
||||
"CurseForge pack (*.zip)", nullptr);
|
||||
tr("CurseForge pack") + " (*.zip)", nullptr);
|
||||
if (output.isEmpty())
|
||||
return;
|
||||
if (!output.endsWith(".zip"))
|
||||
|
||||
@@ -160,7 +160,7 @@ void ExportToModListDialog::done(int result)
|
||||
const QString filename = FS::RemoveInvalidFilenameChars(m_name);
|
||||
const QString output =
|
||||
QFileDialog::getSaveFileName(this, tr("Export %1").arg(m_name), FS::PathCombine(QDir::homePath(), filename + extension()),
|
||||
"File (*.txt *.html *.md *.json *.csv)", nullptr);
|
||||
tr("File") + " (*.txt *.html *.md *.json *.csv)", nullptr);
|
||||
|
||||
if (output.isEmpty())
|
||||
return;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
#include <optional>
|
||||
|
||||
static ModPlatform::ProviderCapabilities ProviderCaps;
|
||||
|
||||
static std::list<Version> mcVersions(BaseInstance* inst)
|
||||
{
|
||||
return { static_cast<MinecraftInstance*>(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion() };
|
||||
@@ -94,17 +92,15 @@ void ModUpdateDialog::checkCandidates()
|
||||
|
||||
if (!m_modrinth_to_update.empty()) {
|
||||
m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model));
|
||||
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
|
||||
m_failed_check_update.append({ mod, reason, recover_url });
|
||||
});
|
||||
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this,
|
||||
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); });
|
||||
check_task.addTask(m_modrinth_check_task);
|
||||
}
|
||||
|
||||
if (!m_flame_to_update.empty()) {
|
||||
m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model));
|
||||
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
|
||||
m_failed_check_update.append({ mod, reason, recover_url });
|
||||
});
|
||||
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this,
|
||||
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); });
|
||||
check_task.addTask(m_flame_check_task);
|
||||
}
|
||||
|
||||
@@ -427,7 +423,7 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStri
|
||||
item_top->setExpanded(true);
|
||||
|
||||
auto provider_item = new QTreeWidgetItem(item_top);
|
||||
provider_item->setText(0, tr("Provider: %1").arg(ProviderCaps.readableName(info.provider)));
|
||||
provider_item->setText(0, tr("Provider: %1").arg(ModPlatform::ProviderCapabilities::readableName(info.provider)));
|
||||
|
||||
auto old_version_item = new QTreeWidgetItem(item_top);
|
||||
old_version_item->setText(0, tr("Old version: %1").arg(info.old_version.isEmpty() ? tr("Not installed") : info.old_version));
|
||||
|
||||
@@ -200,7 +200,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task
|
||||
importVersion.clear();
|
||||
|
||||
if (!task) {
|
||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
|
||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
|
||||
importIcon = false;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, I
|
||||
importVersion = std::move(version);
|
||||
|
||||
if (!task) {
|
||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
|
||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
|
||||
importIcon = false;
|
||||
}
|
||||
|
||||
@@ -236,6 +236,9 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QStr
|
||||
|
||||
void NewInstanceDialog::setSuggestedIcon(const QString& key)
|
||||
{
|
||||
if (key == "default")
|
||||
return;
|
||||
|
||||
auto icon = APPLICATION->icons()->getIcon(key);
|
||||
importIcon = false;
|
||||
|
||||
|
||||
@@ -92,6 +92,19 @@ void ResourceDownloadDialog::accept()
|
||||
|
||||
void ResourceDownloadDialog::reject()
|
||||
{
|
||||
auto selected = getTasks();
|
||||
if (selected.count() > 0) {
|
||||
auto reply = CustomMessageBox::selectable(this, tr("Confirmation Needed"),
|
||||
tr("You have %1 selected resources.\n"
|
||||
"Are you sure you want to close this dialog?")
|
||||
.arg(selected.count()),
|
||||
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
if (reply != QMessageBox::Yes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!geometrySaveKey().isEmpty())
|
||||
APPLICATION->settings()->set(geometrySaveKey(), saveGeometry().toBase64());
|
||||
|
||||
@@ -126,8 +139,6 @@ void ResourceDownloadDialog::connectButtons()
|
||||
connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help);
|
||||
}
|
||||
|
||||
static ModPlatform::ProviderCapabilities ProviderCaps;
|
||||
|
||||
void ResourceDownloadDialog::confirm()
|
||||
{
|
||||
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
|
||||
@@ -169,7 +180,7 @@ void ResourceDownloadDialog::confirm()
|
||||
for (auto& task : selected) {
|
||||
auto extraInfo = dependencyExtraInfo.value(task->getPack()->addonId.toString());
|
||||
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
|
||||
ProviderCaps.name(task->getProvider()), extraInfo.required_by,
|
||||
ModPlatform::ProviderCapabilities::name(task->getProvider()), extraInfo.required_by,
|
||||
task->getVersion().version_type.toString(), !extraInfo.maybe_installed });
|
||||
}
|
||||
|
||||
@@ -358,4 +369,20 @@ QList<BasePage*> ShaderPackDownloadDialog::getPages()
|
||||
return pages;
|
||||
}
|
||||
|
||||
void ModDownloadDialog::setModMetadata(std::shared_ptr<Metadata::ModStruct> meta)
|
||||
{
|
||||
switch (meta->provider) {
|
||||
case ModPlatform::ResourceProvider::MODRINTH:
|
||||
selectPage(Modrinth::id());
|
||||
break;
|
||||
case ModPlatform::ResourceProvider::FLAME:
|
||||
selectPage(Flame::id());
|
||||
break;
|
||||
}
|
||||
setWindowTitle(tr("Change %1 version").arg(meta->name));
|
||||
m_container->hidePageList();
|
||||
m_buttons.hide();
|
||||
auto page = selectedPage();
|
||||
page->openProject(meta->project_id);
|
||||
}
|
||||
} // namespace ResourceDownload
|
||||
|
||||
@@ -107,6 +107,8 @@ class ModDownloadDialog final : public ResourceDownloadDialog {
|
||||
QList<BasePage*> getPages() override;
|
||||
GetModDependenciesTask::Ptr getModDependenciesTask() override;
|
||||
|
||||
void setModMetadata(std::shared_ptr<Metadata::ModStruct>);
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ class VersionSelectDialog : public QDialog {
|
||||
|
||||
public:
|
||||
explicit VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent = 0, bool cancelable = true);
|
||||
virtual ~VersionSelectDialog(){};
|
||||
virtual ~VersionSelectDialog() {};
|
||||
|
||||
int exec() override;
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ void SkinManageDialog::selectionChanged(QItemSelection selected, QItemSelection
|
||||
auto skin = m_list.skin(key);
|
||||
if (!skin)
|
||||
return;
|
||||
ui->selectedModel->setPixmap(skin->getTexture().scaled(128, 128, Qt::KeepAspectRatio, Qt::FastTransformation));
|
||||
ui->selectedModel->setPixmap(skin->getTexture().scaled(size() * (1. / 3), Qt::KeepAspectRatio, Qt::FastTransformation));
|
||||
ui->capeCombo->setCurrentIndex(m_capes_idx.value(skin->getCapeId()));
|
||||
ui->steveBtn->setChecked(skin->getModel() == SkinModel::CLASSIC);
|
||||
ui->alexBtn->setChecked(skin->getModel() == SkinModel::SLIM);
|
||||
@@ -212,7 +212,7 @@ void SkinManageDialog::setupCapes()
|
||||
void SkinManageDialog::on_capeCombo_currentIndexChanged(int index)
|
||||
{
|
||||
auto id = ui->capeCombo->currentData();
|
||||
ui->capeImage->setPixmap(m_capes.value(id.toString(), {}));
|
||||
ui->capeImage->setPixmap(m_capes.value(id.toString(), {}).scaled(size() * (1. / 3), Qt::KeepAspectRatio, Qt::FastTransformation));
|
||||
if (auto skin = m_list.skin(m_selected_skin); skin) {
|
||||
skin->setCapeId(id.toString());
|
||||
}
|
||||
@@ -371,7 +371,7 @@ void SkinManageDialog::on_urlBtn_clicked()
|
||||
|
||||
class WaitTask : public Task {
|
||||
public:
|
||||
WaitTask() : m_loop(), m_done(false){};
|
||||
WaitTask() : m_loop(), m_done(false) {};
|
||||
virtual ~WaitTask() = default;
|
||||
|
||||
public slots:
|
||||
@@ -498,3 +498,15 @@ void SkinManageDialog::on_userBtn_clicked()
|
||||
}
|
||||
m_list.updateSkin(&s);
|
||||
}
|
||||
|
||||
void SkinManageDialog::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
QSize s = size() * (1. / 3);
|
||||
|
||||
if (auto skin = m_list.skin(m_selected_skin); skin) {
|
||||
ui->selectedModel->setPixmap(skin->getTexture().scaled(s, Qt::KeepAspectRatio, Qt::FastTransformation));
|
||||
}
|
||||
auto id = ui->capeCombo->currentData();
|
||||
ui->capeImage->setPixmap(m_capes.value(id.toString(), {}).scaled(s, Qt::KeepAspectRatio, Qt::FastTransformation));
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class SkinManageDialog : public QDialog {
|
||||
public:
|
||||
explicit SkinManageDialog(QWidget* parent, MinecraftAccountPtr acct);
|
||||
virtual ~SkinManageDialog();
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
public slots:
|
||||
void selectionChanged(QItemSelection, QItemSelection);
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -75,7 +78,10 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -4,7 +4,7 @@ class BasePage;
|
||||
|
||||
class BasePageContainer {
|
||||
public:
|
||||
virtual ~BasePageContainer(){};
|
||||
virtual ~BasePageContainer() {};
|
||||
virtual bool selectPage(QString pageId) = 0;
|
||||
virtual BasePage* selectedPage() const = 0;
|
||||
virtual BasePage* getPage(QString pageId) { return nullptr; };
|
||||
|
||||
@@ -371,7 +371,7 @@ void ModrinthManagedPackPage::update()
|
||||
|
||||
void ModrinthManagedPackPage::updateFromFile()
|
||||
{
|
||||
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), "Modrinth pack (*.mrpack *.zip)");
|
||||
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("Modrinth pack") + " (*.mrpack *.zip)");
|
||||
if (output.isEmpty())
|
||||
return;
|
||||
QMap<QString, QString> extra_info;
|
||||
@@ -538,7 +538,7 @@ void FlameManagedPackPage::update()
|
||||
|
||||
void FlameManagedPackPage::updateFromFile()
|
||||
{
|
||||
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), "CurseForge pack (*.zip)");
|
||||
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("CurseForge pack") + " (*.zip)");
|
||||
if (output.isEmpty())
|
||||
return;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class ManagedPackPage : public QWidget, public BasePage {
|
||||
|
||||
/** Gets the necessary information about the managed pack, such as
|
||||
* available versions*/
|
||||
virtual void parseManagedPack(){};
|
||||
virtual void parseManagedPack() {};
|
||||
|
||||
/** URL of the managed pack.
|
||||
* Not the version-specific one.
|
||||
@@ -64,8 +64,8 @@ class ManagedPackPage : public QWidget, public BasePage {
|
||||
*/
|
||||
virtual void suggestVersion();
|
||||
|
||||
virtual void update(){};
|
||||
virtual void updateFromFile(){};
|
||||
virtual void update() {};
|
||||
virtual void updateFromFile() {};
|
||||
|
||||
protected slots:
|
||||
/** Does the necessary UI changes for when something failed.
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "ui_ExternalResourcesPage.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QAction>
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
@@ -122,13 +123,19 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
||||
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
|
||||
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
|
||||
|
||||
auto changeVersion = new QAction(tr("Change Version"));
|
||||
changeVersion->setToolTip(tr("Change mod version"));
|
||||
changeVersion->setEnabled(false);
|
||||
ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, changeVersion);
|
||||
connect(changeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion);
|
||||
|
||||
ui->actionsToolbar->insertActionAfter(ui->actionVisitItemPage, ui->actionExportMetadata);
|
||||
connect(ui->actionExportMetadata, &QAction::triggered, this, &ModFolderPage::exportModMetadata);
|
||||
|
||||
auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); };
|
||||
|
||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
[this, check_allow_update, actionRemoveItemMetadata] {
|
||||
[this, check_allow_update, actionRemoveItemMetadata, changeVersion] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
@@ -138,11 +145,12 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
||||
if (selected <= 1) {
|
||||
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->setToolTip(tr("Go to the pages of the selected mods"));
|
||||
}
|
||||
|
||||
changeVersion->setEnabled(mods_list.length() == 1 && mods_list[0]->metadata() != nullptr);
|
||||
ui->actionVisitItemPage->setEnabled(selected != 0);
|
||||
actionRemoveItemMetadata->setEnabled(selected != 0);
|
||||
});
|
||||
@@ -377,6 +385,57 @@ void ModFolderPage::deleteModMetadata()
|
||||
m_model->deleteModsMetadata(selection);
|
||||
}
|
||||
|
||||
void ModFolderPage::changeModVersion()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||
if (!profile->getModLoaders().has_value()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Please install a mod loader first!"));
|
||||
return;
|
||||
}
|
||||
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Mod updates are unavailable when metadata is disabled!"));
|
||||
return;
|
||||
}
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto mods_list = m_model->selectedMods(selection);
|
||||
if (mods_list.length() != 1 || mods_list[0]->metadata() == nullptr)
|
||||
return;
|
||||
|
||||
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
|
||||
mdownload.setModMetadata((*mods_list.begin())->metadata());
|
||||
if (mdownload.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::aborted, [this, tasks]() {
|
||||
CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::succeeded, [this, tasks]() {
|
||||
QStringList warnings = tasks->warnings();
|
||||
if (warnings.count())
|
||||
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
||||
|
||||
tasks->deleteLater();
|
||||
});
|
||||
|
||||
for (auto& task : mdownload.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ModFolderPage::exportModMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
|
||||
@@ -67,6 +67,7 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||
void installMods();
|
||||
void updateMods(bool includeDeps = false);
|
||||
void visitModPages();
|
||||
void changeModVersion();
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ModFolderModel> m_model;
|
||||
|
||||
@@ -168,7 +168,7 @@ class ServersModel : public QAbstractListModel {
|
||||
m_saveTimer.setInterval(5000);
|
||||
connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
|
||||
}
|
||||
virtual ~ServersModel(){};
|
||||
virtual ~ServersModel() {};
|
||||
|
||||
void observe()
|
||||
{
|
||||
|
||||
@@ -297,7 +297,7 @@ void VersionPage::on_actionRemove_triggered()
|
||||
|
||||
void VersionPage::on_actionAdd_to_Minecraft_jar_triggered()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"),
|
||||
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);
|
||||
@@ -307,7 +307,7 @@ 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)"),
|
||||
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);
|
||||
@@ -317,7 +317,7 @@ void VersionPage::on_actionReplace_Minecraft_jar_triggered()
|
||||
|
||||
void VersionPage::on_actionImport_Components_triggered()
|
||||
{
|
||||
QStringList list = GuiUtil::BrowseForFiles("component", tr("Select components"), tr("Components (*.json)"),
|
||||
QStringList list = GuiUtil::BrowseForFiles("component", tr("Select components"), tr("Components") + " (*.json)",
|
||||
APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
@@ -332,7 +332,7 @@ void VersionPage::on_actionImport_Components_triggered()
|
||||
|
||||
void VersionPage::on_actionAdd_Agents_triggered()
|
||||
{
|
||||
QStringList list = GuiUtil::BrowseForFiles("agent", tr("Select agents"), tr("Java agents (*.jar)"),
|
||||
QStringList list = GuiUtil::BrowseForFiles("agent", tr("Select agents"), tr("Java agents") + " (*.jar)",
|
||||
APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||
|
||||
if (!list.isEmpty())
|
||||
|
||||
@@ -343,7 +343,7 @@ void WorldListPage::worldChanged([[maybe_unused]] const QModelIndex& current, [[
|
||||
|
||||
void WorldListPage::on_actionAdd_triggered()
|
||||
{
|
||||
auto list = GuiUtil::BrowseForFiles(displayName(), tr("Select a Minecraft world zip"), tr("Minecraft World Zip File (*.zip)"),
|
||||
auto list = GuiUtil::BrowseForFiles(displayName(), tr("Select a Minecraft world zip"), tr("Minecraft World Zip File") + " (*.zip)",
|
||||
QString(), this->parentWidget());
|
||||
if (!list.empty()) {
|
||||
m_worlds->stopWatching();
|
||||
|
||||
@@ -88,6 +88,17 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const
|
||||
});
|
||||
}
|
||||
|
||||
QVariant ModModel::getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const
|
||||
{
|
||||
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
||||
for (auto mod : allMods) {
|
||||
if (auto meta = mod->metadata(); meta && meta->provider == pack->provider && meta->project_id == pack->addonId) {
|
||||
return meta->version();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool checkSide(QString filter, QString value)
|
||||
{
|
||||
return filter.isEmpty() || value.isEmpty() || filter == "both" || value == "both" || filter == value;
|
||||
|
||||
@@ -35,6 +35,7 @@ class ModModel : public ResourceModel {
|
||||
virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0;
|
||||
|
||||
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
|
||||
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const override;
|
||||
|
||||
public slots:
|
||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||
|
||||
@@ -59,7 +59,7 @@ class ModPage : public ResourcePage {
|
||||
protected:
|
||||
ModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
|
||||
virtual void prepareProviderCategories(){};
|
||||
virtual void prepareProviderCategories() {};
|
||||
|
||||
protected slots:
|
||||
virtual void filterMods();
|
||||
|
||||
@@ -56,6 +56,7 @@ class ResourceModel : public QAbstractListModel {
|
||||
|
||||
[[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); }
|
||||
|
||||
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const { return {}; }
|
||||
/** Whether the version is opted out or not. Currently only makes sense in CF. */
|
||||
virtual bool optedOut(const ModPlatform::IndexedVersion& ver) const
|
||||
{
|
||||
|
||||
@@ -271,7 +271,9 @@ void ResourcePage::updateVersionList()
|
||||
m_ui->versionSelectionBox->clear();
|
||||
m_ui->versionSelectionBox->blockSignals(false);
|
||||
|
||||
if (current_pack)
|
||||
if (current_pack) {
|
||||
auto installedVersion = m_model->getInstalledPackVersion(current_pack);
|
||||
|
||||
for (int i = 0; i < current_pack->versions.size(); i++) {
|
||||
auto& version = current_pack->versions[i];
|
||||
if (!m_model->checkVersionFilters(version))
|
||||
@@ -280,9 +282,10 @@ void ResourcePage::updateVersionList()
|
||||
auto release_type = current_pack->versions[i].version_type.isValid()
|
||||
? QString(" [%1]").arg(current_pack->versions[i].version_type.toString())
|
||||
: "";
|
||||
m_ui->versionSelectionBox->addItem(current_pack->versions[i].version, QVariant(i));
|
||||
}
|
||||
|
||||
m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i));
|
||||
}
|
||||
}
|
||||
if (m_ui->versionSelectionBox->count() == 0) {
|
||||
m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1));
|
||||
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
|
||||
@@ -399,7 +402,7 @@ void ResourcePage::openUrl(const QUrl& url)
|
||||
}
|
||||
}
|
||||
|
||||
if (!page.isNull()) {
|
||||
if (!page.isNull() && !m_do_not_jump_to_mod) {
|
||||
const QString slug = match.captured(1);
|
||||
|
||||
// ensure the user isn't opening the same mod
|
||||
@@ -443,4 +446,52 @@ void ResourcePage::openUrl(const QUrl& url)
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
void ResourcePage::openProject(QVariant projectID)
|
||||
{
|
||||
m_ui->sortByBox->hide();
|
||||
m_ui->searchEdit->hide();
|
||||
m_ui->resourceFilterButton->hide();
|
||||
m_ui->packView->hide();
|
||||
m_ui->resourceSelectionButton->hide();
|
||||
m_do_not_jump_to_mod = true;
|
||||
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
|
||||
auto okBtn = buttonBox->button(QDialogButtonBox::Ok);
|
||||
okBtn->setDefault(true);
|
||||
okBtn->setAutoDefault(true);
|
||||
okBtn->setText(tr("Reinstall"));
|
||||
okBtn->setShortcut(tr("Ctrl+Return"));
|
||||
okBtn->setEnabled(false);
|
||||
|
||||
auto cancelBtn = buttonBox->button(QDialogButtonBox::Cancel);
|
||||
cancelBtn->setDefault(false);
|
||||
cancelBtn->setAutoDefault(false);
|
||||
|
||||
connect(okBtn, &QPushButton::clicked, this, [this] {
|
||||
onResourceSelected();
|
||||
m_parent_dialog->accept();
|
||||
});
|
||||
|
||||
connect(cancelBtn, &QPushButton::clicked, m_parent_dialog, &ResourceDownloadDialog::reject);
|
||||
m_ui->gridLayout_4->addWidget(buttonBox, 1, 2);
|
||||
|
||||
auto jump = [this, okBtn] {
|
||||
for (int row = 0; row < m_model->rowCount({}); row++) {
|
||||
const QModelIndex index = m_model->index(row);
|
||||
m_ui->packView->setCurrentIndex(index);
|
||||
okBtn->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
m_ui->packDescription->setText(tr("The resource was not found"));
|
||||
};
|
||||
|
||||
m_ui->searchEdit->setText("#" + projectID.toString());
|
||||
triggerSearch();
|
||||
|
||||
if (m_model->hasActiveSearchJob())
|
||||
connect(m_model->activeSearchJob().get(), &Task::finished, jump);
|
||||
else
|
||||
jump();
|
||||
}
|
||||
} // namespace ResourceDownload
|
||||
|
||||
@@ -83,6 +83,8 @@ class ResourcePage : public QWidget, public BasePage {
|
||||
QList<DownloadTaskPtr> selectedPacks() { return m_model->selectedPacks(); }
|
||||
bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); }
|
||||
|
||||
virtual void openProject(QVariant projectID);
|
||||
|
||||
protected slots:
|
||||
virtual void triggerSearch() = 0;
|
||||
|
||||
@@ -111,6 +113,8 @@ class ResourcePage : public QWidget, public BasePage {
|
||||
|
||||
// Used to do instant searching with a delay to cache quick changes
|
||||
QTimer m_search_timer;
|
||||
|
||||
bool m_do_not_jump_to_mod = false;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class BaseWizardPage : public QWizardPage {
|
||||
public:
|
||||
explicit BaseWizardPage(QWidget* parent = Q_NULLPTR) : QWizardPage(parent) {}
|
||||
virtual ~BaseWizardPage(){};
|
||||
virtual ~BaseWizardPage() {};
|
||||
|
||||
virtual bool wantsRefreshButton() { return false; }
|
||||
virtual void refresh() {}
|
||||
|
||||
@@ -9,7 +9,7 @@ class JavaWizardPage : public BaseWizardPage {
|
||||
public:
|
||||
explicit JavaWizardPage(QWidget* parent = Q_NULLPTR);
|
||||
|
||||
virtual ~JavaWizardPage(){};
|
||||
virtual ~JavaWizardPage() {};
|
||||
|
||||
bool wantsRefreshButton() override;
|
||||
void refresh() override;
|
||||
|
||||
@@ -27,7 +27,7 @@ class LanguageSelectionWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LanguageSelectionWidget(QWidget* parent = 0);
|
||||
virtual ~LanguageSelectionWidget(){};
|
||||
virtual ~LanguageSelectionWidget() {};
|
||||
|
||||
QString getSelectedLanguageKey() const;
|
||||
void retranslate();
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QListView>
|
||||
#include <QModelIndex>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -86,6 +87,8 @@ class PageContainer : public QWidget, public BasePageContainer {
|
||||
|
||||
void changeEvent(QEvent*) override;
|
||||
|
||||
void hidePageList() { m_pageList->hide(); }
|
||||
|
||||
private:
|
||||
void createUI();
|
||||
void retranslate();
|
||||
|
||||
Reference in New Issue
Block a user