core,tests: change qml register function

In order to address the C++ object directy in qml, a different
registration is needed.

qmlRegisterType, registers the C++ class, allowing qml code to inherit
from it and make qml objects. This is needed for graphical elemnets
like profile and map

setContentProperty, registers the C++ object, thus allowing signals to be
catched.

Signed-off-by: Jan Iversen <jani@apache.org>
This commit is contained in:
jan Iversen 2018-09-04 11:18:43 +02:00 committed by Dirk Hohndel
parent a71afd31ee
commit d0edc29636
9 changed files with 62 additions and 59 deletions

View file

@ -6,7 +6,6 @@ void init_qt_late();
void init_ui(); void init_ui();
void run_ui(); void run_ui();
void register_qml_types();
void exit_ui(); void exit_ui();
void set_non_bt_addresses(); void set_non_bt_addresses();

View file

@ -2,8 +2,7 @@
#include "qPref.h" #include "qPref.h"
#include "qPrefPrivate.h" #include "qPrefPrivate.h"
#include <QQuickItem> #include <QtQml>
#include <QQmlEngine>
#include <QQmlContext> #include <QQmlContext>
qPref::qPref(QObject *parent) : QObject(parent) qPref::qPref(QObject *parent) : QObject(parent)
@ -39,28 +38,34 @@ void qPref::loadSync(bool doSync)
qPrefUpdateManager::loadSync(doSync); qPrefUpdateManager::loadSync(doSync);
} }
#define REGISTER_QPREF(useClass, useQML) \ Q_DECLARE_METATYPE(deco_mode);
rc = qmlRegisterType<useClass>("org.subsurfacedivelog.mobile", 1, 0, useQML); \ Q_DECLARE_METATYPE(def_file_behavior);
if (rc < 0) \ Q_DECLARE_METATYPE(taxonomy_category);
qWarning() << "ERROR: Cannot register " << useQML << ", QML will not work!!"; void qPref::registerQML(QQmlEngine *engine)
void qPref::registerQML()
{ {
int rc; if (engine) {
QQmlContext *ct = engine->rootContext();
REGISTER_QPREF(qPref, "SsrfPrefs"); ct->setContextProperty("Pref", qPref::instance());
REGISTER_QPREF(qPrefCloudStorage, "SsrfCloudStoragePrefs"); ct->setContextProperty("PrefCloudStorage", qPrefCloudStorage::instance());
REGISTER_QPREF(qPrefDisplay, "SsrfDisplayPrefs"); ct->setContextProperty("PrefDisplay", qPrefDisplay::instance());
REGISTER_QPREF(qPrefDiveComputer, "SsrfDiveComputerPrefs"); ct->setContextProperty("PrefDiveComputer", qPrefDiveComputer::instance());
REGISTER_QPREF(qPrefDivePlanner, "SsrfDivePlannerPrefs"); ct->setContextProperty("PrefDivePlanner", qPrefDivePlanner::instance());
REGISTER_QPREF(qPrefFacebook, "SsrfFacebookPrefs"); ct->setContextProperty("PrefFacebook", qPrefFacebook::instance());
REGISTER_QPREF(qPrefGeneral, "SsrfGeneralPrefs"); ct->setContextProperty("PrefGeneral", qPrefGeneral::instance());
REGISTER_QPREF(qPrefGeocoding, "SsrfGeocodingPrefs"); ct->setContextProperty("PrefGeocoding", qPrefGeocoding::instance());
REGISTER_QPREF(qPrefLanguage, "SsrfLanguagePrefs"); ct->setContextProperty("PrefLanguage", qPrefLanguage::instance());
REGISTER_QPREF(qPrefLocationService, "SsrfLocationServicePrefs"); ct->setContextProperty("PrefLocationService", qPrefLocationService::instance());
REGISTER_QPREF(qPrefPartialPressureGas, "SsrfPartialPressureGasPrefs"); ct->setContextProperty("PrefPartialPressureGas", qPrefPartialPressureGas::instance());
REGISTER_QPREF(qPrefProxy, "SsrfProxyPrefs"); ct->setContextProperty("PrefProxy", qPrefProxy::instance());
REGISTER_QPREF(qPrefTechnicalDetails, "SsrfTechnicalDetailsPrefs"); ct->setContextProperty("PrefTechnicalDetails", qPrefTechnicalDetails::instance());
REGISTER_QPREF(qPrefUnits, "SsrfUnitPrefs"); ct->setContextProperty("PrefUnits", qPrefUnits::instance());
REGISTER_QPREF(qPrefUpdateManager, "SsrfUpdateManagerPrefs"); ct->setContextProperty("PrefUpdateManager", qPrefUpdateManager::instance());
}
// Register special types
qmlRegisterUncreatableType<qPref>("org.subsurfacedivelog.mobile",1,0,"CloudStatus","Enum is not a type");
qRegisterMetaType<deco_mode>();
qRegisterMetaType<def_file_behavior>();
qRegisterMetaType<taxonomy_category>();
} }

