From bf5f5091ef6daeaf7067f4fc8973eb068ddc52fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 9 Aug 2013 00:26:35 +0200 Subject: [PATCH] Various task related improvements. * Errors are reported back to task users via Failure signals. * Lwjgl doesn't download on each legacy instance start anymore. * Tasks were unified when it comes to success/failure. * Task dialogs don't get spawned after short tasks finish anymore. --- backend/BaseUpdate.cpp | 5 --- backend/BaseUpdate.h | 14 +----- backend/LegacyUpdate.cpp | 59 +++++++++++++++----------- backend/LegacyUpdate.h | 3 ++ backend/OneSixUpdate.cpp | 14 +++--- backend/lists/LwjglVersionList.cpp | 3 +- backend/lists/MinecraftVersionList.cpp | 23 ++++------ backend/tasks/LoginTask.cpp | 23 +++++----- backend/tasks/LoginTask.h | 11 ++--- backend/tasks/Task.cpp | 18 ++++---- backend/tasks/Task.h | 23 +++------- gui/mainwindow.cpp | 36 ++++++++-------- gui/mainwindow.h | 6 +-- gui/taskdialog.cpp | 12 +++--- gui/taskdialog.h | 4 +- main.cpp | 16 +++---- 16 files changed, 122 insertions(+), 148 deletions(-) diff --git a/backend/BaseUpdate.cpp b/backend/BaseUpdate.cpp index 8a4aced3..b086ab14 100644 --- a/backend/BaseUpdate.cpp +++ b/backend/BaseUpdate.cpp @@ -5,11 +5,6 @@ BaseUpdate::BaseUpdate ( BaseInstance* inst, QObject* parent ) : Task ( parent ) m_inst = inst; } -void BaseUpdate::error ( const QString& msg ) -{ - emit gameUpdateError(msg); -} - void BaseUpdate::updateDownloadProgress(qint64 current, qint64 total) { // The progress on the current file is current / total diff --git a/backend/BaseUpdate.h b/backend/BaseUpdate.h index 83eb0089..b7d2017e 100644 --- a/backend/BaseUpdate.h +++ b/backend/BaseUpdate.h @@ -38,20 +38,8 @@ public: virtual void executeTask() = 0; -signals: - /*! - * \brief Signal emitted when the game update is complete. - */ - void gameUpdateComplete(); - - /*! - * \brief Signal emitted if an error occurrs during the update. - * \param errorMsg An error message to be displayed to the user. - */ - void gameUpdateError(const QString &errorMsg); - protected slots: - virtual void error(const QString &msg); + //virtual void error(const QString &msg); void updateDownloadProgress(qint64 current, qint64 total); protected: diff --git a/backend/LegacyUpdate.cpp b/backend/LegacyUpdate.cpp index ff42e52d..630f7f29 100644 --- a/backend/LegacyUpdate.cpp +++ b/backend/LegacyUpdate.cpp @@ -18,21 +18,33 @@ void LegacyUpdate::executeTask() void LegacyUpdate::lwjglStart() { LegacyInstance * inst = (LegacyInstance *) m_inst; + + lwjglVersion = inst->lwjglVersion(); + lwjglTargetPath = PathCombine("lwjgl", lwjglVersion ); + lwjglNativesPath = PathCombine( lwjglTargetPath, "natives/"); + + // if the 'done' file exists, we don't have to download this again + QFileInfo doneFile(PathCombine(lwjglTargetPath, "done")); + if(doneFile.exists()) + { + emitSucceeded(); + return; + } + auto &list = LWJGLVersionList::get(); if(!list.isLoaded()) { - error("Too soon! Let the LWJGL list load :)"); - emitEnded(); + emitFailed("Too soon! Let the LWJGL list load :)"); return; } - QString lwjglVer = inst->lwjglVersion(); - auto version = list.getVersion(lwjglVer); + + auto version = list.getVersion(lwjglVersion); if(!version) { - error("Game update failed: the selected LWJGL version is invalid."); - emitEnded(); + emitFailed("Game update failed: the selected LWJGL version is invalid."); + return; } - lwjglVersion = version->name(); + QString url = version->url(); QUrl realUrl(url); QString hostname = realUrl.host(); @@ -56,8 +68,9 @@ void LegacyUpdate::lwjglFinished(QNetworkReply* reply) } if(reply->error() != QNetworkReply::NoError) { - error("Failed to download: " + reply->errorString() + "\nSometimes you have to wait a bit if you download many LWJGL versions in a row. YMMV"); - emitEnded(); + emitFailed( "Failed to download: "+ + reply->errorString()+ + "\nSometimes you have to wait a bit if you download many LWJGL versions in a row. YMMV"); return; } auto &worker = NetWorker::spawn(); @@ -95,22 +108,19 @@ void LegacyUpdate::lwjglFinished(QNetworkReply* reply) void LegacyUpdate::extractLwjgl() { // make sure the directories are there - QString lwjgl_base = PathCombine("lwjgl", lwjglVersion ); - QString nativesPath = PathCombine( lwjgl_base, "natives/"); - bool success = ensurePathExists(nativesPath); + + bool success = ensurePathExists(lwjglNativesPath); if(!success) { - error("Failed to extract the lwjgl libs - error when creating required folders."); - emitEnded(); + emitFailed("Failed to extract the lwjgl libs - error when creating required folders."); return; } QuaZip zip("lwjgl.zip"); if(!zip.open(QuaZip::mdUnzip)) { - error("Failed to extract the lwjgl libs - not a valid archive."); - emitEnded(); + emitFailed("Failed to extract the lwjgl libs - not a valid archive."); return; } @@ -122,8 +132,7 @@ void LegacyUpdate::extractLwjgl() if(!file.open(QIODevice::ReadOnly)) { zip.close(); - error("Failed to extract the lwjgl libs - error while reading archive."); - emitEnded(); + emitFailed("Failed to extract the lwjgl libs - error while reading archive."); return; } QuaZipFileInfo info; @@ -139,7 +148,7 @@ void LegacyUpdate::extractLwjgl() { if (name.endsWith(jarNames[i])) { - destFileName = PathCombine(lwjgl_base, jarNames[i]); + destFileName = PathCombine(lwjglTargetPath, jarNames[i]); } } // Not found? look for the natives @@ -160,7 +169,7 @@ void LegacyUpdate::extractLwjgl() name = name.mid(lastSlash+1); else if(lastBackSlash != -1) name = name.mid(lastBackSlash+1); - destFileName = PathCombine(nativesPath, name); + destFileName = PathCombine(lwjglNativesPath, name); } } // Now if destFileName is still empty, go to the next file. @@ -176,13 +185,15 @@ void LegacyUpdate::extractLwjgl() } zip.close(); m_reply.clear(); - emit gameUpdateComplete(); - emitEnded(); + QFile doneFile(PathCombine(lwjglTargetPath, "done")); + doneFile.open(QIODevice::WriteOnly); + doneFile.write("done."); + doneFile.close(); + emitSucceeded(); } void LegacyUpdate::lwjglFailed() { - error("Bad stuff happened while trying to get the lwjgl libs..."); - emitEnded(); + emitFailed("Bad stuff happened while trying to get the lwjgl libs..."); } diff --git a/backend/LegacyUpdate.h b/backend/LegacyUpdate.h index de5608d0..cc1f5efd 100644 --- a/backend/LegacyUpdate.h +++ b/backend/LegacyUpdate.h @@ -47,6 +47,9 @@ private: // MinecraftVersion *targetVersion; QString lwjglURL; QString lwjglVersion; + + QString lwjglTargetPath; + QString lwjglNativesPath; }; diff --git a/backend/OneSixUpdate.cpp b/backend/OneSixUpdate.cpp index 84d8dfae..db15c923 100644 --- a/backend/OneSixUpdate.cpp +++ b/backend/OneSixUpdate.cpp @@ -43,7 +43,7 @@ void OneSixUpdate::executeTask() if(targetVersion == nullptr) { // don't do anything if it was invalid - emit gameUpdateComplete(); + emitSucceeded(); return; } @@ -104,8 +104,7 @@ void OneSixUpdate::versionFileFinished() void OneSixUpdate::versionFileFailed() { - error("Failed to download the version description. Try again."); - emitEnded(); + emitFailed("Failed to download the version description. Try again."); } void OneSixUpdate::jarlibStart() @@ -114,8 +113,7 @@ void OneSixUpdate::jarlibStart() bool successful = inst->reloadFullVersion(); if(!successful) { - error("Failed to load the version description file (version.json). It might be corrupted, missing or simply too new."); - emitEnded(); + emitFailed("Failed to load the version description file (version.json). It might be corrupted, missing or simply too new."); return; } @@ -149,13 +147,11 @@ void OneSixUpdate::jarlibStart() void OneSixUpdate::jarlibFinished() { - emit gameUpdateComplete(); - emitEnded(); + emitSucceeded(); } void OneSixUpdate::jarlibFailed() { - error("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE"); - emitEnded(); + emitFailed("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE"); } diff --git a/backend/lists/LwjglVersionList.cpp b/backend/lists/LwjglVersionList.cpp index 73a27a58..068394e8 100644 --- a/backend/lists/LwjglVersionList.cpp +++ b/backend/lists/LwjglVersionList.cpp @@ -119,8 +119,7 @@ void LWJGLVersionList::netRequestComplete() int errorLine; if (!doc.setContent(reply->readAll(), false, &xmlErrorMsg, &errorLine)) { - failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + - " at line " + QString::number(errorLine)); + failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " + QString::number(errorLine)); setLoading(false); return; } diff --git a/backend/lists/MinecraftVersionList.cpp b/backend/lists/MinecraftVersionList.cpp index e14d7a25..ae28c46d 100644 --- a/backend/lists/MinecraftVersionList.cpp +++ b/backend/lists/MinecraftVersionList.cpp @@ -179,9 +179,8 @@ void MCVListLoadTask::list_downloaded() { if(vlistReply->error() != QNetworkReply::QNetworkReply::NoError) { - qDebug() << "Failed to load Minecraft main version list" << vlistReply->errorString(); vlistReply->deleteLater(); - emitEnded(); + emitFailed("Failed to load Minecraft main version list" + vlistReply->errorString()); return; } @@ -191,15 +190,13 @@ void MCVListLoadTask::list_downloaded() if (jsonError.error != QJsonParseError::NoError) { - qDebug() << "Error parsing version list JSON:" << jsonError.errorString(); - emitEnded(); + emitFailed("Error parsing version list JSON:" + jsonError.errorString()); return; } if(!jsonDoc.isObject()) { - qDebug() << "Error parsing version list JSON: " << "jsonDoc is not an object"; - emitEnded(); + emitFailed("Error parsing version list JSON: jsonDoc is not an object"); return; } @@ -208,8 +205,7 @@ void MCVListLoadTask::list_downloaded() // Get the ID of the latest release and the latest snapshot. if(!root.value("latest").isObject()) { - qDebug() << "Error parsing version list JSON: " << "version list is missing 'latest' object"; - emitEnded(); + emitFailed("Error parsing version list JSON: version list is missing 'latest' object"); return; } @@ -219,22 +215,19 @@ void MCVListLoadTask::list_downloaded() QString latestSnapshotID = latest.value("snapshot").toString(""); if(latestReleaseID.isEmpty()) { - qDebug() << "Error parsing version list JSON: " << "latest release field is missing"; - emitEnded(); + emitFailed("Error parsing version list JSON: latest release field is missing"); return; } if(latestSnapshotID.isEmpty()) { - qDebug() << "Error parsing version list JSON: " << "latest snapshot field is missing"; - emitEnded(); + emitFailed("Error parsing version list JSON: latest snapshot field is missing"); return; } // Now, get the array of versions. if(!root.value("versions").isArray()) { - qDebug() << "Error parsing version list JSON: " << "version list object is missing 'versions' array"; - emitEnded(); + emitFailed("Error parsing version list JSON: version list object is missing 'versions' array"); return; } QJsonArray versions = root.value("versions").toArray(); @@ -308,7 +301,7 @@ void MCVListLoadTask::list_downloaded() #ifdef PRINT_VERSIONS m_list->printToStdOut(); #endif - emitEnded(); + emitSucceeded(); return; } diff --git a/backend/tasks/LoginTask.cpp b/backend/tasks/LoginTask.cpp index 7a1d5262..48202044 100644 --- a/backend/tasks/LoginTask.cpp +++ b/backend/tasks/LoginTask.cpp @@ -71,44 +71,41 @@ void LoginTask::processNetReply(QNetworkReply *reply) QString username = strings[2]; QString sessionID = strings[3]; - LoginResponse response{username, sessionID, latestVersion}; - emit loginComplete(response); + result = {username, sessionID, latestVersion}; + emitSucceeded(); } else { - emit loginFailed("Failed to parse Minecraft version string."); + emitFailed("Failed to parse Minecraft version string."); } } else { if (responseStr.toLower() == "bad login") - emit loginFailed("Invalid username or password."); + emitFailed("Invalid username or password."); else if (responseStr.toLower() == "old version") - emit loginFailed("Launcher outdated, please update."); + emitFailed("Launcher outdated, please update."); else - emit loginFailed("Login failed: " + responseStr); + emitFailed("Login failed: " + responseStr); } } else if (responseCode == 503) { - emit loginFailed("The login servers are currently unavailable. " - "Check http://help.mojang.com/ for more info."); + emitFailed("The login servers are currently unavailable. Check http://help.mojang.com/ for more info."); } else { - emit loginFailed(QString("Login failed: Unknown HTTP error %1 occurred."). - arg(QString::number(responseCode))); + emitFailed(QString("Login failed: Unknown HTTP error %1 occurred.").arg(QString::number(responseCode))); } break; } case QNetworkReply::OperationCanceledError: - emit loginFailed("Login canceled."); + emitFailed("Login canceled."); break; default: - emit loginFailed("Login failed: " + reply->errorString()); + emitFailed("Login failed: " + reply->errorString()); break; } - emitEnded(); } diff --git a/backend/tasks/LoginTask.h b/backend/tasks/LoginTask.h index 81d1b6cc..77d65255 100644 --- a/backend/tasks/LoginTask.h +++ b/backend/tasks/LoginTask.h @@ -40,17 +40,18 @@ class LIBMULTIMC_EXPORT LoginTask : public Task Q_OBJECT public: explicit LoginTask(const UserInfo& uInfo, QObject *parent = 0); + LoginResponse getResult() + { + return result; + }; -public slots: +protected slots: void processNetReply(QNetworkReply* reply); -signals: - void loginComplete(LoginResponse loginResponse); - void loginFailed(const QString& errorMsg); - protected: void executeTask(); + LoginResponse result; QNetworkReply* netReply; UserInfo uInfo; }; diff --git a/backend/tasks/Task.cpp b/backend/tasks/Task.cpp index 30dd2d10..7c148591 100644 --- a/backend/tasks/Task.cpp +++ b/backend/tasks/Task.cpp @@ -37,11 +37,6 @@ int Task::getProgress() const return progress; } -void Task::calcProgress(int parts, int whole) -{ - setProgress((int)((((float)parts) / ((float)whole))*100)); // Not sure if C++ or LISP... -} - void Task::setProgress(int progress) { this->progress = progress; @@ -58,16 +53,21 @@ void Task::emitStarted() { running = true; emit started(); - emit started(this); } -void Task::emitEnded() +void Task::emitFailed(QString reason) { running = false; - emit ended(); - emit ended(this); + emit failed(reason); } +void Task::emitSucceeded() +{ + running = false; + emit succeeded(); +} + + bool Task::isRunning() const { return running; diff --git a/backend/tasks/Task.h b/backend/tasks/Task.h index bbe27ae1..15219931 100644 --- a/backend/tasks/Task.h +++ b/backend/tasks/Task.h @@ -27,33 +27,21 @@ class LIBMULTIMC_EXPORT Task : public QObject public: explicit Task(QObject *parent = 0); - // Starts the task. - void startTask(); - QString getStatus() const; int getProgress() const; - bool isRunning() const; - /*! - * \brief Calculates and sets the task's progress based on the number of parts completed out of the total number to complete. - * This is essentially just shorthand for setProgress((parts / whole) * 100); - * \param parts The parts out of the whole completed. This parameter should - * be less than whole. If it is greater than whole, progress is set to 100. - * \param whole The total number of things that need to be completed. - */ - void calcProgress(int parts, int whole); +public slots: + void startTask(); protected slots: void setStatus(const QString& status); void setProgress(int progress); signals: - void started(Task* task); - void ended(Task* task); - void started(); - void ended(); + void failed(QString reason); + void succeeded(); void statusChanged(Task* task, const QString& status); void progressChanged(Task* task, int progress); @@ -65,7 +53,8 @@ protected: virtual void executeTask() = 0; virtual void emitStarted(); - virtual void emitEnded(); + virtual void emitFailed(QString reason); + virtual void emitSucceeded(); virtual void emitStatusChange(const QString &status); virtual void emitProgressChange(int progress); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 309e4180..4d6a510b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -173,7 +173,8 @@ void MainWindow::on_actionAddInstance_triggered() m_versionLoadTask && m_versionLoadTask->isRunning()) { QEventLoop waitLoop; - waitLoop.connect(m_versionLoadTask, SIGNAL(ended()), SLOT(quit())); + waitLoop.connect(m_versionLoadTask, SIGNAL(failed(QString)), SLOT(quit())); + waitLoop.connect(m_versionLoadTask, SIGNAL(succeeded()), SLOT(quit())); waitLoop.exec(); } @@ -260,13 +261,11 @@ void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionReportBug_triggered() { - //QDesktopServices::openUrl(QUrl("http://bugs.forkk.net/")); - openWebPage ( QUrl ( "http://bugs.forkk.net/" ) ); + openWebPage ( QUrl ( "http://jira.forkk.net/browse/MMC" ) ); } void MainWindow::on_actionNews_triggered() { - //QDesktopServices::openUrl(QUrl("http://news.forkk.net/")); openWebPage ( QUrl ( "http://news.forkk.net/" ) ); } @@ -397,20 +396,19 @@ void MainWindow::doLogin(const QString& errorMsg) TaskDialog* tDialog = new TaskDialog(this); LoginTask* loginTask = new LoginTask(uInfo, tDialog); - connect(loginTask, SIGNAL(loginComplete(LoginResponse)), - SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection); - connect(loginTask, SIGNAL(loginFailed(QString)), - SLOT(doLogin(QString)), Qt::QueuedConnection); + connect(loginTask, SIGNAL(succeeded()),SLOT(onLoginComplete()), Qt::QueuedConnection); + connect(loginTask, SIGNAL(failed(QString)), SLOT(doLogin(QString)), Qt::QueuedConnection); m_activeInst = selectedInstance(); tDialog->exec(loginTask); } } -void MainWindow::onLoginComplete(LoginResponse response) +void MainWindow::onLoginComplete() { if(!m_activeInst) return; - m_activeLogin = LoginResponse(response); + LoginTask * task = (LoginTask *) QObject::sender(); + m_activeLogin = task->getResult(); BaseUpdate *updateTask = m_activeInst->doUpdate(); if(!updateTask) @@ -420,8 +418,8 @@ void MainWindow::onLoginComplete(LoginResponse response) else { TaskDialog *tDialog = new TaskDialog(this); - connect(updateTask, SIGNAL(gameUpdateComplete()),SLOT(onGameUpdateComplete())); - connect(updateTask, SIGNAL(gameUpdateError(QString)), SLOT(onGameUpdateError(QString))); + connect(updateTask, SIGNAL(succeeded()),SLOT(onGameUpdateComplete())); + connect(updateTask, SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); tDialog->exec(updateTask); } } @@ -451,23 +449,25 @@ void MainWindow::launchInstance(BaseInstance *instance, LoginResponse response) proc->launch(); } -void MainWindow::taskStart(Task *task) +void MainWindow::taskStart() { // Nothing to do here yet. } -void MainWindow::taskEnd(Task *task) +void MainWindow::taskEnd() { - if (task == m_versionLoadTask) + QObject *sender = QObject::sender(); + if (sender == m_versionLoadTask) m_versionLoadTask = NULL; - delete task; + sender->deleteLater(); } void MainWindow::startTask(Task *task) { - connect(task, SIGNAL(started(Task*)), SLOT(taskStart(Task*))); - connect(task, SIGNAL(ended(Task*)), SLOT(taskEnd(Task*))); + connect(task, SIGNAL(started()), SLOT(taskStart())); + connect(task, SIGNAL(succeeded()), SLOT(taskEnd())); + connect(task, SIGNAL(failed(QString)), SLOT(taskEnd())); task->startTask(); } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 6fa83973..2a490ee5 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -98,14 +98,14 @@ private slots: void doLogin(const QString& errorMsg = ""); - void onLoginComplete(LoginResponse response); + void onLoginComplete(); void onGameUpdateComplete(); void onGameUpdateError(QString error); - void taskStart(Task *task); - void taskEnd(Task *task); + void taskStart(); + void taskEnd(); void on_actionChangeInstLWJGLVersion_triggered(); diff --git a/gui/taskdialog.cpp b/gui/taskdialog.cpp index efa64256..f61614e8 100644 --- a/gui/taskdialog.cpp +++ b/gui/taskdialog.cpp @@ -45,12 +45,14 @@ void TaskDialog::exec(Task *task) this->task = task; // Connect signals. - connect(task, SIGNAL(started(Task*)), SLOT(onTaskStarted(Task*))); - connect(task, SIGNAL(ended(Task*)), SLOT(onTaskEnded(Task*))); + connect(task, SIGNAL(started()), SLOT(onTaskStarted())); + connect(task, SIGNAL(failed(QString)), SLOT(onTaskEnded())); + connect(task, SIGNAL(succeeded()), SLOT(onTaskEnded())); connect(task, SIGNAL(statusChanged(const QString&)), SLOT(changeStatus(const QString&))); connect(task, SIGNAL(progressChanged(int)), SLOT(changeProgress(int))); - task->startTask(); + // this makes sure that the task is started after the dialog is created + QMetaObject::invokeMethod(task, "startTask", Qt::QueuedConnection); QDialog::exec(); } @@ -59,12 +61,12 @@ Task* TaskDialog::getTask() return task; } -void TaskDialog::onTaskStarted(Task*) +void TaskDialog::onTaskStarted() { } -void TaskDialog::onTaskEnded(Task*) +void TaskDialog::onTaskEnded() { close(); } diff --git a/gui/taskdialog.h b/gui/taskdialog.h index 86cd4b54..3d31b7be 100644 --- a/gui/taskdialog.h +++ b/gui/taskdialog.h @@ -39,8 +39,8 @@ public: Task* getTask(); public slots: - void onTaskStarted(Task*); - void onTaskEnded(Task*); + void onTaskStarted(); + void onTaskEnded(); void changeStatus(const QString& status); void changeProgress(int progress); diff --git a/main.cpp b/main.cpp index 50fed27f..51516a81 100644 --- a/main.cpp +++ b/main.cpp @@ -61,9 +61,11 @@ private slots: QApplication::instance()->quit(); } - void onLoginComplete(QString instId, LoginResponse response) + void onLoginComplete() { - proc = instance->prepareForLaunch(response.username, response.sessionID); + LoginTask * task = (LoginTask *) QObject::sender(); + auto result = task->getResult(); + proc = instance->prepareForLaunch(result.username, result.sessionID); if(!proc) { //FIXME: report error @@ -78,7 +80,7 @@ private slots: proc->launch(); } - void doLogin(QString instId, const QString &errorMsg) + void doLogin(const QString &errorMsg) { LoginDialog* loginDlg = new LoginDialog(nullptr, errorMsg); if (loginDlg->exec()) @@ -87,10 +89,8 @@ private slots: TaskDialog* tDialog = new TaskDialog(nullptr); LoginTask* loginTask = new LoginTask(uInfo, tDialog); - connect(loginTask, SIGNAL(loginComplete(QString, LoginResponse)), - SLOT(onLoginComplete(QString, LoginResponse)), Qt::QueuedConnection); - connect(loginTask, SIGNAL(loginFailed(QString, QString)), - SLOT(doLogin(QString, QString)), Qt::QueuedConnection); + connect(loginTask, SIGNAL(succeeded()),SLOT(onLoginComplete()), Qt::QueuedConnection); + connect(loginTask, SIGNAL(failed(QString)),SLOT(doLogin(QString)), Qt::QueuedConnection); tDialog->exec(loginTask); } //onLoginComplete(LoginResponse("Offline","Offline", 1)); @@ -111,7 +111,7 @@ public: } std::cout << "Logging in..." << std::endl; - doLogin(instance->id(),""); + doLogin(""); return QApplication::instance()->exec(); }