1 /*
2 * Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "kis_dom_utils.h"
20
21 #include <QTransform>
22
23 #include "kis_debug.h"
24
25 namespace KisDomUtils {
26
saveValue(QDomElement * parent,const QString & tag,const QSize & size)27 void saveValue(QDomElement *parent, const QString &tag, const QSize &size)
28 {
29 QDomDocument doc = parent->ownerDocument();
30 QDomElement e = doc.createElement(tag);
31 parent->appendChild(e);
32
33 e.setAttribute("type", "size");
34
35 e.setAttribute("w", toString(size.width()));
36 e.setAttribute("h", toString(size.height()));
37 }
38
saveValue(QDomElement * parent,const QString & tag,const QRect & rc)39 void saveValue(QDomElement *parent, const QString &tag, const QRect &rc)
40 {
41 QDomDocument doc = parent->ownerDocument();
42 QDomElement e = doc.createElement(tag);
43 parent->appendChild(e);
44
45 e.setAttribute("type", "rect");
46
47 e.setAttribute("x", toString(rc.x()));
48 e.setAttribute("y", toString(rc.y()));
49 e.setAttribute("w", toString(rc.width()));
50 e.setAttribute("h", toString(rc.height()));
51 }
52
saveValue(QDomElement * parent,const QString & tag,const QRectF & rc)53 void saveValue(QDomElement *parent, const QString &tag, const QRectF &rc)
54 {
55 QDomDocument doc = parent->ownerDocument();
56 QDomElement e = doc.createElement(tag);
57 parent->appendChild(e);
58
59 e.setAttribute("type", "rectf");
60
61 e.setAttribute("x", toString(rc.x()));
62 e.setAttribute("y", toString(rc.y()));
63 e.setAttribute("w", toString(rc.width()));
64 e.setAttribute("h", toString(rc.height()));
65 }
66
saveValue(QDomElement * parent,const QString & tag,const QPoint & pt)67 void saveValue(QDomElement *parent, const QString &tag, const QPoint &pt)
68 {
69 QDomDocument doc = parent->ownerDocument();
70 QDomElement e = doc.createElement(tag);
71 parent->appendChild(e);
72
73 e.setAttribute("type", "point");
74
75 e.setAttribute("x", toString(pt.x()));
76 e.setAttribute("y", toString(pt.y()));
77 }
78
saveValue(QDomElement * parent,const QString & tag,const QPointF & pt)79 void saveValue(QDomElement *parent, const QString &tag, const QPointF &pt)
80 {
81 QDomDocument doc = parent->ownerDocument();
82 QDomElement e = doc.createElement(tag);
83 parent->appendChild(e);
84
85 e.setAttribute("type", "pointf");
86
87 e.setAttribute("x", toString(pt.x()));
88 e.setAttribute("y", toString(pt.y()));
89 }
90
saveValue(QDomElement * parent,const QString & tag,const QVector3D & pt)91 void saveValue(QDomElement *parent, const QString &tag, const QVector3D &pt)
92 {
93 QDomDocument doc = parent->ownerDocument();
94 QDomElement e = doc.createElement(tag);
95 parent->appendChild(e);
96
97 e.setAttribute("type", "vector3d");
98
99 e.setAttribute("x", toString(pt.x()));
100 e.setAttribute("y", toString(pt.y()));
101 e.setAttribute("z", toString(pt.z()));
102 }
103
saveValue(QDomElement * parent,const QString & tag,const QTransform & t)104 void saveValue(QDomElement *parent, const QString &tag, const QTransform &t)
105 {
106 QDomDocument doc = parent->ownerDocument();
107 QDomElement e = doc.createElement(tag);
108 parent->appendChild(e);
109
110 e.setAttribute("type", "transform");
111
112 e.setAttribute("m11", toString(t.m11()));
113 e.setAttribute("m12", toString(t.m12()));
114 e.setAttribute("m13", toString(t.m13()));
115
116 e.setAttribute("m21", toString(t.m21()));
117 e.setAttribute("m22", toString(t.m22()));
118 e.setAttribute("m23", toString(t.m23()));
119
120 e.setAttribute("m31", toString(t.m31()));
121 e.setAttribute("m32", toString(t.m32()));
122 e.setAttribute("m33", toString(t.m33()));
123 }
124
saveValue(QDomElement * parent,const QString & tag,const QColor & c)125 void saveValue(QDomElement *parent, const QString &tag, const QColor &c)
126 {
127 QDomDocument doc = parent->ownerDocument();
128 QDomElement e = doc.createElement(tag);
129 parent->appendChild(e);
130
131 e.setAttribute("type", "qcolor");
132 e.setAttribute("value", c.name(QColor::HexArgb));
133 }
134
findOnlyElement(const QDomElement & parent,const QString & tag,QDomElement * el,QStringList * errorMessages)135 bool findOnlyElement(const QDomElement &parent, const QString &tag, QDomElement *el, QStringList *errorMessages)
136 {
137 QDomNodeList list = parent.elementsByTagName(tag);
138 if (list.size() != 1 || !list.at(0).isElement()) {
139 QString msg = i18n("Could not find \"%1\" XML tag in \"%2\"", tag, parent.tagName());
140 if (errorMessages) {
141 *errorMessages << msg;
142 } else {
143 warnKrita << msg;
144 }
145
146 return false;
147 }
148
149 *el = list.at(0).toElement();
150 return true;
151 }
152
removeElements(QDomElement & parent,const QString & tag)153 bool removeElements(QDomElement &parent, const QString &tag) {
154 QDomNodeList list = parent.elementsByTagName(tag);
155 KIS_SAFE_ASSERT_RECOVER_NOOP(list.size() <= 1);
156
157 for (int i = 0; i < list.size(); i++) {
158 parent.removeChild(list.at(i));
159 }
160
161 return list.size() > 0;
162 }
163
164 namespace Private {
checkType(const QDomElement & e,const QString & expectedType)165 bool checkType(const QDomElement &e, const QString &expectedType)
166 {
167 QString type = e.attribute("type", "unknown-type");
168 if (type != expectedType) {
169 warnKrita << i18n("Error: incorrect type (%2) for value %1. Expected %3", e.tagName(), type, expectedType);
170 return false;
171 }
172
173 return true;
174 }
175 }
176
loadValue(const QDomElement & e,float * v)177 bool loadValue(const QDomElement &e, float *v)
178 {
179 if (!Private::checkType(e, "value")) return false;
180 *v = toDouble(e.attribute("value", "0"));
181 return true;
182 }
183
loadValue(const QDomElement & e,double * v)184 bool loadValue(const QDomElement &e, double *v)
185 {
186 if (!Private::checkType(e, "value")) return false;
187 *v = toDouble(e.attribute("value", "0"));
188 return true;
189 }
190
loadValue(const QDomElement & e,QSize * size)191 bool loadValue(const QDomElement &e, QSize *size)
192 {
193 if (!Private::checkType(e, "size")) return false;
194
195 size->setWidth(toInt(e.attribute("w", "0")));
196 size->setHeight(toInt(e.attribute("h", "0")));
197
198 return true;
199 }
200
loadValue(const QDomElement & e,QRect * rc)201 bool loadValue(const QDomElement &e, QRect *rc)
202 {
203 if (!Private::checkType(e, "rect")) return false;
204
205 rc->setX(toInt(e.attribute("x", "0")));
206 rc->setY(toInt(e.attribute("y", "0")));
207 rc->setWidth(toInt(e.attribute("w", "0")));
208 rc->setHeight(toInt(e.attribute("h", "0")));
209
210 return true;
211 }
212
loadValue(const QDomElement & e,QRectF * rc)213 bool loadValue(const QDomElement &e, QRectF *rc)
214 {
215 if (!Private::checkType(e, "rectf")) return false;
216
217 rc->setX(toInt(e.attribute("x", "0")));
218 rc->setY(toInt(e.attribute("y", "0")));
219 rc->setWidth(toInt(e.attribute("w", "0")));
220 rc->setHeight(toInt(e.attribute("h", "0")));
221
222 return true;
223 }
224
loadValue(const QDomElement & e,QPoint * pt)225 bool loadValue(const QDomElement &e, QPoint *pt)
226 {
227 if (!Private::checkType(e, "point")) return false;
228
229 pt->setX(toInt(e.attribute("x", "0")));
230 pt->setY(toInt(e.attribute("y", "0")));
231
232 return true;
233 }
234
loadValue(const QDomElement & e,QPointF * pt)235 bool loadValue(const QDomElement &e, QPointF *pt)
236 {
237 if (!Private::checkType(e, "pointf")) return false;
238
239 pt->setX(toDouble(e.attribute("x", "0")));
240 pt->setY(toDouble(e.attribute("y", "0")));
241
242 return true;
243 }
244
loadValue(const QDomElement & e,QVector3D * pt)245 bool loadValue(const QDomElement &e, QVector3D *pt)
246 {
247 if (!Private::checkType(e, "vector3d")) return false;
248
249 pt->setX(toDouble(e.attribute("x", "0")));
250 pt->setY(toDouble(e.attribute("y", "0")));
251 pt->setZ(toDouble(e.attribute("z", "0")));
252
253 return true;
254 }
255
loadValue(const QDomElement & e,QTransform * t)256 bool loadValue(const QDomElement &e, QTransform *t)
257 {
258 if (!Private::checkType(e, "transform")) return false;
259
260 qreal m11 = toDouble(e.attribute("m11", "1.0"));
261 qreal m12 = toDouble(e.attribute("m12", "0.0"));
262 qreal m13 = toDouble(e.attribute("m13", "0.0"));
263
264 qreal m21 = toDouble(e.attribute("m21", "0.0"));
265 qreal m22 = toDouble(e.attribute("m22", "1.0"));
266 qreal m23 = toDouble(e.attribute("m23", "0.0"));
267
268 qreal m31 = toDouble(e.attribute("m31", "0.0"));
269 qreal m32 = toDouble(e.attribute("m32", "0.0"));
270 qreal m33 = toDouble(e.attribute("m33", "1.0"));
271
272 t->setMatrix(
273 m11, m12, m13,
274 m21, m22, m23,
275 m31, m32, m33);
276
277 return true;
278 }
279
loadValue(const QDomElement & e,QString * value)280 bool loadValue(const QDomElement &e, QString *value)
281 {
282 if (!Private::checkType(e, "value")) return false;
283 *value = e.attribute("value", "no-value");
284 return true;
285 }
286
loadValue(const QDomElement & e,QColor * value)287 bool loadValue(const QDomElement &e, QColor *value)
288 {
289 if (!Private::checkType(e, "qcolor")) return false;
290 value->setNamedColor(e.attribute("value", "#FFFF0000"));
291 return true;
292 }
293
findElementByAttibute(QDomNode parent,const QString & tag,const QString & attribute,const QString & key)294 QDomElement findElementByAttibute(QDomNode parent,
295 const QString &tag,
296 const QString &attribute,
297 const QString &key)
298 {
299 QDomNode node = parent.firstChild();
300
301 while (!node.isNull()) {
302 QDomElement el = node.toElement();
303
304 if (!el.isNull() && el.tagName() == tag) {
305 QString value = el.attribute(attribute, "<undefined>");
306 if (value == key) return el;
307 }
308
309 node = node.nextSibling();
310 }
311
312 return QDomElement();
313 }
314
315
316 }
317