From aae27629c4b6f524911f869694da27dcd2533adb Mon Sep 17 00:00:00 2001 From: Grace Karanja Date: Mon, 13 Jul 2015 13:06:45 +0300 Subject: [PATCH 1/4] QL UI: Add DiveId role to DiveListModel This will be used when rendering the dive profile and also when saving the dive changes. Signed-off-by: Grace Karanja --- qt-models/divelistmodel.cpp | 14 ++++++++++++++ qt-models/divelistmodel.h | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 0fb1cbbf9..8bb895fc8 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -5,6 +5,7 @@ MobileDive::MobileDive(dive *d) { m_thisDive = d; setDiveNumber(QString::number(d->number)); + setDiveId(QString::number(d->id)); dive_trip *trip = d->divetrip; @@ -216,6 +217,16 @@ void MobileDive::setupDiveTempDetails() setWatertemp(get_temperature_string(m_thisDive->watertemp, true)); setAirTemp(get_temperature_string(m_thisDive->airtemp, true)); } +QString MobileDive::diveId() const +{ + return m_diveId; +} + +void MobileDive::setDiveId(const QString &diveId) +{ + m_diveId = diveId; +} + @@ -283,6 +294,8 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const return dive.buddy(); else if (role == DiveMasterRole) return dive.divemaster(); + else if (role == DiveIdRole) + return dive.diveId(); return QVariant(); @@ -308,6 +321,7 @@ QHash DiveListModel::roleNames() const roles[DiveNotesRole] = "notes"; roles[DiveBuddyRole] = "buddy"; roles[DiveMasterRole] = "divemaster"; + roles[DiveIdRole] = "id"; return roles; } diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h index 68f0c6fa7..89f793bbc 100644 --- a/qt-models/divelistmodel.h +++ b/qt-models/divelistmodel.h @@ -62,6 +62,9 @@ public: QString watertemp() const; void setWatertemp(const QString &watertemp); + QString diveId() const; + void setDiveId(const QString &diveId); + private: void setupDiveTempDetails(); @@ -82,6 +85,7 @@ private: QString m_notes; QString m_buddy; QString m_divemaster; + QString m_diveId; dive *m_thisDive; @@ -109,7 +113,8 @@ public: DiveLocationRole, DiveNotesRole, DiveBuddyRole, - DiveMasterRole + DiveMasterRole, + DiveIdRole }; static DiveListModel *instance(); From df1a1f7034c6c332f7f71a64ab45955c089cd56b Mon Sep 17 00:00:00 2001 From: Grace Karanja Date: Fri, 17 Jul 2015 18:28:01 +0300 Subject: [PATCH 2/4] QML UI: Implement saving of dives This implements saving of some dive details to the cloud service. When the user closes an open dives, any changed details will be cached, and when they click on the 'Save Changes' button is pressed, the changes will be saved to the cloud. Signed-off-by: Grace Karanja --- qt-mobile/DiveList.qml | 11 ++++++++- qt-mobile/main.qml | 8 +++++++ qt-mobile/qmlmanager.cpp | 48 +++++++++++++++++++++++++++++++++++++++- qt-mobile/qmlmanager.h | 2 ++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/qt-mobile/DiveList.qml b/qt-mobile/DiveList.qml index 40507e26a..0f358081d 100644 --- a/qt-mobile/DiveList.qml +++ b/qt-mobile/DiveList.qml @@ -109,7 +109,16 @@ Rectangle { opacity: dive.detailsOpacity text: "Close" - onClicked: dive.state = ''; + onClicked: { + manager.commitChanges( + id, + txtSuit.text, + txtBuddy.text, + txtDiveMaster.text, + txtNotes.text + ) + dive.state = ''; + } } states: State { diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml index dac37e09b..d64c27760 100644 --- a/qt-mobile/main.qml +++ b/qt-mobile/main.qml @@ -54,6 +54,14 @@ ApplicationWindow { manager.loadDives(); } } + + Button { + id: saveChanges + text: "Save Changes" + onClicked: { + manager.saveChanges(); + } + } } } diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp index 118465a2d..a1c64191b 100644 --- a/qt-mobile/qmlmanager.cpp +++ b/qt-mobile/qmlmanager.cpp @@ -66,7 +66,53 @@ void QMLManager::loadDives() struct dive *d; for_each_dive(i, d) - DiveListModel::instance()->addDive(d); + DiveListModel::instance()->addDive(d); +} + +void QMLManager::commitChanges(QString diveId, QString suit, QString buddy, QString diveMaster, QString notes) +{ + struct dive *d = get_dive_by_uniq_id(diveId.toInt()); + bool diveChanged = false; + + if (d->suit != suit.toUtf8().data()) { + diveChanged = true; + free(d->suit); + d->suit = strdup(suit.toUtf8().data()); + } + if (d->buddy != buddy.toUtf8().data()) { + diveChanged = true; + free(d->buddy); + d->buddy = strdup(buddy.toUtf8().data()); + } + if (d->divemaster != diveMaster.toUtf8().data()) { + diveChanged = true; + free(d->divemaster); + d->divemaster = strdup(diveMaster.toUtf8().data()); + } + if (d->notes != notes.toUtf8().data()) { + diveChanged = true; + free(d->notes); + d->notes = strdup(notes.toUtf8().data()); + } +} + +void QMLManager::saveChanges() +{ + showMessage("Saving dives."); + QString fileName; + if (getCloudURL(fileName)) { + showMessage(get_error_string()); + return; + } + + if (save_dives(fileName.toUtf8().data())) { + showMessage(get_error_string()); + return; + } + + showMessage("Dives saved."); + set_filename(fileName.toUtf8().data(), true); + mark_divelist_changed(false); } QString QMLManager::cloudPassword() const diff --git a/qt-mobile/qmlmanager.h b/qt-mobile/qmlmanager.h index 558249e4e..2f5ac2894 100644 --- a/qt-mobile/qmlmanager.h +++ b/qt-mobile/qmlmanager.h @@ -22,6 +22,8 @@ public: public slots: void savePreferences(); void loadDives(); + void commitChanges(QString diveId, QString suit, QString buddy, QString diveMaster, QString notes); + void saveChanges(); private: QString m_cloudUserName; QString m_cloudPassword; From 59232ca17237c67254038b8d2abdf13cf6701449 Mon Sep 17 00:00:00 2001 From: Grace Karanja Date: Fri, 17 Jul 2015 19:09:42 +0300 Subject: [PATCH 3/4] QML UI: Add QMLProfile class Add a C++ class to render the dive profile. The rendered image is then passed on to QML. Signed-off-by: Grace Karanja Signed-off-by: Dirk Hohndel --- qt-mobile/qmlprofile.cpp | 43 ++++++++++++++++++++++++++++++++++++++++ qt-mobile/qmlprofile.h | 27 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 qt-mobile/qmlprofile.cpp create mode 100644 qt-mobile/qmlprofile.h diff --git a/qt-mobile/qmlprofile.cpp b/qt-mobile/qmlprofile.cpp new file mode 100644 index 000000000..351b5b1ce --- /dev/null +++ b/qt-mobile/qmlprofile.cpp @@ -0,0 +1,43 @@ +#include "qmlprofile.h" +#include "profilewidget2.h" +#include "dive.h" + +QMLProfile::QMLProfile(QQuickItem *parent) : + QQuickPaintedItem(parent) +{ + profile = new ProfileWidget2(0); + profile->setProfileState(); + profile->setToolTipVisibile(false); +} + +void QMLProfile::paint(QPainter *painter) +{ + if (m_diveId.toInt() < 1) + return; + + struct dive *d; + d = get_dive_by_uniq_id(m_diveId.toInt()); + if (!d) + return; + + int old_animation_speed = prefs.animation_speed; + prefs.animation_speed = 0; // no animations while rendering the QGraphicsView + profile->plotDive(d); + // we need to show the widget so it gets populated, but then + // hide it right away so we get to draw it ourselves below + profile->show(); + profile->hide(); + profile->resize(this->width(), this->height()); + profile->render(painter, profile->geometry()); + prefs.animation_speed = old_animation_speed; +} + +QString QMLProfile::diveId() const +{ + return m_diveId; +} + +void QMLProfile::setDiveId(const QString &diveId) +{ + m_diveId = diveId; +} diff --git a/qt-mobile/qmlprofile.h b/qt-mobile/qmlprofile.h new file mode 100644 index 000000000..b5192913a --- /dev/null +++ b/qt-mobile/qmlprofile.h @@ -0,0 +1,27 @@ +#ifndef QMLPROFILE_H +#define QMLPROFILE_H + +#include + +class ProfileWidget2; + +class QMLProfile : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QString diveId READ diveId WRITE setDiveId NOTIFY diveIdChanged) +public: + explicit QMLProfile(QQuickItem *parent = 0); + void paint(QPainter *painter); + + QString diveId() const; + void setDiveId(const QString &diveId); + +private: + QString m_diveId; + ProfileWidget2 *profile; +signals: + void rightAlignedChanged(); + void diveIdChanged(); +}; + +#endif // QMLPROFILE_H From 0c9756c5d786158f25aaf1ad2d9c316be9e2b9e5 Mon Sep 17 00:00:00 2001 From: Grace Karanja Date: Fri, 17 Jul 2015 19:10:32 +0300 Subject: [PATCH 4/4] QML UI: Implement showing of the dive profile on QML Link the QMLProfile class to the DiveList.qml file. The profile is displayed above the dive details. Signed-off-by: Grace Karanja --- CMakeLists.txt | 2 +- qt-gui.cpp | 2 ++ qt-mobile/DiveList.qml | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab7be1bfc..a3fbb1cb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,7 +458,7 @@ endif() # create the executables if(SUBSURFACE_MOBILE) - set(MOBILE_SRC qt-mobile/qmlmanager.cpp qt-models/divelistmodel.cpp) + set(MOBILE_SRC qt-mobile/qmlmanager.cpp qt-mobile/qmlprofile.cpp qt-models/divelistmodel.cpp) add_definitions(-DSUBSURFACE_MOBILE) qt5_add_resources(MOBILE_RESOURCES qt-mobile/mobile-resources.qrc) if(ANDROID) diff --git a/qt-gui.cpp b/qt-gui.cpp index 175e9c27d..fac743a43 100644 --- a/qt-gui.cpp +++ b/qt-gui.cpp @@ -19,6 +19,7 @@ #include #include "qt-mobile/qmlmanager.h" #include "qt-models/divelistmodel.h" +#include "qt-mobile/qmlprofile.h" QObject *qqWindowObject = NULL; #endif @@ -40,6 +41,7 @@ void run_ui() #ifdef SUBSURFACE_MOBILE window->hide(); qmlRegisterType("org.subsurfacedivelog.mobile", 1, 0, "QMLManager"); + qmlRegisterType("org.subsurfacedivelog.mobile", 1, 0, "QMLProfile"); QQmlApplicationEngine engine; DiveListModel diveListModel; QQmlContext *ctxt = engine.rootContext(); diff --git a/qt-mobile/DiveList.qml b/qt-mobile/DiveList.qml index 0f358081d..7fa7a53f0 100644 --- a/qt-mobile/DiveList.qml +++ b/qt-mobile/DiveList.qml @@ -77,6 +77,13 @@ Rectangle { id: editorDetails width: detailsPage.width columns: 2 + Text { } + QMLProfile { + diveId: id + height: 400 + Layout.fillWidth: true + } + Text { text: "Location:"; font.bold: true } TextField { id: txtLocation; text: location; Layout.fillWidth: true } Text { text: "Air Temp:"; font.bold: true }