]> git.sesse.net Git - kdenlive/blob - src/titledocument.cpp
Reindent the codebase using 'linux' bracket placement.
[kdenlive] / src / titledocument.cpp
1 /***************************************************************************
2                           titledocument.h  -  description
3                              -------------------
4     begin                : Feb 28 2008
5     copyright            : (C) 2008 by Marco Gittler
6     email                : g.marco@freenet.de
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include "titledocument.h"
19
20 #include <KDebug>
21 #include <KTemporaryFile>
22 #include <kio/netaccess.h>
23
24 #include <QGraphicsScene>
25 #include <QDomElement>
26 #include <QGraphicsItem>
27 #include <QGraphicsRectItem>
28 #include <QGraphicsTextItem>
29 #include <QGraphicsSvgItem>
30 #include <QFontInfo>
31 #include <QFile>
32
33
34 TitleDocument::TitleDocument()
35 {
36     scene = NULL;
37 }
38
39 void TitleDocument::setScene(QGraphicsScene* _scene)
40 {
41     scene = _scene;
42 }
43
44 QDomDocument TitleDocument::xml(QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
45 {
46     QDomDocument doc;
47
48     QDomElement main = doc.createElement("kdenlivetitle");
49     doc.appendChild(main);
50
51     foreach(QGraphicsItem* item, scene->items()) {
52         QDomElement e = doc.createElement("item");
53         QDomElement content = doc.createElement("content");
54         QFont font;
55         QGraphicsTextItem *t;
56
57         switch (item->type()) {
58         case 7:
59             e.setAttribute("type", "QGraphicsPixmapItem");
60             content.setAttribute("url", item->data(Qt::UserRole).toString());
61             break;
62         case 13:
63             e.setAttribute("type", "QGraphicsSvgItem");
64             content.setAttribute("url", item->data(Qt::UserRole).toString());
65             break;
66         case 3:
67             e.setAttribute("type", "QGraphicsRectItem");
68             content.setAttribute("rect", rectFToString(((QGraphicsRectItem*)item)->rect()));
69             content.setAttribute("pencolor", colorToString(((QGraphicsRectItem*)item)->pen().color()));
70             content.setAttribute("penwidth", ((QGraphicsRectItem*)item)->pen().width());
71             content.setAttribute("brushcolor", colorToString(((QGraphicsRectItem*)item)->brush().color()));
72             break;
73         case 8:
74             e.setAttribute("type", "QGraphicsTextItem");
75             t = static_cast<QGraphicsTextItem *>(item);
76             // Don't save empty text nodes
77             if (t->toPlainText().simplified().isEmpty()) continue;
78             //content.appendChild(doc.createTextNode(((QGraphicsTextItem*)item)->toHtml()));
79             content.appendChild(doc.createTextNode(t->toPlainText()));
80             font = t->font();
81             content.setAttribute("font", font.family());
82             content.setAttribute("font-bold", font.bold());
83             content.setAttribute("font-pixel-size", font.pixelSize());
84             content.setAttribute("font-italic", font.italic());
85             content.setAttribute("font-underline", font.underline());
86             content.setAttribute("font-color", colorToString(t->defaultTextColor()));
87             break;
88         default:
89             continue;
90         }
91         QDomElement pos = doc.createElement("position");
92         pos.setAttribute("x", item->pos().x());
93         pos.setAttribute("y", item->pos().y());
94         QTransform transform = item->transform();
95         QDomElement tr = doc.createElement("transform");
96         tr.appendChild(doc.createTextNode(
97                            QString("%1,%2,%3,%4,%5,%6,%7,%8,%9").arg(
98                                transform.m11()).arg(transform.m12()).arg(transform.m13()).arg(transform.m21()).arg(transform.m22()).arg(transform.m23()).arg(transform.m31()).arg(transform.m32()).arg(transform.m33())
99                        )
100                       );
101         e.setAttribute("z-index", item->zValue());
102         pos.appendChild(tr);
103
104
105         e.appendChild(pos);
106         e.appendChild(content);
107         if (item->zValue() > -1100) main.appendChild(e);
108     }
109     if (startv && endv) {
110         QDomElement endp = doc.createElement("endviewport");
111         QDomElement startp = doc.createElement("startviewport");
112         endp.setAttribute("x", endv->pos().x());
113         endp.setAttribute("y", endv->pos().y());
114         endp.setAttribute("size", endv->sceneBoundingRect().width() / 2);
115
116         startp.setAttribute("x", startv->pos().x());
117         startp.setAttribute("y", startv->pos().y());
118         startp.setAttribute("size", startv->sceneBoundingRect().width() / 2);
119
120         startp.setAttribute("z-index", startv->zValue());
121         endp.setAttribute("z-index", endv->zValue());
122         main.appendChild(startp);
123         main.appendChild(endp);
124     }
125     QDomElement backgr = doc.createElement("background");
126     QColor color = getBackgroundColor();
127     backgr.setAttribute("color", colorToString(color));
128     main.appendChild(backgr);
129
130     return doc;
131 }
132
133 /** \brief Get the background color (incl. alpha) from the document, if possibly
134   * \returns The background color of the document, inclusive alpha. If none found, returns (0,0,0,0) */
135 QColor TitleDocument::getBackgroundColor()
136 {
137     QColor color(0, 0, 0, 0);
138     if (scene) {
139         QList<QGraphicsItem *> items = scene->items();
140         for (int i = 0; i < items.size(); i++) {
141             if (items.at(i)->zValue() == -1100) {
142                 color = ((QGraphicsRectItem *)items.at(i))->brush().color();
143                 return color;
144             }
145         }
146     }
147     return color;
148 }
149
150
151 bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
152 {
153     if (!scene)
154         return false;
155
156     QDomDocument doc = xml(startv, endv);
157     KTemporaryFile tmpfile;
158     if (!tmpfile.open()) {
159         kWarning() << "/////  CANNOT CREATE TMP FILE in: " << tmpfile.fileName();
160         return false;
161     }
162     QFile xmlf(tmpfile.fileName());
163     xmlf.open(QIODevice::WriteOnly);
164     xmlf.write(doc.toString().toUtf8());
165     if (xmlf.error() != QFile::NoError) {
166         xmlf.close();
167         return false;
168     }
169     xmlf.close();
170     return KIO::NetAccess::upload(tmpfile.fileName(), url, 0);
171 }
172
173 int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
174 {
175     QString tmpfile;
176     QDomDocument doc;
177     if (!scene)
178         return -1;
179
180     if (KIO::NetAccess::download(url, tmpfile, 0)) {
181         QFile file(tmpfile);
182         if (file.open(QIODevice::ReadOnly)) {
183             doc.setContent(&file, false);
184             file.close();
185         } else
186             return -1;
187         KIO::NetAccess::removeTempFile(tmpfile);
188         return loadFromXml(doc, startv, endv);
189     }
190     return -1;
191 }
192
193 int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsPolygonItem* /*startv*/, QGraphicsPolygonItem* /*endv*/)
194 {
195     QDomNodeList titles = doc.elementsByTagName("kdenlivetitle");
196     int maxZValue = 0;
197     if (titles.size()) {
198
199         QDomNodeList items = titles.item(0).childNodes();
200         for (int i = 0;i < items.count();i++) {
201             QGraphicsItem *gitem = NULL;
202             kDebug() << items.item(i).attributes().namedItem("type").nodeValue();
203             int zValue = items.item(i).attributes().namedItem("z-index").nodeValue().toInt();
204             if (zValue > -1000) {
205                 if (items.item(i).attributes().namedItem("type").nodeValue() == "QGraphicsTextItem") {
206                     QDomNamedNodeMap txtProperties = items.item(i).namedItem("content").attributes();
207                     QFont font(txtProperties.namedItem("font").nodeValue());
208                     font.setBold(txtProperties.namedItem("font-bold").nodeValue().toInt());
209                     font.setItalic(txtProperties.namedItem("font-italic").nodeValue().toInt());
210                     font.setUnderline(txtProperties.namedItem("font-underline").nodeValue().toInt());
211                     // Older Kdenlive version did not store pixel size but point size
212                     if (txtProperties.namedItem("font-pixel-size").isNull()) {
213                         QFont f2;
214                         f2.setPointSize(txtProperties.namedItem("font-size").nodeValue().toInt());
215                         font.setPixelSize(QFontInfo(f2).pixelSize());
216                     } else font.setPixelSize(txtProperties.namedItem("font-pixel-size").nodeValue().toInt());
217                     QColor col(stringToColor(txtProperties.namedItem("font-color").nodeValue()));
218                     QGraphicsTextItem *txt = scene->addText(items.item(i).namedItem("content").firstChild().nodeValue(), font);
219                     txt->setDefaultTextColor(col);
220                     txt->setTextInteractionFlags(Qt::NoTextInteraction);
221                     gitem = txt;
222                 } else if (items.item(i).attributes().namedItem("type").nodeValue() == "QGraphicsRectItem") {
223                     QString rect = items.item(i).namedItem("content").attributes().namedItem("rect").nodeValue();
224                     QString br_str = items.item(i).namedItem("content").attributes().namedItem("brushcolor").nodeValue();
225                     QString pen_str = items.item(i).namedItem("content").attributes().namedItem("pencolor").nodeValue();
226                     double penwidth = items.item(i).namedItem("content").attributes().namedItem("penwidth").nodeValue().toDouble();
227                     QGraphicsRectItem *rec = scene->addRect(stringToRect(rect), QPen(QBrush(stringToColor(pen_str)), penwidth), QBrush(stringToColor(br_str)));
228                     gitem = rec;
229                 } else if (items.item(i).attributes().namedItem("type").nodeValue() == "QGraphicsPixmapItem") {
230                     QString url = items.item(i).namedItem("content").attributes().namedItem("url").nodeValue();
231                     QPixmap pix(url);
232                     QGraphicsPixmapItem *rec = scene->addPixmap(pix);
233                     rec->setData(Qt::UserRole, url);
234                     gitem = rec;
235                 } else if (items.item(i).attributes().namedItem("type").nodeValue() == "QGraphicsSvgItem") {
236                     QString url = items.item(i).namedItem("content").attributes().namedItem("url").nodeValue();
237                     QGraphicsSvgItem *rec = new QGraphicsSvgItem(url);
238                     scene->addItem(rec);
239                     rec->setData(Qt::UserRole, url);
240                     gitem = rec;
241                 }
242             }
243             //pos and transform
244             if (gitem) {
245                 QPointF p(items.item(i).namedItem("position").attributes().namedItem("x").nodeValue().toDouble(),
246                           items.item(i).namedItem("position").attributes().namedItem("y").nodeValue().toDouble());
247                 gitem->setPos(p);
248                 gitem->setTransform(stringToTransform(items.item(i).namedItem("position").firstChild().firstChild().nodeValue()));
249                 int zValue = items.item(i).attributes().namedItem("z-index").nodeValue().toInt();
250                 if (zValue > maxZValue) maxZValue = zValue;
251                 gitem->setZValue(zValue);
252                 gitem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
253             }
254             if (items.item(i).nodeName() == "background") {
255                 kDebug() << items.item(i).attributes().namedItem("color").nodeValue();
256                 QColor color = QColor(stringToColor(items.item(i).attributes().namedItem("color").nodeValue()));
257                 //color.setAlpha(items.item(i).attributes().namedItem("alpha").nodeValue().toInt());
258                 QList<QGraphicsItem *> items = scene->items();
259                 for (int i = 0; i < items.size(); i++) {
260                     if (items.at(i)->zValue() == -1100) {
261                         ((QGraphicsRectItem *)items.at(i))->setBrush(QBrush(color));
262                         break;
263                     }
264                 }
265             } /*else if (items.item(i).nodeName() == "startviewport" && startv) {
266                     QPointF p(items.item(i).attributes().namedItem("x").nodeValue().toDouble(), items.item(i).attributes().namedItem("y").nodeValue().toDouble());
267                     double width = items.item(i).attributes().namedItem("size").nodeValue().toDouble();
268                     QRectF rect(-width, -width / aspect_ratio, width*2.0, width / aspect_ratio*2.0);
269                     kDebug() << width << rect;
270                     startv->setPolygon(rect);
271                     startv->setPos(p);
272                 } else if (items.item(i).nodeName() == "endviewport" && endv) {
273                     QPointF p(items.item(i).attributes().namedItem("x").nodeValue().toDouble(), items.item(i).attributes().namedItem("y").nodeValue().toDouble());
274                     double width = items.item(i).attributes().namedItem("size").nodeValue().toDouble();
275                     QRectF rect(-width, -width / aspect_ratio, width*2.0, width / aspect_ratio*2.0);
276                     kDebug() << width << rect;
277                     endv->setPolygon(rect);
278                     endv->setPos(p);
279                 }*/
280         }
281     }
282     return maxZValue;
283 }
284
285 QString TitleDocument::colorToString(const QColor& c)
286 {
287     QString ret = "%1,%2,%3,%4";
288     ret = ret.arg(c.red()).arg(c.green()).arg(c.blue()).arg(c.alpha());
289     return ret;
290 }
291
292 QString TitleDocument::rectFToString(const QRectF& c)
293 {
294     QString ret = "%1,%2,%3,%4";
295     ret = ret.arg(c.x()).arg(c.y()).arg(c.width()).arg(c.height());
296     return ret;
297 }
298
299 QRectF TitleDocument::stringToRect(const QString & s)
300 {
301
302     QStringList l = s.split(',');
303     if (l.size() < 4)
304         return QRectF();
305     return QRectF(l[0].toDouble(), l[1].toDouble(), l[2].toDouble(), l[3].toDouble());
306 }
307
308 QColor TitleDocument::stringToColor(const QString & s)
309 {
310     QStringList l = s.split(',');
311     if (l.size() < 4)
312         return QColor();
313     return QColor(l[0].toInt(), l[1].toInt(), l[2].toInt(), l[3].toInt());;
314 }
315 QTransform TitleDocument::stringToTransform(const QString& s)
316 {
317     QStringList l = s.split(',');
318     if (l.size() < 9)
319         return QTransform();
320     return QTransform(
321                l[0].toDouble(), l[1].toDouble(), l[2].toDouble(),
322                l[3].toDouble(), l[4].toDouble(), l[5].toDouble(),
323                l[6].toDouble(), l[7].toDouble(), l[8].toDouble()
324            );
325 }