[PATCH] Mobile: Downloadfromdivecomputer combo box content
1) Separate part of the downloadfromdivecomputer.cpp code into a separate object "DownloadManager". Implement DownloadManager within downloadfromdivecomputer.cpp. Several other pieces of code from downloadfromdivecomputer.cpp will be transferred to DownloadManager. THIS AFFECTS THE DESKTOP VERSION of Subsurface. The desktop version therefore requires downloadmanager.cpp 2) Initialise the mobile download interface by doing three things in subsurface-mobile-helper.cpp: a) Create a singleton object of DownloadManager b) Create the appropriate QML context pointers for DownLoadManager c) Initialise the comboboxes an progress bar in the download UI. 3) Within main.qml, load initial values into the combobox models. 4) Within DownloadFromDiveComputer.qml, populate and implement the two comboboxes as well as the progress bar. Signed-off-by: Willem Ferguson <[email protected]>
>From 5836dfd0a4c08ec3b67eb1ec32d70a9816942c3e Mon Sep 17 00:00:00 2001 From: Willem Ferguson <[email protected]> Date: Sun, 14 Feb 2016 11:37:33 +0200 Subject: [PATCH] [PATCH] Mobile: Downloadfromdivecomputer combo box content 1) Separate part of the downloadfromdivecomputer.cpp code into a separate object "DownloadManager". Implement DownloadManager within downloadfromdivecomputer.cpp. Several other pieces of code from downloadfromdivecomputer.cpp will be transferred to DownloadManager. THIS AFFECTS THE DESKTOP VERSION of Subsurface. The desktop version therefore requires downloadmanager.cpp 2) Initialise the mobile download interface by doing three things in subsurface-mobile-helper.cpp: a) Create a singleton object of DownloadManager b) Create the appropriate QML context pointers for DownLoadManager c) Initialise the comboboxes an progress bar in the download UI. 3) Within main.qml, load initial values into the combobox models. 4) Within DownloadFromDiveComputer.qml, populate and implement the two comboboxes as well as the progress bar. Signed-off-by: Willem Ferguson <[email protected]> --- desktop-widgets/downloadfromdivecomputer.cpp | 79 +++--------- desktop-widgets/downloadfromdivecomputer.h | 9 +- qt-mobile/qml/DownloadFromDiveComputer.qml | 25 +++- qt-mobile/qml/main.qml | 11 +- subsurface-core/CMakeLists.txt | 1 + subsurface-core/downloadmanager.cpp | 175 +++++++++++++++++++++++++++ subsurface-core/downloadmanager.h | 62 ++++++++++ subsurface-mobile-helper.cpp | 6 + 8 files changed, 290 insertions(+), 78 deletions(-) create mode 100644 subsurface-core/downloadmanager.cpp create mode 100644 subsurface-core/downloadmanager.h diff --git a/desktop-widgets/downloadfromdivecomputer.cpp b/desktop-widgets/downloadfromdivecomputer.cpp index 4c8fa6b..6ad1e2a 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 "subsurface-core/downloadmanager.h" #include <QTimer> #include <QFileDialog> @@ -40,13 +41,12 @@ 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 = DownloadManager::instance(); clear_table(&downloadTable); ui.setupUi(this); ui.progressBar->hide(); @@ -61,10 +61,9 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : ui.downloadedView->setColumnWidth(1, startingWidth * 10); ui.downloadedView->setColumnWidth(2, startingWidth * 10); connect(ui.downloadedView, SIGNAL(clicked(QModelIndex)), diveImportedModel, SLOT(changeSelected(QModelIndex))); - 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 +75,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 +196,9 @@ void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor) if (!currentModel) return; - productModel = new QStringListModel(productList[vendor]); - ui.product->setModel(productModel); + downloadHelper->onVendorChangedSlot(vendor); + ui.product->setModel(downloadHelper->productModel()); + ui.product->setCurrentIndex(0); if (vendor == QString("Uemis")) dcType = DC_TYPE_UEMIS; @@ -214,7 +212,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->getDescriptor(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 +224,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 +283,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->getDescriptor(ui.vendor->currentText(),ui.product->currentText()); data.force_download = ui.forceDownload->isChecked(); data.create_new_trip = ui.createNewTrip->isChecked(); data.trip = NULL; @@ -380,7 +331,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 +347,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..e122c73 100644 --- a/desktop-widgets/downloadfromdivecomputer.h +++ b/desktop-widgets/downloadfromdivecomputer.h @@ -10,6 +10,7 @@ #include "libdivecomputer.h" #include "configuredivecomputerdialog.h" #include "ui_downloadfromdivecomputer.h" +#include "subsurface-core/downloadmanager.h" #if defined(BT_SUPPORT) #include "btdeviceselectiondialog.h" @@ -96,15 +97,9 @@ private: DownloadThread *thread; bool downloading; - 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(); void fill_device_list(int dc_type); QString logFile; QString dumpFile; @@ -112,6 +107,8 @@ private: bool dumpWarningShown; OstcFirmwareCheck *ostcFirmwareCheck; DiveImportedModel *diveImportedModel; + DownloadManager *downloadHelper; + #if defined(BT_SUPPORT) BtDeviceSelectionDialog *btDeviceSelectionDialog; #endif diff --git a/qt-mobile/qml/DownloadFromDiveComputer.qml b/qt-mobile/qml/DownloadFromDiveComputer.qml index 529af82..9a6392a 100644 --- a/qt-mobile/qml/DownloadFromDiveComputer.qml +++ b/qt-mobile/qml/DownloadFromDiveComputer.qml @@ -34,16 +34,35 @@ MobileComponents.Page { anchors.top:parent.top Layout.fillWidth: true Text { text: " Vendor name : " } - ComboBox { Layout.fillWidth: true } + ComboBox { + id: vendorBox + Layout.fillWidth: true + editable: false + model: downloadhelper.vendorModel + textRole: "display" + onCurrentIndexChanged: { + downloadhelper.vendorName = currentText + downloadHelper.progressBar = 0.5 + } + } } RowLayout { Text { text: " Dive Computer:" } - ComboBox { Layout.fillWidth: true } + ComboBox { + id: productBox + Layout.fillWidth: true + editable: false + model:downloadhelper.productModel + textRole: "display" + } } RowLayout { Text { text: " Progress:" } Layout.fillWidth: true - ProgressBar { Layout.fillWidth: true } + ProgressBar { + Layout.fillWidth: true + value: downloadhelper.progressBar + } } RowLayout { SubsurfaceButton { diff --git a/qt-mobile/qml/main.qml b/qt-mobile/qml/main.qml index 2c066e2..d1b7947 100644 --- a/qt-mobile/qml/main.qml +++ b/qt-mobile/qml/main.qml @@ -48,7 +48,7 @@ MobileComponents.ApplicationWindow { if (diveList.numDives > 0) { manager.startPageText = "Enter different credentials or return to dive list" } else { - manager.startPageText = "Enter valdi cloud storage credentials" + manager.startPageText = "Enter valid cloud storage credentials" } manager.credentialStatus = QMLManager.UNKNOWN @@ -57,16 +57,17 @@ MobileComponents.ApplicationWindow { MobileComponents.ActionGroup { text: "Manage dives" enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL - /* - * disable for the beta to avoid confusion +// /* +// * disable for the beta to avoid confusion Action { - text: "Download from computer" + text: "Download from dive computer" onTriggered: { + downloadhelper.fill_computer_list() detailsWindow.endEditMode() stackView.push(downloadDivesWindow) } } - */ +// */ Action { text: "Add dive manually" onTriggered: { diff --git a/subsurface-core/CMakeLists.txt b/subsurface-core/CMakeLists.txt index 703864a..0f29e97 100644 --- a/subsurface-core/CMakeLists.txt +++ b/subsurface-core/CMakeLists.txt @@ -82,6 +82,7 @@ set(SUBSURFACE_CORE_LIB_SRCS isocialnetworkintegration.cpp gpslocation.cpp cloudstorage.cpp + downloadmanager.cpp #Subsurface Qt have the Subsurface structs QObjectified for easy access via QML. subsurface-qt/DiveObjectHelper.cpp diff --git a/subsurface-core/downloadmanager.cpp b/subsurface-core/downloadmanager.cpp new file mode 100644 index 0000000..7a465ff --- /dev/null +++ b/subsurface-core/downloadmanager.cpp @@ -0,0 +1,175 @@ +#include <QStringListModel> +#include <QStringList> +#include <QString> +#include <QHash> +#include <QMap> +#include "downloadmanager.h" +#include "libdivecomputer.h" +#include "divecomputer.h" +#include "display.h" + +struct mydescriptor { + const char *vendor; + const char *product; + dc_family_t type; + unsigned int model; +}; + +DownloadManager *DownloadManager::m_instance = NULL; + +DownloadManager::DownloadManager() +{ + m_instance = this; +} + +DownloadManager::~DownloadManager() +{ + m_instance = NULL; +} + +DownloadManager *DownloadManager::instance() +{ + if(!m_instance) + m_instance = new DownloadManager(); + return m_instance; +} + +/* ------------------------ 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 *mydescriptor; + + dc_iterator_t *iterator = NULL; + dc_descriptor_t *descriptor = NULL; + + 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); + + vendorModelObject=new QStringListModel(vendorList); + m_vendorModel = vendorModelObject; + + if (default_dive_computer_vendor) + { + productModelObject=new QStringListModel(productList[default_dive_computer_vendor]); + m_vendorName = default_dive_computer_vendor; + } else { + productModelObject=new QStringListModel(productList[vendorModelObject->stringList().at(0)]); + m_vendorName = vendorModelObject->stringList().at(0); + } + m_productModel = productModelObject; +} + +/* These following methods follow from these properties defined in the header downloadmanager.h: +Q_PROPERTY(QStringListModel *productModel READ productModel WRITE setProductModel) +Q_PROPERTY(QStringListModel *vendorModel READ vendorModel WRITE setVendorModel NOTIFY vendorChanged) */ + +void DownloadManager::setProductModel(QStringListModel *PModel) +{ + m_productModel = PModel; + emit productModelChanged(); // Trigger QML UI combobox update +} + +void DownloadManager::setVendorModel(QStringListModel *VModel) +{ + VModel->setStringList(this->vendorList); // This method uses vendorList + m_vendorModel = VModel; // as an external data source. +} + +QStringListModel *DownloadManager::vendorModel() +{ + return(m_vendorModel); +} + +QStringListModel *DownloadManager::productModel() +{ + return(m_productModel); +} + +void DownloadManager::onVendorChangedSlot(const QString vendorText) // Load productModel with product mame +{ // stringlist determined by vendorText. This method + productModelObject->setStringList(productList[vendorText]); // is called by the mobile and the desktop versions + setProductModel(productModelObject); //.when the product combobox needs appropriate update. +} + +dc_descriptor_t *DownloadManager::getDescriptor(QString vendorName, QString productName) +{ + m_descriptor = descriptorLookup[vendorName + productName]; + return m_descriptor; +} + +QString DownloadManager::vendorName() +{ + return(m_vendorName); +} + +void DownloadManager::setVendorName(const QString &vendorName) +{ + m_vendorName = vendorName; + onVendorChangedSlot(vendorName); +} + +void DownloadManager::changeProgressValue(float val) +{ + m_progressBarValue.setValue(val); // Need a floating point value to set the + setProgressBar(m_progressBarValue); // progressbar. Then call Q_PROPERTY-defined +} // function (below) to trigger signal. + +void DownloadManager::setProgressBar(QVariant value) +{ // The argument to this method HAS to be a QVariant + emit progressBarChanged(); // required by the Q_PROPERTY construct +} + +QVariant DownloadManager::progressBar() +{ + return m_progressBarValue; +} + +void DownloadManager::printList(QStringList M) // Print a QStringList M +{ + for (int i = 0; i < M.size(); ++i) { + QByteArray ba = M.at(i).toLatin1(); + printf("(%d) %s\n",i,ba.data()); + } +} + diff --git a/subsurface-core/downloadmanager.h b/subsurface-core/downloadmanager.h new file mode 100644 index 0000000..f834c48 --- /dev/null +++ b/subsurface-core/downloadmanager.h @@ -0,0 +1,62 @@ +#ifndef DOWNLOADMANAGER_H +#define DOWNLOADMANAGER_H + +#include <QStringList> +#include <QStringListModel> +#include <QAbstractListModel> +#include <QString> +#include <QHash> +#include <QMap> +#include <QDebug> +#include "libdivecomputer.h" + +// ================================ DownloadManager ============================================================= +class DownloadManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringListModel *productModel READ productModel WRITE setProductModel NOTIFY productModelChanged) + Q_PROPERTY(QStringListModel *vendorModel READ vendorModel WRITE setVendorModel NOTIFY vendorModelChanged) + Q_PROPERTY(QString vendorName READ vendorName WRITE setVendorName) + Q_PROPERTY(QVariant progressBar READ progressBar WRITE setProgressBar NOTIFY progressBarChanged) + Q_PROPERTY(DownloadManager *DownloadManager READ instance) +public: + static DownloadManager *instance(); + Q_INVOKABLE void fill_computer_list(); + void setProductModel(QStringListModel *PModel); + void setVendorModel(QStringListModel *VModel); + void newProductModel(QString vendorName); + dc_descriptor_t *getDescriptor(QString vendorName, QString productName); + QStringListModel *productModel(); + QStringListModel *vendorModel(); + QString vendorName(); + void setVendorName(const QString &vendorName); + void changeProgressValue(float val); + void setProgressBar(QVariant value); + QVariant progressBar(); +private: + DownloadManager(); + ~DownloadManager(); + static DownloadManager *m_instance; + QString m_vendorName; + QStringListModel *m_vendorModel; + QStringListModel *m_productModel; + dc_descriptor_t *m_descriptor; + QVariant m_progressBarValue; + QStringListModel *vendorModelObject; + QStringListModel *productModelObject; + QMap<QString, dc_descriptor_t *> descriptorLookup; + QStringList vendorList; + QHash<QString, QStringList> productList; + void printList(QStringList M); + +signals: + void productModelChanged(); + void vendorModelChanged(); + void progressBarChanged(); + +public slots: + void onVendorChangedSlot(const QString vendorText); + +}; + +#endif // DOWNLOADMANAGER_H diff --git a/subsurface-mobile-helper.cpp b/subsurface-mobile-helper.cpp index f6c6694..658be11 100644 --- a/subsurface-mobile-helper.cpp +++ b/subsurface-mobile-helper.cpp @@ -19,6 +19,7 @@ #include "qt-models/divelistmodel.h" #include "qt-models/gpslistmodel.h" #include "qt-mobile/qmlprofile.h" +#include "subsurface-core/downloadmanager.h" QObject *qqWindowObject = NULL; @@ -27,6 +28,8 @@ void init_ui() init_qt_late(); } +static DownloadManager *downloadhelper = DownloadManager::instance(); + void run_ui() { qmlRegisterType<QMLManager>("org.subsurfacedivelog.mobile", 1, 0, "QMLManager"); @@ -61,6 +64,9 @@ void run_ui() QQmlContext *ctxt = engine.rootContext(); ctxt->setContextProperty("diveModel", sortModel); ctxt->setContextProperty("gpsModel", gpsSortModel); + ctxt->setContextProperty("downloadhelper", downloadhelper); + downloadhelper->fill_computer_list(); + downloadhelper->changeProgressValue(0.0); engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml"))); qqWindowObject = engine.rootObjects().value(0); if (!qqWindowObject) { -- 2.5.0
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
