Working on snapshot save/loading
This commit is contained in:
parent
2a95e09a09
commit
78b0d9c91e
7 changed files with 177 additions and 9 deletions
|
@ -137,8 +137,8 @@ void FGQCanvasFontCache::lookupFile(QByteArray name)
|
|||
reply->setProperty("font", name);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, &FGQCanvasFontCache::onFontDownloadFinished);
|
||||
// connect(reply, &QNetworkReply::error, this, &FGQCanvasFontCache::onFontDownloadError);
|
||||
|
||||
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
|
||||
this, SLOT(onFontDownloadError(QNetworkReply::NetworkError)));
|
||||
m_transfers.append(reply);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include <QDebug>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
class TransferSignalHolder : public QObject
|
||||
{
|
||||
|
@ -43,8 +47,11 @@ void FGQCanvasImageLoader::onDownloadFinished()
|
|||
if (!pm.loadFromData(reply->readAll())) {
|
||||
qWarning() << "image loading failed";
|
||||
} else {
|
||||
qDebug() << "did download:" << reply->property("image").toByteArray();
|
||||
m_cache.insert(reply->property("image").toByteArray(), pm);
|
||||
QByteArray imagePath = reply->property("image").toByteArray();
|
||||
m_cache.insert(imagePath, pm);
|
||||
|
||||
// cache on disk also, so snapshots work
|
||||
writeToDiskCache(imagePath, reply);
|
||||
|
||||
TransferSignalHolder* signalHolder = reply->findChild<TransferSignalHolder*>("holder");
|
||||
if (signalHolder) {
|
||||
|
@ -57,6 +64,23 @@ void FGQCanvasImageLoader::onDownloadFinished()
|
|||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void FGQCanvasImageLoader::writeToDiskCache(QByteArray imagePath, QNetworkReply* reply)
|
||||
{
|
||||
QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
||||
QString absPath = cacheDir.absoluteFilePath(imagePath);
|
||||
|
||||
QFileInfo finfo(imagePath);
|
||||
cacheDir.mkpath(finfo.dir().path());
|
||||
|
||||
QFile f(absPath);
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "failed to open cache file" << f.fileName();
|
||||
}
|
||||
|
||||
f.write(reply->readAll());
|
||||
f.close();
|
||||
}
|
||||
|
||||
void FGQCanvasImageLoader::setHost(QString hostName, int portNumber)
|
||||
{
|
||||
m_hostName = hostName;
|
||||
|
@ -70,6 +94,15 @@ QPixmap FGQCanvasImageLoader::getImage(const QByteArray &imagePath)
|
|||
return m_cache.value(imagePath);
|
||||
}
|
||||
|
||||
QString diskCachePath = QStandardPaths::locate(QStandardPaths::CacheLocation, imagePath);
|
||||
if (!diskCachePath.isEmpty()) {
|
||||
QPixmap pix;
|
||||
pix.load(diskCachePath);
|
||||
m_cache.insert(imagePath, pix);
|
||||
qDebug() << "loaded from on-disk cache:" << imagePath;
|
||||
return pix;
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
url.setScheme("http");
|
||||
url.setHost(m_hostName);
|
||||
|
@ -82,7 +115,6 @@ QPixmap FGQCanvasImageLoader::getImage(const QByteArray &imagePath)
|
|||
}
|
||||
}
|
||||
|
||||
qDebug() << "requesting image" << url;
|
||||
QNetworkReply* reply = m_downloader->get(QNetworkRequest(url));
|
||||
reply->setProperty("image", imagePath);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ signals:
|
|||
private:
|
||||
|
||||
void onDownloadFinished();
|
||||
void writeToDiskCache(QByteArray imagePath, QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager* m_downloader;
|
||||
|
|
|
@ -20,6 +20,18 @@
|
|||
#include <QJsonValue>
|
||||
#include <QDebug>
|
||||
|
||||
QDataStream& operator<<(QDataStream& stream, const NameIndexTuple& nameIndex)
|
||||
{
|
||||
stream << nameIndex.name << nameIndex.index;
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& stream, NameIndexTuple& nameIndex)
|
||||
{
|
||||
stream >> nameIndex.name >> nameIndex.index;
|
||||
return stream;
|
||||
}
|
||||
|
||||
LocalProp *LocalProp::getOrCreateWithPath(const QByteArray &path)
|
||||
{
|
||||
if (path.isEmpty()) {
|
||||
|
@ -119,6 +131,41 @@ void LocalProp::changeValue(const char *path, QVariant value)
|
|||
p->valueChanged(value);
|
||||
}
|
||||
|
||||
void LocalProp::saveToStream(QDataStream &stream) const
|
||||
{
|
||||
stream << _id << _position << _value;
|
||||
stream << static_cast<int>(_children.size());
|
||||
for (auto child : _children) {
|
||||
child->saveToStream(stream);
|
||||
}
|
||||
}
|
||||
|
||||
LocalProp* LocalProp::restoreFromStream(QDataStream &stream, LocalProp* parent)
|
||||
{
|
||||
NameIndexTuple id;
|
||||
stream >> id;
|
||||
LocalProp* prop = new LocalProp(parent, id);
|
||||
stream >> prop->_position >> prop->_value;
|
||||
int childCount;
|
||||
stream >> childCount;
|
||||
for (int c=0; c< childCount; ++c) {
|
||||
prop->_children.push_back(restoreFromStream(stream, prop));
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
void LocalProp::recursiveNotifyRestored()
|
||||
{
|
||||
emit valueChanged(_value);
|
||||
for (auto child : _children) {
|
||||
emit childAdded(child);
|
||||
}
|
||||
|
||||
for (auto child : _children) {
|
||||
child->recursiveNotifyRestored();
|
||||
}
|
||||
}
|
||||
|
||||
LocalProp *LocalProp::getOrCreateChildWithNameAndIndex(const NameIndexTuple& ni)
|
||||
{
|
||||
|
|
|
@ -22,12 +22,16 @@
|
|||
#include <QVariant>
|
||||
#include <QVector>
|
||||
#include <QObject>
|
||||
#include <QDataStream>
|
||||
|
||||
struct NameIndexTuple
|
||||
{
|
||||
QByteArray name;
|
||||
unsigned int index = 0;
|
||||
|
||||
NameIndexTuple()
|
||||
{}
|
||||
|
||||
NameIndexTuple(const char* nm, unsigned int idx) :
|
||||
name(nm),
|
||||
index(idx)
|
||||
|
@ -66,8 +70,12 @@ struct NameIndexTuple
|
|||
|
||||
return name < other.name;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
QDataStream& operator<<(QDataStream& stream, const NameIndexTuple& nameIndex);
|
||||
QDataStream& operator>>(QDataStream& stream, NameIndexTuple& nameIndex);
|
||||
|
||||
class LocalProp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -126,6 +134,12 @@ public:
|
|||
bool hasChild(const char* name) const;
|
||||
|
||||
void changeValue(const char* path, QVariant value);
|
||||
|
||||
void saveToStream(QDataStream& stream) const;
|
||||
|
||||
static LocalProp* restoreFromStream(QDataStream& stream, LocalProp *parent);
|
||||
|
||||
void recursiveNotifyRestored();
|
||||
signals:
|
||||
void valueChanged(QVariant val);
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QQuickItem>
|
||||
#include <QAction>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "fgqcanvasfontcache.h"
|
||||
#include "fgqcanvasimageloader.h"
|
||||
|
@ -49,6 +52,16 @@ TemporaryWidget::TemporaryWidget(QWidget *parent) :
|
|||
connect(ui->canvasSelectCombo, SIGNAL(activated(int)),
|
||||
this, SLOT(onCanvasSelected(int)));
|
||||
ui->canvasSelectCombo->hide();
|
||||
|
||||
QAction* saveTreeAction = new QAction("Save", this);
|
||||
saveTreeAction->setShortcut(Qt::CTRL | Qt::Key_S);
|
||||
connect(saveTreeAction, &QAction::triggered, this, &TemporaryWidget::onSave);
|
||||
addAction(saveTreeAction);
|
||||
|
||||
QAction* openSnapshotAction = new QAction("Open snapshot", this);
|
||||
openSnapshotAction->setShortcut(Qt::CTRL | Qt::Key_O);
|
||||
connect(openSnapshotAction, &QAction::triggered, this, &TemporaryWidget::onLoadSnapshot);
|
||||
addAction(openSnapshotAction);
|
||||
}
|
||||
|
||||
TemporaryWidget::~TemporaryWidget()
|
||||
|
@ -117,13 +130,59 @@ void TemporaryWidget::onFinishedGetCanvasList()
|
|||
}
|
||||
}
|
||||
|
||||
void TemporaryWidget::onWebSocketConnected()
|
||||
void TemporaryWidget::onSave()
|
||||
{
|
||||
connect(&m_webSocket, &QWebSocket::textMessageReceived,
|
||||
this, &TemporaryWidget::onTextMessageReceived);
|
||||
qDebug() << "should save";
|
||||
if (!m_localPropertyRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_localPropertyRoot = new LocalProp(nullptr, NameIndexTuple(""));
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("Choose name to save"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile f(path);
|
||||
f.open(QIODevice::ReadWrite);
|
||||
|
||||
{
|
||||
QDataStream ds(&f);
|
||||
m_localPropertyRoot->saveToStream(ds);
|
||||
}
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
void TemporaryWidget::onLoadSnapshot()
|
||||
{
|
||||
qDebug() << "should load";
|
||||
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Select a saved snapshot"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile f(path);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
|
||||
{
|
||||
QDataStream ds(&f);
|
||||
m_localPropertyRoot = LocalProp::restoreFromStream(ds, nullptr);
|
||||
|
||||
createdRootProperty();
|
||||
|
||||
m_localPropertyRoot->recursiveNotifyRestored();
|
||||
|
||||
// this is needed for either QtQuick or QPainter drawing
|
||||
ui->canvas->rootElement()->update();
|
||||
|
||||
// this is the widget re-draw request (QtQuick draws all the time)
|
||||
ui->canvas->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TemporaryWidget::createdRootProperty()
|
||||
{
|
||||
ui->canvas->setRootProperty(m_localPropertyRoot);
|
||||
ui->stack->setCurrentIndex(1);
|
||||
|
||||
|
@ -136,6 +195,16 @@ void TemporaryWidget::onWebSocketConnected()
|
|||
ui->elementData->setModel(m_elementModel);
|
||||
|
||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TemporaryWidget::onTreeCurrentChanged);
|
||||
}
|
||||
|
||||
void TemporaryWidget::onWebSocketConnected()
|
||||
{
|
||||
connect(&m_webSocket, &QWebSocket::textMessageReceived,
|
||||
this, &TemporaryWidget::onTextMessageReceived);
|
||||
|
||||
m_localPropertyRoot = new LocalProp(nullptr, NameIndexTuple(""));
|
||||
|
||||
createdRootProperty();
|
||||
|
||||
FGQCanvasFontCache::instance()->setHost(ui->hostName->text(),
|
||||
ui->portEdit->text().toInt());
|
||||
|
|
|
@ -52,12 +52,17 @@ private Q_SLOTS:
|
|||
void onCanvasSelected(int index);
|
||||
|
||||
void onFinishedGetCanvasList();
|
||||
|
||||
void onSave();
|
||||
void onLoadSnapshot();
|
||||
private:
|
||||
void saveSettings();
|
||||
void restoreSettings();
|
||||
|
||||
LocalProp* propertyFromPath(QByteArray path) const;
|
||||
|
||||
void createdRootProperty();
|
||||
|
||||
QNetworkAccessManager* m_netAccess;
|
||||
QWebSocket m_webSocket;
|
||||
Ui::TemporaryWidget *ui;
|
||||
|
|
Loading…
Reference in a new issue