From a22a17a995e5b3fc34a14b28d95f5b208f283b0f Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 5 Nov 2017 19:42:57 +0000 Subject: [PATCH] Further work on snapshots feature --- utils/fgqcanvas/applicationcontroller.cpp | 69 +++++++++++++++-------- utils/fgqcanvas/canvasconnection.cpp | 15 +++++ utils/fgqcanvas/canvasconnection.h | 8 ++- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/utils/fgqcanvas/applicationcontroller.cpp b/utils/fgqcanvas/applicationcontroller.cpp index c97e65470..b2cb74dd2 100644 --- a/utils/fgqcanvas/applicationcontroller.cpp +++ b/utils/fgqcanvas/applicationcontroller.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "canvasconnection.h" @@ -117,7 +118,7 @@ void ApplicationController::saveSnapshot(QString snapshotName) // convert spaces to underscores QString filesystemCleanName = snapshotName.replace(QRegularExpression("[\\s-\\\"/]"), "_"); - QFile f(d.filePath(filesystemCleanName + ".json")); + QFile f(d.filePath(filesystemCleanName + ".fgcanvassnapshot")); if (f.exists()) { qWarning() << "not over-writing" << f.fileName(); return; @@ -135,7 +136,29 @@ void ApplicationController::saveSnapshot(QString snapshotName) void ApplicationController::restoreSnapshot(int index) { + QString path = m_snapshots.at(index).toMap().value("path").toString(); + QFile f(path); + if (!f.open(QIODevice::ReadOnly)) { + qWarning() << Q_FUNC_INFO << "failed to open the file"; + return; + } + clearConnections(); + + { + QDataStream ds(&f); + int version, canvasCount; + QString name; + ds >> version >> name >> canvasCount; + + for (int i=0; i < canvasCount; ++i) { + CanvasConnection* cc = new CanvasConnection(this); + cc->restoreSnapshot(ds); + m_activeCanvases.append(cc); + } + } + + emit activeCanvasesChanged(); } void ApplicationController::rebuildSnapshotData() @@ -148,17 +171,21 @@ void ApplicationController::rebuildSnapshotData() return; } - // this requires parsing each snapshit in its entirety just to extract - // the name, which is horrible. - Q_FOREACH (auto entry, d.entryList(QStringList() << "*.json")) { + Q_FOREACH (auto entry, d.entryList(QStringList() << "*.fgcanvassnapshot")) { QFile f(d.filePath(entry)); f.open(QIODevice::ReadOnly); - QJsonDocument doc = QJsonDocument::fromJson(f.readAll()); + { + QDataStream ds(&f); + int version; + QString name; + ds >> version; - QVariantMap m; - m["path"] = f.fileName(); - m["name"] = doc.object().value("snapshotName").toString(); - m_snapshots.append(m); + QVariantMap m; + m["path"] = f.fileName(); + ds >>name; + m["name"] = name; + m_snapshots.append(m); + } } emit snapshotListChanged(); @@ -405,19 +432,17 @@ void ApplicationController::clearConnections() QByteArray ApplicationController::createSnapshot(QString name) const { - QJsonObject json; - json["snapshotName"] = name; -#if 0 - QJsonArray canvases; - Q_FOREACH (auto canvas, m_activeCanvases) { - canvases.append(canvas->saveState()); + QByteArray bytes; + const int version = 1; + { + QDataStream ds(&bytes, QIODevice::WriteOnly); + ds << version << name; + + ds << m_activeCanvases.size(); + Q_FOREACH(auto c, m_activeCanvases) { + c->saveSnapshot(ds); + } } - json["canvases"] = canvases; - // background color? - // window geometry and state? -#endif - QJsonDocument doc; - doc.setObject(json); - return doc.toJson(); + return bytes; } diff --git a/utils/fgqcanvas/canvasconnection.cpp b/utils/fgqcanvas/canvasconnection.cpp index 159504481..c0985afb8 100644 --- a/utils/fgqcanvas/canvasconnection.cpp +++ b/utils/fgqcanvas/canvasconnection.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "localprop.h" #include "fgqcanvasfontcache.h" @@ -88,6 +89,20 @@ bool CanvasConnection::restoreState(QJsonObject state) return true; } +void CanvasConnection::saveSnapshot(QDataStream &ds) const +{ + ds << m_webSocketUrl << m_rootPropertyPath << m_destRect; + m_localPropertyRoot->saveToStream(ds); +} + +void CanvasConnection::restoreSnapshot(QDataStream &ds) +{ + ds >> m_webSocketUrl >> m_rootPropertyPath >> m_destRect; + m_localPropertyRoot.reset(new LocalProp{nullptr, NameIndexTuple("")}); + m_localPropertyRoot->restoreFromStream(ds, nullptr); + setStatus(Snapshot); +} + void CanvasConnection::reconnect() { m_webSocket.open(m_webSocketUrl); diff --git a/utils/fgqcanvas/canvasconnection.h b/utils/fgqcanvas/canvasconnection.h index a12d21c48..37a5d598b 100644 --- a/utils/fgqcanvas/canvasconnection.h +++ b/utils/fgqcanvas/canvasconnection.h @@ -30,6 +30,7 @@ class LocalProp; class QNetworkAccessManager; class FGQCanvasImageLoader; class FGQCanvasFontCache; +class QDataStream; class CanvasConnection : public QObject { @@ -59,7 +60,8 @@ public: Connected, Closed, Reconnecting, - Error + Error, + Snapshot // offline mode, data from snapshot }; Status status() const @@ -70,6 +72,9 @@ public: QJsonObject saveState() const; bool restoreState(QJsonObject state); + void saveSnapshot(QDataStream& ds) const; + void restoreSnapshot(QDataStream &ds); + void connectWebSocket(QByteArray hostName, int port); QPointF origin() const; @@ -129,7 +134,6 @@ private: std::unique_ptr m_localPropertyRoot; QHash idPropertyDict; Status m_status = NotConnected; - QString m_rootPath; mutable FGQCanvasImageLoader* m_imageLoader = nullptr; mutable FGQCanvasFontCache* m_fontCache = nullptr;