diff options
-rw-r--r-- | api/logic/modplatform/FtbPackDownloader.cpp | 9 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackDownloader.h | 5 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackFetchTask.cpp | 21 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackFetchTask.h | 1 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackInstallTask.cpp | 159 | ||||
-rw-r--r-- | api/logic/modplatform/FtbPackInstallTask.h | 14 | ||||
-rw-r--r-- | api/logic/modplatform/PackHelpers.h | 7 | ||||
-rw-r--r-- | api/logic/net/NetJob.cpp | 4 | ||||
-rw-r--r-- | application/CMakeLists.txt | 10 | ||||
-rw-r--r-- | application/FtbListModel.cpp | 138 | ||||
-rw-r--r-- | application/FtbListModel.h | 45 | ||||
-rw-r--r-- | application/dialogs/ChooseFtbPackDialog.cpp | 54 | ||||
-rw-r--r-- | application/dialogs/ChooseFtbPackDialog.h | 7 | ||||
-rw-r--r-- | application/dialogs/ChooseFtbPackDialog.ui | 170 | ||||
-rw-r--r-- | application/widgets/FtbModpackListItem.cpp | 8 | ||||
-rw-r--r-- | application/widgets/FtbModpackListItem.h | 15 |
16 files changed, 498 insertions, 169 deletions
diff --git a/api/logic/modplatform/FtbPackDownloader.cpp b/api/logic/modplatform/FtbPackDownloader.cpp index a3951bfd..caadd4ae 100644 --- a/api/logic/modplatform/FtbPackDownloader.cpp +++ b/api/logic/modplatform/FtbPackDownloader.cpp @@ -9,8 +9,6 @@ FtbPackDownloader::FtbPackDownloader() { } FtbPackDownloader::~FtbPackDownloader(){ - delete netJobContainer.get(); - netJobContainer.reset(nullptr); } bool FtbPackDownloader::isValidPackSelected(){ @@ -22,7 +20,7 @@ bool FtbPackDownloader::isValidPackSelected(){ return false; } - return other.oldVersions.contains(selectedVersion); + return other.oldVersions.contains(selectedVersion) && !other.broken; } QString FtbPackDownloader::getSuggestedInstanceName() { @@ -104,3 +102,8 @@ void FtbPackDownloader::_downloadFailed(QString reason) { netJobContainer.reset(); emit downloadFailed(reason); } + +NetJobPtr FtbPackDownloader::getNetJob() +{ + return netJobContainer; +} diff --git a/api/logic/modplatform/FtbPackDownloader.h b/api/logic/modplatform/FtbPackDownloader.h index 45490afc..c5cc9bd2 100644 --- a/api/logic/modplatform/FtbPackDownloader.h +++ b/api/logic/modplatform/FtbPackDownloader.h @@ -18,8 +18,8 @@ class MULTIMC_LOGIC_EXPORT FtbPackDownloader : public QObject { private: QMap<QString, FtbModpack> fetchedPacks; - bool fetching; - bool done; + bool fetching = false; + bool done = false; FtbModpack selected; QString selectedVersion; @@ -51,6 +51,7 @@ public: QString getSuggestedInstanceName(); FtbModpackList getModpacks(); + NetJobPtr getNetJob(); signals: void ready(); diff --git a/api/logic/modplatform/FtbPackFetchTask.cpp b/api/logic/modplatform/FtbPackFetchTask.cpp index 6f578e04..9e151186 100644 --- a/api/logic/modplatform/FtbPackFetchTask.cpp +++ b/api/logic/modplatform/FtbPackFetchTask.cpp @@ -58,6 +58,26 @@ void FtbPackFetchTask::fileDownloadFinished(){ modpack.mods = element.attribute("mods"); modpack.image = element.attribute("image"); modpack.oldVersions = element.attribute("oldVersions").split(";"); + + //remove empty if the xml is bugged + for(QString curr : modpack.oldVersions) { + if(curr.isNull() || curr.isEmpty()) { + modpack.oldVersions.removeAll(curr); + modpack.bugged = true; + qWarning() << "Removed some empty versions from" << modpack.name; + } + } + + if(modpack.oldVersions.size() < 1) { + if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) { + modpack.oldVersions.append(modpack.currentVersion); + qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")"; + } else { + modpack.broken = true; + qWarning() << "Broken pack:" << modpack.name << " => No valid version!"; + } + } + modpack.author = element.attribute("author"); modpack.dir = element.attribute("dir"); @@ -66,6 +86,7 @@ void FtbPackFetchTask::fileDownloadFinished(){ modpackList.append(modpack); } + emit finished(modpackList); } diff --git a/api/logic/modplatform/FtbPackFetchTask.h b/api/logic/modplatform/FtbPackFetchTask.h index df5a96e6..3cfac4ed 100644 --- a/api/logic/modplatform/FtbPackFetchTask.h +++ b/api/logic/modplatform/FtbPackFetchTask.h @@ -1,6 +1,5 @@ #pragma once -#include "multimc_logic_export.h" #include "net/NetJob.h" #include <QTemporaryDir> #include <QByteArray> diff --git a/api/logic/modplatform/FtbPackInstallTask.cpp b/api/logic/modplatform/FtbPackInstallTask.cpp index bedf3942..8c0bc70c 100644 --- a/api/logic/modplatform/FtbPackInstallTask.cpp +++ b/api/logic/modplatform/FtbPackInstallTask.cpp @@ -2,6 +2,11 @@ #include "Env.h" #include "MMCZip.h" #include "QtConcurrent" +#include "BaseInstance.h" +#include "FileSystem.h" +#include "settings/INISettingsObject.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/ComponentList.h" FtbPackInstallTask::FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString &stagingPath, const QString &instName, const QString &instIcon, const QString &instGroup) : @@ -16,18 +21,19 @@ void FtbPackInstallTask::executeTask() { void FtbPackInstallTask::downloadPack(){ FtbModpack toInstall = m_downloader->getSelectedPack(); - setStatus(tr("Installing new FTB Pack %1").arg(toInstall.name)); + setStatus(tr("Downloading zip for %1").arg(toInstall.name)); - auto entry = ENV.metacache()->resolveEntry("general", "FTBPack/" + toInstall.name); + auto entry = ENV.metacache()->resolveEntry("general", "FTBPacks/" + toInstall.name); m_downloader->downloadSelected(entry); connect(m_downloader, &FtbPackDownloader::downloadSucceded, this, &FtbPackInstallTask::onDownloadSucceeded); connect(m_downloader, &FtbPackDownloader::downloadProgress, this, &FtbPackInstallTask::onDownloadProgress); connect(m_downloader, &FtbPackDownloader::downloadFailed, this,&FtbPackInstallTask::onDownloadFailed); + progress(1, 4); } void FtbPackInstallTask::onDownloadSucceeded(QString archivePath){ - qDebug() << "Download succeeded!"; + abortable = false; unzip(archivePath); } @@ -36,11 +42,14 @@ void FtbPackInstallTask::onDownloadFailed(QString reason) { } void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total){ - progress(current, total); + abortable = true; + progress(current, total * 4); + setStatus(tr("Downloading zip for %1 (%2\%)").arg(m_downloader->getSelectedPack().name).arg(current / 10)); } void FtbPackInstallTask::unzip(QString archivePath) { - setStatus(QString("Extracting modpack from %1").arg(archivePath)); + progress(2, 4); + setStatus(tr("Extracting modpack")); QDir extractDir(m_stagingPath); m_packZip.reset(new QuaZip(archivePath)); @@ -49,17 +58,151 @@ void FtbPackInstallTask::unzip(QString archivePath) { return; } - m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString("/"), extractDir.absolutePath()); + m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip"); connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &FtbPackInstallTask::onUnzipFinished); connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &FtbPackInstallTask::onUnzipCanceled); m_extractFutureWatcher.setFuture(m_extractFuture); } void FtbPackInstallTask::onUnzipFinished() { - qDebug() << "Unzipped:" << m_stagingPath; - emitSucceeded(); + install(); } void FtbPackInstallTask::onUnzipCanceled() { emitAborted(); } + +void FtbPackInstallTask::install() { + progress(3, 4); + FtbModpack toInstall = m_downloader->getSelectedPack(); + setStatus(tr("Installing modpack")); + QDir unzipMcDir(m_stagingPath + "/unzip/minecraft"); + if(unzipMcDir.exists()) { + //ok, found minecraft dir, move contents to instance dir + moveRecursively(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"); + } + + QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); + auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath); + instanceSettings->registerSetting("InstanceType", "Legacy"); + instanceSettings->set("InstanceType", "OneSix"); + + MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); + auto components = instance.getComponentList(); + components->buildingFromScratch(); + components->setComponentVersion("net.minecraft", toInstall.mcVersion, true); + + bool fallback = true; + + //handle different versions + QFile packJson(m_stagingPath + "/.minecraft/pack.json"); + QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods"); + if(packJson.exists()) { + packJson.open(QIODevice::ReadOnly | QIODevice::Text); + QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll()); + packJson.close(); + + //we only care about the libs + QJsonArray libs = doc.object().value("libraries").toArray(); + + foreach (const QJsonValue &value, libs) { + QString nameValue = value.toObject().value("name").toString(); + if(!nameValue.startsWith("net.minecraftforge")) { + continue; + } + + //It is always maven like + //net.minecraftforge:forge:1.7.10-10.13.4.1448-1.7.10:universal => 1.7.10-10.13.4.1448-1.7.10 + QString forgeVersion = nameValue.split(":").at(2); + + //1.7.10-10.13.4.1448-1.7.10 => 10.13.4.1448 + forgeVersion = forgeVersion.replace(toInstall.mcVersion, "").replace("-", ""); + components->setComponentVersion("net.minecraftforge", forgeVersion); + packJson.remove(); + fallback = false; + break; + } + + } + + if(jarmodDir.exists()) { + qDebug() << "Found jarmods, installing..."; + + QStringList jarmods; + for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) + { + qDebug() << "Jarmod:" << info.fileName(); + jarmods.push_back(info.absoluteFilePath()); + } + + components->installJarMods(jarmods); + fallback = false; + } + + //just nuke unzip directory, it s not needed anymore + FS::deletePath(m_stagingPath + "/unzip"); + + if(fallback) { + //TODO: Some fallback mechanism... or just keep failing! + emitFailed(tr("No installation method found!")); + return; + } + + components->saveNow(); + + progress(4, 4); + + instance.init(); + instance.setName(m_instName); + if(m_instIcon == "default") { + m_instIcon = "ftb_logo"; + } + instance.setIconKey(m_instIcon); + instance.setGroupInitial(m_instGroup); + instanceSettings->resumeSave(); + + emitSucceeded(); +} + +bool FtbPackInstallTask::moveRecursively(QString sourceFolder, QString destFolder) +{ + bool success = false; + QDir sourceDir(sourceFolder); + + if(!sourceDir.exists()) + return false; + + QDir destDir(destFolder); + if(!destDir.exists()) + destDir.mkdir(destFolder); + + QStringList files = sourceDir.entryList(QDir::Files); + for(int i = 0; i< files.count(); i++) { + QString srcName = sourceFolder + QDir::separator() + files[i]; + QString destName = destFolder + QDir::separator() + files[i]; + success = QFile::copy(srcName, destName); + if(!success) + return false; + QFile::remove(srcName); + } + + files.clear(); + files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); + for(int i = 0; i< files.count(); i++) + { + QString srcName = sourceFolder + QDir::separator() + files[i]; + QString destName = destFolder + QDir::separator() + files[i]; + success = moveRecursively(srcName, destName); + if(!success) + return false; + } + + return QDir(sourceFolder).rmdir(sourceFolder); +} + +bool FtbPackInstallTask::abort() { + if(abortable) { + return m_downloader->getNetJob()->abort(); + } + return false; +} diff --git a/api/logic/modplatform/FtbPackInstallTask.h b/api/logic/modplatform/FtbPackInstallTask.h index 23ef0811..cf477ae2 100644 --- a/api/logic/modplatform/FtbPackInstallTask.h +++ b/api/logic/modplatform/FtbPackInstallTask.h @@ -5,14 +5,18 @@ #include "net/NetJob.h" #include "quazip.h" #include "quazipdir.h" +#include "meta/Index.h" +#include "meta/Version.h" +#include "meta/VersionList.h" class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public Task { Q_OBJECT public: - explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString & stagingPath, const QString &instName, + explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString &stagingPath, const QString &instName, const QString &instIcon, const QString &instGroup); + bool abort() override; protected: //! Entry point for tasks. @@ -25,7 +29,8 @@ private: /* data */ QString m_instIcon; QString m_instGroup; NetJobPtr m_netJobPtr; - FtbPackDownloader *m_downloader = nullptr; + + FtbPackDownloader *m_downloader; std::unique_ptr<QuaZip> m_packZip; QFuture<QStringList> m_extractFuture; @@ -35,6 +40,10 @@ private: /* data */ void unzip(QString archivePath); void install(); + bool moveRecursively(QString source, QString dest); + + bool abortable = false; + private slots: void onDownloadSucceeded(QString archivePath); void onDownloadFailed(QString reason); @@ -42,4 +51,5 @@ private slots: void onUnzipFinished(); void onUnzipCanceled(); + }; diff --git a/api/logic/modplatform/PackHelpers.h b/api/logic/modplatform/PackHelpers.h index ba0e5cb0..f761ed6b 100644 --- a/api/logic/modplatform/PackHelpers.h +++ b/api/logic/modplatform/PackHelpers.h @@ -1,8 +1,8 @@ #pragma once #include <QList> +#include "qmetatype.h" //Header for structs etc... - struct FtbModpack { QString name; QString description; @@ -16,6 +16,11 @@ struct FtbModpack { //Technical data QString dir; QString file; //<- Url in the xml, but doesn't make much sense + + bool bugged = false; + bool broken = false; }; +//We need it for the proxy model +Q_DECLARE_METATYPE(FtbModpack) typedef QList<FtbModpack> FtbModpackList; diff --git a/api/logic/net/NetJob.cpp b/api/logic/net/NetJob.cpp index 304b5820..1ff8e28f 100644 --- a/api/logic/net/NetJob.cpp +++ b/api/logic/net/NetJob.cpp @@ -84,6 +84,10 @@ void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal) auto current = done * 1000 + doing * inprogress; auto current_total = all * 1000; // HACK: make sure it never jumps backwards. + // FAIL: This breaks if the size is not known (or is it something else?) and jumps to 1000, so if it is 1000 reset it to inprogress + if(m_current_progress == 1000) { + m_current_progress = inprogress; + } if(m_current_progress > current) { current = m_current_progress; 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 <MMCStrings.h> + +#include <QtMath> + +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>(); + FtbModpack rightPack = sourceModel()->data(right, Qt::UserRole).value<FtbModpack>(); + + 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<QString, FtbFilterModel::Sorting> 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("<br>")).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 <QAbstractListModel> +#include <QSortFilterProxyModel> +#include <modplatform/PackHelpers.h> + +class FtbFilterModel : public QSortFilterProxyModel +{ +public: + FtbFilterModel(QObject* parent = Q_NULLPTR); + enum Sorting { + ByName, + ByGameVersion + }; + const QMap<QString, Sorting> 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<QString, Sorting> 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 <QPushButton> -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<FtbModpackListItem*>(item)->getModpack(); + FtbModpack selectedPack = filterModel->data(now, Qt::UserRole).value<FtbModpack>(); ui->modpackInfo->setHtml("Pack by <b>" + selectedPack.author + "</b>" + "<br>Minecraft " + selectedPack.mcVersion + "<br>" - "<br>" + selectedPack.description + "<ul><li>" + selectedPack.mods.replace(";", "</li><li>") + "</li></ul>"); + "<br>" + selectedPack.description + "<ul><li>" + selectedPack.mods.replace(";", "</li><li>") + "</li></ul>"); 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 <modplatform/PackHelpers.h> #include "ui_ChooseFtbPackDialog.h" #include <modplatform/PackHelpers.h> +#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 @@ <rect> <x>0</x> <y>0</y> - <width>730</width> + <width>700</width> <height>437</height> </rect> </property> <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -19,111 +19,67 @@ <property name="sizeGripEnabled"> <bool>false</bool> </property> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="geometry"> - <rect> - <x>540</x> - <y>400</y> - <width>176</width> - <height>25</height> - </rect> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - <widget class="QScrollArea" name="scrollArea"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>261</width> - <height>381</height> - </rect> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>259</width> - <height>379</height> - </rect> - </property> - <widget class="QListWidget" name="packList"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>261</width> - <height>381</height> - </rect> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="1"> + <widget class="QLabel" name="selectedVersionLabel"> + <property name="text"> + <string>Version selected:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QTreeView" name="packList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QComboBox" name="sortByBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + <property name="centerButtons"> + <bool>false</bool> </property> </widget> - </widget> - </widget> - <widget class="QScrollArea" name="scrollArea_2"> - <property name="geometry"> - <rect> - <x>280</x> - <y>10</y> - <width>441</width> - <height>381</height> - </rect> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_2"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>439</width> - <height>379</height> - </rect> - </property> - <widget class="QTextBrowser" name="modpackInfo"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>441</width> - <height>381</height> - </rect> + </item> + <item row="1" column="2"> + <widget class="QComboBox" name="packVersionSelection"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> </widget> - </widget> - </widget> - <widget class="QComboBox" name="packVersionSelection"> - <property name="geometry"> - <rect> - <x>450</x> - <y>400</y> - <width>72</width> - <height>25</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="selectedVersionLabel"> - <property name="geometry"> - <rect> - <x>340</x> - <y>400</y> - <width>101</width> - <height>21</height> - </rect> - </property> - <property name="text"> - <string>Version selected:</string> - </property> - <property name="alignment"> - <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> - </property> - </widget> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QTextBrowser" name="modpackInfo"/> + </item> + </layout> </widget> <resources/> <connections> @@ -134,8 +90,8 @@ <slot>accept()</slot> <hints> <hint type="sourcelabel"> - <x>666</x> - <y>422</y> + <x>211</x> + <y>173</y> </hint> <hint type="destinationlabel"> <x>889</x> @@ -150,8 +106,8 @@ <slot>reject()</slot> <hints> <hint type="sourcelabel"> - <x>680</x> - <y>411</y> + <x>225</x> + <y>162</y> </hint> <hint type="destinationlabel"> <x>524</x> 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 <modplatform/PackHelpers.h> - -class FtbModpackListItem : public QListWidgetItem { - -private: - FtbModpack modpack; - -public: - FtbModpackListItem(QListWidget *list, FtbModpack modpack); - FtbModpack getModpack(); - -}; |