]> git.sesse.net Git - kdenlive/blob - src/effectslist.cpp
Fix various effect dropping regressions
[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     QDomElement namenode = effect.firstChildElement("name");
104     info << i18n(namenode.text().toUtf8().data()) << effect.attribute("tag") << effect.attribute("id");
105     return info;
106 }
107
108 QStringList EffectsList::effectNames()
109 {
110     QStringList list;
111     QDomNodeList effects = m_baseElement.childNodes();
112     for (int i = 0; i < effects.count(); i++) {
113         QDomElement effect =  effects.at(i).toElement();
114         QDomElement namenode = effect.firstChildElement("name");
115         if (!namenode.isNull()) list.append(i18n(namenode.text().toUtf8().data()));
116     }
117     return list;
118 }
119
120 QString EffectsList::getInfo(const QString & tag, const QString & id) const
121 {
122     QString info;
123     return getEffectInfo(getEffectByTag(tag, id));
124 }
125
126 QString EffectsList::getInfoFromIndex(const int ix) const
127 {
128     QString info;
129     return getEffectInfo(m_baseElement.childNodes().at(ix).toElement());
130 }
131
132 QString EffectsList::getEffectInfo(const QDomElement effect) const
133 {
134     QString info;
135     QDomElement namenode = effect.firstChildElement("description");
136     if (!namenode.isNull())
137         info = i18n(namenode.firstChild().nodeValue().simplified().toUtf8().data());
138
139     namenode = effect.firstChildElement("author");
140     if (!namenode.isNull())
141         info.append("<br /><strong>" + i18n("Author:") + " </strong>" + i18n(namenode.text().toUtf8().data()));
142
143     namenode = effect.firstChildElement("version");
144     if (!namenode.isNull())
145         info.append(QString(" (%1)").arg(namenode.text()));
146
147     return info;
148 }
149
150 // static
151 bool EffectsList::hasKeyFrames(QDomElement effect)
152 {
153     QDomNodeList params = effect.elementsByTagName("parameter");
154     for (int i = 0; i < params.count(); i++) {
155         QDomElement e = params.item(i).toElement();
156         if (e.attribute("type") == "keyframe") return true;
157     }
158     return false;
159 }
160
161 // static
162 bool EffectsList::hasSimpleKeyFrames(QDomElement effect)
163 {
164     QDomNodeList params = effect.elementsByTagName("parameter");
165     for (int i = 0; i < params.count(); i++) {
166         QDomElement e = params.item(i).toElement();
167         if (e.attribute("type") == "simplekeyframe") return true;
168     }
169     return false;
170 }
171
172 // static
173 bool EffectsList::hasGeometryKeyFrames(QDomElement effect)
174 {
175     QDomNodeList params = effect.elementsByTagName("parameter");
176     for (int i = 0; i < params.count(); ++i) {
177         QDomElement param = params.item(i).toElement();
178         if (param.attribute("type") == "geometry" && !param.hasAttribute("fixed"))
179             return true;
180     }
181     return false;
182 }
183
184 void EffectsList::clone(const EffectsList &original)
185 {
186     setContent(original.toString());
187     m_baseElement = documentElement();
188 }
189
190 void EffectsList::clearList()
191 {
192     while (!m_baseElement.firstChild().isNull())
193         m_baseElement.removeChild(m_baseElement.firstChild());
194 }
195
196 // static
197 void EffectsList::setParameter(QDomElement effect, const QString &name, const QString &value)
198 {
199     QDomNodeList params = effect.elementsByTagName("parameter");
200     for (int i = 0; i < params.count(); i++) {
201         QDomElement e = params.item(i).toElement();
202         if (e.attribute("name") == name) {
203             e.setAttribute("value", value);
204             break;
205         }
206     }
207 }
208
209 // static
210 QString EffectsList::parameter(QDomElement effect, const QString &name)
211 {
212     QDomNodeList params = effect.elementsByTagName("parameter");
213     for (int i = 0; i < params.count(); i++) {
214         QDomElement e = params.item(i).toElement();
215         if (e.attribute("name") == name) {
216             return e.attribute("value");
217         }
218     }
219     return QString();
220 }
221
222 // static
223 void EffectsList::setProperty(QDomElement effect, const QString &name, const QString &value)
224 {
225     QDomNodeList params = effect.elementsByTagName("property");
226     // Update property if it already exists
227     bool found = false;
228     for (int i = 0; i < params.count(); i++) {
229         QDomElement e = params.item(i).toElement();
230         if (e.attribute("name") == name) {
231             e.firstChild().setNodeValue(value);
232             found = true;
233             break;
234         }
235     }
236     if (!found) {
237         // create property
238         QDomDocument doc = effect.ownerDocument();
239         QDomElement e = doc.createElement("property");
240         e.setAttribute("name", name);
241         QDomText val = doc.createTextNode(value);
242         e.appendChild(val);
243         effect.appendChild(e);
244     }
245 }
246
247 // static
248 void EffectsList::renameProperty(QDomElement effect, const QString &oldName, const QString &newName)
249 {
250     QDomNodeList params = effect.elementsByTagName("property");
251     // Update property if it already exists
252     for (int i = 0; i < params.count(); i++) {
253         QDomElement e = params.item(i).toElement();
254         if (e.attribute("name") == oldName) {
255             e.setAttribute("name", newName);
256             break;
257         }
258     }
259 }
260
261 // static
262 QString EffectsList::property(QDomElement effect, const QString &name)
263 {
264     QDomNodeList params = effect.elementsByTagName("property");
265     for (int i = 0; i < params.count(); i++) {
266         QDomElement e = params.item(i).toElement();
267         if (e.attribute("name") == name) {
268             return e.firstChild().nodeValue();
269         }
270     }
271     return QString();
272 }
273
274 // static
275 void EffectsList::removeProperty(QDomElement effect, const QString &name)
276 {
277     QDomNodeList params = effect.elementsByTagName("property");
278     for (int i = 0; i < params.count(); i++) {
279         QDomElement e = params.item(i).toElement();
280         if (e.attribute("name") == name) {
281             effect.removeChild(params.item(i));
282             break;
283         }
284     }
285 }
286
287 // static
288 void EffectsList::removeMetaProperties(QDomElement producer)
289 {
290     QDomNodeList params = producer.elementsByTagName("property");
291     for (int i = 0; i < params.count(); i++) {
292         QDomElement e = params.item(i).toElement();
293         if (e.attribute("name").startsWith("meta")) {
294             producer.removeChild(params.item(i));
295             i--;
296         }
297     }
298 }
299
300 QDomElement EffectsList::append(QDomElement e)
301 {
302     QDomElement result;
303     if (!e.isNull()) {
304         result = m_baseElement.appendChild(importNode(e, true)).toElement();
305         if (m_useIndex) {
306             updateIndexes(m_baseElement.childNodes());
307         }
308     }
309     return result;
310 }
311
312 int EffectsList::count() const
313 {
314     return m_baseElement.childNodes().count();
315 }
316
317 bool EffectsList::isEmpty() const
318 {
319     return !m_baseElement.hasChildNodes();
320 }
321
322 const QDomElement EffectsList::at(int ix) const
323 {
324     QDomNodeList effects = m_baseElement.childNodes();
325     if (ix < 0 || ix >= effects.count()) return QDomElement();
326     return effects.at(ix).toElement();
327 }
328
329 void EffectsList::removeAt(int ix)
330 {
331     QDomNodeList effects = m_baseElement.childNodes();
332     if (ix <= 0 || ix > effects.count()) return;
333     m_baseElement.removeChild(effects.at(ix - 1));
334     if (m_useIndex) updateIndexes(effects);
335 }
336
337 QDomElement EffectsList::itemFromIndex(int ix) const
338 {
339     QDomNodeList effects = m_baseElement.childNodes();
340     if (ix <= 0 || ix > effects.count()) return QDomElement();
341     return effects.at(ix - 1).toElement();
342 }
343
344 QDomElement EffectsList::insert(QDomElement effect)
345 {
346     QDomNodeList effects = m_baseElement.childNodes();
347     int ix = effect.attribute("kdenlive_ix").toInt();
348     QDomElement result;
349     if (effect.hasAttribute("kdenlive_ix") && ix > effects.count()) result = m_baseElement.appendChild(importNode(effect, true)).toElement();
350     else {
351         QDomElement listeffect =  effects.at(ix - 1).toElement();
352         result = m_baseElement.insertBefore(importNode(effect, true), listeffect).toElement();
353     }
354     if (m_useIndex) updateIndexes(effects);
355     return result;
356 }
357
358 void EffectsList::updateIndexes(QDomNodeList effects)
359 {
360     for (int i = 0; i < effects.count(); i++) {
361         QDomElement listeffect =  effects.at(i).toElement();
362         listeffect.setAttribute("kdenlive_ix", i + 1);
363     }
364 }
365
366 QDomElement EffectsList::effectFromIndex(QDomNodeList effects, int ix)
367 {
368     if (ix <= 0 || ix > effects.count()) return QDomElement();
369     return effects.at(ix - 1).toElement();
370 }
371
372 void EffectsList::updateEffect(QDomElement effect)
373 {
374     QDomNodeList effects = m_baseElement.childNodes();
375     int ix = effect.attribute("kdenlive_ix").toInt();
376     QDomElement current = effectFromIndex(effects, ix);
377     if (!current.isNull()) {
378         m_baseElement.insertBefore(importNode(effect, true), current);
379         m_baseElement.removeChild(current);
380     }
381     else m_baseElement.appendChild(importNode(effect, true));
382 }