171 lines
3.4 KiB
C++
171 lines
3.4 KiB
C++
#include "document.h"
|
|
#include "designerScene.h"
|
|
|
|
#include "graphicsItem/graphicsBaseItem.h"
|
|
#include "graphicsItem/graphicsItemGroup.h"
|
|
#include "util/serializationRegistry.h"
|
|
#include "global.h"
|
|
|
|
#include <QFile>
|
|
#include <QJsonDocument>
|
|
#include <QJsonArray>
|
|
#include <QGraphicsScene>
|
|
|
|
#include <QUndoStack>
|
|
#include <QUndoCommand>
|
|
|
|
Document::Document(QObject *parent)
|
|
: QObject(parent)
|
|
, m_pScene(nullptr)
|
|
, m_pUndoStack(nullptr)
|
|
, m_bModified(false)
|
|
, m_nSavedIndex(0)
|
|
{
|
|
setupNewScene();
|
|
|
|
m_pUndoStack = new QUndoStack(this);
|
|
connect(m_pUndoStack, &QUndoStack::indexChanged, this, [this](int idx) {
|
|
setModified(idx != m_nSavedIndex);
|
|
});
|
|
}
|
|
|
|
Document::~Document()
|
|
{
|
|
}
|
|
|
|
void Document::setupNewScene()
|
|
{
|
|
if (m_pScene) {
|
|
m_pScene->clear();
|
|
} else {
|
|
m_pScene = new DesignerScene(this);
|
|
}
|
|
}
|
|
|
|
DesignerScene *Document::scene() const
|
|
{
|
|
return m_pScene;
|
|
}
|
|
|
|
QUndoStack *Document::undoStack() const
|
|
{
|
|
return m_pUndoStack;
|
|
}
|
|
|
|
bool Document::isModified() const
|
|
{
|
|
return m_bModified;
|
|
}
|
|
|
|
QString Document::filePath() const
|
|
{
|
|
return m_sFilePath;
|
|
}
|
|
|
|
void Document::setModified(bool modified)
|
|
{
|
|
if (m_bModified != modified) {
|
|
m_bModified = modified;
|
|
emit modifiedChanged(m_bModified);
|
|
}
|
|
}
|
|
|
|
void Document::execute(QUndoCommand *cmd)
|
|
{
|
|
m_pUndoStack->push(cmd);
|
|
}
|
|
|
|
void Document::markDirty()
|
|
{
|
|
setModified(true);
|
|
}
|
|
|
|
void Document::clear()
|
|
{
|
|
m_nSavedIndex = 0;
|
|
m_pUndoStack->clear();
|
|
setupNewScene();
|
|
m_sFilePath.clear();
|
|
setModified(false);
|
|
emit filePathChanged(m_sFilePath);
|
|
}
|
|
|
|
bool Document::save()
|
|
{
|
|
if (m_sFilePath.isEmpty())
|
|
return false;
|
|
return saveAs(m_sFilePath);
|
|
}
|
|
|
|
bool Document::saveAs(const QString &filePath)
|
|
{
|
|
QJsonArray items;
|
|
const auto sceneItems = m_pScene->items();
|
|
for (QGraphicsItem *item : sceneItems) {
|
|
if (item->parentItem())
|
|
continue;
|
|
QJsonObject obj;
|
|
if (auto *group = dynamic_cast<GraphicsItemGroup *>(item))
|
|
obj = group->serialize();
|
|
else if (auto *shape = dynamic_cast<IShape *>(item))
|
|
obj = shape->serialize();
|
|
if (!obj.isEmpty())
|
|
items.append(obj);
|
|
}
|
|
|
|
QJsonObject root;
|
|
root["version"] = "1.0";
|
|
root["items"] = items;
|
|
|
|
QFile file(filePath);
|
|
if (!file.open(QIODevice::WriteOnly))
|
|
return false;
|
|
|
|
file.write(QJsonDocument(root).toJson());
|
|
file.close();
|
|
|
|
m_sFilePath = filePath;
|
|
m_nSavedIndex = m_pUndoStack->index();
|
|
setModified(false);
|
|
emit filePathChanged(m_sFilePath);
|
|
emit saved();
|
|
return true;
|
|
}
|
|
|
|
bool Document::load(const QString &filePath)
|
|
{
|
|
QFile file(filePath);
|
|
if (!file.open(QIODevice::ReadOnly))
|
|
return false;
|
|
|
|
QByteArray data = file.readAll();
|
|
file.close();
|
|
|
|
QJsonParseError error;
|
|
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
|
if (error.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
QJsonObject root = doc.object();
|
|
|
|
m_nSavedIndex = 0;
|
|
m_pUndoStack->clear();
|
|
setupNewScene();
|
|
|
|
QJsonArray items = root["items"].toArray();
|
|
for (const QJsonValue &val : items) {
|
|
QGraphicsItem *item = createItemFromJson(val.toObject());
|
|
if (item)
|
|
m_pScene->addItem(item);
|
|
}
|
|
|
|
m_pScene->clearSelection();
|
|
|
|
m_sFilePath = filePath;
|
|
m_nSavedIndex = 0;
|
|
setModified(false);
|
|
emit filePathChanged(m_sFilePath);
|
|
emit loaded();
|
|
return true;
|
|
}
|