Skip to content

Commit 8dd5798

Browse files
committed
Add DspxDocument and update model loading
1 parent bc02aed commit 8dd5798

9 files changed

Lines changed: 171 additions & 22 deletions

‎src/plugins/coreplugin/CMakeLists.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ qm_configure_target(${PROJECT_NAME}
5858
svscraft::QmlExtras
5959
# ChorusKit::AppCore
6060
# JetBrainsDockingSystem
61-
# dspxmodel
61+
dspxmodel
6262
opendspx::model
6363
opendspx::serializer
6464
ScopicFlowCore
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "DspxDocument.h"
2+
#include "DspxDocument_p.h"
3+
4+
#include <dspxmodel/Model.h>
5+
#include <dspxmodel/BasicModelStrategy.h>
6+
7+
namespace Core {
8+
9+
DspxDocument::DspxDocument(QObject *parent) : QObject(parent), d_ptr(new DspxDocumentPrivate) {
10+
Q_D(DspxDocument);
11+
d->q_ptr = this;
12+
auto strategy = new dspx::BasicModelStrategy; // TODO use substate in future
13+
d->model = new dspx::Model(strategy, this);
14+
strategy->setParent(d->model);
15+
}
16+
17+
DspxDocument::~DspxDocument() = default;
18+
19+
dspx::Model * DspxDocument::model() const {
20+
Q_D(const DspxDocument);
21+
return d->model;
22+
}
23+
24+
}
25+
26+
#include "moc_DspxDocument.cpp"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_H
2+
#define DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_H
3+
4+
#include <QObject>
5+
#include <qqmlintegration.h>
6+
7+
namespace dspx {
8+
class Model;
9+
}
10+
11+
namespace Core {
12+
13+
class DspxDocumentPrivate;
14+
15+
class DspxDocument : public QObject {
16+
Q_OBJECT
17+
QML_ELEMENT
18+
Q_DECLARE_PRIVATE(DspxDocument)
19+
Q_PROPERTY(dspx::Model *model READ model CONSTANT)
20+
public:
21+
explicit DspxDocument(QObject *parent = nullptr);
22+
~DspxDocument() override;
23+
24+
dspx::Model *model() const;
25+
26+
private:
27+
QScopedPointer<DspxDocumentPrivate> d_ptr;
28+
};
29+
30+
}
31+
32+
#endif //DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_H
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_P_H
2+
#define DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_P_H
3+
4+
#include <coreplugin/DspxDocument.h>
5+
6+
namespace Core {
7+
class DspxDocumentPrivate {
8+
Q_DECLARE_PUBLIC(DspxDocument)
9+
public:
10+
DspxDocument *q_ptr;
11+
dspx::Model *model;
12+
};
13+
}
14+
15+
#endif //DIFFSCOPE_COREPLUGIN_DSPXDOCUMENT_P_H

‎src/plugins/coreplugin/project/OpenSaveProjectFileScenario.cpp‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "OpenSaveProjectFileScenario.h"
22
#include "OpenSaveProjectFileScenario_p.h"
33

4+
#include <QApplication>
45
#include <QFileDialog>
56
#include <QQmlComponent>
67
#include <QQuickWindow>
@@ -120,4 +121,26 @@ namespace Core {
120121
SVS::MessageBox::customExec(mb.get());
121122
}
122123

124+
bool OpenSaveProjectFileScenario::confirmFileCreatedByAnotherApplication(const QString &name) const {
125+
Q_D(const OpenSaveProjectFileScenario);
126+
return SVS::MessageBox::question(
127+
RuntimeInterface::qmlEngine(),
128+
d->window,
129+
tr("File Created With Another Application"),
130+
QStringLiteral("This project file was created with another application (%1). Some features may not be fully compatible or may behave differently.\n\nDo you want to continue opening it?")
131+
.arg(name.isEmpty() ? tr("name unknown") : name)
132+
) == SVS::SVSCraft::Yes;
133+
}
134+
135+
bool OpenSaveProjectFileScenario::confirmFileCreatedByIncompatibleVersion(const QString &version) const {
136+
Q_D(const OpenSaveProjectFileScenario);
137+
return SVS::MessageBox::question(
138+
RuntimeInterface::qmlEngine(),
139+
d->window,
140+
tr("File Created With Incompatible Version"),
141+
QStringLiteral("This project file was created with an newer version or test version of %1 (%2). Some features may not be fully compatible or may behave differently.\n\nDo you want to continue opening it?")
142+
.arg(QApplication::applicationDisplayName(), version)
143+
) == SVS::SVSCraft::Yes;
144+
}
145+
123146
}

