schemaeditor.cpp 5.69 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
    Copyright (C) 2016 Volker Krause <vkrause@kde.org>

    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "schemaeditor.h"
#include "ui_schemaeditor.h"

21
#include <core/aggregation.h>
22
23
#include <core/product.h>
#include <core/schemaentrytemplates.h>
24
#include <rest/restapi.h>
25

26
#include <QFileDialog>
27
#include <QMenu>
28
29
#include <QMessageBox>
#include <QNetworkReply>
30

Volker Krause's avatar
Volker Krause committed
31
using namespace UserFeedback::Console;
32

33

34
35
36
37
38
39
40
SchemaEditor::SchemaEditor(QWidget* parent) :
    QWidget(parent),
    ui(new Ui::SchemaEditor)
{
    ui->setupUi(this);

    connect(ui->schema, &SchemaEditWidget::logMessage, this, &SchemaEditor::logMessage);
41
42
    connect(ui->schema, &SchemaEditWidget::productChanged, ui->aggregation, [this]() {
        ui->aggregation->setProduct(product());
43
        setDirty();
44
    });
45
    connect(ui->aggregation, &AggregationEditWidget::productChanged, this, [this]() {
46
        setDirty();
47
    });
48

49
50
    connect(ui->tabWidget, &QTabWidget::currentChanged, this, &SchemaEditor::updateState);

Volker Krause's avatar
Volker Krause committed
51
    auto templateMenu = new QMenu(tr("Source Templates"), this);
52
53
54
55
56
    for (const auto &t : SchemaEntryTemplates::availableTemplates()) {
        auto a = templateMenu->addAction(t.name());
        a->setData(QVariant::fromValue(t));
        connect(a, &QAction::triggered, this, [this, a]() {
            const auto t = a->data().value<Product>();
57
            auto p = product();
58
59
            p.addTemplate(t);
            setProduct(p);
60
            setDirty();
61
62
63
64
65
66
        });
    }

    m_createFromTemplateAction = templateMenu->menuAction();
    m_createFromTemplateAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new-from-template")));

67
68
69
70
71
72
    ui->actionSave->setShortcut(QKeySequence::Save);
    connect(ui->actionSave, &QAction::triggered, this, &SchemaEditor::save);
    connect(ui->actionImportSchema, &QAction::triggered, this, &SchemaEditor::importSchema);
    connect(ui->actionExportSchema, &QAction::triggered, this, &SchemaEditor::exportSchema);

    addActions({ m_createFromTemplateAction, ui->actionSave, ui->actionImportSchema, ui->actionExportSchema });
Volker Krause's avatar
Volker Krause committed
73
    auto sep = new QAction(this);
74
75
    sep->setSeparator(true);
    addAction(sep);
76
77
    addActions(ui->schema->actions());
    addActions(ui->aggregation->actions());
78

79
    updateState();
80
81
82
83
84
85
}

SchemaEditor::~SchemaEditor() = default;

void SchemaEditor::setRESTClient(RESTClient* client)
{
86
    m_restClient = client;
87
88
89
    ui->schema->setRESTClient(client);
}

90
91
92
93
94
95
96
Product SchemaEditor::product() const
{
    auto p = ui->schema->product();
    p.setAggregations(ui->aggregation->product().aggregations());
    return p;
}

97
98
99
100
void SchemaEditor::setProduct(const Product& product)
{
    ui->schema->setProduct(product);
    ui->aggregation->setProduct(product);
101
    setDirty(false);
102
103
}

104
105
106
107
108
bool SchemaEditor::isDirty() const
{
    return m_isDirty;
}

109
110
111
112
113
114
void SchemaEditor::setDirty(bool dirty)
{
    m_isDirty = dirty;
    updateState();
}

115
116
117
118
119
120
void SchemaEditor::save()
{
    auto reply = RESTApi::updateProduct(m_restClient, product());
    connect(reply, &QNetworkReply::finished, this, [this, reply]() {
        if (reply->error() != QNetworkReply::NoError)
            return;
121
        setDirty(false);
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
        emit logMessage(QString::fromUtf8((reply->readAll())));
        emit productChanged(product());
    });
}

void SchemaEditor::exportSchema()
{
    const auto fileName = QFileDialog::getSaveFileName(this, tr("Export Schema"));
    if (fileName.isEmpty())
        return;

    QFile f(fileName);
    if (!f.open(QFile::WriteOnly)) {
        QMessageBox::critical(this, tr("Export Failed"), tr("Could not open file: %1").arg(f.errorString()));
        return;
    }
    f.write(product().toJson());
Volker Krause's avatar
Volker Krause committed
139
    emit logMessage(tr("Schema of %1 exported to %2.").arg(product().name(), f.fileName()));
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
}

void SchemaEditor::importSchema()
{
    const auto fileName = QFileDialog::getOpenFileName(this, tr("Import Schema"));
    if (fileName.isEmpty())
        return;

    QFile f(fileName);
    if (!f.open(QFile::ReadOnly)) {
        QMessageBox::critical(this, tr("Import Failed"), tr("Could not open file: %1").arg(f.errorString()));
        return;
    }
    const auto products = Product::fromJson(f.readAll());
    if (products.size() != 1 || !products.at(0).isValid()) {
        QMessageBox::critical(this, tr("Import Failed"), tr("Selected file contains no valid product schema."));
        return;
    }

    auto p = products.at(0);
    p.setName(product().name());
    setProduct(p);
162
    setDirty();
Volker Krause's avatar
Volker Krause committed
163
    emit logMessage(tr("Schema of %1 imported from %2.").arg(product().name(), f.fileName()));
164
165
}

166
167
void SchemaEditor::updateState()
{
168
169
170
    const auto p = product();

    m_createFromTemplateAction->setEnabled(p.isValid());
171
    ui->actionSave->setEnabled(p.isValid() && isDirty());
172
173
174
175
176
177
178
179
180
    ui->actionExportSchema->setEnabled(p.isValid());
    ui->actionImportSchema->setEnabled(p.isValid());

    const auto schemaEditActive = ui->tabWidget->currentWidget() == ui->schema;
    const auto aggrEditActive = ui->tabWidget->currentWidget() == ui->aggregation;
    for (auto action : ui->schema->actions())
        action->setVisible(schemaEditActive);
    for (auto action : ui->aggregation->actions())
        action->setVisible(aggrEditActive);
181
}