]> git.sesse.net Git - kdenlive/blob - src/effectslist.cpp
First steps for the incredible filter region
[kdenlive] / src / effectslist.cpp
1 /***************************************************************************
2                           effectslist.cpp  -  description
3                              -------------------
4     begin                : Sat Aug 10 2002
5     copyright            : (C) 2002 by Jason Wood
6     email                : jasonwood@blueyonder.co.uk
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
19 #include "effectslist.h"
20
21 #include <KDebug>
22 #include <KLocale>
23
24
25 EffectsList::EffectsList(bool indexRequired) : m_useIndex(indexRequired)
26 {
27     m_baseElement = createElement("list");
28     appendChild(m_baseElement);
29 }
30
31 EffectsList::~EffectsList()
32 {
33 }
34
35 QDomElement EffectsList::getEffectByName(const QString & name) const
36 {
37     QString effectName;
38     QDomNodeList effects = m_baseElement.childNodes();
39     for (int i = 0; i < effects.count(); i++) {
40         QDomElement effect =  effects.at(i).toElement();
41         QDomElement namenode = effect.firstChildElement("name");
42         if (!namenode.isNull()) effectName = i18n(namenode.text().toUtf8().data());
43         if (name == effectName) {
44             QDomNodeList params = effect.elementsByTagName("parameter");
45             for (int i = 0; i < params.count(); i++) {
46                 QDomElement e = params.item(i).toElement();
47                 if (!e.hasAttribute("value"))
48                     e.setAttribute("value", e.attribute("default"));
49             }
50             return effect;
51         }
52     }
53
54     return QDomElement();
55 }
56
57 QDomElement EffectsList::getEffectByTag(const QString & tag, const QString & id) const
58 {
59     QDomNodeList effects = m_baseElement.childNodes();
60     for (int i = 0; i < effects.count(); i++) {
61         QDomElement effect =  effects.at(i).toElement();
62         if (!id.isEmpty()) {
63             if (effect.attribute("id") == id) {
64                 QDomNodeList params = effect.elementsByTagName("parameter");
65                 for (int i = 0; i < params.count(); i++) {
66                     QDomElement e = params.item(i).toElement();
67                     if (!e.hasAttribute("value"))
68                         e.setAttribute("value", e.attribute("default"));
69                 }
70                 return effect;
71             }
72         } else if (!tag.isEmpty()) {
73             if (effect.attribute("tag") == tag) {
74                 QDomNodeList params = effect.elementsByTagName("parameter");
75                 for (int i = 0; i < params.count(); i++) {
76                     QDomElement e = params.item(i).toElement();
77                     if (!e.hasAttribute("value"))
78                         e.setAttribute("value", e.attribute("default"));
79                 }
80                 return effect;
81             }
82         }
83     }
84     return QDomElement();
85 }
86
87 int EffectsList::hasEffect(const QString & tag, const QString & id) const
88 {
89     QDomNodeList effects = m_baseElement.childNodes();
90     for (int i = 0; i < effects.count(); i++) {
91         QDomElement effect =  effects.at(i).toElement();
92         if (!id.isEmpty()) {
93             if (effect.attribute("id") == id) return effect.attribute("kdenlive_ix").toInt();
94         } else if (!tag.isEmpty() && effect.attribute("tag") == tag) return effect.attribute("kdenlive_ix").toInt();
95     }
96     return -1;
97 }
98
99 QStringList EffectsList::effectIdInfo(const int ix) const
100 {
101     QStringList info;
102     QDomElement effect = m_baseElement.childNodes().at(ix).toElement();
103     if (effect.tagName() == "effectgroup") {
104         QString groupName = effect.attribute("name");
105         info << groupName << groupName << groupName << QString::number(Kdenlive::groupEffect);
106     }
107     else {
108         QDomElement namenode = effect.firstChildElement("name");
109         info << i18n(namenode.text().toUtf8().data()) << effect.attribute("tag") << effect.attribute("id");
110     }
111     return info;
112 }
113
114 QStringList EffectsList::effectNames()
115 {
116     QStringList list;
117     QDomNodeList effects = m_baseElement.childNodes();
118     for (int i = 0; i < effects.count(); i++) {
119         QDomElement effect =  effects.at(i).toElement();
120         QDomElement namenode = effect.firstChildElement("name");
121         if (!namenode.isNull()) list.append(i18n(namenode.text().toUtf8().data()));
122     }
123     return list;
124 }
125
126 QString EffectsList::getInfo(const QString & tag, const QString & id) const
127 {
128     QString info;
129     return getEffectInfo(getEffectByTag(tag, id));
130 }
131
132 QString EffectsList::getInfoFromIndex(const int ix) const
133 {
134     QString info;
135     return getEffectInfo(m_baseElement.childNodes().at(ix).toElement());
136 }
137
138 QString EffectsList::getEffectInfo(const QDomElement effect) const
139 {
140     QString info;
141     QDomElement namenode = effect.firstChildElement("description");
142     if (!namenode.isNull())
143         info = i18n(namenode.firstChild().nodeValue().simplified().toUtf8().data());
144
145     namenode = effect.firstChildElement("author");
146     if (!namenode.isNull())
147         info.append("<br /><strong>" + i18n("Author:") + " </strong>" + i18n(namenode.text().toUtf8().data()));
148
149     namenode = effect.firstChildElement("version");
150     if (!namenode.isNull())
151         info.append(QString(" (%1)").arg(namenode.text()));
152
153     return info;
154 }
155
156 // static
157 bool EffectsList::hasKeyFrames(QDomElement effect)
158 {
159     QDomNodeList params = effect.elementsByTagName("parameter");
160     for (int i = 0; i < params.count(); i++) {
161         QDomElement e = params.item(i).toElement();
162         if (e.attribute("type") == "keyframe") return true;
163     }
164     return false;
165 }
166
167 // static
168 bool EffectsList::hasSimpleKeyFrames(QDomElement effect)
169 {
170     QDomNodeList params = effect.elementsByTagName("parameter");
171     for (int i = 0; i < params.count(); i++) {
172         QDomElement e = params.item(i).toElement();
173         if (e.attribute("type") == "simplekeyframe") return true;
174     }
175     return false;
176 }
177
178 // static
179 bool EffectsList::hasGeometryKeyFrames(QDomElement effect)
180 {
181     QDomNodeList params = effect.elementsByTagName("parameter");
182     for (int i = 0; i < params.count(); ++i) {
183         QDomElement param = params.item(i).toElement();
184         if (param.attribute("type") == "geometry" && !param.hasAttribute("fixed"))
185             return true;
186     }
187     return false;
188 }
189
190 void EffectsList::clone(const EffectsList &original)
191 {
192     setContent(original.toString());
193     m_baseElement = documentElement();
194 }
195
196 void EffectsList::clearList()
197 {
198     while (!m_baseElement.firstChild().isNull())
199         m_baseElement.removeChild(m_baseElement.firstChild());
200 }
201
202 // static
203 void EffectsList::setParameter(QDomElement effect, const QString &name, const QString &value)
204 {
205     QDomNodeList params = effect.elementsByTagName("parameter");
206     bool found = false;
207     for (int i = 0; i < params.count(); i++) {
208         QDomElement e = params.item(i).toElement();
209         if (e.attribute("name") == name) {
210             e.setAttribute("value", value);
211             found = true;
212             break;
213         }
214     }
215     if (!found) {
216         // create property
217         QDomDocument doc = effect.ownerDocument();
218         QDomElement e = doc.createElement("parameter");
219         e.setAttribute("name", name);
220         QDomText val = doc.createTextNode(value);
221         e.appendChild(val);
222         effect.appendChild(e);
223     }
224 }
225
226 // static
227 QString EffectsList::parameter(QDomElement effect, const QString &name)
228 {
229     QDomNodeList params = effect.elementsByTagName("parameter");
230     for (int i = 0; i < params.count(); i++) {
231         QDomElement e = params.item(i).toElement();
232         if (e.attribute("name") == name) {
233             return e.attribute("value");
234         }
235     }
236     return QString();
237 }
238
239 // static
240 void EffectsList::setProperty(QDomElement effect, const QString &name, const QString &value)
241 {
242     QDomNodeList params = effect.elementsByTagName("property");
243     // Update property if it already exists
244     bool found = false;
245     for (int i = 0; i < params.count(); i++) {
246         QDomElement e = params.item(i).toElement();
247         if (e.attribute("name") == name) {
248             e.firstChild().setNodeValue(value);
249             found = true;
250             break;
251         }
252     }
253     if (!found) {
254         // create property
255         QDomDocument doc = effect.ownerDocument();
256         QDomElement e = doc.createElement("property");
257         e.setAttribute("name", name);
258         QDomText val = doc.createTextNode(value);
259         e.appendChild(val);
260         effect.appendChild(e);
261     }
262 }
263
264 // static
265 void EffectsList::renameProperty(QDomElement effect, const QString &oldName, const QString &newName)
266 {
267     QDomNodeList params = effect.elementsByTagName("property");
268     // Update property if it already exists
269     for (int i = 0; i < params.count(); i++) {
270         QDomElement e = params.item(i).toElement();
271         if (e.attribute("name") == oldName) {
272             e.setAttribute("name", newName);
273             break;
274         }
275     }
276 }
277
278 // static
279 QString EffectsList::property(QDomElement effect, const QString &name)
280 {
281     QDomNodeList params = effect.elementsByTagName("property");
282     for (int i = 0; i < params.count(); i++) {
283         QDomElement e = params.item(i).toElement();
284         if (e.attribute("name") == name) {
285             return e.firstChild().nodeValue();
286         }
287     }
288     return QString();
289 }
290
291 // static
292 void EffectsList::removeProperty(QDomElement effect, const QString &name)
293 {
294     QDomNodeList params = effect.elementsByTagName("property");
295     for (int i = 0; i < params.count(); i++) {
296         QDomElement e = params.item(i).toElement();
297         if (e.attribute("name") == name) {
298             effect.removeChild(params.item(i));
299             break;
300         }
301     }
302 }
303
304 // static
305 void EffectsList::removeMetaProperties(QDomElement producer)
306 {
307     QDomNodeList params = producer.elementsByTagName("property");
308     for (int i = 0; i < params.count(); i++) {
309         QDomElement e = params.item(i).toElement();
310         if (e.attribute("name").startsWith("meta")) {
311             producer.removeChild(params.item(i));
312             i--;
313         }
314     }
315 }
316
317 QDomElement EffectsList::append(QDomElement e)
318 {
319     QDomElement result;
320     if (!e.isNull()) {
321         result = m_baseElement.appendChild(importNode(e, true)).toElement();
322         if (m_useIndex) {
323             updateIndexes(m_baseElement.childNodes(), m_baseElement.childNodes().count() - 1);
324         }
325     }
326     return result;
327 }
328
329 int EffectsList::count() const
330 {
331     return m_baseElement.childNodes().count();
332 }
333
334 bool EffectsList::isEmpty() const
335 {
336     return !m_baseElement.hasChildNodes();
337 }
338
339 const QDomElement EffectsList::at(int ix) const
340 {
341     QDomNodeList effects = m_baseElement.childNodes();
342     if (ix < 0 || ix >= effects.count()) return QDomElement();
343     return effects.at(ix).toElement();
344 }
345
346 void EffectsList::removeAt(int ix)
347 {
348     QDomNodeList effects = m_baseElement.childNodes();
349     if (ix <= 0 || ix > effects.count()) return;
350     m_baseElement.removeChild(effects.at(ix - 1));
351     if (m_useIndex) updateIndexes(effects, ix - 1);
352 }
353
354 QDomElement EffectsList::itemFromIndex(int ix) const
355 {
356     QDomNodeList effects = m_baseElement.childNodes();
357     if (ix <= 0 || ix > effects.count()) return QDomElement();
358     return effects.at(ix - 1).toElement();
359 }
360
361 QDomElement EffectsList::insert(QDomElement effect)
362 {
363     QDomNodeList effects = m_baseElement.childNodes();
364     int ix = effect.attribute("kdenlive_ix").toInt();
365     QDomElement result;
366     if (ix <= 0 || ix > effects.count()) {
367         ix = effects.count();
368         result = m_baseElement.appendChild(importNode(effect, true)).toElement();
369     }
370     else {
371         QDomElement listeffect =  effects.at(ix - 1).toElement();
372         result = m_baseElement.insertBefore(importNode(effect, true), listeffect).toElement();
373     }
374     if (m_useIndex && ix > 0)
375         updateIndexes(effects, ix - 1);
376     return result;
377 }
378
379 void EffectsList::updateIndexes(QDomNodeList effects, int startIndex)
380 {
381     for (int i = startIndex; i < effects.count(); i++) {
382         QDomElement listeffect =  effects.at(i).toElement();
383         listeffect.setAttribute("kdenlive_ix", i + 1);
384     }
385 }
386
387 QDomElement EffectsList::effectFromIndex(QDomNodeList effects, int ix)
388 {
389     if (ix <= 0 || ix > effects.count()) return QDomElement();
390     return effects.at(ix - 1).toElement();
391 }
392
393 void EffectsList::updateEffect(QDomElement effect)
394 {
395     QDomNodeList effects = m_baseElement.childNodes();
396     int ix = effect.attribute("kdenlive_ix").toInt();
397     QDomElement current = effectFromIndex(effects, ix);
398     if (!current.isNull()) {
399         m_baseElement.insertBefore(importNode(effect, true), current);
400         m_baseElement.removeChild(current);
401     }
402     else m_baseElement.appendChild(importNode(effect, true));
403 }