‎src/plugins/coreplugin/project/OpenSaveProjectFileScenario.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace Core {
2828
Q_INVOKABLE void showOpenFailMessageBox(const QString &path, const QString &error) const;
2929
Q_INVOKABLE void showSaveFailMessageBox(const QString &path, const QString &error) const;
3030
Q_INVOKABLE void showDeserializationFailMessageBox(const QString &path) const;
31+
Q_INVOKABLE bool confirmFileCreatedByAnotherApplication(const QString &name) const;
32+
Q_INVOKABLE bool confirmFileCreatedByIncompatibleVersion(const QString &version) const;
3133

3234
Q_SIGNALS:
3335
void windowChanged();

‎src/plugins/coreplugin/project/ProjectDocumentContext.cpp‎

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "ProjectDocumentContext.h"
22
#include "ProjectDocumentContext_p.h"
33

4+
#include <application_config.h>
5+
46
#include <QDir>
57
#include <QLoggingCategory>
68

@@ -10,34 +12,80 @@
1012
#include <opendspx/model.h>
1113
#include <opendspxserializer/serializer.h>
1214

15+
#include <SVSCraftCore/Semver.h>
1316
#include <SVSCraftQuick/MessageBox.h>
1417

18+
#include <dspxmodel/Model.h>
19+
1520
#include <coreplugin/OpenSaveProjectFileScenario.h>
1621
#include <coreplugin/internal/BehaviorPreference.h>
22+
#include <coreplugin/DspxDocument.h>
1723

1824
namespace Core {
1925

2026
Q_LOGGING_CATEGORY(lcProjectDocumentContext, "diffscope.core.projectdocumentcontext")
2127

28+
constexpr char kEditorId[] = "org.diffscope.diffscope";
29+
30+
static void writeEditorInfo(QDspx::Model &model) {
31+
model.content.global.editorId = kEditorId;
32+
model.content.global.editorName = QStringLiteral("DiffScope");
33+
model.content.workspace["diffscope"].insert("editorVersion", QStringLiteral(APPLICATION_SEMVER));
34+
}
35+
36+
static bool checkIsVersionCompatible(const QString &version) {
37+
if (version.isEmpty())
38+
return true;
39+
SVS::Semver currentSemver(QStringLiteral(APPLICATION_SEMVER));
40+
SVS::Semver fileSemver(version);
41+
if (fileSemver == currentSemver)
42+
return true;
43+
if (fileSemver > currentSemver)
44+
return false;
45+
if (!fileSemver.preRelease().isEmpty() || !fileSemver.build().isEmpty()) {
46+
return false;
47+
}
48+
return true;
49+
}
50+
2251
void ProjectDocumentContextPrivate::markSaved() {
2352
// TODO
2453
}
2554

2655
QByteArray ProjectDocumentContextPrivate::serializeDocument() const {
27-
// TODO
2856
QDspx::SerializationErrorList errors;
29-
return QDspx::Serializer::serialize(model_TODO, errors, QDspx::Serializer::CheckError);
57+
auto model = document->model()->toQDspx();
58+
writeEditorInfo(model);
59+
return QDspx::Serializer::serialize(model, errors, QDspx::Serializer::CheckError);
60+
}
61+
62+
bool ProjectDocumentContextPrivate::initializeDocument(const QDspx::Model &model, bool doCheck) {
63+
Q_Q(ProjectDocumentContext);
64+
document = new DspxDocument(q);
65+
if (doCheck) {
66+
if (model.content.global.editorId != kEditorId) {
67+
if (!openSaveProjectFileScenario->confirmFileCreatedByAnotherApplication(model.content.global.editorName)) {
68+
return false;
69+
}
70+
} else if (auto version = model.content.workspace.value("diffscope").value("editorVersion").toString(); !checkIsVersionCompatible(version)) {
71+
if (!openSaveProjectFileScenario->confirmFileCreatedByIncompatibleVersion(version)) {
72+
return false;
73+
}
74+
}
75+
}
76+
auto postProcessedModel = model;
77+
writeEditorInfo(postProcessedModel);
78+
document->model()->fromQDspx(postProcessedModel);
79+
return true;
3080
}
3181

32-
bool ProjectDocumentContextPrivate::deserializeDocument(const QByteArray &data) {
82+
bool ProjectDocumentContextPrivate::deserializeAndInitializeDocument(const QByteArray &data) {
3383
QDspx::SerializationErrorList errors;
3484
auto model = QDspx::Serializer::deserialize(data, errors);
3585
if (errors.containsFatal() || errors.containsError()) {
3686
return false;
3787
}
38-
// TODO
39-
model_TODO = model;
40-
return true;
88+
return initializeDocument(model, true);
4189
}
4290

4391
ProjectDocumentContext::ProjectDocumentContext(QObject *parent) : QObject(parent), d_ptr(new ProjectDocumentContextPrivate) {
@@ -55,7 +103,7 @@ namespace Core {
55103

56104
DspxDocument *ProjectDocumentContext::document() const {
57105
Q_D(const ProjectDocumentContext);
58-
return nullptr; // TODO
106+
return d->document;
59107
}
60108

61109
OpenSaveProjectFileScenario * ProjectDocumentContext::openSaveProjectFileScenario() const {
@@ -65,16 +113,16 @@ namespace Core {
65113

66114
bool ProjectDocumentContext::openFile(const QString &filePath) {
67115
Q_D(ProjectDocumentContext);
68-
if (false) {
69-
return false; // TODO document should not be opened
116+
if (d->document) {
117+
qCWarning(lcProjectDocumentContext) << "Cannot open file: document already exists.";
118+
return false;
70119
}
71120
d->fileLocker = new FileLocker(this);
72121
if (!d->fileLocker->open(filePath)) {
73122
qCCritical(lcProjectDocumentContext) << "Failed to open file:" << filePath;
74123
d->openSaveProjectFileScenario->showOpenFailMessageBox(filePath, d->fileLocker->errorString());
75124
return false;
76125
}
77-
// TODO initialize document
78126
bool ok;
79127
auto data = d->fileLocker->readData(&ok);
80128
if (
@@ -91,7 +139,7 @@ namespace Core {
91139
d->openSaveProjectFileScenario->showOpenFailMessageBox(filePath, d->fileLocker->errorString());
92140
return false;
93141
}
94-
if (!d->deserializeDocument(data)) {
142+
if (!d->deserializeAndInitializeDocument(data)) {
95143
qCCritical(lcProjectDocumentContext) << "Failed to deserialize file:" << filePath;
96144
d->openSaveProjectFileScenario->showDeserializationFailMessageBox(filePath);
97145
return false;
@@ -101,20 +149,21 @@ namespace Core {
101149

102150
void ProjectDocumentContext::newFile(const QDspx::Model &templateModel, bool isNonFileDocument) {
103151
Q_D(ProjectDocumentContext);
104-
if (false) {
105-
return; // TODO document should not be opened
152+
if (d->document) {
153+
qCWarning(lcProjectDocumentContext) << "Cannot create new file: document already exists.";
154+
return;
106155
}
107156
if (!isNonFileDocument) {
108157
d->fileLocker = new FileLocker(this);
109158
}
110-
// TODO initialize document
111-
d->model_TODO = templateModel;
159+
d->initializeDocument(templateModel, false);
112160
}
113161

114162
bool ProjectDocumentContext::newFile(const QString &templateFilePath, bool isNonFileDocument) {
115163
Q_D(ProjectDocumentContext);
116-
if (false) {
117-
return false; // TODO document should not be opened
164+
if (d->document) {
165+
qCWarning(lcProjectDocumentContext) << "Cannot create new file: document already exists.";
166+
return false;
118167
}
119168
if (!isNonFileDocument) {
120169
d->fileLocker = new FileLocker(this);
@@ -132,7 +181,7 @@ namespace Core {
132181
d->openSaveProjectFileScenario->showOpenFailMessageBox(templateFilePath, d->fileLocker->errorString());
133182
return false;
134183
}
135-
if (!d->deserializeDocument(data)) {
184+
if (!d->deserializeAndInitializeDocument(data)) {
136185
qCCritical(lcProjectDocumentContext) << "Failed to deserialize template file:" << templateFilePath;
137186
d->openSaveProjectFileScenario->showDeserializationFailMessageBox(templateFilePath);
138187
return false;

‎src/plugins/coreplugin/project/ProjectDocumentContext.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace Core {
2121
Q_OBJECT
2222
Q_DECLARE_PRIVATE(ProjectDocumentContext)
2323
Q_PROPERTY(FileLocker *fileLocker READ fileLocker CONSTANT)
24+
Q_PROPERTY(DspxDocument *document READ document CONSTANT)
2425
Q_PROPERTY(OpenSaveProjectFileScenario *openSaveProjectFileScenario READ openSaveProjectFileScenario CONSTANT)
2526
public:
2627
explicit ProjectDocumentContext(QObject *parent = nullptr);

‎src/plugins/coreplugin/project/ProjectDocumentContext_p.h‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ namespace Core {
1313
ProjectDocumentContext *q_ptr;
1414

1515
FileLocker *fileLocker{};
16+
DspxDocument *document{};
1617
OpenSaveProjectFileScenario *openSaveProjectFileScenario;
1718

18-
QDspx::Model model_TODO; // TODO
19-
2019
void markSaved();
2120
QByteArray serializeDocument() const;
22-
bool deserializeDocument(const QByteArray &data);
21+
22+
bool deserializeAndInitializeDocument(const QByteArray &data);
23+
bool initializeDocument(const QDspx::Model &model, bool doCheck);
2324
};
2425

2526
}

0 commit comments

Comments
 (0)