Skip to content

Commit bc02aed

Browse files
committed
Add OpenSaveProjectFileScenario and update project loading
1 parent 5cc8c01 commit bc02aed

10 files changed

Lines changed: 275 additions & 90 deletions

‎src/plugins/coreplugin/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ qm_configure_target(${PROJECT_NAME}
6060
# JetBrainsDockingSystem
6161
# dspxmodel
6262
opendspx::model
63+
opendspx::serializer
6364
ScopicFlowCore
6465
ScopicFlowViews
6566
INCLUDE_PRIVATE

‎src/plugins/coreplugin/core/CoreInterface.cpp‎

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <coreplugin/internal/BehaviorPreference.h>
4040
#include <coreplugin/internal/CoreAchievementsModel.h>
4141
#include <coreplugin/internal/ProjectStartupTimerAddOn.h>
42+
#include <coreplugin/OpenSaveProjectFileScenario.h>
4243
#include <coreplugin/ProjectDocumentContext.h>
4344
#include <coreplugin/ProjectWindowInterface.h>
4445

@@ -224,12 +225,6 @@ namespace Core {
224225
QQmlEngine::setObjectOwnership(windowInterface, QQmlEngine::CppOwnership);
225226
}
226227

227-
QString CoreInterface::dspxFileFilter(bool withAllFiles) {
228-
auto dspxFileFilter = tr("DiffScope Project Exchange Format (*.dspx)");
229-
auto allFileFilter = tr("All Files (*)");
230-
return withAllFiles ? dspxFileFilter + ";;" + allFileFilter : dspxFileFilter;
231-
}
232-
233228
static ProjectWindowInterface *createProjectWindow(ProjectDocumentContext *projectDocumentContext) {
234229
Internal::ProjectStartupTimerAddOn::startTimer();
235230
auto windowInterface = ProjectWindowInterfaceRegistry::instance()->create(projectDocumentContext);
@@ -244,28 +239,6 @@ namespace Core {
244239
return windowInterface;
245240
}
246241

247-
static QString promptOpenDspxFile(QWindow *parent) {
248-
auto settings = RuntimeInterface::settings();
249-
settings->beginGroup(CoreInterface::staticMetaObject.className());
250-
auto defaultOpenDir = settings->value(QStringLiteral("defaultOpenDir"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
251-
settings->endGroup();
252-
253-
auto path = QFileDialog::getOpenFileName(
254-
nullptr,
255-
{},
256-
defaultOpenDir,
257-
CoreInterface::dspxFileFilter(true)
258-
);
259-
if (path.isEmpty())
260-
return {};
261-
262-
settings->beginGroup(CoreInterface::staticMetaObject.className());
263-
settings->setValue(QStringLiteral("defaultOpenDir"), QFileInfo(path).absolutePath());
264-
settings->endGroup();
265-
266-
return path;
267-
}
268-
269242
static void triggerAchievementAfterNewProjectWindowOpened(QWindow *win) {
270243
class ExposedListener : public QObject {
271244
public:
@@ -285,25 +258,31 @@ namespace Core {
285258
}
286259

287260
ProjectWindowInterface *CoreInterface::newFile(QWindow *parent) {
288-
static QDspx::Model defaultModel;
261+
static QDspx::Model defaultModel{
262+
.version = QDspx::Model::V1,
263+
.content = {
264+
265+
}
266+
};
289267
qCInfo(lcCoreInterface) << "New file";
290268
auto projectDocumentContext = std::make_unique<ProjectDocumentContext>();
291-
projectDocumentContext->newFile(defaultModel, false, parent);
269+
projectDocumentContext->newFile(defaultModel, false);
292270
auto windowInterface = createProjectWindow(projectDocumentContext.release());
293271
triggerAchievementAfterNewProjectWindowOpened(windowInterface->window());
294272
return windowInterface;
295273
}
296274

297275
ProjectWindowInterface *CoreInterface::newFileFromTemplate(const QString &templateFilePath_, QWindow *parent) {
298276
qCInfo(lcCoreInterface) << "New file from template" << templateFilePath_;
277+
auto projectDocumentContext = std::make_unique<ProjectDocumentContext>();
278+
projectDocumentContext->openSaveProjectFileScenario()->setWindow(parent);
299279
auto templateFilePath = templateFilePath_;
300280
if (templateFilePath.isEmpty()) {
301-
templateFilePath = promptOpenDspxFile(parent);
281+
templateFilePath = projectDocumentContext->openSaveProjectFileScenario()->openProjectFile();
302282
if (templateFilePath.isEmpty())
303283
return nullptr;
304284
}
305-
auto projectDocumentContext = std::make_unique<ProjectDocumentContext>();
306-
if (!projectDocumentContext->newFile(templateFilePath, false, nullptr)) {
285+
if (!projectDocumentContext->newFile(templateFilePath, false)) {
307286
return nullptr;
308287
}
309288
auto windowInterface = createProjectWindow(projectDocumentContext.release());
@@ -313,9 +292,11 @@ namespace Core {
313292

314293
ProjectWindowInterface *CoreInterface::openFile(const QString &filePath_, QWindow *parent) {
315294
qCInfo(lcCoreInterface) << "Open file" << filePath_;
295+
auto projectDocumentContext = std::make_unique<ProjectDocumentContext>();
296+
projectDocumentContext->openSaveProjectFileScenario()->setWindow(parent);
316297
auto filePath = filePath_;
317298
if (filePath.isEmpty()) {
318-
filePath = promptOpenDspxFile(parent);
299+
filePath = projectDocumentContext->openSaveProjectFileScenario()->openProjectFile();
319300
if (filePath.isEmpty())
320301
return nullptr;
321302
}
@@ -334,8 +315,7 @@ namespace Core {
334315
raiseWindow((*openedWindow)->window());
335316
return qobject_cast<ProjectWindowInterface *>(*openedWindow);
336317
}
337-
auto projectDocumentContext = std::make_unique<ProjectDocumentContext>();
338-
if (!projectDocumentContext->openFile(filePath, parent)) {
318+
if (!projectDocumentContext->openFile(filePath)) {
339319
return nullptr;
340320
}
341321
auto windowInterface = createProjectWindow(projectDocumentContext.release());

‎src/plugins/coreplugin/core/CoreInterface.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ namespace Core {
4444
Q_INVOKABLE static void showHome();
4545

4646
public:
47-
Q_INVOKABLE static QString dspxFileFilter(bool withAllFiles = false);
4847
Q_INVOKABLE static ProjectWindowInterface *newFile(QWindow *parent = nullptr);
4948
Q_INVOKABLE static ProjectWindowInterface *newFileFromTemplate(const QString &templateFilePath, QWindow *parent = nullptr);
5049
Q_INVOKABLE static ProjectWindowInterface *openFile(const QString &filePath, QWindow *parent = nullptr);
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include "OpenSaveProjectFileScenario.h"
2+
#include "OpenSaveProjectFileScenario_p.h"
3+
4+
#include <QFileDialog>
5+
#include <QQmlComponent>
6+
#include <QQuickWindow>
7+
#include <QStandardPaths>
8+
#include <QWindow>
9+
10+
#include <QtQuickTemplates2/private/qquickbutton_p.h>
11+
12+
#include <CoreApi/runtimeinterface.h>
13+
14+
#include <SVSCraftQuick/MessageBox.h>
15+
16+
#include <coreplugin/CoreInterface.h>
17+
18+
namespace Core {
19+
20+
OpenSaveProjectFileScenario::OpenSaveProjectFileScenario(QObject *parent) : QObject(parent), d_ptr(new OpenSaveProjectFileScenarioPrivate) {
21+
Q_D(OpenSaveProjectFileScenario);
22+
d->q_ptr = this;
23+
}
24+
25+
OpenSaveProjectFileScenario::~OpenSaveProjectFileScenario() = default;
26+
27+
QWindow *OpenSaveProjectFileScenario::window() const {
28+
Q_D(const OpenSaveProjectFileScenario);
29+
return d->window;
30+
}
31+
32+
void OpenSaveProjectFileScenario::setWindow(QWindow *window) {
33+
Q_D(OpenSaveProjectFileScenario);
34+
if (d->window != window) {
35+
d->window = window;
36+
Q_EMIT windowChanged();
37+
}
38+
}
39+
40+
QString OpenSaveProjectFileScenario::dspxFileFilter(bool withAllFiles) {
41+
auto dspxFileFilter = tr("DiffScope Project Exchange Format (*.dspx)");
42+
auto allFileFilter = tr("All Files (*)");
43+
return withAllFiles ? dspxFileFilter + ";;" + allFileFilter : dspxFileFilter;
44+
}
45+
46+
QString OpenSaveProjectFileScenario::openProjectFile(const QString &defaultDir) const {
47+
Q_D(const OpenSaveProjectFileScenario);
48+
Q_UNUSED(d->window);
49+
auto settings = RuntimeInterface::settings();
50+
settings->beginGroup(staticMetaObject.className());
51+
auto defaultOpenDir = !defaultDir.isEmpty() ? defaultDir : settings->value(QStringLiteral("defaultOpenDir"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
52+
settings->endGroup();
53+
auto path = QFileDialog::getOpenFileName(
54+
nullptr,
55+
{},
56+
defaultOpenDir,
57+
dspxFileFilter(true)
58+
);
59+
if (path.isEmpty())
60+
return {};
61+
settings->beginGroup(staticMetaObject.className());
62+
settings->setValue(QStringLiteral("defaultOpenDir"), QFileInfo(path).absolutePath());
63+
settings->endGroup();
64+
65+
return path;
66+
}
67+
68+
QString OpenSaveProjectFileScenario::saveProjectFile(const QString &defaultDir) const {
69+
Q_D(const OpenSaveProjectFileScenario);
70+
Q_UNUSED(d->window);
71+
auto settings = RuntimeInterface::settings();
72+
settings->beginGroup(staticMetaObject.className());
73+
auto defaultSaveDir = !defaultDir.isEmpty() ? defaultDir : settings->value(QStringLiteral("defaultSaveDir"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
74+
settings->endGroup();
75+
76+
auto path = QFileDialog::getSaveFileName(
77+
nullptr,
78+
{},
79+
defaultSaveDir,
80+
dspxFileFilter(true)
81+
);
82+
if (path.isEmpty())
83+
return {};
84+
settings->beginGroup(staticMetaObject.className());
85+
settings->setValue(QStringLiteral("defaultSaveDir"), QFileInfo(path).absolutePath());
86+
settings->endGroup();
87+
88+
return path;
89+
}
90+
91+
void OpenSaveProjectFileScenario::showOpenFailMessageBox(const QString &path, const QString &error) const {
92+
Q_D(const OpenSaveProjectFileScenario);
93+
SVS::MessageBox::critical(RuntimeInterface::qmlEngine(), d->window, tr("Failed to open file"), QStringLiteral("%1\n\n%2").arg(QDir::toNativeSeparators(path), error));
94+
}
95+
96+
void OpenSaveProjectFileScenario::showSaveFailMessageBox(const QString &path, const QString &error) const {
97+
Q_D(const OpenSaveProjectFileScenario);
98+
SVS::MessageBox::critical(RuntimeInterface::qmlEngine(), d->window, tr("Failed to save file"), QStringLiteral("%1\n\n%2").arg(QDir::toNativeSeparators(path), error));
99+
}
100+
101+
void OpenSaveProjectFileScenario::showDeserializationFailMessageBox(const QString &path) const {
102+
Q_D(const OpenSaveProjectFileScenario);
103+
QQmlComponent buttonComponent(RuntimeInterface::qmlEngine(), "SVSCraft.UIComponents", "Button");
104+
auto button = qobject_cast<QQuickButton *>(buttonComponent.create());
105+
Q_ASSERT(button);
106+
button->setText(tr("Open DSPX Inspector"));
107+
QQmlComponent component(RuntimeInterface::qmlEngine(), "SVSCraft.UIComponents", "MessageBoxDialog");
108+
std::unique_ptr<QQuickWindow> mb(qobject_cast<QQuickWindow *>(component.createWithInitialProperties(
109+
{{"text", tr("Failed to Parse File Content")},
110+
{"informativeText", tr("%1\n\nYou can check for problems in the file with DSPX Inspector.").arg(QDir::toNativeSeparators(path))},
111+
{"icon", SVS::SVSCraft::Critical},
112+
{"transientParent", QVariant::fromValue(d->window)},
113+
{"content", QVariant::fromValue(button)}}
114+
)));
115+
Q_ASSERT(mb);
116+
connect(button, &QQuickButton::clicked, [this, path, &mb] {
117+
mb->close();
118+
// TODO open DSPX Inspector
119+
});
120+
SVS::MessageBox::customExec(mb.get());
121+
}
122+
123+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_H
2+
#define DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_H
3+
4+
#include <QObject>
5+
#include <qqmlintegration.h>
6+
7+
class QWindow;
8+
9+
namespace Core {
10+
11+
class OpenSaveProjectFileScenarioPrivate;
12+
13+
class OpenSaveProjectFileScenario : public QObject {
14+
Q_OBJECT
15+
QML_ELEMENT
16+
Q_DECLARE_PRIVATE(OpenSaveProjectFileScenario)
17+
Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged)
18+
public:
19+
explicit OpenSaveProjectFileScenario(QObject *parent = nullptr);
20+
~OpenSaveProjectFileScenario() override;
21+
22+
QWindow *window() const;
23+
void setWindow(QWindow *window);
24+
25+
Q_INVOKABLE static QString dspxFileFilter(bool withAllFiles = false);
26+
Q_INVOKABLE QString openProjectFile(const QString &defaultDir = {}) const;
27+
Q_INVOKABLE QString saveProjectFile(const QString &defaultDir = {}) const;
28+
Q_INVOKABLE void showOpenFailMessageBox(const QString &path, const QString &error) const;
29+
Q_INVOKABLE void showSaveFailMessageBox(const QString &path, const QString &error) const;
30+
Q_INVOKABLE void showDeserializationFailMessageBox(const QString &path) const;
31+
32+
Q_SIGNALS:
33+
void windowChanged();
34+
35+
private:
36+
QScopedPointer<OpenSaveProjectFileScenarioPrivate> d_ptr;
37+
};
38+
39+
}
40+
41+
#endif //DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_H
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_P_H
2+
#define DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_P_H
3+
4+
#include <coreplugin/OpenSaveProjectFileScenario.h>
5+
6+
namespace Core {
7+
8+
class OpenSaveProjectFileScenarioPrivate {
9+
Q_DECLARE_PUBLIC(OpenSaveProjectFileScenario)
10+
public:
11+
OpenSaveProjectFileScenario *q_ptr;
12+
QWindow *window{};
13+
};
14+
15+
}
16+
17+
#endif //DIFFSCOPE_COREPLUGIN_OPENSAVEPROJECTFILESCENARIO_P_H

0 commit comments

Comments
 (0)