View file

@ -5,6 +5,7 @@
#include "ssrf-version.h" #include "ssrf-version.h"
#include <QObject> #include <QObject>
#include <QQmlEngine>
#include "qPrefCloudStorage.h" #include "qPrefCloudStorage.h"
#include "qPrefDisplay.h" #include "qPrefDisplay.h"
@ -23,7 +24,6 @@
class qPref : public QObject { class qPref : public QObject {
Q_OBJECT Q_OBJECT
Q_ENUMS(cloud_status);
Q_PROPERTY(QString canonical_version READ canonical_version); Q_PROPERTY(QString canonical_version READ canonical_version);
Q_PROPERTY(QString mobile_version READ mobile_version); Q_PROPERTY(QString mobile_version READ mobile_version);
@ -36,7 +36,7 @@ public:
static void sync() { loadSync(true); } static void sync() { loadSync(true); }
// Register QML // Register QML
void registerQML(); void registerQML(QQmlEngine *engine);
public: public:
enum cloud_status { enum cloud_status {
@ -46,6 +46,7 @@ public:
CS_VERIFIED, CS_VERIFIED,
CS_NOCLOUD CS_NOCLOUD
}; };
Q_ENUM(cloud_status);
static const QString canonical_version() { return QString(CANONICAL_VERSION_STRING); } static const QString canonical_version() { return QString(CANONICAL_VERSION_STRING); }
static const QString mobile_version() { return QString(MOBILE_VERSION_STRING); } static const QString mobile_version() { return QString(MOBILE_VERSION_STRING); }

View file

@ -144,7 +144,7 @@ Item {
text: qsTr("No cloud mode") text: qsTr("No cloud mode")
onClicked: { onClicked: {
manager.syncToCloud = false manager.syncToCloud = false
prefs.credentialStatus = SsrfPrefs.CS_NOCLOUD prefs.credentialStatus = CloudStatus.CS_NOCLOUD
manager.saveCloudCredentials() manager.saveCloudCredentials()
manager.openNoCloudRepo() manager.openNoCloudRepo()
} }

View file

@ -23,7 +23,7 @@ Kirigami.ScrollablePage {
supportsRefreshing: true supportsRefreshing: true
onRefreshingChanged: { onRefreshingChanged: {
if (refreshing) { if (refreshing) {
if (prefs.credentialStatus === SsrfPrefs.CS_VERIFIED) { if (prefs.credentialStatus === CloudStatus.CS_VERIFIED) {
console.log("User pulled down dive list - syncing with cloud storage") console.log("User pulled down dive list - syncing with cloud storage")
detailsWindow.endEditMode() detailsWindow.endEditMode()
manager.saveChangesCloud(true) manager.saveChangesCloud(true)
@ -339,8 +339,8 @@ Kirigami.ScrollablePage {
StartPage { StartPage {
id: startPage id: startPage
anchors.fill: parent anchors.fill: parent
opacity: credentialStatus === SsrfPrefs.CS_NOCLOUD || opacity: credentialStatus === CloudStatus.CS_NOCLOUD ||
(credentialStatus === SsrfPrefs.CS_VERIFIED) ? 0 : 1 (credentialStatus === CloudStatus.CS_VERIFIED) ? 0 : 1
visible: opacity > 0 visible: opacity > 0
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } } Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
function setupActions() { function setupActions() {
@ -348,8 +348,8 @@ Kirigami.ScrollablePage {
page.actions.main = null page.actions.main = null
page.actions.right = null page.actions.right = null
page.title = qsTr("Cloud credentials") page.title = qsTr("Cloud credentials")
} else if (prefs.credentialStatus === SsrfPrefs.CS_VERIFIED || } else if (prefs.credentialStatus === CloudStatus.CS_VERIFIED ||
prefs.credentialStatus === SsrfPrefs.CS_NOCLOUD) { prefs.credentialStatus === CloudStatus.CS_NOCLOUD) {
page.actions.main = page.downloadFromDCAction page.actions.main = page.downloadFromDCAction
page.actions.right = page.addDiveAction page.actions.right = page.addDiveAction
page.title = qsTr("Dive list") page.title = qsTr("Dive list")
@ -440,7 +440,7 @@ Kirigami.ScrollablePage {
onBackRequested: { onBackRequested: {
if (startPage.visible && diveListView.count > 0 && if (startPage.visible && diveListView.count > 0 &&
prefs.credentialStatus !== SsrfPrefs.CS_INCORRECT_USER_PASSWD) { prefs.credentialStatus !== CloudStatus.CS_INCORRECT_USER_PASSWD) {
prefs.credentialStatus = oldStatus prefs.credentialStatus = oldStatus
event.accepted = true; event.accepted = true;
} }

View file

@ -45,7 +45,7 @@ Kirigami.ScrollablePage {
Layout.preferredHeight: Kirigami.Units.gridUnit * 2 Layout.preferredHeight: Kirigami.Units.gridUnit * 2
} }
Controls.Label { Controls.Label {
text: prefs.credentialStatus === SsrfPrefs.CS_NOCLOUD ? qsTr("Not applicable") : prefs.cloudUserName text: prefs.credentialStatus === CloudStatus.CS_NOCLOUD ? qsTr("Not applicable") : prefs.cloudUserName
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.preferredWidth: gridWidth * 0.60 Layout.preferredWidth: gridWidth * 0.60
Layout.preferredHeight: Kirigami.Units.gridUnit * 2 Layout.preferredHeight: Kirigami.Units.gridUnit * 2
@ -333,7 +333,7 @@ Kirigami.ScrollablePage {
inputMethodHints: Qt.ImhNoPredictiveText inputMethodHints: Qt.ImhNoPredictiveText
Layout.fillWidth: true Layout.fillWidth: true
onActivated: { onActivated: {
general.set_default_cylinder(defaultCylinderBox.currentText) PrefGeneral.set_default_cylinder(defaultCylinderBox.currentText)
} }
} }
} }

View file

@ -102,7 +102,7 @@ Kirigami.ApplicationWindow {
detailsWindow.cylinderModel2 = manager.cylinderInit detailsWindow.cylinderModel2 = manager.cylinderInit
detailsWindow.cylinderModel3 = manager.cylinderInit detailsWindow.cylinderModel3 = manager.cylinderInit
detailsWindow.cylinderModel4 = manager.cylinderInit detailsWindow.cylinderModel4 = manager.cylinderInit
detailsWindow.cylinderIndex0 = general.default_cylinder == "" ? -1 : detailsWindow.cylinderModel0.indexOf(general.default_cylinder) detailsWindow.cylinderIndex0 = PrefGeneral.default_cylinder == "" ? -1 : detailsWindow.cylinderModel0.indexOf(PrefGeneral.default_cylinder)
detailsWindow.usedCyl = ["",] detailsWindow.usedCyl = ["",]
detailsWindow.weight = "" detailsWindow.weight = ""
detailsWindow.usedGas = [] detailsWindow.usedGas = []
@ -192,10 +192,10 @@ Kirigami.ApplicationWindow {
text: qsTr("Dive list") text: qsTr("Dive list")
onTriggered: { onTriggered: {
manager.appendTextToLog("requested dive list with credential status " + prefs.credentialStatus) manager.appendTextToLog("requested dive list with credential status " + prefs.credentialStatus)
if (prefs.credentialStatus == SsrfPrefs.CS_UNKNOWN) { if (prefs.credentialStatus == CloudStatus.CS_UNKNOWN) {
// the user has asked to change credentials - if the credentials before that // the user has asked to change credentials - if the credentials before that
// were valid, go back to dive list // were valid, go back to dive list
if (oldStatus == SsrfPrefs.CS_VERIFIED) { if (oldStatus == CloudStatus.CS_VERIFIED) {
prefs.credentialStatus = oldStatus prefs.credentialStatus = oldStatus
} }
} }
@ -222,8 +222,8 @@ Kirigami.ApplicationWindow {
name: ":/icons/ic_add.svg" name: ":/icons/ic_add.svg"
} }
text: qsTr("Add dive manually") text: qsTr("Add dive manually")
enabled: prefs.credentialStatus === SsrfPrefs.CS_VERIFIED || enabled: prefs.credentialStatus === CloudStatus.CS_VERIFIED ||
prefs.credentialStatus === SsrfPrefs.CS_NOCLOUD prefs.credentialStatus === CloudStatus.CS_NOCLOUD
onTriggered: { onTriggered: {
globalDrawer.close() globalDrawer.close()
returnTopPage() // otherwise odd things happen with the page stack returnTopPage() // otherwise odd things happen with the page stack
@ -257,14 +257,14 @@ Kirigami.ApplicationWindow {
name: ":/icons/cloud_sync.svg" name: ":/icons/cloud_sync.svg"
} }
text: qsTr("Manual sync with cloud") text: qsTr("Manual sync with cloud")
enabled: prefs.credentialStatus === SsrfPrefs.CS_VERIFIED || enabled: prefs.credentialStatus === CloudStatus.CS_VERIFIED ||
prefs.credentialStatus === SsrfPrefs.CS_NOCLOUD prefs.credentialStatus === CloudStatus.CS_NOCLOUD
onTriggered: { onTriggered: {
if (prefs.credentialStatus === SsrfPrefs.CS_NOCLOUD) { if (prefs.credentialStatus === CloudStatus.CS_NOCLOUD) {
returnTopPage() returnTopPage()
oldStatus = prefs.credentialStatus oldStatus = prefs.credentialStatus
manager.startPageText = "Enter valid cloud storage credentials" manager.startPageText = "Enter valid cloud storage credentials"
prefs.credentialStatus = SsrfPrefs.CS_UNKNOWN prefs.credentialStatus = CloudStatus.CS_UNKNOWN
globalDrawer.close() globalDrawer.close()
} else { } else {
globalDrawer.close() globalDrawer.close()
@ -279,7 +279,7 @@ Kirigami.ApplicationWindow {
name: syncToCloud ? ":/icons/ic_cloud_off.svg" : ":/icons/ic_cloud_done.svg" name: syncToCloud ? ":/icons/ic_cloud_off.svg" : ":/icons/ic_cloud_done.svg"
} }
text: syncToCloud ? qsTr("Disable auto cloud sync") : qsTr("Enable auto cloud sync") text: syncToCloud ? qsTr("Disable auto cloud sync") : qsTr("Enable auto cloud sync")
enabled: prefs.credentialStatus !== SsrfPrefs.CS_NOCLOUD enabled: prefs.credentialStatus !== CloudStatus.CS_NOCLOUD
onTriggered: { onTriggered: {
syncToCloud = !syncToCloud syncToCloud = !syncToCloud
if (!syncToCloud) { if (!syncToCloud) {
@ -351,7 +351,7 @@ if you have network connectivity and want to sync your data to cloud storage."),
onTriggered: { onTriggered: {
globalDrawer.close() globalDrawer.close()
settingsWindow.defaultCylinderModel = manager.cylinderInit settingsWindow.defaultCylinderModel = manager.cylinderInit
general.default_cylinder === "" ? defaultCylinderIndex = "-1" : defaultCylinderIndex = settingsWindow.defaultCylinderModel.indexOf(general.default_cylinder) PrefGeneral.default_cylinder === "" ? defaultCylinderIndex = "-1" : defaultCylinderIndex = settingsWindow.defaultCylinderModel.indexOf(PrefGeneral.default_cylinder)
stackView.push(settingsWindow) stackView.push(settingsWindow)
detailsWindow.endEditMode() detailsWindow.endEditMode()
} }
@ -600,10 +600,6 @@ if you have network connectivity and want to sync your data to cloud storage."),
visible: false visible: false
} }
SsrfGeneralPrefs {
id: general
}
onPluggedInDeviceNameChanged: { onPluggedInDeviceNameChanged: {
if (detailsWindow.state === 'edit' || detailsWindow.state === 'add') { if (detailsWindow.state === 'edit' || detailsWindow.state === 'add') {
/* we're in the middle of editing / adding a dive */ /* we're in the middle of editing / adding a dive */

View file

@ -35,7 +35,6 @@ static void register_meta_types();
void init_ui() void init_ui()
{ {
init_qt_late(); init_qt_late();
register_qml_types();
register_meta_types(); register_meta_types();
#ifndef SUBSURFACE_MOBILE #ifndef SUBSURFACE_MOBILE
PluginManager::instance().loadPlugins(); PluginManager::instance().loadPlugins();
@ -60,11 +59,15 @@ double get_screen_dpi()
return mydesk->physicalDpiX(); return mydesk->physicalDpiX();
} }
// Forward declaration
static void register_qml_types(QQmlEngine *);
void run_ui() void run_ui()
{ {
#ifdef SUBSURFACE_MOBILE #ifdef SUBSURFACE_MOBILE
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
register_qml_types(&engine);
LOG_STP("run_ui qml engine started"); LOG_STP("run_ui qml engine started");
KirigamiPlugin::getInstance().registerTypes(); KirigamiPlugin::getInstance().registerTypes();
#if defined(__APPLE__) && !defined(Q_OS_IOS) #if defined(__APPLE__) && !defined(Q_OS_IOS)
@ -135,6 +138,7 @@ void run_ui()
qml_window->show(); qml_window->show();
LOG_STP("run_ui running exec"); LOG_STP("run_ui running exec");
#else #else
register_qml_types(NULL);
MainWindow::instance()->show(); MainWindow::instance()->show();
#endif // SUBSURFACE_MOBILE #endif // SUBSURFACE_MOBILE
qApp->exec(); qApp->exec();
@ -152,16 +156,14 @@ static void register_meta_types()
if (rc < 0) \ if (rc < 0) \
qWarning() << "ERROR: Cannot register " << useQML << ", QML will not work!!"; qWarning() << "ERROR: Cannot register " << useQML << ", QML will not work!!";
void register_qml_types() void register_qml_types(QQmlEngine *engine)
{ {
int rc;
(void)rc;
// register qPref* // register qPref*
qPref::instance()->registerQML(); qPref::instance()->registerQML(engine);
#ifndef SUBSURFACE_TEST_DATA #ifndef SUBSURFACE_TEST_DATA
int rc;
#ifdef SUBSURFACE_MOBILE #ifdef SUBSURFACE_MOBILE
REGISTER_TYPE(QMLManager, "QMLManager"); REGISTER_TYPE(QMLManager, "QMLManager");
REGISTER_TYPE(QMLPrefs, "QMLPrefs"); REGISTER_TYPE(QMLPrefs, "QMLPrefs");

View file

@ -37,7 +37,7 @@ int main(int argc, char **argv)
argc--; argc--;
// Register types // Register types
qPref::instance()->registerQML(); qPref::instance()->registerQML(NULL);
// Run all tst_*.qml files // Run all tst_*.qml files
return quick_test_main(argc, argv, "TestQML", tst_dir); return quick_test_main(argc, argv, "TestQML", tst_dir);