diff options
author | Jędrzej Nowacki <jedrzej.nowacki@digia.com> | 2014-04-04 15:19:47 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-08-08 11:07:18 +0200 |
commit | 19a551e09264513766c569770539d55b6cc00d35 (patch) | |
tree | 2b8d62be4bcbd23f9c0cb87d7c7d796c543320f4 /src | |
parent | e7c189f13d0fc0d72cbcaf1770055da252e0fb3f (diff) |
Allow update all item's properties in one EnginioModel::setData call
This change adds a new preconfigured role to EnginioModel, which
can be used to update multiple properties of an item in one function
call.
[ChangeLog] EnginioModel is able to update multiple
properties of an item in one setData function call. It can be achieved
by using Enginio::JsonObjectRole.
Change-Id: Ibc640d44f28d40fa349c6efdf65e3bb321a4fc79
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/enginio_client/enginio.h | 1 | ||||
-rw-r--r-- | src/enginio_client/enginiobasemodel_p.h | 22 | ||||
-rw-r--r-- | src/enginio_client/enginiomodel.cpp | 30 | ||||
-rw-r--r-- | src/enginio_client/enginiomodel.h | 1 | ||||
-rw-r--r-- | src/enginio_client/enginiostring_p.h | 1 |
5 files changed, 49 insertions, 6 deletions
diff --git a/src/enginio_client/enginio.h b/src/enginio_client/enginio.h index fb3088b..666678d 100644 --- a/src/enginio_client/enginio.h +++ b/src/enginio_client/enginio.h @@ -91,6 +91,7 @@ public: UpdatedAtRole, IdRole, ObjectTypeRole, + JsonObjectRole, CustomPropertyRole = Qt::UserRole + 10 // the first fully dynamic role }; diff --git a/src/enginio_client/enginiobasemodel_p.h b/src/enginio_client/enginiobasemodel_p.h index c815aad..dbcb403 100644 --- a/src/enginio_client/enginiobasemodel_p.h +++ b/src/enginio_client/enginiobasemodel_p.h @@ -830,11 +830,21 @@ public: EnginioReplyState *setDataNow(const int row, const QVariant &value, int role, const QJsonObject &oldObject, const QString &id) { Q_ASSERT(!id.isEmpty()); - const QString roleName(_roles.value(role)); - Q_ASSERT(!roleName.isEmpty()); QJsonObject deltaObject; QJsonObject newObject = oldObject; - deltaObject[roleName] = newObject[roleName] = QJsonValue::fromVariant(value); + if (role != Enginio::JsonObjectRole) { + const QString roleName(_roles.value(role)); + Q_ASSERT(!roleName.isEmpty()); + deltaObject[roleName] = newObject[roleName] = QJsonValue::fromVariant(value); + } else { + const QJsonObject updateObject = value.toJsonObject(); + if (updateObject.isEmpty()) { + QNetworkReply *nreply = new EnginioFakeReply(_enginio, EnginioClientConnectionPrivate::constructErrorMessage(EnginioString::EnginioModel_Trying_to_update_an_object_with_unknown_role)); + return _enginio->createReply(nreply); + } + for (QJsonObject::const_iterator i = updateObject.constBegin(); i != updateObject.constEnd(); ++i) + deltaObject[i.key()] = i.value(); + } deltaObject[EnginioString::id] = id; deltaObject[EnginioString::objectType] = newObject[EnginioString::objectType]; ObjectAdaptor<QJsonObject> aDeltaObject(deltaObject); @@ -876,11 +886,11 @@ public: const QJsonObject object = _data.at(row).toObject(); if (!object.isEmpty()) { + if (role == Qt::DisplayRole || role == Enginio::JsonObjectRole) + return _data.at(row); const QString roleName = _roles.value(role); if (!roleName.isEmpty()) return object[roleName]; - else if (role == Qt::DisplayRole) - return _data.at(row); } return QVariant(); @@ -1021,7 +1031,7 @@ struct EnginioModelPrivateT : public EnginioBaseModelPrivate Reply *remove(int row) { return static_cast<Reply*>(Base::remove(row)); } Reply *setValue(int row, const QString &role, const QVariant &value) { return static_cast<Reply*>(Base::setValue(row, role, value)); } Reply *reload() { return static_cast<Reply*>(Base::reload()); } - + Reply *setData(const int row, const QVariant &value, int role) { return static_cast<Reply*>(Base::setData(row, value, role)); } bool queryIsEmpty() const Q_DECL_OVERRIDE { return ObjectAdaptor<Data>(_query, static_cast<ClientPrivate*>(_enginio)).isEmpty(); diff --git a/src/enginio_client/enginiomodel.cpp b/src/enginio_client/enginiomodel.cpp index 722a2fc..3ff34a3 100644 --- a/src/enginio_client/enginiomodel.cpp +++ b/src/enginio_client/enginiomodel.cpp @@ -404,6 +404,7 @@ EnginioBaseModel::~EnginioBaseModel() \value ObjectTypeRole \c What is item type \value SyncedRole \c Mark if an item is in sync with the backend \value CustomPropertyRole \c The first role id that may be used for dynamically created roles. + \value JsonObjectRole \c Object like representation of an item \omitvalue InvalidRole Additionally EnginioModel supports dynamic roles which are mapped @@ -562,6 +563,35 @@ EnginioReply *EnginioModel::setData(int row, const QVariant &value, const QStrin return d->setValue(row, role, value); } +/*! + \overload + Update a \a value on \a row of this model's local cache + and send an update request to the Enginio backend. + + All properties of the \a value will be used to update the item in \a row. + This can be useful to update multiple item's properties with one request. + + \return reply from backend + \sa EnginioClient::update() +*/ +EnginioReply *EnginioModel::setData(int row, const QJsonObject &value) +{ + Q_D(EnginioModel); + if (Q_UNLIKELY(!d->enginio())) { + qWarning("EnginioModel::setData(): Enginio client is not set"); + return 0; + } + + if (unsigned(row) >= unsigned(d->rowCount())) { + EnginioClientConnectionPrivate *client = EnginioClientConnectionPrivate::get(d->enginio()); + QNetworkReply *nreply = new EnginioFakeReply(client, EnginioClientConnectionPrivate::constructErrorMessage(EnginioString::EnginioModel_setProperty_row_is_out_of_range)); + EnginioReply *ereply = new EnginioReply(client, nreply); + return ereply; + } + + return d->setData(row, value, Enginio::JsonObjectRole); +} + Qt::ItemFlags EnginioBaseModel::flags(const QModelIndex &index) const { return QAbstractListModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; diff --git a/src/enginio_client/enginiomodel.h b/src/enginio_client/enginiomodel.h index f3cb0ca..538a532 100644 --- a/src/enginio_client/enginiomodel.h +++ b/src/enginio_client/enginiomodel.h @@ -80,6 +80,7 @@ public: Q_INVOKABLE EnginioReply *append(const QJsonObject &value); Q_INVOKABLE EnginioReply *remove(int row); Q_INVOKABLE EnginioReply *setData(int row, const QVariant &value, const QString &role); + Q_INVOKABLE EnginioReply *setData(int row, const QJsonObject &value); using EnginioBaseModel::setData; Q_INVOKABLE EnginioReply *reload(); diff --git a/src/enginio_client/enginiostring_p.h b/src/enginio_client/enginiostring_p.h index 559f4a3..dcc45a2 100644 --- a/src/enginio_client/enginiostring_p.h +++ b/src/enginio_client/enginiostring_p.h @@ -128,6 +128,7 @@ F(EnginioModel_was_removed_before_this_request_was_prepared, "EnginioModel was removed before this request was prepared")\ F(EnginioModel_The_query_was_changed_before_the_request_could_be_sent, "EnginioModel: The query was changed before the request could be sent")\ F(EnginioModel_Trying_to_update_an_object_with_unknown_role, "EnginioModel: Trying to update an object with unknown role")\ + F(EnginioModel_Trying_to_update_an_item_with_an_empty_object, "EnginioModel: Trying to update an item with an empty object")\ F(Content_Range, "Content-Range")\ F(Content_Type, "Content-Type")\ F(Get, "GET")\ |