diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2013-09-10 12:07:34 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-09-10 12:07:34 -0700 |
commit | 636477becc3d8bea147382a7fec13d53c0e04433 (patch) | |
tree | e7a714d5da006021f3a633c09153faec2c04851f | |
parent | e7fd45c7efe8dcb2c38bd518e02e20bfb8898c86 (diff) | |
parent | 3f8e183008530fb8e110b77d04cf794c46ba4720 (diff) | |
download | subsurface-636477becc3d8bea147382a7fec13d53c0e04433.tar.gz |
Merge branch 'downloaddialog' of github.com:danilocesar/subsurface
-rw-r--r-- | qt-ui/downloadfromdivecomputer.cpp | 170 | ||||
-rw-r--r-- | qt-ui/downloadfromdivecomputer.h | 40 |
2 files changed, 143 insertions, 67 deletions
diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp index 7514c9482..acdca89d3 100644 --- a/qt-ui/downloadfromdivecomputer.cpp +++ b/qt-ui/downloadfromdivecomputer.cpp @@ -10,6 +10,8 @@ #include <QThread> #include <QDebug> #include <QStringListModel> +#include <QTimer> +#include <QMessageBox> struct product { const char *product; @@ -42,7 +44,8 @@ DownloadFromDCWidget *DownloadFromDCWidget::instance() } DownloadFromDCWidget::DownloadFromDCWidget(QWidget* parent, Qt::WindowFlags f) : - QDialog(parent, f), ui(new Ui::DownloadFromDiveComputer), thread(0), downloading(false) + QDialog(parent, f), ui(new Ui::DownloadFromDiveComputer), thread(0), timer(new QTimer(this)), + currentState(INITIAL) { ui->setupUi(this); ui->progressBar->hide(); @@ -61,21 +64,86 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget* parent, Qt::WindowFlags f) : } if (default_dive_computer_device) ui->device->setText(default_dive_computer_device); + + timer->setInterval(200); + connect(timer, SIGNAL(timeout()), this, SLOT(updateProgressBar())); + + updateState(INITIAL); } void DownloadFromDCWidget::runDialog() { - // Since the DownloadDialog is only - // created once, we need to do put some starting code here - ui->progressBar->hide(); - markChildrenAsEnabled(); + updateState(INITIAL); exec(); } -void DownloadFromDCWidget::stoppedDownloading() +void DownloadFromDCWidget::updateProgressBar() +{ + ui->progressBar->setValue(progress_bar_fraction *100); +} + +void DownloadFromDCWidget::updateState(states state) { - downloading = false; + if (state == currentState) + return; + + if (state == INITIAL) { + ui->progressBar->hide(); + markChildrenAsEnabled(); + timer->stop(); + } + + // tries to cancel an on going download + else if (currentState == DOWNLOADING && state == CANCELLING) { + import_thread_cancelled = true; + ui->cancel->setEnabled(false); + } + + // user pressed cancel but the application isn't doing anything. + // means close the window + else if ((currentState == INITIAL || currentState == CANCELLED || currentState == DONE || currentState == ERROR) + && state == CANCELLING) { + timer->stop(); + reject(); + } + + // the cancelation process is finished + else if (currentState == CANCELLING && (state == DONE || state == CANCELLED)) { + timer->stop(); + state = CANCELLED; + ui->progressBar->setValue(0); + ui->progressBar->hide(); + markChildrenAsEnabled(); + } + + // DOWNLOAD is finally done, close the dialog and go back to the main window + else if (currentState == DOWNLOADING && state == DONE) { + timer->stop(); + ui->progressBar->setValue(100); + markChildrenAsEnabled(); + accept(); + } + + // DOWNLOAD is started. + else if (state == DOWNLOADING) { + timer->start(); + ui->progressBar->setValue(0); + ui->progressBar->show(); + markChildrenAsDisabled(); + } + + // got an error + else if (state == ERROR) { + QMessageBox::critical(this, tr("Error"), this->thread->error, QMessageBox::Ok); + + markChildrenAsEnabled(); + ui->progressBar->hide(); + ui->ok->setText(tr("retry")); + } + + // properly updating the widget state + currentState = state; } void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString& vendor) @@ -136,28 +204,15 @@ void DownloadFromDCWidget::fill_computer_list() void DownloadFromDCWidget::on_cancel_clicked() { - import_thread_cancelled = true; - if (thread) { - thread->wait(); - thread->deleteLater(); - thread = 0; - } - - // Confusing, but if the user press cancel during a download - // he probably want to cancel the download, not to close the window. - if (!downloading) - close(); + updateState(CANCELLING); } void DownloadFromDCWidget::on_ok_clicked() { - if (downloading) - return; - - markChildrenAsDisabled(); - ui->progressBar->setValue(0); - ui->progressBar->show(); + updateState(DOWNLOADING); + // I don't really think that create/destroy the thread + // is really necessary. if (thread) { thread->deleteLater(); } @@ -172,14 +227,15 @@ void DownloadFromDCWidget::on_ok_clicked() set_default_dive_computer(data.vendor, data.product); set_default_dive_computer_device(data.devname); - thread = new InterfaceThread(this, &data); - connect(thread, SIGNAL(updateInterface(int)), - ui->progressBar, SLOT(setValue(int)), Qt::QueuedConnection); // Qt::QueuedConnection == threadsafe. + thread = new DownloadThread(this, &data); + + connect(thread, SIGNAL(finished()), + this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection); - connect(thread, SIGNAL(finished()), this, SLOT(close())); + MainWindow *w = mainWindow(); + connect(thread, SIGNAL(finished()), w, SLOT(refreshDisplay())); thread->start(); - downloading = true; } bool DownloadFromDCWidget::preferDownloaded() @@ -191,10 +247,21 @@ void DownloadFromDCWidget::reject() { // we don't want the download window being able to close // while we're still downloading. - if (!downloading) + if (currentState != DOWNLOADING && currentState != CANCELLING) QDialog::reject(); } +void DownloadFromDCWidget::onDownloadThreadFinished() +{ + if (currentState == DOWNLOADING) { + if (thread->error.isEmpty()) + updateState(DONE); + else + updateState(ERROR); + } else + updateState(CANCELLED); +} + void DownloadFromDCWidget::markChildrenAsDisabled() { ui->device->setDisabled(true); @@ -214,37 +281,40 @@ void DownloadFromDCWidget::markChildrenAsEnabled() ui->forceDownload->setDisabled(false); ui->preferDownloaded->setDisabled(false); ui->ok->setDisabled(false); + ui->cancel->setDisabled(false); ui->search->setDisabled(false); } -DownloadThread::DownloadThread(device_data_t* data): data(data) +DownloadThread::DownloadThread(QObject* parent, device_data_t* data): QThread(parent), + data(data) +{ +} + +static QString str_error(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + const QString str = QString().vsprintf( fmt, args ); + va_end(args); + + return str; } void DownloadThread::run() { DownloadFromDCWidget *dfdcw = DownloadFromDCWidget::instance(); + const char *error; + if (!strcmp(data->vendor, "Uemis")) - do_uemis_import(data->devname, data->force_download); + error = do_uemis_import(data->devname, data->force_download); else - do_libdivecomputer_import(data); - process_dives(TRUE, dfdcw->preferDownloaded()); - dfdcw->stoppedDownloading(); -} - -InterfaceThread::InterfaceThread(QObject* parent, device_data_t* data): QThread(parent), data(data) -{ -} + error = do_libdivecomputer_import(data); -void InterfaceThread::run() -{ - DownloadThread *download = new DownloadThread(data); - MainWindow *w = mainWindow(); - connect(download, SIGNAL(finished()), w, SLOT(refreshDisplay())); - download->start(); - while (download->isRunning()) { - msleep(200); - updateInterface(progress_bar_fraction *100); + if (error) { + this->error = str_error(error, data->devname, data->vendor, data->product); } - updateInterface(100); + + // I'm not sure if we should really call process_dives even + // if there's an error or a cancelation + process_dives(TRUE, dfdcw->preferDownloaded()); } diff --git a/qt-ui/downloadfromdivecomputer.h b/qt-ui/downloadfromdivecomputer.h index 26216c1e0..e10d61b38 100644 --- a/qt-ui/downloadfromdivecomputer.h +++ b/qt-ui/downloadfromdivecomputer.h @@ -15,20 +15,10 @@ struct device_data_t; class DownloadThread : public QThread{ Q_OBJECT public: - explicit DownloadThread(device_data_t* data); - virtual void run(); -private: - device_data_t *data; -}; - -class InterfaceThread : public QThread{ - Q_OBJECT -public: - InterfaceThread(QObject *parent, device_data_t *data); + DownloadThread(QObject* parent, device_data_t* data); virtual void run(); -signals: - void updateInterface(int value); + QString error; private: device_data_t *data; }; @@ -41,19 +31,30 @@ public: static DownloadFromDCWidget *instance(); void reject(); + enum states { + INITIAL, + DOWNLOADING, + CANCELLING, + CANCELLED, + ERROR, + DONE, + }; + public slots: void on_ok_clicked(); void on_cancel_clicked(); - void runDialog(); - void stoppedDownloading(); void on_vendor_currentIndexChanged(const QString& vendor); + void onDownloadThreadFinished(); + void updateProgressBar(); + void runDialog(); + private: - void markChildrenAsDisabled(); - void markChildrenAsEnabled(); + void markChildrenAsDisabled(); + void markChildrenAsEnabled(); Ui::DownloadFromDiveComputer *ui; - InterfaceThread *thread; + DownloadThread *thread; bool downloading; QStringList vendorList; @@ -65,8 +66,13 @@ private: QStringListModel *productModel; void fill_computer_list(); + QTimer *timer; + public: bool preferDownloaded(); + void updateState(states state); + states currentState; + }; #endif |