From 5779ffd6645ba3fae5abe068d456fc1ee9dd91ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 2 May 2015 23:42:33 +0200 Subject: [PATCH] GH-922 improve version select dialogs --- application/MultiMC.cpp | 1 - application/dialogs/CopyInstanceDialog.cpp | 2 - application/dialogs/VersionSelectDialog.cpp | 98 ++++++++++++++++++--- application/dialogs/VersionSelectDialog.h | 21 ++++- application/dialogs/VersionSelectDialog.ui | 10 +++ application/pages/VersionPage.cpp | 2 + application/widgets/VersionListView.cpp | 31 ++++++- application/widgets/VersionListView.h | 16 +++- logic/forge/ForgeVersionList.cpp | 5 ++ logic/forge/ForgeVersionList.h | 1 + logic/tasks/Task.cpp | 2 + logic/tasks/Task.h | 1 + 12 files changed, 168 insertions(+), 22 deletions(-) diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index ba6d7880..b993aa5e 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -12,7 +12,6 @@ #include #include -#include "dialogs/VersionSelectDialog.h" #include "InstanceList.h" #include "auth/MojangAccountList.h" #include "icons/IconList.h" diff --git a/application/dialogs/CopyInstanceDialog.cpp b/application/dialogs/CopyInstanceDialog.cpp index 7c98978b..5b8e3096 100644 --- a/application/dialogs/CopyInstanceDialog.cpp +++ b/application/dialogs/CopyInstanceDialog.cpp @@ -21,8 +21,6 @@ #include "ui_CopyInstanceDialog.h" #include "Platform.h" -#include "dialogs/VersionSelectDialog.h" -#include "dialogs/ProgressDialog.h" #include "dialogs/IconPickerDialog.h" #include "BaseVersion.h" diff --git a/application/dialogs/VersionSelectDialog.cpp b/application/dialogs/VersionSelectDialog.cpp index 354857e7..57514fe7 100644 --- a/application/dialogs/VersionSelectDialog.cpp +++ b/application/dialogs/VersionSelectDialog.cpp @@ -19,6 +19,7 @@ #include #include +#include "CustomMessageBox.h" #include "Platform.h" #include @@ -46,6 +47,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, ui->listView->setModel(m_proxyModel); ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + ui->sneakyProgressBar->setHidden(true); if (!cancelable) { @@ -58,6 +60,11 @@ void VersionSelectDialog::setEmptyString(QString emptyString) ui->listView->setEmptyString(emptyString); } +void VersionSelectDialog::setEmptyErrorString(QString emptyErrorString) +{ + ui->listView->setEmptyErrorString(emptyErrorString); +} + VersionSelectDialog::~VersionSelectDialog() { delete ui; @@ -77,26 +84,89 @@ int VersionSelectDialog::exec() { loadList(); } + else + { + if (m_proxyModel->rowCount() == 0) + { + ui->listView->setEmptyMode(VersionListView::String); + } + preselect(); + } + return QDialog::exec(); +} + +void VersionSelectDialog::closeEvent(QCloseEvent * event) +{ + if(loadTask) + { + loadTask->abort(); + loadTask->deleteLater(); + loadTask = nullptr; + } + QDialog::closeEvent(event); +} + +void VersionSelectDialog::loadList() +{ + if(loadTask) + { + return; + } + loadTask = m_vlist->getLoadTask(); + if (!loadTask) + { + return; + } + connect(loadTask, &Task::finished, this, &VersionSelectDialog::onTaskFinished); + connect(loadTask, &Task::progress, this, &VersionSelectDialog::changeProgress); + loadTask->start(); + ui->sneakyProgressBar->setHidden(false); +} + +void VersionSelectDialog::onTaskFinished() +{ + if (!loadTask->successful()) + { + CustomMessageBox::selectable(this, tr("Error"), + tr("List update failed:\n%1").arg(loadTask->failReason()), + QMessageBox::Warning)->show(); + if (m_proxyModel->rowCount() == 0) + { + ui->listView->setEmptyMode(VersionListView::ErrorString); + } + } + else if (m_proxyModel->rowCount() == 0) + { + ui->listView->setEmptyMode(VersionListView::String); + } + ui->sneakyProgressBar->setHidden(true); + loadTask->deleteLater(); + loadTask = nullptr; + preselect(); +} + +void VersionSelectDialog::changeProgress(qint64 current, qint64 total) +{ + ui->sneakyProgressBar->setMaximum(total); + ui->sneakyProgressBar->setValue(current); +} + +void VersionSelectDialog::preselect() +{ + if(preselectedAlready) + return; + preselectedAlready = true; + selectRecommended(); +} + +void VersionSelectDialog::selectRecommended() +{ auto idx = m_proxyModel->getRecommended(); if(idx.isValid()) { ui->listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); ui->listView->scrollTo(idx, QAbstractItemView::PositionAtCenter); } - return QDialog::exec(); -} - -void VersionSelectDialog::loadList() -{ - Task *loadTask = m_vlist->getLoadTask(); - if (!loadTask) - { - return; - } - ProgressDialog *taskDlg = new ProgressDialog(this); - loadTask->setParent(taskDlg); - taskDlg->exec(loadTask); - delete taskDlg; } BaseVersionPtr VersionSelectDialog::selectedVersion() const diff --git a/application/dialogs/VersionSelectDialog.h b/application/dialogs/VersionSelectDialog.h index 23bd158a..6b83535e 100644 --- a/application/dialogs/VersionSelectDialog.h +++ b/application/dialogs/VersionSelectDialog.h @@ -46,19 +46,34 @@ public: void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter); void setEmptyString(QString emptyString); + void setEmptyErrorString(QString emptyErrorString); void setResizeOn(int column); void setUseLatest(const bool useLatest); +protected: + virtual void closeEvent ( QCloseEvent* ); + private slots: void on_refreshButton_clicked(); + void onTaskFinished(); + void changeProgress(qint64 current, qint64 total); + private: - Ui::VersionSelectDialog *ui; + void preselect(); + void selectRecommended(); - BaseVersionList *m_vlist; +private: + Ui::VersionSelectDialog *ui = nullptr; - VersionProxyModel *m_proxyModel; + BaseVersionList *m_vlist = nullptr; + + VersionProxyModel *m_proxyModel = nullptr; int resizeOnColumn = 0; + + Task * loadTask = nullptr; + + bool preselectedAlready = false; }; diff --git a/application/dialogs/VersionSelectDialog.ui b/application/dialogs/VersionSelectDialog.ui index e4014e11..420e853d 100644 --- a/application/dialogs/VersionSelectDialog.ui +++ b/application/dialogs/VersionSelectDialog.ui @@ -39,6 +39,16 @@ + + + + 24 + + + %p% + + + diff --git a/application/pages/VersionPage.cpp b/application/pages/VersionPage.cpp index 3de6a4c7..7cb99763 100644 --- a/application/pages/VersionPage.cpp +++ b/application/pages/VersionPage.cpp @@ -272,6 +272,7 @@ void VersionPage::on_forgeBtn_clicked() vselect.setExactFilter(BaseVersionList::ParentGameVersionRole, m_inst->currentVersionId()); vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_inst->currentVersionId()); + vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!")); if (vselect.exec() && vselect.selectedVersion()) { ProgressDialog dialog(this); @@ -287,6 +288,7 @@ void VersionPage::on_liteloaderBtn_clicked() vselect.setExactFilter(BaseVersionList::ParentGameVersionRole, m_inst->currentVersionId()); vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_inst->currentVersionId()); + vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!")); if (vselect.exec() && vselect.selectedVersion()) { ProgressDialog dialog(this); diff --git a/application/widgets/VersionListView.cpp b/application/widgets/VersionListView.cpp index fc0bcd0a..1e327534 100644 --- a/application/widgets/VersionListView.cpp +++ b/application/widgets/VersionListView.cpp @@ -65,6 +65,23 @@ void VersionListView::reset() void VersionListView::setEmptyString(QString emptyString) { m_emptyString = emptyString; + updateEmptyViewPort(); +} + +void VersionListView::setEmptyErrorString(QString emptyErrorString) +{ + m_emptyErrorString = emptyErrorString; + updateEmptyViewPort(); +} + +void VersionListView::setEmptyMode(VersionListView::EmptyMode mode) +{ + m_emptyMode = mode; + updateEmptyViewPort(); +} + +void VersionListView::updateEmptyViewPort() +{ if(!m_itemCount) { viewport()->update(); @@ -85,6 +102,18 @@ void VersionListView::paintEvent(QPaintEvent *event) void VersionListView::paintInfoLabel(QPaintEvent *event) { + QString emptyString; + switch(m_emptyMode) + { + case VersionListView::Empty: + return; + case VersionListView::String: + emptyString = m_emptyString; + break; + case VersionListView::ErrorString: + emptyString = m_emptyErrorString; + break; + } //calculate the rect for the overlay QPainter painter(viewport()); painter.setRenderHint(QPainter::Antialiasing, true); @@ -93,7 +122,7 @@ void VersionListView::paintInfoLabel(QPaintEvent *event) QRect bounds = viewport()->geometry(); bounds.moveTop(0); - QTextLayout layout(m_emptyString, font); + QTextLayout layout(emptyString, font); qreal height = 0.0; qreal widthUsed = 0.0; QStringList lines = viewItemTextLayout(layout, bounds.width() - 20, height, widthUsed); diff --git a/application/widgets/VersionListView.h b/application/widgets/VersionListView.h index f33a6fdb..4fcbd8ee 100644 --- a/application/widgets/VersionListView.h +++ b/application/widgets/VersionListView.h @@ -22,11 +22,22 @@ class VersionListView : public QTreeView { Q_OBJECT public: + explicit VersionListView(QWidget *parent = 0); virtual void paintEvent(QPaintEvent *event) override; - void setEmptyString(QString emptyString); virtual void setModel ( QAbstractItemModel* model ); + enum EmptyMode + { + Empty, + String, + ErrorString + }; + + void setEmptyString(QString emptyString); + void setEmptyErrorString(QString emptyErrorString); + void setEmptyMode(EmptyMode mode); + public slots: virtual void reset() override; @@ -36,8 +47,11 @@ protected slots: private: /* methods */ void paintInfoLabel(QPaintEvent *event); + void updateEmptyViewPort(); private: /* variables */ int m_itemCount = 0; QString m_emptyString; + QString m_emptyErrorString; + EmptyMode m_emptyMode = Empty; }; diff --git a/logic/forge/ForgeVersionList.cpp b/logic/forge/ForgeVersionList.cpp index b2320a6d..4f9870f7 100644 --- a/logic/forge/ForgeVersionList.cpp +++ b/logic/forge/ForgeVersionList.cpp @@ -144,6 +144,11 @@ void ForgeListLoadTask::executeTask() listJob->start(); } +void ForgeListLoadTask::abort() +{ + listJob->abort(); +} + bool ForgeListLoadTask::parseForgeList(QList &out) { QByteArray data; diff --git a/logic/forge/ForgeVersionList.h b/logic/forge/ForgeVersionList.h index baae570d..2ffc2d68 100644 --- a/logic/forge/ForgeVersionList.h +++ b/logic/forge/ForgeVersionList.h @@ -66,6 +66,7 @@ public: explicit ForgeListLoadTask(ForgeVersionList *vlist); virtual void executeTask(); + virtual void abort(); protected slots: diff --git a/logic/tasks/Task.cpp b/logic/tasks/Task.cpp index 150ea48d..8fed810b 100644 --- a/logic/tasks/Task.cpp +++ b/logic/tasks/Task.cpp @@ -44,6 +44,7 @@ void Task::emitFailed(QString reason) m_failReason = reason; qCritical() << "Task failed: " << reason; emit failed(reason); + emit finished(); } void Task::emitSucceeded() @@ -53,6 +54,7 @@ void Task::emitSucceeded() m_succeeded = true; qDebug() << "Task succeeded"; emit succeeded(); + emit finished(); } bool Task::isRunning() const diff --git a/logic/tasks/Task.h b/logic/tasks/Task.h index 746a2b26..3ab85d7d 100644 --- a/logic/tasks/Task.h +++ b/logic/tasks/Task.h @@ -42,6 +42,7 @@ public: signals: void started(); void progress(qint64 current, qint64 total); + void finished(); void succeeded(); void failed(QString reason); void status(QString status);