aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflow <thiagodonato300@gmail.com>2022-04-01 09:10:51 -0300
committerflow <thiagodonato300@gmail.com>2022-04-01 09:32:00 -0300
commit9b8493c30499e06bbef7b96ff415f80c140c1a7f (patch)
treef56773d7f046def84a98e45f741457767d3fb4e4
parente22d54abd35560213377bb41f2bc902f67c8de64 (diff)
downloadPrismLauncher-9b8493c30499e06bbef7b96ff415f80c140c1a7f.tar.gz
PrismLauncher-9b8493c30499e06bbef7b96ff415f80c140c1a7f.tar.bz2
PrismLauncher-9b8493c30499e06bbef7b96ff415f80c140c1a7f.zip
feat: Use a single progress dialog when doing multiple tasks
This puts all mod downloading tasks inside a SequentialTask, which is, for more than one task, a multi step task. This is handled by the ProgressDialog by showing both the global progress of tasks executed, and the individual progress of each of them.
-rw-r--r--launcher/tasks/SequentialTask.cpp50
-rw-r--r--launcher/tasks/SequentialTask.h28
-rw-r--r--launcher/tasks/Task.h68
-rw-r--r--launcher/ui/dialogs/ProgressDialog.cpp22
-rw-r--r--launcher/ui/dialogs/ProgressDialog.h5
-rw-r--r--launcher/ui/dialogs/ProgressDialog.ui45
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp37
7 files changed, 161 insertions, 94 deletions
diff --git a/launcher/tasks/SequentialTask.cpp b/launcher/tasks/SequentialTask.cpp
index a66b9d78..1573e476 100644
--- a/launcher/tasks/SequentialTask.cpp
+++ b/launcher/tasks/SequentialTask.cpp
@@ -1,7 +1,23 @@
#include "SequentialTask.h"
-SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-1)
+SequentialTask::SequentialTask(QObject* parent, const QString& task_name) : Task(parent), m_name(task_name), m_currentIndex(-1) {}
+
+SequentialTask::~SequentialTask()
+{
+ for(auto task : m_queue){
+ if(task)
+ task->deleteLater();
+ }
+}
+
+auto SequentialTask::getStepProgress() const -> qint64
+{
+ return m_stepProgress;
+}
+
+auto SequentialTask::getStepTotalProgress() const -> qint64
{
+ return m_stepTotalProgress;
}
void SequentialTask::addTask(Task::Ptr task)
@@ -15,16 +31,24 @@ void SequentialTask::executeTask()
startNext();
}
+bool SequentialTask::abort()
+{
+ bool succeeded = true;
+ for (auto& task : m_queue) {
+ if (!task->abort()) succeeded = false;
+ }
+
+ return succeeded;
+}
+
void SequentialTask::startNext()
{
- if (m_currentIndex != -1)
- {
+ if (m_currentIndex != -1) {
Task::Ptr previous = m_queue[m_currentIndex];
disconnect(previous.get(), 0, this, 0);
}
m_currentIndex++;
- if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
- {
+ if (m_queue.isEmpty() || m_currentIndex >= m_queue.size()) {
emitSucceeded();
return;
}
@@ -33,23 +57,27 @@ void SequentialTask::startNext()
connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
+
+ setStatus(tr("Executing task %1 out of %2").arg(m_currentIndex + 1).arg(m_queue.size()));
next->start();
}
-void SequentialTask::subTaskFailed(const QString &msg)
+void SequentialTask::subTaskFailed(const QString& msg)
{
emitFailed(msg);
}
-void SequentialTask::subTaskStatus(const QString &msg)
+void SequentialTask::subTaskStatus(const QString& msg)
{
- setStatus(msg);
+ setStepStatus(m_queue[m_currentIndex]->getStatus());
}
void SequentialTask::subTaskProgress(qint64 current, qint64 total)
{
- if(total == 0)
- {
+ if (total == 0) {
setProgress(0, 100);
return;
}
- setProgress(current, total);
+ setProgress(m_currentIndex, m_queue.count());
+
+ m_stepProgress = current;
+ m_stepTotalProgress = total;
}
diff --git a/launcher/tasks/SequentialTask.h b/launcher/tasks/SequentialTask.h
index 027744f3..5b3c0111 100644
--- a/launcher/tasks/SequentialTask.h
+++ b/launcher/tasks/SequentialTask.h
@@ -9,13 +9,21 @@ class SequentialTask : public Task
{
Q_OBJECT
public:
- explicit SequentialTask(QObject *parent = 0);
- virtual ~SequentialTask() {};
+ explicit SequentialTask(QObject *parent = nullptr, const QString& task_name = "");
+ virtual ~SequentialTask();
+
+ inline auto isMultiStep() const -> bool override { return m_queue.size() > 1; };
+ auto getStepProgress() const -> qint64 override;
+ auto getStepTotalProgress() const -> qint64 override;
+
+ inline auto getStepStatus() const -> QString override { return m_step_status; }
void addTask(Task::Ptr task);
-protected:
- void executeTask();
+protected slots:
+ void executeTask() override;
+public slots:
+ bool abort() override;
private
slots:
@@ -24,7 +32,19 @@ slots:
void subTaskStatus(const QString &msg);
void subTaskProgress(qint64 current, qint64 total);
+signals:
+ void stepStatus(QString status);
+
private:
+ void setStepStatus(QString status) { m_step_status = status; };
+
+private:
+ QString m_name;
+ QString m_step_status;
+
QQueue<Task::Ptr > m_queue;
int m_currentIndex;
+
+ qint64 m_stepProgress = 0;
+ qint64 m_stepTotalProgress = 100;
};
diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h
index 9cf08dbd..47c249b3 100644
--- a/launcher/tasks/Task.h
+++ b/launcher/tasks/Task.h
@@ -21,29 +21,27 @@
#include "QObjectPtr.h"
-class Task : public QObject
-{
+class Task : public QObject {
Q_OBJECT
-public:
+ public:
using Ptr = shared_qobject_ptr<Task>;
- enum class State
- {
- Inactive,
- Running,
- Succeeded,
- Failed,
- AbortedByUser
- };
+ enum class State { Inactive, Running, Succeeded, Failed, AbortedByUser };
-public:
- explicit Task(QObject *parent = 0);
- virtual ~Task() {};
+ public:
+ explicit Task(QObject* parent = 0);
+ virtual ~Task() = default;
bool isRunning() const;
bool isFinished() const;
bool wasSuccessful() const;
+ /*!
+ * MultiStep tasks are combinations of multiple tasks into a single logical task.
+ * The main usage of this is in SequencialTask.
+ */
+ virtual auto isMultiStep() const -> bool { return false; }
+
/*!
* Returns the string that was passed to emitFailed as the error message when the task failed.
* If the task hasn't failed, returns an empty string.
@@ -54,52 +52,45 @@ public:
virtual bool canAbort() const { return false; }
- QString getStatus()
- {
- return m_status;
- }
+ QString getStatus() { return m_status; }
+ virtual auto getStepStatus() const -> QString { return {}; }
- qint64 getProgress()
- {
- return m_progress;
- }
+ qint64 getProgress() { return m_progress; }
+ qint64 getTotalProgress() { return m_progressTotal; }
+ virtual auto getStepProgress() const -> qint64 { return 0; }
+ virtual auto getStepTotalProgress() const -> qint64 { return 100; }
- qint64 getTotalProgress()
- {
- return m_progressTotal;
- }
+ protected:
+ void logWarning(const QString& line);
-protected:
- void logWarning(const QString & line);
-
-private:
+ private:
QString describe();
-signals:
+ signals:
void started();
- void progress(qint64 current, qint64 total);
+ virtual void progress(qint64 current, qint64 total);
void finished();
void succeeded();
void failed(QString reason);
void status(QString status);
-public slots:
+ public slots:
virtual void start();
virtual bool abort() { return false; };
-protected:
+ protected:
virtual void executeTask() = 0;
-protected slots:
+ protected slots:
virtual void emitSucceeded();
virtual void emitAborted();
virtual void emitFailed(QString reason);
-public slots:
- void setStatus(const QString &status);
+ public slots:
+ void setStatus(const QString& status);
void setProgress(qint64 current, qint64 total);
-private:
+ private:
State m_state = State::Inactive;
QStringList m_Warnings;
QString m_failReason = "";
@@ -107,4 +98,3 @@ private:
int m_progress = 0;
int m_progressTotal = 100;
};
-
diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp
index 4b092859..648bd88b 100644
--- a/launcher/ui/dialogs/ProgressDialog.cpp
+++ b/launcher/ui/dialogs/ProgressDialog.cpp
@@ -81,6 +81,12 @@ int ProgressDialog::execWithTask(Task *task)
connect(task, SIGNAL(status(QString)), SLOT(changeStatus(const QString &)));
connect(task, SIGNAL(progress(qint64, qint64)), SLOT(changeProgress(qint64, qint64)));
+ m_is_multi_step = task->isMultiStep();
+ if(!m_is_multi_step){
+ ui->globalStatusLabel->setHidden(true);
+ ui->globalProgressBar->setHidden(true);
+ }
+
// if this didn't connect to an already running task, invoke start
if(!task->isRunning())
{
@@ -152,14 +158,24 @@ void ProgressDialog::onTaskSucceeded()
void ProgressDialog::changeStatus(const QString &status)
{
- ui->statusLabel->setText(status);
+ ui->statusLabel->setText(task->getStepStatus());
+ ui->globalStatusLabel->setText(status);
updateSize();
}
void ProgressDialog::changeProgress(qint64 current, qint64 total)
{
- ui->taskProgressBar->setMaximum(total);
- ui->taskProgressBar->setValue(current);
+ ui->globalProgressBar->setMaximum(total);
+ ui->globalProgressBar->setValue(current);
+
+ if(!m_is_multi_step){
+ ui->taskProgressBar->setMaximum(total);
+ ui->taskProgressBar->setValue(current);
+ }
+ else{
+ ui->taskProgressBar->setMaximum(task->getStepProgress());
+ ui->taskProgressBar->setValue(task->getStepTotalProgress());
+ }
}
void ProgressDialog::keyPressEvent(QKeyEvent *e)
diff --git a/launcher/ui/dialogs/ProgressDialog.h b/launcher/ui/dialogs/ProgressDialog.h
index b28ad4fa..0b4b78a4 100644
--- a/launcher/ui/dialogs/ProgressDialog.h
+++ b/launcher/ui/dialogs/ProgressDialog.h
@@ -19,6 +19,7 @@
#include <memory>
class Task;
+class SequentialTask;
namespace Ui
{
@@ -35,7 +36,7 @@ public:
void updateSize();
- int execWithTask(Task *task);
+ int execWithTask(Task* task);
int execWithTask(std::unique_ptr<Task> &&task);
int execWithTask(std::unique_ptr<Task> &task);
@@ -68,4 +69,6 @@ private:
Ui::ProgressDialog *ui;
Task *task;
+
+ bool m_is_multi_step = false;
};
diff --git a/launcher/ui/dialogs/ProgressDialog.ui b/launcher/ui/dialogs/ProgressDialog.ui
index 04b8fef3..bf119a78 100644
--- a/launcher/ui/dialogs/ProgressDialog.ui
+++ b/launcher/ui/dialogs/ProgressDialog.ui
@@ -2,14 +2,6 @@
<ui version="4.0">
<class>ProgressDialog</class>
<widget class="QDialog" name="ProgressDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>100</height>
- </rect>
- </property>
<property name="minimumSize">
<size>
<width>400</width>
@@ -26,7 +18,27 @@
<string>Please wait...</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="4" column="0">
+ <widget class="QPushButton" name="skipButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Skip</string>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
+ <widget class="QLabel" name="globalStatusLabel">
+ <property name="text">
+ <string>Global Task Status...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
<widget class="QLabel" name="statusLabel">
<property name="text">
<string>Task Status...</string>
@@ -36,7 +48,7 @@
</property>
</widget>
</item>
- <item row="1" column="0">
+ <item row="3" column="0">
<widget class="QProgressBar" name="taskProgressBar">
<property name="value">
<number>24</number>
@@ -46,16 +58,13 @@
</property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QPushButton" name="skipButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <item row="1" column="0">
+ <widget class="QProgressBar" name="globalProgressBar">
+ <property name="enabled">
+ <bool>true</bool>
</property>
- <property name="text">
- <string>Skip</string>
+ <property name="value">
+ <number>24</number>
</property>
</widget>
</item>
diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp
index 599f0e11..fcb6022d 100644
--- a/launcher/ui/pages/instance/ModFolderPage.cpp
+++ b/launcher/ui/pages/instance/ModFolderPage.cpp
@@ -58,6 +58,7 @@
#include "Version.h"
#include "ui/dialogs/ProgressDialog.h"
+#include "tasks/SequentialTask.h"
namespace {
// FIXME: wasteful
@@ -394,25 +395,25 @@ void ModFolderPage::on_actionInstall_mods_triggered()
return;
}
ModDownloadDialog mdownload(m_mods, this, m_inst);
- if(mdownload.exec()) {
- for(auto task : mdownload.getTasks()){
- connect(task, &Task::failed, [this, task](QString reason) {
- task->deleteLater();
- CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
- });
- connect(task, &Task::succeeded, [this, task]() {
- QStringList warnings = task->warnings();
- if (warnings.count()) {
- CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'),
- QMessageBox::Warning)->show();
- }
- task->deleteLater();
- });
- ProgressDialog loadDialog(this);
- loadDialog.setSkipButton(true, tr("Abort"));
- loadDialog.execWithTask(task);
- m_mods->update();
+ if (mdownload.exec()) {
+ SequentialTask* tasks = new SequentialTask(this);
+ connect(tasks, &Task::failed, [this, tasks](QString reason) {
+ CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->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_mods->update();
}
}