From b8ca36372be11b9ddddb3daa3d32583d286f19e2 Mon Sep 17 00:00:00 2001 From: Janrupf Date: Sat, 3 Mar 2018 21:22:00 +0100 Subject: GH-2124 First complete implementation, installing is working now! GH-2172 Added sorting --- application/CMakeLists.txt | 10 +- application/FtbListModel.cpp | 138 ++++++++++++++++++++++ application/FtbListModel.h | 45 ++++++++ application/dialogs/ChooseFtbPackDialog.cpp | 54 ++++++--- application/dialogs/ChooseFtbPackDialog.h | 7 +- application/dialogs/ChooseFtbPackDialog.ui | 170 +++++++++++----------------- application/widgets/FtbModpackListItem.cpp | 8 -- application/widgets/FtbModpackListItem.h | 15 --- 8 files changed, 295 insertions(+), 152 deletions(-) create mode 100644 application/FtbListModel.cpp create mode 100644 application/FtbListModel.h delete mode 100644 application/widgets/FtbModpackListItem.cpp delete mode 100644 application/widgets/FtbModpackListItem.h (limited to 'application') diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index da9a42c6..148b6d9f 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -25,6 +25,8 @@ SET(MULTIMC_SOURCES InstanceProxyModel.cpp VersionProxyModel.h VersionProxyModel.cpp + FtbListModel.h + FtbListModel.cpp ColorCache.h ColorCache.cpp HoeDown.h @@ -153,8 +155,8 @@ SET(MULTIMC_SOURCES dialogs/VersionSelectDialog.h dialogs/SkinUploadDialog.cpp dialogs/SkinUploadDialog.h - dialogs/ChooseFtbPackDialog.cpp - dialogs/ChooseFtbPackDialog.h + dialogs/ChooseFtbPackDialog.cpp + dialogs/ChooseFtbPackDialog.h # GUI - widgets @@ -189,8 +191,6 @@ SET(MULTIMC_SOURCES widgets/VersionSelectWidget.h widgets/ProgressWidget.h widgets/ProgressWidget.cpp - widgets/FtbModpackListItem.h - widgets/FtbModpackListItem.cpp # GUI - instance group view groupview/GroupedProxyModel.cpp @@ -240,7 +240,7 @@ SET(MULTIMC_UIS dialogs/UpdateDialog.ui dialogs/NotificationDialog.ui dialogs/SkinUploadDialog.ui - dialogs/ChooseFtbPackDialog.ui + dialogs/ChooseFtbPackDialog.ui # Widgets/other widgets/CustomCommands.ui diff --git a/application/FtbListModel.cpp b/application/FtbListModel.cpp new file mode 100644 index 00000000..290767ff --- /dev/null +++ b/application/FtbListModel.cpp @@ -0,0 +1,138 @@ +#include "FtbListModel.h" +#include "MultiMC.h" + +#include + +#include + +FtbFilterModel::FtbFilterModel(QObject *parent) : QSortFilterProxyModel(parent) +{ + currentSorting = Sorting::ByGameVersion; + sortings.insert("Sort by name", Sorting::ByName); + sortings.insert("Sort by game version", Sorting::ByGameVersion); +} + +bool FtbFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + FtbModpack leftPack = sourceModel()->data(left, Qt::UserRole).value(); + FtbModpack rightPack = sourceModel()->data(right, Qt::UserRole).value(); + + if(currentSorting == Sorting::ByGameVersion) { + QStringList leftList = leftPack.mcVersion.split("."); + QStringList rightList = rightPack.mcVersion.split("."); + + if(leftList.size() < 1) { + return true; + } else if(rightList.size() < 1) { + return false; + } else { + for(int i = 0; i < qMax(leftList.size(), rightList.size()); i++) { + if(leftList.size() -1 < i) { + return true; + } + + if(rightList.size() -1 < i) { + return false; + } + + int leftV = leftList.at(i).toInt(); + int rightV = rightList.at(i).toInt(); + + if(leftV != rightV) { + return leftV < rightV; + } + + } + return false; + } + + } else if(currentSorting == Sorting::ByName) { + return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + } + + //UHM, some inavlid value set?! + qWarning() << "Invalid sorting set!"; + return true; +} + +bool FtbFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + return true; +} + +const QMap FtbFilterModel::getAvailableSortings() +{ + return sortings; +} + +void FtbFilterModel::setSorting(Sorting s) +{ + currentSorting = s; + invalidate(); +} + +FtbFilterModel::Sorting FtbFilterModel::getCurrentSorting() +{ + return currentSorting; +} + +FtbListModel::FtbListModel(QObject *parent) : QAbstractListModel(parent) +{ +} + +int FtbListModel::rowCount(const QModelIndex &parent) const +{ + return modpacks.size(); +} + +int FtbListModel::columnCount(const QModelIndex &parent) const +{ + return 1; +} + +QVariant FtbListModel::data(const QModelIndex &index, int role) const +{ + int pos = index.row(); + if(modpacks.size() < pos || pos < 0) { + return QString("INVALID INDEX %1").arg(pos); + } + + FtbModpack pack = modpacks.at(pos); + + if(role == Qt::DisplayRole) { + return pack.name; + } else if (role == Qt::ToolTipRole) { + if(pack.description.length() > 100) { + //some magic to prevent to long tooltips and replace html linebreaks + QString edit = pack.description.left(97); + edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); + return edit; + + } + return pack.description; + } else if(role == Qt::DecorationRole) { + //TODO: Add pack logos or something... but they have a weird size. This needs some design hacks + } else if(role == Qt::TextColorRole) { + if(pack.broken) { + return QColor(255, 0, 50); + } else if(pack.bugged) { + //bugged pack, currently only indicates bugged xml + return QColor(244, 229, 66); + } + } else if(role == Qt::UserRole) { + QVariant v; + v.setValue(pack); + return v; + } + return QVariant(); +} + +void FtbListModel::fill(FtbModpackList modpacks) +{ + this->modpacks = modpacks; +} + +FtbModpack FtbListModel::at(int row) +{ + return modpacks.at(row); +} diff --git a/application/FtbListModel.h b/application/FtbListModel.h new file mode 100644 index 00000000..e41e9b62 --- /dev/null +++ b/application/FtbListModel.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +class FtbFilterModel : public QSortFilterProxyModel +{ +public: + FtbFilterModel(QObject* parent = Q_NULLPTR); + enum Sorting { + ByName, + ByGameVersion + }; + const QMap getAvailableSortings(); + Sorting getCurrentSorting(); + void setSorting(Sorting sorting); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + +private: + QMap sortings; + Sorting currentSorting; + +}; + +class FtbListModel : public QAbstractListModel +{ + Q_OBJECT +private: + FtbModpackList modpacks; + +public: + FtbListModel(QObject *parent); + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + + void fill(FtbModpackList modpacks); + + FtbModpack at(int row); + +}; diff --git a/application/dialogs/ChooseFtbPackDialog.cpp b/application/dialogs/ChooseFtbPackDialog.cpp index ae7c72e1..b1deae6e 100644 --- a/application/dialogs/ChooseFtbPackDialog.cpp +++ b/application/dialogs/ChooseFtbPackDialog.cpp @@ -1,33 +1,49 @@ #include "ChooseFtbPackDialog.h" -#include "widgets/FtbModpackListItem.h" +#include -ChooseFtbPackDialog::ChooseFtbPackDialog(FtbModpackList modpacks) : ui(new Ui::ChooseFtbPackDialog) { +ChooseFtbPackDialog::ChooseFtbPackDialog(FtbModpackList modpacks) : ui(new Ui::ChooseFtbPackDialog) +{ ui->setupUi(this); - for(int i = 0; i < modpacks.size(); i++) { - FtbModpackListItem *item = new FtbModpackListItem(ui->packList, modpacks.at(i)); + filterModel = new FtbFilterModel(this); + listModel = new FtbListModel(this); + filterModel->setSourceModel(listModel); + listModel->fill(modpacks); - item->setText(modpacks.at(i).name); + ui->packList->setModel(filterModel); + ui->packList->setSortingEnabled(true); + ui->packList->header()->hide(); + ui->packList->setIndentation(0); + + filterModel->setSorting(FtbFilterModel::Sorting::ByName); + + for(int i = 0; i < filterModel->getAvailableSortings().size(); i++){ + ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i)); } - //TODO: Use a model/view instead of a widget - connect(ui->packList, &QListWidget::itemClicked, this, &ChooseFtbPackDialog::onListItemClicked); + ui->sortByBox->setCurrentText(filterModel->getAvailableSortings().key(filterModel->getCurrentSorting())); + + connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &ChooseFtbPackDialog::onSortingSelectionChanged); connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &ChooseFtbPackDialog::onVersionSelectionItemChanged); + connect(ui->packList->selectionModel(), &QItemSelectionModel::currentChanged, this, &ChooseFtbPackDialog::onPackSelectionChanged); ui->modpackInfo->setOpenExternalLinks(true); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } -ChooseFtbPackDialog::~ChooseFtbPackDialog(){ +ChooseFtbPackDialog::~ChooseFtbPackDialog() +{ delete ui; } -void ChooseFtbPackDialog::onListItemClicked(QListWidgetItem *item){ +void ChooseFtbPackDialog::onPackSelectionChanged(QModelIndex now, QModelIndex prev) +{ ui->packVersionSelection->clear(); - FtbModpack selectedPack = static_cast(item)->getModpack(); + FtbModpack selectedPack = filterModel->data(now, Qt::UserRole).value(); ui->modpackInfo->setHtml("Pack by " + selectedPack.author + "" + "
Minecraft " + selectedPack.mcVersion + "
" - "
" + selectedPack.description + "
  • " + selectedPack.mods.replace(";", "
  • ") + "
"); + "
" + selectedPack.description + "
  • " + selectedPack.mods.replace(";", "
  • ") + "
"); bool currentAdded = false; @@ -43,10 +59,11 @@ void ChooseFtbPackDialog::onListItemClicked(QListWidgetItem *item){ } selected = selectedPack; - + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!selected.broken); } -void ChooseFtbPackDialog::onVersionSelectionItemChanged(QString data) { +void ChooseFtbPackDialog::onVersionSelectionItemChanged(QString data) +{ if(data.isNull() || data.isEmpty()) { selectedVersion = ""; return; @@ -55,10 +72,17 @@ void ChooseFtbPackDialog::onVersionSelectionItemChanged(QString data) { selectedVersion = data; } -FtbModpack ChooseFtbPackDialog::getSelectedModpack() { +FtbModpack ChooseFtbPackDialog::getSelectedModpack() +{ return selected; } -QString ChooseFtbPackDialog::getSelectedVersion() { +QString ChooseFtbPackDialog::getSelectedVersion() +{ return selectedVersion; } + +void ChooseFtbPackDialog::onSortingSelectionChanged(QString data) +{ + filterModel->setSorting(filterModel->getAvailableSortings().value(data)); +} diff --git a/application/dialogs/ChooseFtbPackDialog.h b/application/dialogs/ChooseFtbPackDialog.h index 212aa27b..0b021138 100644 --- a/application/dialogs/ChooseFtbPackDialog.h +++ b/application/dialogs/ChooseFtbPackDialog.h @@ -5,6 +5,7 @@ #include #include "ui_ChooseFtbPackDialog.h" #include +#include "FtbListModel.h" namespace Ui { class ChooseFtbPackDialog; @@ -18,11 +19,13 @@ private: Ui::ChooseFtbPackDialog *ui; FtbModpack selected; QString selectedVersion; + FtbListModel* listModel; + FtbFilterModel* filterModel; private slots: - void onListItemClicked(QListWidgetItem *item); + void onSortingSelectionChanged(QString data); void onVersionSelectionItemChanged(QString data); - + void onPackSelectionChanged(QModelIndex first, QModelIndex second); public: ChooseFtbPackDialog(FtbModpackList packs); ~ChooseFtbPackDialog(); diff --git a/application/dialogs/ChooseFtbPackDialog.ui b/application/dialogs/ChooseFtbPackDialog.ui index fdf845a9..f590a4cd 100644 --- a/application/dialogs/ChooseFtbPackDialog.ui +++ b/application/dialogs/ChooseFtbPackDialog.ui @@ -6,12 +6,12 @@ 0 0 - 730 + 700 437 - + 0 0 @@ -19,111 +19,67 @@ false - - - - 540 - 400 - 176 - 25 - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 10 - 10 - 261 - 381 - - - - true - - - - - 0 - 0 - 259 - 379 - - - - - - 0 - 0 - 261 - 381 - + + + + + Version selected: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + true + + + false + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + false - - - - - - 280 - 10 - 441 - 381 - - - - true - - - - - 0 - 0 - 439 - 379 - - - - - - 0 - 0 - 441 - 381 - + + + + + + 0 + 0 + - - - - - - 450 - 400 - 72 - 25 - - - - - - - 340 - 400 - 101 - 21 - - - - Version selected: - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - + + + + + @@ -134,8 +90,8 @@ accept() - 666 - 422 + 211 + 173 889 @@ -150,8 +106,8 @@ reject() - 680 - 411 + 225 + 162 524 diff --git a/application/widgets/FtbModpackListItem.cpp b/application/widgets/FtbModpackListItem.cpp deleted file mode 100644 index 874e0eac..00000000 --- a/application/widgets/FtbModpackListItem.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "FtbModpackListItem.h" - -FtbModpackListItem::FtbModpackListItem(QListWidget *list, FtbModpack modpack) : QListWidgetItem(list), modpack(modpack) { -} - -FtbModpack FtbModpackListItem::getModpack(){ - return modpack; -} diff --git a/application/widgets/FtbModpackListItem.h b/application/widgets/FtbModpackListItem.h deleted file mode 100644 index 977cad2d..00000000 --- a/application/widgets/FtbModpackListItem.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "QListWidget" -#include - -class FtbModpackListItem : public QListWidgetItem { - -private: - FtbModpack modpack; - -public: - FtbModpackListItem(QListWidget *list, FtbModpack modpack); - FtbModpack getModpack(); - -}; -- cgit