File indexing completed on 2024-05-12 04:35:03
0001 /* This file is part of the TikZKit project. 0002 * 0003 * Copyright (C) 2013-2018 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 "Node.h" 0021 #include "Style.h" 0022 #include "Document.h" 0023 #include "Visitor.h" 0024 #include "MetaPos.h" 0025 0026 #include "UndoSetNodePos.h" 0027 0028 #include <cmath> 0029 0030 #include <QUndoStack> 0031 #include <QDebug> 0032 0033 namespace tikz { 0034 namespace core { 0035 0036 class NodePrivate 0037 { 0038 public: 0039 NodePrivate(Document * doc) 0040 : pos(doc) 0041 {} 0042 0043 // node position 0044 MetaPos pos; 0045 0046 // node text 0047 QString text; 0048 0049 // this node's style 0050 Uid styleUid; 0051 Style * style = nullptr; 0052 }; 0053 0054 Node::Node(const Uid & uid) 0055 : Entity(uid) 0056 , d(new NodePrivate(uid.document())) 0057 { 0058 setStyle(Uid()); 0059 } 0060 0061 Node::~Node() 0062 { 0063 if (d->style) { 0064 delete d->style; 0065 d->style = nullptr; 0066 } 0067 delete d; 0068 } 0069 0070 tikz::EntityType Node::entityType() const 0071 { 0072 return EntityType::Node; 0073 } 0074 0075 bool Node::accept(Visitor & visitor) 0076 { 0077 visitor.visit(this); 0078 return true; 0079 } 0080 0081 void Node::loadData(const QJsonObject & json) 0082 { 0083 ConfigTransaction transaction(this); 0084 0085 if (json.contains("text")) { 0086 setText(json["text"].toString()); 0087 } 0088 0089 if (json.contains("pos")) { 0090 d->pos = MetaPos(json["pos"].toString(), document()); 0091 } 0092 0093 if (json.contains("style")) { 0094 const Uid styleId(json["style"].toString(), document()); 0095 setStyle(styleId); 0096 } 0097 } 0098 0099 QJsonObject Node::saveData() const 0100 { 0101 QJsonObject json = Entity::saveData(); 0102 0103 json["text"] = d->text; 0104 json["pos"] = d->pos.toString(); 0105 json["style"] = style()->uid().toString(); 0106 0107 return json; 0108 } 0109 0110 void Node::setPos(const tikz::Pos & pos) 0111 { 0112 auto newPos = metaPos(); 0113 newPos.setPos(pos); 0114 setMetaPos(newPos); 0115 0116 Q_ASSERT(d->pos.pos() == pos); 0117 } 0118 0119 tikz::Pos Node::pos() const 0120 { 0121 return d->pos.pos(); 0122 } 0123 0124 void Node::setMetaPos(const tikz::core::MetaPos & pos) 0125 { 0126 if (d->pos == pos) { 0127 return; 0128 } 0129 0130 if (document()->undoActive()) { 0131 ConfigTransaction transaction(this); 0132 d->pos = pos; 0133 } else { 0134 document()->addUndoItem(new UndoSetNodePos(this, pos, document())); 0135 } 0136 } 0137 0138 const tikz::core::MetaPos & Node::metaPos() const 0139 { 0140 return d->pos; 0141 } 0142 0143 void Node::setText(const QString& text) 0144 { 0145 // only continue when change is required 0146 if (d->text == text) { 0147 return; 0148 } 0149 0150 ConfigTransaction transaction(this); 0151 d->text = text; 0152 Q_EMIT textChanged(d->text); 0153 } 0154 0155 QString Node::text() const 0156 { 0157 return d->text; 0158 } 0159 0160 Style* Node::style() const 0161 { 0162 return d->styleUid.isValid() ? d->styleUid.entity<Style>() : d->style; 0163 } 0164 0165 Uid Node::styleUid() const 0166 { 0167 return d->styleUid; 0168 } 0169 0170 void Node::setStyle(const Uid & styleUid) 0171 { 0172 if (!d->styleUid.isValid()) { 0173 delete d->style; 0174 d->style = nullptr; 0175 } else { 0176 disconnect(d->styleUid.entity<Style>(), SIGNAL(changed()), this, SLOT(emitChangedIfNeeded())); 0177 } 0178 0179 if (styleUid.isValid()) { 0180 d->styleUid = styleUid; 0181 } else { 0182 d->style = new Style(); 0183 d->style->setParentStyle(document()->style()->uid()); 0184 } 0185 0186 connect(style(), SIGNAL(changed()), this, SLOT(emitChangedIfNeeded())); 0187 } 0188 0189 } 0190 } 0191 0192 // kate: indent-width 4; replace-tabs on;