diff options
-rw-r--r-- | doc/snippets/models.qml | 2 | ||||
-rw-r--r-- | examples/qml/todos/doc/images/todolist.png | bin | 0 -> 32344 bytes | |||
-rw-r--r-- | examples/qml/todos/doc/src/todos.qdoc | 37 | ||||
-rw-r--r-- | examples/qml/todos/todo.qml | 18 | ||||
-rw-r--r-- | src/enginio_client/enginiomodel.cpp | 3 | ||||
-rw-r--r-- | src/enginio_plugin/enginioqmlclient.cpp | 48 | ||||
-rw-r--r-- | src/enginio_plugin/enginioqmlmodel.cpp | 50 | ||||
-rw-r--r-- | src/enginio_plugin/enginioqmlreply.cpp | 36 |
8 files changed, 168 insertions, 26 deletions
diff --git a/doc/snippets/models.qml b/doc/snippets/models.qml index ae6e046..bd3f53e 100644 --- a/doc/snippets/models.qml +++ b/doc/snippets/models.qml @@ -64,7 +64,7 @@ Rectangle { anchors.fill: parent model: enginioModel delegate: Text { - text: model.name + ": " + model.population + text: name + ": " + population } } //! [view] diff --git a/examples/qml/todos/doc/images/todolist.png b/examples/qml/todos/doc/images/todolist.png Binary files differnew file mode 100644 index 0000000..b6005a7 --- /dev/null +++ b/examples/qml/todos/doc/images/todolist.png diff --git a/examples/qml/todos/doc/src/todos.qdoc b/examples/qml/todos/doc/src/todos.qdoc index 35c3b10..bb6d3ea 100644 --- a/examples/qml/todos/doc/src/todos.qdoc +++ b/examples/qml/todos/doc/src/todos.qdoc @@ -33,12 +33,26 @@ In this example a simple list of objects is displayed in a ListView. Each item in the list is a "To Do" object which can be "done" or "not yet done". - Todos can be added and removed (when hovering + Todos can be added and removed (when hovering with the mouse). + \image todolist.png + + In this simple schema the objects will only have two properties that are added + to the default properties (such as creation date which always exists). + A string "title" and a bool "completed". The object type will be created + when a call to create, or in this case \l{Enginio1::EnginioModel::append()}{EnginioModel::append()} is made. + + A todo object will look like this (in JSON): + \code +{ + "title": "Buy Milk", + "completed": false +} + \endcode The example uses Qt Quick Controls, Layouts and Enginio \snippet todos/todo.qml imports - The first step is to create a \l{EnginioModelQml}{EnginioModel} and + The first step is to create a \l{Enginio1::EnginioModel} and the Enginio instance with the backend configuration. \snippet todos/todo.qml model @@ -53,7 +67,22 @@ so that a new Todo can be entered. \snippet todos/todo.qml append - Inside the delegate the data for the index is available in the "model" property. + Inside the delegate the data for the index is available by using the property names (\e title and \e completed). + The title property is directly assigned to the text displayed on each list item and the completed + boolean is used to display the item with strikeout font and light color. + \snippet todos/todo.qml delegate-properties + + To update the data on the Enginio backend \l Enginio1::EnginioModel::setProperty() is called. + + \snippet todos/todo.qml setProperty + + In order to know when an item is not yet synced, the _synced property can be used. + It is always available in the delegate and used to show a text while the syncing is ongoing. + + \snippet todos/todo.qml sync - \snippet todos/todo.qml delegate + Finally a remove button is visible when hovering an item + with the mouse. + Removal is implemented by calling \l{Enginio1::EnginioModel::remove()}{EnginioModel::remove()} with the row of the item. + \snippet todos/todo.qml remove */ diff --git a/examples/qml/todos/todo.qml b/examples/qml/todos/todo.qml index 3624386..811e505 100644 --- a/examples/qml/todos/todo.qml +++ b/examples/qml/todos/todo.qml @@ -43,7 +43,7 @@ Rectangle { //![append] TextField { id: textInput - placeholderText: "Enter ToDo here..." + placeholderText: "Enter Todo here..." onAccepted: { enginioModel.append({"title": text, "completed": false}) text = "" @@ -52,7 +52,7 @@ Rectangle { } //![append] Button { - text: "Add ToDo" + text: "Add Todo" onClicked: textInput.accepted() } } @@ -85,6 +85,7 @@ Rectangle { anchors.bottom: parent.bottom } + //![setProperty] MouseArea { id: mouse anchors.fill: parent @@ -95,7 +96,9 @@ Rectangle { } } } + //![setProperty] + //![delegate-properties] Text { id: todoText text: title @@ -110,8 +113,9 @@ Rectangle { anchors.rightMargin: 40 elide: Text.ElideRight } + //![delegate-properties] - // Show an indication when syncing with the server is in progress + //![sync] Text { visible: !_synced anchors.margins: 4 @@ -120,6 +124,7 @@ Rectangle { id: syncText text: "Syncing..." } + //![sync] // Show a delete button when the mouse is over the delegate Image { @@ -137,13 +142,12 @@ Rectangle { opacity: mouse.containsMouse ? 1.0 : 0.0 Behavior on opacity { NumberAnimation { duration: 200 } } + //![remove] MouseArea { anchors.fill: parent - onClicked: { - if (index !== -1) - enginioModel.remove(index) - } + onClicked: enginioModel.remove(index) } + //![remove] } } } diff --git a/src/enginio_client/enginiomodel.cpp b/src/enginio_client/enginiomodel.cpp index ce670c6..fba36cd 100644 --- a/src/enginio_client/enginiomodel.cpp +++ b/src/enginio_client/enginiomodel.cpp @@ -433,10 +433,9 @@ const int EnginioModelPrivate::IncrementalModelUpdate = -2; Sorting is done server side, as soon as data is changed locally it will be invalid. - \note that the EnginioClient does not emit the finished and error signals for the model. - For the QML version of this class see \l {EnginioModelQml}{EnginioModel (QML)} + For the QML version of this class see \l {Enginio1::EnginioModel }{EnginioModel (QML)} */ /*! diff --git a/src/enginio_plugin/enginioqmlclient.cpp b/src/enginio_plugin/enginioqmlclient.cpp index 3fdc628..7bf0795 100644 --- a/src/enginio_plugin/enginioqmlclient.cpp +++ b/src/enginio_plugin/enginioqmlclient.cpp @@ -46,11 +46,10 @@ /*! \qmltype Enginio \instantiates EnginioQmlClient - \inqmlmodule enginio-plugin + \inqmlmodule Enginio 1 \ingroup engino-qml \brief client interface to access Enginio - \snippet simple.qml import Enginio is the heart of the QML API for Enginio. @@ -70,17 +69,17 @@ */ /*! - \qmlproperty string Enginio::backendId + \qmlproperty string Enginio1::Enginio::backendId Enginio backend ID. This can be obtained from the Enginio dashboard. */ /*! - \qmlproperty string Enginio::backendSecret + \qmlproperty string Enginio1::Enginio::backendSecret Enginio backend secret. This can be obtained from the Enginio dashboard. */ /*! - \qmlproperty url Enginio::serviceUrl + \qmlproperty url Enginio1::Enginio::serviceUrl \internal Enginio backend URL. @@ -88,7 +87,29 @@ */ /*! - \qmlmethod EnginioReply Enginio::uploadFile(QJsonObject object, QUrl file) + \qmlmethod EnginioReply Enginio1::Enginio::search(QJsonObject query) + \brief Perform a full text search on the database +*/ + +/*! + \qmlmethod EnginioReply Enginio1::Enginio::query(QJsonObject query, Operation operation) + \brief Query the database. +*/ +/*! + \qmlmethod EnginioReply Enginio1::Enginio::create(QJsonObject query, Operation operation) + \brief Create an object in the database. +*/ +/*! + \qmlmethod EnginioReply Enginio1::Enginio::update(QJsonObject query, Operation operation) + \brief Update an object in the database. +*/ +/*! + \qmlmethod EnginioReply Enginio1::Enginio::remove(QJsonObject query, Operation operation) + \brief Remove an object from the database. +*/ + +/*! + \qmlmethod EnginioReply Enginio1::Enginio::uploadFile(QJsonObject object, QUrl file) \brief Stores a \a file attached to an \a object in Enginio Each uploaded file needs to be associated with an object in the database. @@ -109,7 +130,7 @@ */ /*! - \qmlmethod EnginioReply Enginio::downloadFile(QJsonObject object) + \qmlmethod EnginioReply Enginio1::Enginio::downloadFile(QJsonObject object) \brief Get the download URL for a file \snippet qmltests/tst_files.qml download @@ -123,6 +144,19 @@ \sa uploadFile() */ +/*! + \qmlsignal Enginio1::Enginio::finished(EnginioReply reply) + This signal is emitted when a \a reply finishes. + + \note that this signal is alwasy emitted, independent of whether + the reply finished successfully or not. +*/ + +/*! + \qmlsignal Enginio1::Enginio::error(EnginioReply reply) + This signal is emitted when a \a reply finishes and contains an error. +*/ + EnginioQmlClient::EnginioQmlClient(QObject *parent) : EnginioClient(parent, new EnginioQmlClientPrivate(this)) { diff --git a/src/enginio_plugin/enginioqmlmodel.cpp b/src/enginio_plugin/enginioqmlmodel.cpp index ce991c6..54a8854 100644 --- a/src/enginio_plugin/enginioqmlmodel.cpp +++ b/src/enginio_plugin/enginioqmlmodel.cpp @@ -40,11 +40,11 @@ /*! \qmltype EnginioModel \instantiates EnginioQmlModel - \inqmlmodule enginio-plugin + \inqmlmodule Enginio 1 \ingroup engino-qml - \target EnginioModelQml \brief Makes accessing collections of objects easy + \snippet simple.qml import The query property of the model takes a JSON object. @@ -58,14 +58,54 @@ In this example, we have the type "objects.city" in the backend with two properties: "name" and "population". - The model supports several function to modify the data, for example it is - easy to add another city to the backend by appending it: - \snippet models.qml append + The model supports several function to modify the data, for example + \l append(), \l remove(), \l setProperty() The QML version of EnginioModel supports the same functionality as the C++ version. \l {EnginioModelCpp}{EnginioModel C++} */ +/*! + \qmlproperty QJsonObject Enginio1::EnginioModel::query + The query used to populate the model with data. +*/ + +/*! + \qmlproperty Enginio Enginio1::EnginioModel::enginio + The instance of \l Enginio used for this model. +*/ + +/*! + \qmlproperty EnginioClient::Operation Enginio1::EnginioModel::operation + The operation used for the \l query. +*/ + +/*! + \qmlmethod EnginioReply Enginio1::EnginioModel::append(QJsonObject value) + \brief Add a new object to the model and database. + + To add a "city" object to the model by appending it: + \snippet models.qml append + The append will be reflected by the model immediately and will be propagated + to the server asynchronously. + + The returned \l Enginio1::EnginioReply can be used to react to a finished object creation. +*/ + +/*! + \qmlmethod EnginioReply Enginio1::EnginioModel::setProperty(int row, string propertyName, QVariant value) + \brief Change a property of an object in the model + + The property \a propertyName of the object at \a row will be set to \a value. + The model will locally reflect the change immediately and propagage the change to the + server in the background. +*/ + +/*! + \qmlmethod EnginioReply Enginio1::EnginioModel::remove(int row) + \brief removes the object at \a row +*/ + EnginioQmlModel::EnginioQmlModel(QObject *parent) : EnginioModel(parent) { diff --git a/src/enginio_plugin/enginioqmlreply.cpp b/src/enginio_plugin/enginioqmlreply.cpp index f4b7594..1e89dc6 100644 --- a/src/enginio_plugin/enginioqmlreply.cpp +++ b/src/enginio_plugin/enginioqmlreply.cpp @@ -6,6 +6,42 @@ #include <QtCore/qobject.h> #include <QtCore/qmetaobject.h> + +/*! + \qmltype EnginioReply + \instantiates EnginioQmlReply + \inqmlmodule Enginio 1 + \ingroup engino-qml + \target EnginioModelQml + + \brief A reply to any \l Enginio request. +*/ + +/*! + \qmlproperty QJsonObject Enginio1::EnginioReply::data + The data of this reply. +*/ + +/*! + \qmlproperty EnginioReply::ErrorTypes Enginio1::EnginioReply::errorType + The type of error (if any) of this reply. +*/ + +/*! + \qmlproperty QNetworkReply::NetworkError Enginio1::EnginioReply::networkError + The network error (if any). +*/ + +/*! + \qmlproperty string Enginio1::EnginioReply::errorString + The error message if this reply was an error. +*/ + +/*! + \qmlproperty int Enginio1::EnginioReply::backendStatus + The backend status code. +*/ + class EnginioQmlReplyPrivate : public EnginioReplyPrivate { EnginioQmlReply *q; |