1 /*
2 * SPDX-FileCopyrightText: 2014-2015 Andreas Cord-Landwehr <cordlandwehr@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7 #include "view.h"
8 #include "models/nodemodel.h"
9 #include "models/edgemodel.h"
10 #include "models/nodepropertymodel.h"
11 #include "models/edgepropertymodel.h"
12 #include "models/nodetypemodel.h"
13 #include "models/edgetypemodel.h"
14 #include "qtquickitems/nodeitem.h"
15 #include "qtquickitems/edgeitem.h"
16 #include "dialogs/nodeproperties.h"
17 #include "dialogs/edgeproperties.h"
18 #include "logging_p.h"
19
20 #include <QQmlApplicationEngine>
21 #include <KLocalizedContext>
22 #include <QQmlComponent>
23 #include <QQmlContext>
24 #include <QQmlEngine>
25 #include <QPointer>
26 #include <QStandardPaths>
27
28 using namespace GraphTheory;
29
30 class GraphTheory::ViewPrivate {
31 public:
ViewPrivate()32 ViewPrivate()
33 : m_edgeModel(new EdgeModel())
34 , m_nodeModel(new NodeModel())
35 , m_edgeTypeModel(new EdgeTypeModel())
36 , m_nodeTypeModel(new NodeTypeModel)
37 {
38 }
39
~ViewPrivate()40 ~ViewPrivate()
41 {
42 delete m_edgeModel;
43 delete m_nodeModel;
44 delete m_edgeTypeModel;
45 delete m_nodeTypeModel;
46 }
47
48 GraphDocumentPtr m_document;
49 EdgeModel *m_edgeModel;
50 NodeModel *m_nodeModel;
51 EdgeTypeModel *m_edgeTypeModel;
52 NodeTypeModel *m_nodeTypeModel;
53 };
54
55
View(QWidget * parent)56 View::View(QWidget *parent)
57 : QQuickWidget(parent)
58 , d(new ViewPrivate)
59 {
60 setResizeMode(QQuickWidget::SizeRootObjectToView);
61
62 // workaround for QTBUG-40765
63 qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
64
65 // prepare i18n
66 auto context = new KLocalizedContext(this);
67 context->setTranslationDomain("libgraphtheory");
68 engine()->rootContext()->setContextObject(context);
69
70 qmlRegisterType<GraphTheory::Node>("org.kde.rocs.graphtheory", 1, 0, "Node");
71 qmlRegisterType<GraphTheory::Edge>("org.kde.rocs.graphtheory", 1, 0, "Edge");
72 qmlRegisterType<GraphTheory::NodeType>("org.kde.rocs.graphtheory", 1, 0, "NodeType");
73 qmlRegisterType<GraphTheory::EdgeType>("org.kde.rocs.graphtheory", 1, 0, "EdgeType");
74 qmlRegisterType<GraphTheory::NodeItem>("org.kde.rocs.graphtheory", 1, 0, "NodeItem");
75 qmlRegisterType<GraphTheory::EdgeItem>("org.kde.rocs.graphtheory", 1, 0, "EdgeItem");
76 qmlRegisterType<GraphTheory::NodeModel>("org.kde.rocs.graphtheory", 1, 0, "NodeModel");
77 qmlRegisterType<GraphTheory::EdgeModel>("org.kde.rocs.graphtheory", 1, 0, "EdgeModel");
78 qmlRegisterType<GraphTheory::NodePropertyModel>("org.kde.rocs.graphtheory", 1, 0, "NodePropertyModel");
79 qmlRegisterType<GraphTheory::EdgePropertyModel>("org.kde.rocs.graphtheory", 1, 0, "EdgePropertyModel");
80 qmlRegisterType<GraphTheory::NodeTypeModel>("org.kde.rocs.graphtheory", 1, 0, "NodeTypeModel");
81 qmlRegisterType<GraphTheory::EdgeTypeModel>("org.kde.rocs.graphtheory", 1, 0, "EdgeTypeModel");
82
83 QUrl path = QUrl("qrc:/libgraphtheory/qml/Scene.qml");
84 QQmlComponent *component = new QQmlComponent(engine());
85 component->loadUrl(path);
86 if (!component->isReady() ) {
87 qCWarning(GRAPHTHEORY_GENERAL) << component->errorString();
88 return;
89 }
90
91 // register editor elements at context
92 engine()->rootContext()->setContextProperty("nodeModel", d->m_nodeModel);
93 engine()->rootContext()->setContextProperty("edgeModel", d->m_edgeModel);
94 engine()->rootContext()->setContextProperty("nodeTypeModel", d->m_nodeTypeModel);
95 engine()->rootContext()->setContextProperty("edgeTypeModel", d->m_edgeTypeModel);
96
97 // create rootObject after context is set up
98 QObject *topLevel = component->create();
99
100 // connections to QML signals
101 connect(topLevel, SIGNAL(createNode(qreal,qreal,int)),
102 this, SLOT(createNode(qreal,qreal,int)));
103 connect(topLevel, SIGNAL(createEdge(GraphTheory::Node*,GraphTheory::Node*,int)),
104 this, SLOT(createEdge(GraphTheory::Node*,GraphTheory::Node*,int)));
105 connect(topLevel, SIGNAL(deleteNode(GraphTheory::Node*)),
106 this, SLOT(deleteNode(GraphTheory::Node*)));
107 connect(topLevel, SIGNAL(deleteEdge(GraphTheory::Edge*)),
108 this, SLOT(deleteEdge(GraphTheory::Edge*)));
109 connect(topLevel, SIGNAL(showNodePropertiesDialog(GraphTheory::Node*)),
110 this, SLOT(showNodePropertiesDialog(GraphTheory::Node*)));
111 connect(topLevel, SIGNAL(showEdgePropertiesDialog(GraphTheory::Edge*)),
112 this, SLOT(showEdgePropertiesDialog(GraphTheory::Edge*)));
113
114 // create widget
115 setContent(path, component, topLevel);
116 }
117
~View()118 View::~View()
119 {
120
121 }
122
setGraphDocument(GraphDocumentPtr document)123 void View::setGraphDocument(GraphDocumentPtr document)
124 {
125 d->m_document = document;
126 d->m_nodeModel->setDocument(d->m_document);
127 d->m_edgeModel->setDocument(d->m_document);
128 d->m_nodeTypeModel->setDocument(d->m_document);
129 d->m_edgeTypeModel->setDocument(d->m_document);
130 }
131
graphDocument() const132 GraphDocumentPtr View::graphDocument() const
133 {
134 return d->m_document;
135 }
136
createNode(qreal x,qreal y,int typeIndex)137 void View::createNode(qreal x, qreal y, int typeIndex)
138 {
139 Q_ASSERT(typeIndex >= 0);
140 Q_ASSERT(typeIndex < d->m_nodeTypeModel->rowCount());
141 NodePtr node = Node::create(d->m_document);
142 node->setType(d->m_nodeTypeModel->type(typeIndex));
143 node->setX(x);
144 node->setY(y);
145 }
146
createEdge(Node * from,Node * to,int typeIndex)147 void View::createEdge(Node *from, Node *to, int typeIndex)
148 {
149 Q_ASSERT(typeIndex >= 0);
150 Q_ASSERT(typeIndex < d->m_edgeTypeModel->rowCount());
151 if (!from || !to) {
152 return;
153 }
154 if (!from->isValid() || !to->isValid()) {
155 return;
156 }
157 EdgePtr edge = Edge::create(from->self(), to->self());
158 edge->setType(d->m_edgeTypeModel->type(typeIndex));
159 }
160
deleteNode(GraphTheory::Node * node)161 void View::deleteNode(GraphTheory::Node *node)
162 {
163 if (!node || !node->isValid()) {
164 return;
165 }
166 node->destroy();
167 }
168
deleteEdge(GraphTheory::Edge * edge)169 void View::deleteEdge(GraphTheory::Edge *edge)
170 {
171 if (!edge || !edge->isValid()) {
172 return;
173 }
174 edge->destroy();
175 }
176
showNodePropertiesDialog(Node * node)177 void View::showNodePropertiesDialog(Node *node)
178 {
179 QPointer<NodeProperties> dialog = new NodeProperties();
180 dialog->setData(node->self());
181 dialog->show(); // workaround: scene-drag not working with modal dialogs
182 }
183
showEdgePropertiesDialog(Edge * edge)184 void View::showEdgePropertiesDialog(Edge *edge)
185 {
186 QPointer<EdgeProperties> dialog = new EdgeProperties();
187 dialog->setData(edge->self());
188 dialog->show(); // workaround: scene-drag not working with modal dialogs
189 }
190