Skip to content

Commit df0eedd

Browse files
committed
Adding QtJson for first time
1 parent 28dc7dc commit df0eedd

File tree

8 files changed

+904
-0
lines changed

8 files changed

+904
-0
lines changed

src/JObject.cpp

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include "JObject.h"
2+
#include <QJsonDocument>
3+
4+
JObject::JObject(QObject *parent) :
5+
QObject(parent)
6+
{
7+
}
8+
9+
10+
void JObject::registerPtrProperty(const QString &prop, const QMetaObject *mo)
11+
{
12+
if (!_ptrPropMap.contains(prop)) {
13+
_ptrPropMap.insert(prop, mo);
14+
}
15+
}
16+
17+
18+
const QMetaObject* JObject::metaObjectForProp(const QString &prop)
19+
{
20+
if (!_ptrPropMap.contains(prop)) {
21+
QMetaObject::invokeMethod(this, QString(QString("_type") + prop).toStdString().c_str(),
22+
Qt::DirectConnection, Q_ARG(QString, prop));
23+
}
24+
25+
return _ptrPropMap.value(prop, 0);
26+
}
27+
28+
29+
QVariant JObject::exportToVariant()
30+
{
31+
QVariantMap map;
32+
const QMetaObject* mo = metaObject();
33+
int count = mo->propertyCount();
34+
for (int i = 0; i < count; i++) {
35+
QMetaProperty mp = mo->property(i);
36+
QString name(mp.name());
37+
if (name == "objectName") continue;
38+
QVariant::Type type = mp.type();
39+
switch (type) {
40+
case QMetaType::QObjectStar: {
41+
JObject* child = property(mp.name()).value<JObject*>();
42+
if (child) {
43+
map.insert(name, child->exportToVariant());
44+
}}
45+
break;
46+
case QVariant::List:{
47+
QVariantList newList;
48+
QVariantList list = property(mp.name()).toList();
49+
foreach (QVariant v, list) {
50+
if (v.type() == QMetaType::User) {
51+
JObject* child = v.value<JObject*>();
52+
if (child) {
53+
newList.append(child->exportToVariant());
54+
}
55+
}
56+
else {
57+
newList.append(v);
58+
}
59+
}
60+
map.insert(name, newList);}
61+
break;
62+
default:
63+
{map.insert(name, property(mp.name()));}break;
64+
}
65+
}
66+
67+
QVariant root(QVariant::Map);
68+
root.setValue(map);
69+
return root;
70+
}
71+
72+
73+
bool JObject::importFromVariant(const QVariant &v)
74+
{
75+
if (v.type() != QVariant::Map) return false;
76+
77+
QVariantMap map = v.toMap();
78+
const QMetaObject* mo = metaObject();
79+
int count = mo->propertyCount();
80+
81+
if ( (count - 1) > map.count()) return false;
82+
83+
for (int i = 0; i < count; i++) {
84+
QMetaProperty mp = mo->property(i);
85+
QString name(mp.name());
86+
if (name == "objectName") continue;
87+
if (!map.contains(name)) return false;
88+
QVariant value = map[name];
89+
QVariant::Type type = mp.type();
90+
switch (type) {
91+
case QMetaType::QObjectStar: {
92+
const QMetaObject* cmo = metaObjectForProp(name);
93+
if (cmo) {
94+
JObject* child = qobject_cast < JObject* > (cmo->newInstance());
95+
if (child) {
96+
child->setParent(this);
97+
child->importFromVariant(value);
98+
}
99+
else {
100+
return false;
101+
}
102+
}
103+
else {
104+
return false;
105+
}
106+
}
107+
break;
108+
case QVariant::List:
109+
{QVariantList newList;
110+
QVariantList list = value.toList();
111+
const QMetaObject* cmo = metaObjectForProp(name);
112+
foreach (QVariant v, list) {
113+
if (v.type() == QVariant::Map) {
114+
JObject* child = cmo == 0? 0 : qobject_cast< JObject* >(cmo->newInstance());
115+
if (child) {
116+
child->importFromVariant(v);
117+
newList.append(QVariant::fromValue(child));
118+
}
119+
else {
120+
return false;
121+
}
122+
}
123+
else {
124+
newList.append(v);
125+
}
126+
}
127+
setProperty(mp.name(), newList);}
128+
break;
129+
default:
130+
{setProperty(mp.name(), value);}break;
131+
}
132+
}
133+
134+
return true;
135+
}
136+
137+
138+
QByteArray JObject::exportToJson(bool indented)
139+
{
140+
return QJsonDocument::fromVariant(exportToVariant()).toJson(indented ? QJsonDocument::Indented : QJsonDocument::Compact); //
141+
}
142+
143+
144+
bool JObject::importFromJson(const QByteArray &json)
145+
{
146+
return importFromVariant(QJsonDocument::fromJson(json).toVariant());
147+
}
148+

src/JObject.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#ifndef JOBJECT_H
2+
#define JOBJECT_H
3+
4+
#include <QObject>
5+
#include <QVariant>
6+
#include <QVariantList>
7+
#include <QMetaObject>
8+
#include <QString>
9+
#include <QMetaProperty>
10+
11+
// t: type, x: property name
12+
#define PropertyPrivateSet(t, x) private: t _##x; \
13+
public: t x() const {return _##x;} \
14+
private: void x(const t& v){_##x = v;}
15+
16+
// t: type, x: property name
17+
#define PropertyPublicSet(t, x) private: t _##x; \
18+
public: t x() const {return _##x;} \
19+
void x(const t& v){_##x = v;}
20+
21+
// t: type, x: property name
22+
#define PropertyPrivateSet_Ptr(t, x) private: t* _##x; \
23+
public: t* x() {return _##x;} \
24+
private: void x(t* v){_##x = v;}
25+
26+
// t: type, x: property name
27+
#define PropertyPublicSet_Ptr(t, x) private: t* _##x; \
28+
public: t* x() {return _##x;} \
29+
void x(t* v){_##x = v;}
30+
31+
// t: type, x: property name
32+
#define MetaPropertyPrivateSet(t, x) private: Q_PROPERTY(t x READ x WRITE x) \
33+
PropertyPrivateSet(t, x)
34+
35+
// t: type, x: property name
36+
#define MetaPropertyPublicSet(t, x) private: Q_PROPERTY(t x READ x WRITE x) \
37+
PropertyPublicSet(t, x)
38+
39+
// t: type, x: property name
40+
#define MetaPropertyPrivateSet_Ptr(t, x) private: Q_PROPERTY(QObject* x READ x WRITE x) \
41+
PropertyPrivateSet_Ptr(t, x) \
42+
public: Q_INVOKABLE void _type##x(const QString& prop){registerPtrProperty(prop, &t::staticMetaObject);}
43+
44+
// t: type, x: property name
45+
#define MetaPropertyPublicSet_Ptr(t, x) private: Q_PROPERTY(QObject* x READ x WRITE x) \
46+
PropertyPublicSet_Ptr(QObject, x) \
47+
public: Q_INVOKABLE void _type##x(const QString& prop){registerPtrProperty(prop, &t::staticMetaObject);}
48+
49+
// t: type, x: property name
50+
#define MetaPropertyPublicSet_Ptr_List(t, x) private: Q_PROPERTY(QVariantList x READ x WRITE x) \
51+
PropertyPublicSet(QVariantList, x) \
52+
public: Q_INVOKABLE void _type##x(const QString& prop){registerPtrProperty(prop, &t::staticMetaObject);} \
53+
void append##t(t* i){QVariant v = QVariant::fromValue(i); if (v.isValid()) { _##x.append(v);}}
54+
55+
56+
/**
57+
* Base class of classes that should import/export all its properties from/to QVariant via JSON.
58+
*/
59+
class JObject : public QObject
60+
{
61+
Q_OBJECT
62+
public:
63+
Q_INVOKABLE explicit JObject(QObject *parent = 0);
64+
65+
QVariant exportToVariant();
66+
bool importFromVariant(const QVariant& v);
67+
68+
QByteArray exportToJson(bool indented = true);
69+
bool importFromJson(const QByteArray& json);
70+
71+
protected:
72+
void registerPtrProperty(const QString& prop, const QMetaObject* mo);
73+
const QMetaObject* metaObjectForProp(const QString& prop);
74+
75+
private:
76+
Q_DISABLE_COPY(JObject)
77+
QMap <QString, const QMetaObject* > _ptrPropMap;
78+
};
79+
80+
#endif // JOBJECT_H

0 commit comments

Comments
 (0)