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;