Fix crash when selecting same mod from different providers (#1029)
This commit is contained in:

committed by
GitHub

parent
0ece0b5b27
commit
1840505a0f
@ -20,14 +20,15 @@
|
||||
#include "ResourceDownloadDialog.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "minecraft/mod/ResourcePackFolderModel.h"
|
||||
#include "minecraft/mod/TexturePackFolderModel.h"
|
||||
#include "minecraft/mod/ShaderPackFolderModel.h"
|
||||
#include "minecraft/mod/TexturePackFolderModel.h"
|
||||
|
||||
#include "ui/dialogs/ReviewMessageBox.h"
|
||||
|
||||
@ -41,7 +42,10 @@
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, const std::shared_ptr<ResourceFolderModel> base_model)
|
||||
: QDialog(parent), m_base_model(base_model), m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel), m_vertical_layout(this)
|
||||
: QDialog(parent)
|
||||
, m_base_model(base_model)
|
||||
, m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel)
|
||||
, m_vertical_layout(this)
|
||||
{
|
||||
setObjectName(QStringLiteral("ResourceDownloadDialog"));
|
||||
|
||||
@ -102,7 +106,8 @@ void ResourceDownloadDialog::initializeContainer()
|
||||
void ResourceDownloadDialog::connectButtons()
|
||||
{
|
||||
auto OkButton = m_buttons.button(QDialogButtonBox::Ok);
|
||||
OkButton->setToolTip(tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString()));
|
||||
OkButton->setToolTip(
|
||||
tr("Opens a new popup to review your selected %1 and confirm your selection. Shortcut: Ctrl+Return").arg(resourcesString()));
|
||||
connect(OkButton, &QPushButton::clicked, this, &ResourceDownloadDialog::confirm);
|
||||
|
||||
auto CancelButton = m_buttons.button(QDialogButtonBox::Cancel);
|
||||
@ -114,21 +119,24 @@ void ResourceDownloadDialog::connectButtons()
|
||||
|
||||
void ResourceDownloadDialog::confirm()
|
||||
{
|
||||
auto keys = m_selected.keys();
|
||||
keys.sort(Qt::CaseInsensitive);
|
||||
auto selected = getTasks();
|
||||
std::sort(selected.begin(), selected.end(), [](const DownloadTaskPtr& a, const DownloadTaskPtr& b) {
|
||||
return QString::compare(a->getName(), b->getName(), Qt::CaseInsensitive) < 0;
|
||||
});
|
||||
|
||||
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
|
||||
confirm_dialog->retranslateUi(resourcesString());
|
||||
|
||||
for (auto& task : keys) {
|
||||
auto selected = m_selected.constFind(task).value();
|
||||
confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() });
|
||||
for (auto& task : selected) {
|
||||
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath() });
|
||||
}
|
||||
|
||||
if (confirm_dialog->exec()) {
|
||||
auto deselected = confirm_dialog->deselectedResources();
|
||||
for (auto name : deselected) {
|
||||
m_selected.remove(name);
|
||||
for (auto page : m_container->getPages()) {
|
||||
auto res = static_cast<ResourcePage*>(page);
|
||||
for (auto name : deselected)
|
||||
res->removeResourceFromPage(name);
|
||||
}
|
||||
|
||||
this->accept();
|
||||
@ -145,46 +153,39 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage()
|
||||
return m_selectedPage;
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed)
|
||||
void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& ver)
|
||||
{
|
||||
removeResource(pack, ver);
|
||||
|
||||
ver.is_currently_selected = true;
|
||||
m_selected.insert(pack.name, makeShared<ResourceDownloadTask>(pack, ver, getBaseModel(), is_indexed));
|
||||
|
||||
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
||||
removeResource(pack->name);
|
||||
m_selectedPage->addResourceToPage(pack, ver, getBaseModel());
|
||||
setButtonStatus();
|
||||
}
|
||||
|
||||
static ModPlatform::IndexedVersion& getVersionWithID(ModPlatform::IndexedPack& pack, QVariant id)
|
||||
void ResourceDownloadDialog::removeResource(const QString& pack_name)
|
||||
{
|
||||
Q_ASSERT(pack.versionsLoaded);
|
||||
auto it = std::find_if(pack.versions.begin(), pack.versions.end(), [id](auto const& v) { return v.fileId == id; });
|
||||
Q_ASSERT(it != pack.versions.end());
|
||||
return *it;
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver)
|
||||
{
|
||||
if (auto selected_task_it = m_selected.find(pack.name); selected_task_it != m_selected.end()) {
|
||||
auto selected_task = *selected_task_it;
|
||||
auto old_version_id = selected_task->getVersionID();
|
||||
|
||||
// If the new and old version IDs don't match, search for the old one and deselect it.
|
||||
if (ver.fileId != old_version_id)
|
||||
getVersionWithID(pack, old_version_id).is_currently_selected = false;
|
||||
for (auto page : m_container->getPages()) {
|
||||
static_cast<ResourcePage*>(page)->removeResourceFromPage(pack_name);
|
||||
}
|
||||
setButtonStatus();
|
||||
}
|
||||
|
||||
// Deselect the new version too, since all versions of that pack got removed.
|
||||
ver.is_currently_selected = false;
|
||||
|
||||
m_selected.remove(pack.name);
|
||||
|
||||
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
||||
void ResourceDownloadDialog::setButtonStatus()
|
||||
{
|
||||
auto selected = false;
|
||||
for (auto page : m_container->getPages()) {
|
||||
auto res = static_cast<ResourcePage*>(page);
|
||||
selected = selected || res->hasSelectedPacks();
|
||||
}
|
||||
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(selected);
|
||||
}
|
||||
|
||||
const QList<ResourceDownloadDialog::DownloadTaskPtr> ResourceDownloadDialog::getTasks()
|
||||
{
|
||||
return m_selected.values();
|
||||
QList<DownloadTaskPtr> selected;
|
||||
for (auto page : m_container->getPages()) {
|
||||
auto res = static_cast<ResourcePage*>(page);
|
||||
selected.append(res->selectedPacks());
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* selected)
|
||||
@ -205,8 +206,6 @@ void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* s
|
||||
m_selectedPage->setSearchTerm(prev_page->getSearchTerm());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ModDownloadDialog::ModDownloadDialog(QWidget* parent, const std::shared_ptr<ModFolderModel>& mods, BaseInstance* instance)
|
||||
: ResourceDownloadDialog(parent, mods), m_instance(instance)
|
||||
{
|
||||
@ -232,7 +231,6 @@ QList<BasePage*> ModDownloadDialog::getPages()
|
||||
return pages;
|
||||
}
|
||||
|
||||
|
||||
ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<ResourcePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance)
|
||||
@ -258,7 +256,6 @@ QList<BasePage*> ResourcePackDownloadDialog::getPages()
|
||||
return pages;
|
||||
}
|
||||
|
||||
|
||||
TexturePackDownloadDialog::TexturePackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<TexturePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance)
|
||||
@ -284,7 +281,6 @@ QList<BasePage*> TexturePackDownloadDialog::getPages()
|
||||
return pages;
|
||||
}
|
||||
|
||||
|
||||
ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<ShaderPackFolderModel>& shaders,
|
||||
BaseInstance* instance)
|
||||
|
@ -62,8 +62,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
||||
bool selectPage(QString pageId);
|
||||
ResourcePage* getSelectedPage();
|
||||
|
||||
void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, bool is_indexed = false);
|
||||
void removeResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
|
||||
void addResource(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&);
|
||||
void removeResource(const QString&);
|
||||
|
||||
const QList<DownloadTaskPtr> getTasks();
|
||||
[[nodiscard]] const std::shared_ptr<ResourceFolderModel> getBaseModel() const { return m_base_model; }
|
||||
@ -79,6 +79,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual QString geometrySaveKey() const { return ""; }
|
||||
void setButtonStatus();
|
||||
|
||||
protected:
|
||||
const std::shared_ptr<ResourceFolderModel> m_base_model;
|
||||
@ -88,12 +89,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
||||
|
||||
QDialogButtonBox m_buttons;
|
||||
QVBoxLayout m_vertical_layout;
|
||||
|
||||
QHash<QString, DownloadTaskPtr> m_selected;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ModDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@ -135,8 +132,8 @@ class TexturePackDownloadDialog final : public ResourceDownloadDialog {
|
||||
|
||||
public:
|
||||
explicit TexturePackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<TexturePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance);
|
||||
const std::shared_ptr<TexturePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance);
|
||||
~TexturePackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the texture pack download dialog title ("Download " + resourcesString())
|
||||
@ -153,9 +150,7 @@ class ShaderPackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ShaderPackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<ShaderPackFolderModel>& shader_packs,
|
||||
BaseInstance* instance);
|
||||
explicit ShaderPackDownloadDialog(QWidget* parent, const std::shared_ptr<ShaderPackFolderModel>& shader_packs, BaseInstance* instance);
|
||||
~ShaderPackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the shader pack download dialog title ("Download " + resourcesString())
|
||||
|
Reference in New Issue
Block a user