Open NielsMayer opened 7 years ago
In fact, It is not difficult. You just need a JSON parsing code to load as QVariantMap/ QVariantList then convert to your own data structure.
Example code of JSON parsing (QVariantMap)
QVariantMap parse(const QString &text)
{
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(text.toUtf8(),&error);
if (error.error != QJsonParseError::NoError) {
qWarning() << "JSON::parse() error: "<< error.errorString();
}
return doc.object().toVariantMap();
}
stringify
QString stringify(const QVariantMap &data)
{
QJsonObject object = QJsonObject::fromVariantMap(data);
QJsonDocument doc;
doc.setObject(object);
QByteArray bytes = doc.toJson(QJsonDocument::Indented);
return bytes;
}
Thanks for the hint!
I added to appdelegatge.cpp:
// NPM -- see https://github.com/benlau/qsyncable/issues/2
QString AppDelegate::stringifyModel()
{
QVariantList lists;
int count = cardListStore->storage().size();
for (int i = 0 ; i < count ; i++) {
lists << cardListStore->get(i);
}
QVariantMap map;
map["lists"] = lists;
QJsonObject object = QJsonObject::fromVariantMap(map);
QJsonDocument doc;
doc.setObject(object);
QByteArray bytes = doc.toJson(QJsonDocument::Indented);
return bytes;
}
// NPM -- see https://github.com/benlau/qsyncable/issues/2
QString AppDelegate::stringifyBoard()
{
QVariantMap map = m_board.toMap();
QJsonObject object = QJsonObject::fromVariantMap(map);
QJsonDocument doc;
doc.setObject(object);
QByteArray bytes = doc.toJson(QJsonDocument::Indented);
return bytes;
}
And then call in main.qml:
onClosing: {
close.accepted = true;
console.log("Board=" + App.stringifyBoard())
console.log("Model=" + App.stringifyModel())
}
Which, on application close, outputs the initial board layout from both the model and the board (which are the same).
qml: Board={
"lists": [
{
"cards": [
{
"text": "Card 3",
"uuid": "b643690e-a288-4097-89fe-b40176e66869"
},
{
"text": "Card 2",
"uuid": "384a1f8e-f62a-48f3-bb99-982dd453abbe"
},
{
"text": "Card 1",
"uuid": "3f16b090-7947-4f5c-b9c8-d4ce8875b219"
}
],
"title": "List 1",
"uuid": "552fefa3-da81-4387-a9da-8ad9a5a501ac"
},
{
"cards": [
{
"text": "Card 8",
"uuid": "92b27107-30d1-429f-8cc6-230eb163e711"
},
{
"text": "Card 7",
"uuid": "4e3cdb17-706f-4d04-bea1-7bd6286d2891"
},
{
"text": "Card 6",
"uuid": "193391f2-2ca1-452e-b587-eccc78557953"
},
{
"text": "Card 5",
"uuid": "7cc32364-7726-4a28-b058-8bcfc67d4790"
},
{
"text": "Card 4",
"uuid": "e32f8f2e-7387-48de-a669-a1195e53714b"
}
],
"title": "List 2",
"uuid": "442efed1-43c2-4903-846a-867f28ed7eab"
}
]
}
qml: Model={
"lists": [
{
"cards": [
{
"text": "Card 3",
"uuid": "b643690e-a288-4097-89fe-b40176e66869"
},
{
"text": "Card 2",
"uuid": "384a1f8e-f62a-48f3-bb99-982dd453abbe"
},
{
"text": "Card 1",
"uuid": "3f16b090-7947-4f5c-b9c8-d4ce8875b219"
}
],
"title": "List 1",
"uuid": "552fefa3-da81-4387-a9da-8ad9a5a501ac"
},
{
"cards": [
{
"text": "Card 8",
"uuid": "92b27107-30d1-429f-8cc6-230eb163e711"
},
{
"text": "Card 7",
"uuid": "4e3cdb17-706f-4d04-bea1-7bd6286d2891"
},
{
"text": "Card 6",
"uuid": "193391f2-2ca1-452e-b587-eccc78557953"
},
{
"text": "Card 5",
"uuid": "7cc32364-7726-4a28-b058-8bcfc67d4790"
},
{
"text": "Card 4",
"uuid": "e32f8f2e-7387-48de-a669-a1195e53714b"
}
],
"title": "List 2",
"uuid": "442efed1-43c2-4903-846a-867f28ed7eab"
}
]
}
TODO: onClosing, save to a file in ~/.local/share/
QUESTION: In AppDelegate::stringifyModel() is there a simpler way of getting the toplevel model from cardListStore as a QVariantMap or do I need to create a toplevel map of "lists" , and then convert that to JSON (as done in code example above). Probably makes sense to add such code to QSListsModel, to provide a QVariantMap version of the model, rather than do it in appdelegate.cpp ...
See #3 for an implementation of this feature. https://github.com/NielsMayer/qsyncable/tree/faketrello-persistence-feature
In faketrello example, Board::load() currently loads board statically from code. It would be a more complete example app if it showed "end to end" usage of the model, from initial creation, modification, and persistence on application close.
What's the simplest implementation of a "print method" for the model so that it can be persisted to a file? For example a method to output the current model as JSON?
How could Board::load() read such a file, and then reconstruct the model from the JSON-persisted file?