File indexing completed on 2024-05-19 04:36:34
0001 /* This file is part of the TikZKit project. 0002 * 0003 * Copyright (C) 2013-2016 Dominik Haumann <dhaumann@kde.org> 0004 * 0005 * This library is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU Library General Public License as published 0007 * by the Free Software Foundation, either version 2 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, see 0017 * <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include "DocumentPrivate.h" 0021 0022 0023 #include <tikz/core/Node.h> 0024 #include <tikz/core/Path.h> 0025 #include <tikz/core/Style.h> 0026 #include <tikz/core/Document.h> 0027 #include <tikz/core/UndoSetProperty.h> 0028 0029 //BEGIN DEBUG 0030 #include <tikz/core/Style.h> 0031 #include <tikz/core/EdgePath.h> 0032 #include <tikz/core/EllipsePath.h> 0033 //END DEBUG 0034 0035 #include "EditorPrivate.h" 0036 #include "ViewPrivate.h" 0037 #include "Renderer.h" 0038 0039 #include "NodeItem.h" 0040 #include "PathItem.h" 0041 #include "EllipsePathItem.h" 0042 #include "EdgePathItem.h" 0043 #include "TikzScene.h" 0044 0045 #include <QDebug> 0046 #include <QGraphicsView> 0047 0048 namespace tikz { 0049 namespace ui { 0050 0051 static void setProp(const tikz::core::Uid & entity, const QString & key, const QVariant & value) 0052 { 0053 entity.document()->addUndoItem(new tikz::core::UndoSetProperty(entity, key, value)); 0054 } 0055 0056 DocumentPrivate::DocumentPrivate(QObject * parent) 0057 : tikz::ui::Document(this, parent) 0058 { 0059 // register document 0060 tikz::ui::EditorPrivate::self()->registerDocument(this); 0061 0062 // create scene 0063 m_scene = new TikzScene(this); 0064 0065 connect(m_scene, SIGNAL(editModeChanged(TikzEditMode)), this, SIGNAL(editModeChanged(TikzEditMode))); 0066 connect(this, SIGNAL(aboutToClear()), this, SLOT(clearDocumentPrivate())); 0067 } 0068 0069 DocumentPrivate::~DocumentPrivate() 0070 { 0071 // purge all Nodes and Paths 0072 clearDocumentPrivate(); 0073 0074 // make sure they are gone 0075 Q_ASSERT(m_nodeMap.isEmpty()); 0076 Q_ASSERT(m_nodes.isEmpty()); 0077 Q_ASSERT(m_pathMap.isEmpty()); 0078 Q_ASSERT(m_paths.isEmpty()); 0079 0080 // finally unregister document 0081 tikz::ui::EditorPrivate::self()->unregisterDocument(this); 0082 } 0083 0084 void DocumentPrivate::clearDocumentPrivate() 0085 { 0086 // free UI part of nodes and paths 0087 qDeleteAll(m_paths); 0088 m_pathMap.clear(); 0089 m_paths.clear(); 0090 0091 qDeleteAll(m_nodes); 0092 m_nodeMap.clear(); 0093 m_nodes.clear(); 0094 } 0095 0096 void DocumentPrivate::setEditMode(TikzEditMode mode) 0097 { 0098 m_scene->setEditMode(mode); 0099 } 0100 0101 TikzEditMode DocumentPrivate::editMode() const 0102 { 0103 return m_scene->editMode(); 0104 } 0105 0106 tikz::Pos DocumentPrivate::scenePos(const tikz::core::MetaPos & pos) const 0107 { 0108 const auto node = pos.node(); 0109 if (node) { 0110 const NodeItem * nodeItem = nodeItemFromId(node->uid()); 0111 Q_ASSERT(nodeItem != nullptr); 0112 return nodeItem->anchor(pos.anchor()); 0113 } 0114 0115 return Document::scenePos(pos); 0116 } 0117 0118 TikzScene * DocumentPrivate::scene() const 0119 { 0120 return m_scene; 0121 } 0122 0123 View * DocumentPrivate::createView(QWidget * parent, 0124 tikz::ui::MainWindow * mainWindow) 0125 { 0126 // construct new view, we use a dummyMainWindow interface if no mainWindow is there 0127 auto view = new ViewPrivate(this, parent, mainWindow ? mainWindow : tikz::ui::EditorPrivate::self()->dummyMainWindow()); 0128 Q_ASSERT(m_views.contains(view)); 0129 0130 //BEGIN DEBUG 0131 beginTransaction("Create Nodes"); 0132 tikz::ui::NodeItem* item1 = createNodeItem(); 0133 item1->node()->setPos(tikz::Pos(-3, 3, tikz::Unit::Centimeter)); 0134 qDebug() << " ____" << item1->style()->uid(); 0135 qDebug() << " ____" << item1->style()->property("style"); 0136 setProp(item1->style()->uid(), "lineWidth", tikz::Value::veryThin()); 0137 setProp(item1->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0138 setProp(item1->style()->uid(), "innerSep", 2.0_mm); 0139 setProp(item1->node()->uid(), "text", "$\\int f(x) dx$"); 0140 0141 tikz::ui::NodeItem* item2 = createNodeItem(); 0142 item2->node()->setPos(tikz::Pos(3, 3, tikz::Unit::Centimeter)); 0143 setProp(item2->style()->uid(), "lineWidth", tikz::Value::thin()); 0144 setProp(item2->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0145 setProp(item2->style()->uid(), "innerSep", 2.0_mm); 0146 setProp(item2->node()->uid(), "text", "$\\Leftrightarrow$"); 0147 finishTransaction(); 0148 0149 beginTransaction("Create Paths"); 0150 0151 // an ellipse path 0152 // tikz::ui::PathItem* path = createPathItem(tikz::PathType::Ellipse); 0153 // auto ellipse = qobject_cast<tikz::core::EllipsePath*>(path->path()); 0154 // tikz::core::Style es; 0155 // es.setStyle(ellipse->style()); 0156 // es.setRadiusX(2.0_cm); 0157 // es.setRadiusY(1.0_cm); 0158 // es.setLineWidth(tikz::Value::semiThick()); 0159 // ellipse->setStyle(es); 0160 0161 // add a line path 0162 auto path = createPathItem(tikz::PathType::Line); 0163 auto edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0164 setProp(edge->style()->uid(), "lineWidth", tikz::Value::semiThick()); 0165 //setProp(edge->style()->uid(), "doubleLine", true); 0166 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0167 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::ToArrow)); 0168 edge->setStartNode(item1->node()); 0169 edge->setEndNode(item2->node()); 0170 finishTransaction(); 0171 0172 #if 0 0173 item1 = m_doc->createNodeItem(); 0174 item1->setPos(tikz::Pos(-3, 1, tikz::Unit::Centimeter)); 0175 item1->node()->style()->setLineWidth(tikz::Value::thin()); 0176 item1->node()->style()->setShape(tikz::Shape::ShapeRectangle); 0177 item1->node()->style()->setInnerSep(2.0_mm); 0178 item1->node()->setText("$a$"); 0179 0180 item2 = m_doc->createNodeItem(); 0181 item2->node()->setPos(tikz::Pos(3, 1, tikz::Unit::Centimeter)); 0182 item2->node()->style()->setLineWidth(tikz::Value::semiThick()); 0183 item2->node()->style()->setShape(tikz::Shape::ShapeCircle); 0184 item2->node()->style()->setInnerSep(2.0_mm); 0185 item2->node()->setText("a"); 0186 0187 // an path 0188 path = m_doc->createPathItem(); 0189 // path->setStartNode(item1); 0190 // path->setEndNode(item2); 0191 path->path()->style()->setLineWidth(tikz::Value::semiThick()); 0192 0193 0194 item1 = m_doc->createNodeItem(); 0195 item1->setPos(tikz::Pos(-3, -1, tikz::Unit::Centimeter)); 0196 item1->node()->style()->setLineWidth(tikz::Value::veryThick()); 0197 item1->node()->style()->setShape(tikz::Shape::ShapeRectangle); 0198 item1->node()->style()->setInnerSep(2.0_mm); 0199 item1->node()->setText("$\\iiint \\max$"); 0200 0201 item2 = m_doc->createNodeItem(); 0202 item2->node()->setPos(tikz::Pos(3, -1, tikz::Unit::Centimeter)); 0203 item2->node()->style()->setLineWidth(tikz::Value::ultraThick()); 0204 item2->node()->style()->setShape(tikz::Shape::ShapeRectangle); 0205 item2->node()->style()->setInnerSep(2.0_mm); 0206 item2->node()->setText("A long text\\\\which is wrapped"); 0207 0208 // item2->style()->setParentStyle(item1->style()); 0209 0210 // an path 0211 path = m_doc->createPathItem(); 0212 // path->setStartNode(item1); 0213 // path->setEndNode(item2); 0214 path->path()->style()->setLineWidth(tikz::Value::ultraThick()); 0215 path->path()->style()->setArrowTail(tikz::Arrow::LatexArrow); 0216 path->path()->style()->setArrowHead(tikz::Arrow::PipeArrow); 0217 0218 0219 item1 = m_doc->createNodeItem(); 0220 item1->setPos(tikz::Pos(-3, -3, tikz::Unit::Centimeter)); 0221 item1->node()->style()->setLineWidth(tikz::Value::veryThick()); 0222 item1->node()->style()->setShape(tikz::Shape::ShapeRectangle); 0223 item1->node()->style()->setInnerSep(2.0_mm); 0224 item1->node()->setText("c"); 0225 0226 a = item1; 0227 0228 item2 = m_doc->createNodeItem(); 0229 item2->node()->setPos(tikz::Pos(3, -3, tikz::Unit::Centimeter)); 0230 item2->node()->style()->setDoubleLine(true); 0231 item2->node()->style()->setLineWidth(tikz::Value::semiThick()); 0232 item2->node()->style()->setShape(tikz::Shape::ShapeEllipse); 0233 item2->node()->style()->setInnerSep(2.0_mm); 0234 item2->node()->style()->setMinimumWidth(2); 0235 item2->node()->setText("8"); 0236 0237 // an path 0238 path = m_doc->createPathItem(); 0239 // path->setStartNode(item1); 0240 // path->setEndNode(item2); 0241 path->path()->style()->setLineWidth(tikz::Value::ultraThick()); 0242 path->path()->style()->setBendAngle(30); 0243 // path->path()->style()->setCurveMode(tikz::HVLineTo); 0244 path->path()->style()->setArrowTail(tikz::Arrow::StealthArrow); 0245 path->path()->style()->setArrowHead(tikz::Arrow::ToArrow); 0246 0247 0248 // arrow demo 0249 for (int i = 0; i < tikz::Arrow::ArrowCount; ++i) { 0250 path = m_doc->createPathItem(); 0251 // path->path()->setStartPos(QPointF(-6, i - 4)); 0252 // path->path()->setEndPos(QPointF(-4, i - 4)); 0253 path->path()->style()->beginConfig(); 0254 path->path()->style()->setLineWidth(tikz::Value::ultraThick()); 0255 path->path()->style()->setArrowTail(tikz::Arrow(i)); 0256 path->path()->style()->setArrowHead(tikz::Arrow(i)); 0257 path->path()->style()->endConfig(); 0258 } 0259 0260 // arrow demo 0261 for (int i = 0; i < tikz::Arrow::ArrowCount; ++i) { 0262 path = m_doc->createPathItem(); 0263 // path->path()->setStartPos(QPointF(4, i - 4)); 0264 // path->path()->setEndPos(QPointF(6, i - 4)); 0265 path->path()->style()->beginConfig(); 0266 path->path()->style()->setDoubleLine(true); 0267 path->path()->style()->setInnerLineWidth(tikz::Value::veryThick()); 0268 path->path()->style()->setLineWidth(tikz::UltraThick); 0269 path->path()->style()->setArrowTail(tikz::Arrow(i)); 0270 path->path()->style()->setArrowHead(tikz::Arrow(i)); 0271 path->path()->style()->endConfig(); 0272 } 0273 #endif 0274 0275 // test example 0276 { 0277 beginTransaction("Create Diagram"); 0278 0279 tikz::ui::NodeItem *n1 = createNodeItem(); 0280 n1->node()->setPos(tikz::Pos(0, 6, tikz::Unit::Centimeter)); 0281 setProp(n1->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0282 setProp(n1->style()->uid(), "innerSep", 2.0_mm); 0283 setProp(n1->style()->uid(), "minimumWidth", 2.0_cm); 0284 setProp(n1->style()->uid(), "minimumHeight", 1.5_cm); 0285 setProp(n1->style()->uid(), "penColor", QColor(0, 0, 204)); 0286 setProp(n1->style()->uid(), "fillColor", QColor(204, 204, 255)); 0287 setProp(n1->node()->uid(), "text", "Kate Part\\\\(Backend library)"); 0288 0289 tikz::ui::NodeItem *n2 = createNodeItem(); 0290 n2->node()->setPos(tikz::Pos(0, 8, tikz::Unit::Centimeter)); 0291 setProp(n2->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0292 setProp(n2->style()->uid(), "innerSep", 2.0_mm); 0293 setProp(n2->style()->uid(), "minimumWidth", 2.0_cm); 0294 setProp(n2->style()->uid(), "minimumHeight", 1.5_cm); 0295 setProp(n2->style()->uid(), "penColor", QColor(255, 153, 51)); 0296 setProp(n2->style()->uid(), "fillColor", QColor(255, 230, 204)); 0297 setProp(n2->node()->uid(), "text", "KTextEditor\\\\(Interfaces)"); 0298 0299 tikz::ui::NodeItem *n3 = createNodeItem(); 0300 n3->node()->setPos(tikz::Pos(-5.8, 10, tikz::Unit::Centimeter)); 0301 setProp(n3->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0302 setProp(n3->style()->uid(), "innerSep", 2.0_mm); 0303 setProp(n3->style()->uid(), "minimumWidth", 2.5_cm); 0304 setProp(n3->style()->uid(), "minimumHeight", 1.5_cm); 0305 setProp(n3->style()->uid(), "penColor", QColor(255, 51, 51)); 0306 setProp(n3->style()->uid(), "fillColor", QColor(255, 204, 204)); 0307 setProp(n3->node()->uid(), "text", "Kate\\\\(Application)"); 0308 0309 tikz::ui::NodeItem *n4 = createNodeItem(); 0310 n4->node()->setPos(tikz::Pos(-2.9, 10, tikz::Unit::Centimeter)); 0311 setProp(n4->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0312 setProp(n4->style()->uid(), "innerSep", 2.0_mm); 0313 setProp(n4->style()->uid(), "minimumWidth", 2.5_cm); 0314 setProp(n4->style()->uid(), "minimumHeight", 1.5_cm); 0315 setProp(n4->style()->uid(), "penColor", QColor(255, 51, 51)); 0316 setProp(n4->style()->uid(), "fillColor", QColor(255, 204, 204)); 0317 setProp(n4->node()->uid(), "text", "KWrite\\\\(Application)"); 0318 0319 tikz::ui::NodeItem *n5 = createNodeItem(); 0320 n5->node()->setPos(tikz::Pos(0, 10, tikz::Unit::Centimeter)); 0321 setProp(n5->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0322 setProp(n5->style()->uid(), "innerSep", 2.0_mm); 0323 setProp(n5->style()->uid(), "minimumWidth", 2.5_cm); 0324 setProp(n5->style()->uid(), "minimumHeight", 1.5_cm); 0325 setProp(n5->style()->uid(), "penColor", QColor(255, 51, 51)); 0326 setProp(n5->style()->uid(), "fillColor", QColor(255, 204, 204)); 0327 setProp(n5->node()->uid(), "text", "KDevelop\\\\(Application)"); 0328 0329 tikz::ui::NodeItem *n6 = createNodeItem(); 0330 n6->node()->setPos(tikz::Pos(2.9, 10, tikz::Unit::Centimeter)); 0331 setProp(n6->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0332 setProp(n6->style()->uid(), "innerSep", 2.0_mm); 0333 setProp(n6->style()->uid(), "minimumWidth", 2.5_cm); 0334 setProp(n6->style()->uid(), "minimumHeight", 1.5_cm); 0335 setProp(n6->style()->uid(), "penColor", QColor(255, 51, 51)); 0336 setProp(n6->style()->uid(), "fillColor", QColor(255, 204, 204)); 0337 setProp(n6->node()->uid(), "text", "Kile\\\\(Application)"); 0338 0339 tikz::ui::NodeItem *n7 = createNodeItem(); 0340 n7->node()->setPos(tikz::Pos(5.8, 10, tikz::Unit::Centimeter)); 0341 setProp(n7->style()->uid(), "shape", QVariant::fromValue(tikz::Shape::ShapeRectangle)); 0342 setProp(n7->style()->uid(), "innerSep", 2.0_mm); 0343 setProp(n7->style()->uid(), "minimumWidth", 2.5_cm); 0344 setProp(n7->style()->uid(), "minimumHeight", 1.5_cm); 0345 setProp(n7->style()->uid(), "penColor", QColor(255, 51, 51)); 0346 setProp(n7->style()->uid(), "fillColor", QColor(255, 204, 204)); 0347 setProp(n7->node()->uid(), "text", "3rd party\\\\(Application)"); 0348 0349 // 0350 // paths 0351 // 0352 tikz::ui::PathItem* path = createPathItem(); 0353 auto edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0354 edge->setStartNode(n1->node()); 0355 edge->setEndNode(n2->node()); 0356 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0357 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0358 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0359 0360 path = createPathItem(); 0361 edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0362 edge->setStartNode(n2->node()); 0363 edge->setEndNode(n3->node()); 0364 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0365 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0366 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0367 edge->setStartAnchor("west"); 0368 0369 path = createPathItem(); 0370 edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0371 edge->setStartNode(n2->node()); 0372 edge->setEndNode(n4->node()); 0373 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0374 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0375 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0376 0377 path = createPathItem(); 0378 edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0379 edge->setStartNode(n2->node()); 0380 edge->setEndNode(n5->node()); 0381 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0382 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0383 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0384 0385 path = createPathItem(); 0386 edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0387 edge->setStartNode(n2->node()); 0388 edge->setEndNode(n6->node()); 0389 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0390 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0391 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0392 0393 path = createPathItem(); 0394 edge = qobject_cast<tikz::core::EdgePath*>(path->path()); 0395 edge->setStartNode(n2->node()); 0396 edge->setEndNode(n7->node()); 0397 setProp(edge->style()->uid(), "arrowTail", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0398 setProp(edge->style()->uid(), "arrowHead", QVariant::fromValue(tikz::Arrow::LatexArrow)); 0399 setProp(edge->style()->uid(), "penColor", QColor(128, 128, 128)); 0400 edge->setStartAnchor("east"); 0401 0402 finishTransaction(); 0403 } 0404 //END DEBUG 0405 0406 // return view 0407 return view; 0408 } 0409 0410 QVector<View *> DocumentPrivate::views() const 0411 { 0412 return m_views; 0413 } 0414 0415 void DocumentPrivate::registerView(tikz::ui::View * view) 0416 { 0417 Q_ASSERT(! m_views.contains(view)); 0418 m_views.append(view); 0419 } 0420 0421 void DocumentPrivate::unregisterView(tikz::ui::View * view) 0422 { 0423 Q_ASSERT(m_views.contains(view)); 0424 m_views.remove(m_views.indexOf(view)); 0425 } 0426 0427 QVector<NodeItem*> DocumentPrivate::nodeItems() const 0428 { 0429 return m_nodes; 0430 } 0431 0432 QVector<PathItem*> DocumentPrivate::pathItems() const 0433 { 0434 return m_paths; 0435 } 0436 0437 NodeItem * DocumentPrivate::createNodeItem() 0438 { 0439 // create node 0440 tikz::core::Node * node = qobject_cast<tikz::core::Node*>(Document::createNode()); 0441 Q_ASSERT(m_nodeMap.contains(node->uid())); 0442 0443 return m_nodeMap[node->uid()]; 0444 } 0445 0446 tikz::ui::PathItem * DocumentPrivate::createPathItem(tikz::PathType type) 0447 { 0448 // create path 0449 auto path = Document::createPath(); // FIXME: type 0450 Q_ASSERT(m_pathMap.contains(path->uid())); 0451 0452 return m_pathMap[path->uid()]; 0453 } 0454 0455 void DocumentPrivate::deleteNodeItem(NodeItem * node) 0456 { 0457 // delete node from id 0458 const auto uid = node->uid(); 0459 Q_ASSERT(m_nodeMap.contains(uid)); 0460 Document::deleteEntity(node->node()); 0461 Q_ASSERT(! m_nodeMap.contains(uid)); 0462 } 0463 0464 void DocumentPrivate::deletePathItem(tikz::ui::PathItem * path) 0465 { 0466 // delete path from id 0467 const auto uid = path->uid(); 0468 Q_ASSERT(m_pathMap.contains(uid)); 0469 Document::deleteEntity(path->path()); 0470 Q_ASSERT(! m_pathMap.contains(uid)); 0471 } 0472 0473 tikz::core::Entity * DocumentPrivate::createEntity(const tikz::core::Uid & uid, EntityType type) 0474 { 0475 // create entity by tikz::core::Document 0476 auto entity = Document::createEntity(uid, type); 0477 0478 switch (type) { 0479 case tikz::EntityType::Node: { 0480 auto node = qobject_cast<tikz::core::Node *>(entity); 0481 Q_ASSERT(uid == node->uid()); 0482 Q_ASSERT(! m_nodeMap.contains(uid)); 0483 0484 // create GUI item 0485 NodeItem * nodeItem = new NodeItem(node); 0486 m_nodes.append(nodeItem); 0487 m_nodeMap.insert(uid, nodeItem); 0488 0489 // add to graphics scene 0490 m_scene->addItem(nodeItem); 0491 0492 break; 0493 } 0494 case tikz::EntityType::Path: { 0495 auto path = qobject_cast<tikz::core::EdgePath *>(entity); 0496 Q_ASSERT(uid == path->uid()); 0497 Q_ASSERT(! m_pathMap.contains(uid)); 0498 0499 // create GUI item 0500 auto * pathItem = new tikz::ui::EdgePathItem(path); 0501 m_paths.append(pathItem); 0502 m_pathMap.insert(uid, pathItem); 0503 0504 // add to graphics scene 0505 m_scene->addItem(pathItem); 0506 0507 break; 0508 } 0509 case tikz::EntityType::Style: 0510 // nothing to do 0511 break; 0512 default: Q_ASSERT(false); 0513 } 0514 0515 return entity; 0516 } 0517 0518 void DocumentPrivate::deleteEntity(const tikz::core::Uid & uid) 0519 { 0520 switch (uid.entityType()) { 0521 case tikz::EntityType::Node: { 0522 Q_ASSERT(m_nodeMap.contains(uid)); 0523 0524 // get NodeItem 0525 NodeItem * nodeItem = m_nodeMap[uid]; 0526 0527 // remove from scene 0528 m_scene->removeItem(nodeItem); 0529 0530 const int index = m_nodes.indexOf(nodeItem); 0531 Q_ASSERT(index >= 0); 0532 0533 // delete item 0534 m_nodeMap.remove(uid); 0535 m_nodes.remove(index); 0536 delete nodeItem; 0537 break; 0538 } 0539 case tikz::EntityType::Path: { 0540 Q_ASSERT(m_pathMap.contains(uid)); 0541 0542 // get NodeItem 0543 PathItem * pathItem = m_pathMap[uid]; 0544 0545 // remove from scene 0546 m_scene->removeItem(pathItem); 0547 0548 const int index = m_paths.indexOf(pathItem); 0549 Q_ASSERT(index >= 0); 0550 0551 // delete item 0552 m_pathMap.remove(uid); 0553 m_paths.remove(index); 0554 delete pathItem; 0555 break; 0556 } 0557 case tikz::EntityType::Style: 0558 // nothing to do 0559 break; 0560 default: Q_ASSERT(false); 0561 } 0562 0563 tikz::core::Document::deleteEntity(uid); 0564 } 0565 0566 tikz::core::Path * DocumentPrivate::createPath(tikz::PathType type, const tikz::core::Uid & uid) 0567 { 0568 auto path = Document::createPath(type, uid); 0569 Q_ASSERT(uid == path->uid()); 0570 Q_ASSERT(! m_pathMap.contains(uid)); 0571 0572 // create GUI item 0573 tikz::ui::PathItem * pathItem = nullptr; 0574 switch (type) { 0575 case tikz::PathType::Line: { 0576 pathItem = new tikz::ui::EdgePathItem(path); 0577 break; 0578 } 0579 case tikz::PathType::HVLine: break; 0580 case tikz::PathType::VHLine: break; 0581 case tikz::PathType::BendCurve: break; 0582 case tikz::PathType::InOutCurve: break; 0583 case tikz::PathType::BezierCurve: break; 0584 case tikz::PathType::Ellipse: { 0585 pathItem = new tikz::ui::EllipsePathItem(path); 0586 break; 0587 } 0588 case tikz::PathType::Rectangle: break; 0589 case tikz::PathType::Grid: break; 0590 case tikz::PathType::Invalid: 0591 default: break; 0592 } 0593 0594 // we should always have a valid ui tikz path 0595 Q_ASSERT(pathItem); 0596 0597 // register path 0598 m_paths.append(pathItem); 0599 m_pathMap.insert(uid, pathItem); 0600 0601 // add to graphics scene 0602 m_scene->addItem(pathItem); 0603 0604 return path; 0605 } 0606 0607 NodeItem * DocumentPrivate::nodeItemFromId(const tikz::core::Uid & uid) const 0608 { 0609 if (! uid.isValid()) { 0610 return nullptr; 0611 } 0612 0613 Q_ASSERT(m_nodeMap.contains(uid)); 0614 return m_nodeMap[uid]; 0615 } 0616 0617 tikz::ui::PathItem * DocumentPrivate::pathItemFromId(const tikz::core::Uid & uid) const 0618 { 0619 if (! uid.isValid()) { 0620 return nullptr; 0621 } 0622 0623 Q_ASSERT(m_pathMap.contains(uid)); 0624 return m_pathMap[uid]; 0625 } 0626 0627 } 0628 } 0629 0630 // kate: indent-width 4; replace-tabs on;