mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Import: Make DownloadThread a subobject of DiveImportedModel
Currently, desktop and mobile are accessing the DownloadThread and the DiveImportedModel concurrently. This makes a big data flow mess. To achieve a more hierarchical data flow, start by making the DownloadThread a subobject of DiveImportedModel. Start the download by calling a function in DiveImportedModel. Route the finished signal through DiveImportedModel. Thus, the model can reload itself with the new data. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
6e343c734a
commit
ad7ffa0af0
5 changed files with 45 additions and 33 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "core/settings/qPrefDiveComputer.h"
|
#include "core/settings/qPrefDiveComputer.h"
|
||||||
#include "core/subsurface-string.h"
|
#include "core/subsurface-string.h"
|
||||||
#include "core/uemis.h"
|
#include "core/uemis.h"
|
||||||
|
#include "core/downloadfromdcthread.h"
|
||||||
#include "desktop-widgets/divelistview.h"
|
#include "desktop-widgets/divelistview.h"
|
||||||
#include "desktop-widgets/mainwindow.h"
|
#include "desktop-widgets/mainwindow.h"
|
||||||
#include "qt-models/diveimportedmodel.h"
|
#include "qt-models/diveimportedmodel.h"
|
||||||
|
@ -67,8 +68,7 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) :
|
||||||
connect(close, SIGNAL(activated()), this, SLOT(close()));
|
connect(close, SIGNAL(activated()), this, SLOT(close()));
|
||||||
connect(quit, SIGNAL(activated()), parent, SLOT(close()));
|
connect(quit, SIGNAL(activated()), parent, SLOT(close()));
|
||||||
|
|
||||||
connect(&thread, SIGNAL(finished()),
|
connect(diveImportedModel, &DiveImportedModel::downloadFinished, this, &DownloadFromDCWidget::onDownloadThreadFinished);
|
||||||
this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection);
|
|
||||||
|
|
||||||
if (!qPrefDiveComputer::vendor().isEmpty()) {
|
if (!qPrefDiveComputer::vendor().isEmpty()) {
|
||||||
ui.vendor->setCurrentIndex(ui.vendor->findText(qPrefDiveComputer::vendor()));
|
ui.vendor->setCurrentIndex(ui.vendor->findText(qPrefDiveComputer::vendor()));
|
||||||
|
@ -272,7 +272,7 @@ void DownloadFromDCWidget::updateState(states state)
|
||||||
markChildrenAsEnabled();
|
markChildrenAsEnabled();
|
||||||
progress_bar_text = "";
|
progress_bar_text = "";
|
||||||
} else {
|
} else {
|
||||||
if (thread.table()->nr != 0)
|
if (diveImportedModel->thread.table()->nr != 0)
|
||||||
progress_bar_text = "";
|
progress_bar_text = "";
|
||||||
ui.progressBar->setValue(100);
|
ui.progressBar->setValue(100);
|
||||||
markChildrenAsEnabled();
|
markChildrenAsEnabled();
|
||||||
|
@ -297,7 +297,7 @@ void DownloadFromDCWidget::updateState(states state)
|
||||||
else if (state == ERRORED) {
|
else if (state == ERRORED) {
|
||||||
timer->stop();
|
timer->stop();
|
||||||
|
|
||||||
QMessageBox::critical(this, TITLE_OR_TEXT(tr("Error"), thread.error), QMessageBox::Ok);
|
QMessageBox::critical(this, TITLE_OR_TEXT(tr("Error"), diveImportedModel->thread.error), QMessageBox::Ok);
|
||||||
markChildrenAsEnabled();
|
markChildrenAsEnabled();
|
||||||
progress_bar_text = "";
|
progress_bar_text = "";
|
||||||
ui.progressBar->hide();
|
ui.progressBar->hide();
|
||||||
|
@ -367,7 +367,7 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked()
|
||||||
// this means we are retrying - so we better clean out the partial
|
// this means we are retrying - so we better clean out the partial
|
||||||
// list of downloaded dives from the last attempt
|
// list of downloaded dives from the last attempt
|
||||||
diveImportedModel->clearTable();
|
diveImportedModel->clearTable();
|
||||||
clear_dive_table(thread.table());
|
clear_dive_table(diveImportedModel->thread.table());
|
||||||
}
|
}
|
||||||
updateState(DOWNLOADING);
|
updateState(DOWNLOADING);
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked()
|
||||||
ui.cancel->setEnabled(false);
|
ui.cancel->setEnabled(false);
|
||||||
ui.downloadCancelRetryButton->setText(tr("Cancel download"));
|
ui.downloadCancelRetryButton->setText(tr("Cancel download"));
|
||||||
|
|
||||||
auto data = thread.data();
|
auto data = diveImportedModel->thread.data();
|
||||||
data->setVendor(ui.vendor->currentText());
|
data->setVendor(ui.vendor->currentText());
|
||||||
data->setProduct(ui.product->currentText());
|
data->setProduct(ui.product->currentText());
|
||||||
#if defined(BT_SUPPORT)
|
#if defined(BT_SUPPORT)
|
||||||
|
@ -417,7 +417,7 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked()
|
||||||
|
|
||||||
// before we start, remember where the dive_table ended
|
// before we start, remember where the dive_table ended
|
||||||
previousLast = dive_table.nr;
|
previousLast = dive_table.nr;
|
||||||
thread.start();
|
diveImportedModel->startDownload();
|
||||||
|
|
||||||
// FIXME: We should get the _actual_ device info instead of whatever
|
// FIXME: We should get the _actual_ device info instead of whatever
|
||||||
// the user entered in the dropdown.
|
// the user entered in the dropdown.
|
||||||
|
@ -500,7 +500,7 @@ void DownloadFromDCWidget::onDownloadThreadFinished()
|
||||||
showRememberedDCs();
|
showRememberedDCs();
|
||||||
|
|
||||||
if (currentState == DOWNLOADING) {
|
if (currentState == DOWNLOADING) {
|
||||||
if (thread.error.isEmpty())
|
if (diveImportedModel->thread.error.isEmpty())
|
||||||
updateState(DONE);
|
updateState(DONE);
|
||||||
else
|
else
|
||||||
updateState(ERRORED);
|
updateState(ERRORED);
|
||||||
|
@ -509,7 +509,6 @@ void DownloadFromDCWidget::onDownloadThreadFinished()
|
||||||
}
|
}
|
||||||
ui.downloadCancelRetryButton->setText(tr("Retry download"));
|
ui.downloadCancelRetryButton->setText(tr("Retry download"));
|
||||||
ui.downloadCancelRetryButton->setEnabled(true);
|
ui.downloadCancelRetryButton->setEnabled(true);
|
||||||
diveImportedModel->repopulate(thread.table(), thread.sites());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadFromDCWidget::on_cancel_clicked()
|
void DownloadFromDCWidget::on_cancel_clicked()
|
||||||
|
@ -518,7 +517,7 @@ void DownloadFromDCWidget::on_cancel_clicked()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// now discard all the dives
|
// now discard all the dives
|
||||||
clear_dive_table(thread.table());
|
clear_dive_table(diveImportedModel->thread.table());
|
||||||
done(-1);
|
done(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,8 +525,8 @@ void DownloadFromDCWidget::on_ok_clicked()
|
||||||
{
|
{
|
||||||
if (currentState != DONE && currentState != ERRORED)
|
if (currentState != DONE && currentState != ERRORED)
|
||||||
return;
|
return;
|
||||||
struct dive_table *table = thread.table();
|
struct dive_table *table = diveImportedModel->thread.table();
|
||||||
struct dive_site_table *sites = thread.sites();
|
struct dive_site_table *sites = diveImportedModel->thread.sites();
|
||||||
|
|
||||||
// delete non-selected dives
|
// delete non-selected dives
|
||||||
int total = table->nr;
|
int total = table->nr;
|
||||||
|
@ -536,11 +535,11 @@ void DownloadFromDCWidget::on_ok_clicked()
|
||||||
if (diveImportedModel->data(diveImportedModel->index(i, 0), Qt::CheckStateRole) == Qt::Checked)
|
if (diveImportedModel->data(diveImportedModel->index(i, 0), Qt::CheckStateRole) == Qt::Checked)
|
||||||
j++;
|
j++;
|
||||||
else
|
else
|
||||||
delete_dive_from_table(thread.table(), j);
|
delete_dive_from_table(diveImportedModel->thread.table(), j);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->nr > 0) {
|
if (table->nr > 0) {
|
||||||
auto data = thread.data();
|
auto data = diveImportedModel->thread.data();
|
||||||
int flags = IMPORT_IS_DOWNLOADED;
|
int flags = IMPORT_IS_DOWNLOADED;
|
||||||
if (preferDownloaded())
|
if (preferDownloaded())
|
||||||
flags |= IMPORT_PREFER_IMPORTED;
|
flags |= IMPORT_PREFER_IMPORTED;
|
||||||
|
@ -550,7 +549,7 @@ void DownloadFromDCWidget::on_ok_clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ostcFirmwareCheck && currentState == DONE)
|
if (ostcFirmwareCheck && currentState == DONE)
|
||||||
ostcFirmwareCheck->checkLatest(this, thread.data()->internalData());
|
ostcFirmwareCheck->checkLatest(this, diveImportedModel->thread.data()->internalData());
|
||||||
accept();
|
accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include "core/libdivecomputer.h"
|
#include "core/libdivecomputer.h"
|
||||||
#include "desktop-widgets/configuredivecomputerdialog.h"
|
#include "desktop-widgets/configuredivecomputerdialog.h"
|
||||||
#include "core/downloadfromdcthread.h"
|
|
||||||
|
|
||||||
#include "ui_downloadfromdivecomputer.h"
|
#include "ui_downloadfromdivecomputer.h"
|
||||||
|
|
||||||
|
@ -21,6 +20,7 @@
|
||||||
|
|
||||||
class QStringListModel;
|
class QStringListModel;
|
||||||
class DiveImportedModel;
|
class DiveImportedModel;
|
||||||
|
class BTDiscovery;
|
||||||
|
|
||||||
class DownloadFromDCWidget : public QDialog {
|
class DownloadFromDCWidget : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -72,7 +72,6 @@ private:
|
||||||
QStringListModel vendorModel;
|
QStringListModel vendorModel;
|
||||||
QStringListModel productModel;
|
QStringListModel productModel;
|
||||||
Ui::DownloadFromDiveComputer ui;
|
Ui::DownloadFromDiveComputer ui;
|
||||||
DownloadThread thread;
|
|
||||||
bool downloading;
|
bool downloading;
|
||||||
|
|
||||||
int previousLast;
|
int previousLast;
|
||||||
|
|
|
@ -24,18 +24,13 @@ Kirigami.Page {
|
||||||
property alias product: comboProduct.currentIndex
|
property alias product: comboProduct.currentIndex
|
||||||
property alias connection: comboConnection.currentIndex
|
property alias connection: comboConnection.currentIndex
|
||||||
|
|
||||||
DCDownloadThread {
|
DCImportModel {
|
||||||
id: downloadThread
|
id: importModel
|
||||||
|
|
||||||
onFinished : {
|
onDownloadFinished : {
|
||||||
if (!table || !sites) {
|
|
||||||
console.warn("DCDownloadThread::onFinished(): table or sites is null!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
importModel.repopulate(table, sites)
|
|
||||||
progressBar.visible = false
|
progressBar.visible = false
|
||||||
if (dcImportModel.rowCount() > 0) {
|
if (rowCount() > 0) {
|
||||||
console.log(dcImportModel.rowCount() + " dive downloaded")
|
console.log(rowCount() + " dive downloaded")
|
||||||
divesDownloaded = true
|
divesDownloaded = true
|
||||||
} else {
|
} else {
|
||||||
console.log("no new dives downloaded")
|
console.log("no new dives downloaded")
|
||||||
|
@ -45,10 +40,6 @@ Kirigami.Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DCImportModel {
|
|
||||||
id: importModel
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
@ -295,7 +286,7 @@ Kirigami.Page {
|
||||||
message += " downloading " + (manager.DC_forceDownload ? "all" : "only new" ) + " dives";
|
message += " downloading " + (manager.DC_forceDownload ? "all" : "only new" ) + " dives";
|
||||||
manager.appendTextToLog(message)
|
manager.appendTextToLog(message)
|
||||||
progressBar.visible = true
|
progressBar.visible = true
|
||||||
downloadThread.start()
|
importModel.startDownload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SsrfButton {
|
SsrfButton {
|
||||||
|
|
|
@ -8,6 +8,7 @@ DiveImportedModel::DiveImportedModel(QObject *o) : QAbstractTableModel(o),
|
||||||
diveTable(nullptr),
|
diveTable(nullptr),
|
||||||
sitesTable(nullptr)
|
sitesTable(nullptr)
|
||||||
{
|
{
|
||||||
|
connect(&thread, &QThread::finished, this, &DiveImportedModel::downloadThreadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DiveImportedModel::columnCount(const QModelIndex&) const
|
int DiveImportedModel::columnCount(const QModelIndex&) const
|
||||||
|
@ -129,6 +130,17 @@ void DiveImportedModel::clearTable()
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiveImportedModel::downloadThreadFinished()
|
||||||
|
{
|
||||||
|
repopulate(thread.table(), thread.sites());
|
||||||
|
emit downloadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiveImportedModel::startDownload()
|
||||||
|
{
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
void DiveImportedModel::repopulate(dive_table_t *table, struct dive_site_table *sites)
|
void DiveImportedModel::repopulate(dive_table_t *table, struct dive_site_table *sites)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "core/divesite.h"
|
#include "core/divesite.h"
|
||||||
|
#include "core/downloadfromdcthread.h"
|
||||||
|
|
||||||
class DiveImportedModel : public QAbstractTableModel
|
class DiveImportedModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
|
@ -20,8 +21,10 @@ public:
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
Q_INVOKABLE void clearTable();
|
Q_INVOKABLE void clearTable();
|
||||||
QHash<int, QByteArray> roleNames() const;
|
QHash<int, QByteArray> roleNames() const;
|
||||||
Q_INVOKABLE void repopulate(dive_table_t *table, dive_site_table_t *sites);
|
|
||||||
Q_INVOKABLE void recordDives();
|
Q_INVOKABLE void recordDives();
|
||||||
|
Q_INVOKABLE void startDownload();
|
||||||
|
|
||||||
|
DownloadThread thread;
|
||||||
public
|
public
|
||||||
slots:
|
slots:
|
||||||
void changeSelected(QModelIndex clickedIndex);
|
void changeSelected(QModelIndex clickedIndex);
|
||||||
|
@ -29,7 +32,15 @@ slots:
|
||||||
void selectAll();
|
void selectAll();
|
||||||
void selectNone();
|
void selectNone();
|
||||||
|
|
||||||
|
private
|
||||||
|
slots:
|
||||||
|
void downloadThreadFinished();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void downloadFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void repopulate(dive_table_t *table, dive_site_table_t *sites);
|
||||||
int firstIndex;
|
int firstIndex;
|
||||||
int lastIndex;
|
int lastIndex;
|
||||||
std::vector<char> checkStates; // char instead of bool to avoid silly pessimization of std::vector.
|
std::vector<char> checkStates; // char instead of bool to avoid silly pessimization of std::vector.
|
||||||
|
|
Loading…
Reference in a new issue