[PATCH] Separate downloadfromdivecomputer code into a separate class
This patch provides a separate class for downloading divelogs from dive computers, used for implementing common code used by both the desktop and mobile versions of Subsurface. The new class is called DownloadManager, inherited from QObject. The models used by vendor and product comboboxes are implemented with QStringListModel, both of these as members of DownloadManager that passes these models to both the desktop and mobile applications. Two points: 1) At this stage only the desktop-oriented code is implemented. The addition of mobile-oriented code is the next step. 2) DownloadManager will include several functions, signals and slots in addition to the present code. Signed-off-by: Willem Ferguson <willemfergu...@zoology.up.ac.za> At the moment, downloadmanager is in the Desktop-widgets. This is for development purposes only because it is handy to have downloadfromdivecomputer.cpp close to downloadmanager.cpp Kind regards, willem
>From d05d63e157e86d289afd1e9b55d00a2cf42c7840 Mon Sep 17 00:00:00 2001 From: Willem Ferguson <willemfergu...@zoology.up.ac.za> Date: Thu, 4 Feb 2016 08:19:12 +0200 Subject: [PATCH 3/3] [PATCH] Separate downloadfromdivecomputer code into a separate class This patch provides a separate class for downloading divelogs from dive computers, used for implementing common code used by both the desktop and mobile versions of Subsurface. The new class is called DownloadManager, inherited from QObject. The models used by vendor and product comoboxes are implemented with QStringListModel, both of these as members of DownloadManager that passes these models to both the desktop and mobile applications. Two points: 1) At this stage only the desktop-oriented code is implemented. The addition of mobile-oriented code is the next step. 2) DownloadManager will include several functions, signals and slots in addition to the present code. Signed-off-by: Willem Ferguson <willemfergu...@zoology.up.ac.za> --- desktop-widgets/CMakeLists.txt | 1 + desktop-widgets/downloadfromdivecomputer.cpp | 78 +++++------------------- desktop-widgets/downloadfromdivecomputer.h | 15 +++-- desktop-widgets/downloadmanager.cpp | 89 ++++++++++++++++++++++++++++ desktop-widgets/downloadmanager.h | 39 ++++++++++++ 5 files changed, 153 insertions(+), 69 deletions(-) create mode 100644 desktop-widgets/downloadmanager.cpp create mode 100644 desktop-widgets/downloadmanager.h diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt index dc55035..ec077d7 100644 --- a/desktop-widgets/CMakeLists.txt +++ b/desktop-widgets/CMakeLists.txt @@ -57,6 +57,7 @@ set(SUBSURFACE_INTERFACE diveplanner.cpp diveshareexportdialog.cpp downloadfromdivecomputer.cpp + downloadmanager.cpp globe.cpp kmessagewidget.cpp maintab.cpp diff --git a/desktop-widgets/downloadfromdivecomputer.cpp b/desktop-widgets/downloadfromdivecomputer.cpp index 4c8fa6b..78a7714 100644 --- a/desktop-widgets/downloadfromdivecomputer.cpp +++ b/desktop-widgets/downloadfromdivecomputer.cpp @@ -5,6 +5,7 @@ #include "display.h" #include "uemis.h" #include "models.h" +#include "downloadmanager.h" #include <QTimer> #include <QFileDialog> @@ -40,13 +41,13 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : thread(0), downloading(false), previousLast(0), - vendorModel(0), - productModel(0), timer(new QTimer(this)), dumpWarningShown(false), ostcFirmwareCheck(0), currentState(INITIAL) + { + downloadHelper = new DownloadManager(); clear_table(&downloadTable); ui.setupUi(this); ui.progressBar->hide(); @@ -64,7 +65,7 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : progress_bar_text = ""; - fill_computer_list(); + downloadHelper->fill_computer_list(); ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked()); connect(ui.chooseDumpFile, SIGNAL(clicked()), this, SLOT(pickDumpFile())); @@ -76,12 +77,10 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : ui.unselectAllButton->setEnabled(false); connect(ui.selectAllButton, SIGNAL(clicked()), diveImportedModel, SLOT(selectAll())); connect(ui.unselectAllButton, SIGNAL(clicked()), diveImportedModel, SLOT(selectNone())); - vendorModel = new QStringListModel(vendorList); - ui.vendor->setModel(vendorModel); + ui.vendor->setModel(downloadHelper->vendorModel); if (default_dive_computer_vendor) { ui.vendor->setCurrentIndex(ui.vendor->findText(default_dive_computer_vendor)); - productModel = new QStringListModel(productList[default_dive_computer_vendor]); - ui.product->setModel(productModel); + ui.product->setModel(downloadHelper->productModel); if (default_dive_computer_product) ui.product->setCurrentIndex(ui.product->findText(default_dive_computer_product)); } @@ -199,8 +198,8 @@ void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor) if (!currentModel) return; - productModel = new QStringListModel(productList[vendor]); - ui.product->setModel(productModel); + downloadHelper->productModel->setStringList(downloadHelper->productList[vendor]); + ui.product->setModel(downloadHelper->productModel); if (vendor == QString("Uemis")) dcType = DC_TYPE_UEMIS; @@ -214,7 +213,7 @@ void DownloadFromDCWidget::on_product_currentIndexChanged(const QString &product { // Set up the DC descriptor dc_descriptor_t *descriptor = NULL; - descriptor = descriptorLookup[ui.vendor->currentText() + product]; + descriptor = downloadHelper->descriptorLookup[ui.vendor->currentText() + product]; // call dc_descriptor_get_transport to see if the dc_transport_t is DC_TRANSPORT_SERIAL if (dc_descriptor_get_transport(descriptor) == DC_TRANSPORT_SERIAL) { @@ -226,60 +225,13 @@ void DownloadFromDCWidget::on_product_currentIndexChanged(const QString &product } } -void DownloadFromDCWidget::fill_computer_list() -{ - dc_iterator_t *iterator = NULL; - dc_descriptor_t *descriptor = NULL; - struct mydescriptor *mydescriptor; - - QStringList computer; - dc_descriptor_iterator(&iterator); - while (dc_iterator_next(iterator, &descriptor) == DC_STATUS_SUCCESS) { - const char *vendor = dc_descriptor_get_vendor(descriptor); - const char *product = dc_descriptor_get_product(descriptor); - - if (!vendorList.contains(vendor)) - vendorList.append(vendor); - - if (!productList[vendor].contains(product)) - productList[vendor].push_back(product); - - descriptorLookup[QString(vendor) + QString(product)] = descriptor; - } - dc_iterator_free(iterator); - Q_FOREACH (QString vendor, vendorList) - qSort(productList[vendor]); - - /* and add the Uemis Zurich which we are handling internally - THIS IS A HACK as we magically have a data structure here that - happens to match a data structure that is internal to libdivecomputer; - this WILL BREAK if libdivecomputer changes the dc_descriptor struct... - eventually the UEMIS code needs to move into libdivecomputer, I guess */ - - mydescriptor = (struct mydescriptor *)malloc(sizeof(struct mydescriptor)); - mydescriptor->vendor = "Uemis"; - mydescriptor->product = "Zurich"; - mydescriptor->type = DC_FAMILY_NULL; - mydescriptor->model = 0; - - if (!vendorList.contains("Uemis")) - vendorList.append("Uemis"); - - if (!productList["Uemis"].contains("Zurich")) - productList["Uemis"].push_back("Zurich"); - - descriptorLookup["UemisZurich"] = (dc_descriptor_t *)mydescriptor; - - qSort(vendorList); -} - void DownloadFromDCWidget::on_search_clicked() { if (ui.vendor->currentText() == "Uemis") { QString dirName = QFileDialog::getExistingDirectory(this, - tr("Find Uemis dive computer"), - QDir::homePath(), - QFileDialog::ShowDirsOnly); + tr("Find Uemis dive computer"), + QDir::homePath(), + QFileDialog::ShowDirsOnly); if (ui.device->findText(dirName) == -1) ui.device->addItem(dirName); ui.device->setEditText(dirName); @@ -332,7 +284,7 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked() } else { data.devname = strdup(ui.device->currentText().toUtf8().data()); } - data.descriptor = descriptorLookup[ui.vendor->currentText() + ui.product->currentText()]; + data.descriptor = downloadHelper->descriptorLookup[ui.vendor->currentText() + ui.product->currentText()]; data.force_download = ui.forceDownload->isChecked(); data.create_new_trip = ui.createNewTrip->isChecked(); data.trip = NULL; @@ -380,7 +332,7 @@ void DownloadFromDCWidget::pickLogFile() QFileInfo fi(filename); filename = fi.absolutePath().append(QDir::separator()).append("subsurface.log"); logFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer download logfile"), - filename, tr("Log files (*.log)")); + filename, tr("Log files (*.log)")); if (!logFile.isEmpty()) { free(logfile_name); logfile_name = strdup(logFile.toUtf8().data()); @@ -396,7 +348,7 @@ void DownloadFromDCWidget::checkDumpFile(int state) pickDumpFile(); if (!dumpWarningShown) { QMessageBox::warning(this, tr("Warning"), - tr("Saving the libdivecomputer dump will NOT download dives to the dive list.")); + tr("Saving the libdivecomputer dump will NOT download dives to the dive list.")); dumpWarningShown = true; } } diff --git a/desktop-widgets/downloadfromdivecomputer.h b/desktop-widgets/downloadfromdivecomputer.h index 7acd49e..15e90f2 100644 --- a/desktop-widgets/downloadfromdivecomputer.h +++ b/desktop-widgets/downloadfromdivecomputer.h @@ -10,11 +10,13 @@ #include "libdivecomputer.h" #include "configuredivecomputerdialog.h" #include "ui_downloadfromdivecomputer.h" +#include "downloadmanager.h" #if defined(BT_SUPPORT) #include "btdeviceselectiondialog.h" #endif + class QStringListModel; class DownloadThread : public QThread { @@ -96,15 +98,15 @@ private: DownloadThread *thread; bool downloading; - QStringList vendorList; - QHash<QString, QStringList> productList; - QMap<QString, dc_descriptor_t *> descriptorLookup; +// QStringList vendorList; +// QHash<QString, QStringList> productList; +// QMap<QString, dc_descriptor_t *> descriptorLookup; device_data_t data; int previousLast; - QStringListModel *vendorModel; - QStringListModel *productModel; - void fill_computer_list(); +// QStringListModel *vendorModel; +// QStringListModel *productModel; +// void fill_computer_list(); void fill_device_list(int dc_type); QString logFile; QString dumpFile; @@ -117,6 +119,7 @@ private: #endif public: + DownloadManager *downloadHelper; bool preferDownloaded(); void updateState(states state); states currentState; diff --git a/desktop-widgets/downloadmanager.cpp b/desktop-widgets/downloadmanager.cpp new file mode 100644 index 0000000..1100014 --- /dev/null +++ b/desktop-widgets/downloadmanager.cpp @@ -0,0 +1,89 @@ +#include <QStringListModel> +#include <QStringList> +#include <QString> +#include <QHash> +#include <QMap> +#include "downloadmanager.h" +#include "libdivecomputer.h" +#include "divecomputer.h" +#include "display.h" + +DownloadManager::DownloadManager(QObject *parent) : QObject(parent) { +} + +DownloadManager::~DownloadManager() {} + +/* ------------------------ Fill_computer_list -------------------------- +1) Fill the QstringList structures containing the vendor names as well as the + products of all the supported dive computers. +2) Set up the hash table that points to the descriptor structure for each + dive computer. +This method is used by both the desktop and the mobile software. + ----------------------------------------------------------------------- */ +void DownloadManager::fill_computer_list() +{ + struct mydescriptor { + const char *vendor; + const char *product; + dc_family_t type; + unsigned int model; + }; + + struct mydescriptor *mydescriptor; + + dc_iterator_t *iterator = NULL; + dc_descriptor_t *descriptor = NULL; + + dc_descriptor_iterator(&iterator); + int vendorRow = 0; + int productRow = 0; + while (dc_iterator_next(iterator, &descriptor) == DC_STATUS_SUCCESS) { + const char *vendor = dc_descriptor_get_vendor(descriptor); + const char *product = dc_descriptor_get_product(descriptor); + + if (!vendorList.contains(vendor)) + vendorList.append(vendor); + + if (!productList[vendor].contains(product)) + productList[vendor].push_back(product); + + descriptorLookup[QString(vendor) + QString(product)] = descriptor; + } + dc_iterator_free(iterator); + Q_FOREACH (QString vendor, vendorList) + qSort(productList[vendor]); + + /* and add the Uemis Zurich which we are handling internally + THIS IS A HACK as we magically have a data structure here that + happens to match a data structure that is internal to libdivecomputer; + this WILL BREAK if libdivecomputer changes the dc_descriptor struct... + eventually the UEMIS code needs to move into libdivecomputer, I guess */ + + mydescriptor = (struct mydescriptor *)malloc(sizeof(struct mydescriptor)); + mydescriptor->vendor = "Uemis"; + mydescriptor->product = "Zurich"; + mydescriptor->type = DC_FAMILY_NULL; + mydescriptor->model = 0; + + if (!vendorList.contains("Uemis")) + vendorList.append("Uemis"); + + if (!productList["Uemis"].contains("Zurich")) + productList["Uemis"].push_back("Zurich"); + + descriptorLookup["UemisZurich"] = (dc_descriptor_t *)mydescriptor; + + qSort(vendorList); + + vendorModel=new QStringListModel(vendorList); + if (default_dive_computer_vendor) + productModel=new QStringListModel(productList[default_dive_computer_vendor]); + +} + +void DownloadManager::onVendorChanged(const QString &vendor) +{ + productModel->setStringList(productList[vendor]); +} + + diff --git a/desktop-widgets/downloadmanager.h b/desktop-widgets/downloadmanager.h new file mode 100644 index 0000000..0b438f4 --- /dev/null +++ b/desktop-widgets/downloadmanager.h @@ -0,0 +1,39 @@ +#ifndef DOWNLOADMANAGER_H +#define DOWNLOADMANAGER_H + +#include <QStringList> +#include <QStringListModel> +#include <QAbstractListModel> +#include <QString> +#include <QHash> +#include <QMap> +#include <QDebug> +#include "libdivecomputer.h" + +class DownloadManager : public QObject +{ + Q_OBJECT +public: + DownloadManager(QObject *parent = 0); + ~DownloadManager(); + + QStringList vendorList; + QHash<QString, QStringList> productList; + + QStringListModel *vendorModel; + QStringListModel *productModel; + QMap<QString, dc_descriptor_t *> descriptorLookup; + + void fill_computer_list(); + void onVendorChanged(const QString &vendor); + void printStringList(QStringList SList); + +private: + +signals: + +public slots: + +}; + +#endif // DOWNLOADMANAGER_H -- 2.1.4
_______________________________________________ subsurface mailing list subsurface@subsurface-divelog.org http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface