]> git.sesse.net Git - kdenlive/blob - src/initeffects.cpp
first po file
[kdenlive] / src / initeffects.cpp
1 /***************************************************************************
2                           initeffects.cpp  -  description
3                              -------------------
4     begin                :  Jul 2006
5     copyright            : (C) 2006 by Jean-Baptiste Mardelle
6     email                : jb@ader.ch
7     copyright            : (C) 2008 Marco Gittler
8     email                : g.marco@freenet.de
9  ***************************************************************************/
10
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19
20
21 #include <QFile>
22 #include <qregexp.h>
23 #include <QDir>
24
25 #include <KDebug>
26 #include <kglobal.h>
27 #include <KStandardDirs>
28
29 #include "initeffects.h"
30 #include "kdenlivesettings.h"
31 #include "effectslist.h"
32
33 initEffects::initEffects() {
34 }
35
36 initEffects::~initEffects() {
37 }
38
39 //static
40 Mlt::Repository *initEffects::parseEffectFiles(EffectsList *audioEffectList, EffectsList *videoEffectList, EffectsList* transitionsList) {
41     QStringList::Iterator more;
42     QStringList::Iterator it;
43     QStringList fileList;
44     QString itemName;
45
46
47     // Build effects. Retrieve the list of MLT's available effects first.
48     Mlt::Repository *repository = Mlt::Factory::init();
49     if (!repository) {
50         kDebug() << "Repository did not finish init " ;
51         return NULL;
52     }
53     Mlt::Properties *filters = repository->filters();
54     QStringList filtersList;
55
56     for (int i = 0 ; i < filters->count() ; i++) {
57         filtersList << filters->get_name(i);
58     }
59
60     // Build effects. check producers first.
61
62     Mlt::Properties *producers = repository->producers();
63     QStringList producersList;
64     for (int i = 0 ; i < producers->count() ; i++) {
65         producersList << producers->get_name(i);
66     }
67     delete filters;
68     delete producers;
69
70     Mlt::Properties *transitions = repository->transitions();
71     QStringList transitionsItemList;
72     for (int i = 0 ; i < transitions->count() ; i++) {
73         transitionsItemList << transitions->get_name(i);
74     }
75     delete transitions;
76     fillTransitionsList(repository, transitionsList, transitionsItemList);
77
78     KGlobal::dirs()->addResourceType("ladspa_plugin", 0, "lib/ladspa");
79     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/lib/ladspa");
80     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/local/lib/ladspa");
81     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/lib/ladspa");
82     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/local/lib/ladspa");
83
84     kDebug() << "//  INIT EFFECT SEARCH" << endl;
85
86     QStringList direc = KGlobal::dirs()->findDirs("data", "kdenlive/effects");
87
88     QDir directory;
89     for (more = direc.begin() ; more != direc.end() ; ++more) {
90         directory = QDir(*more);
91         fileList = directory.entryList(QDir::Files);
92         for (it = fileList.begin() ; it != fileList.end() ; ++it) {
93             itemName = KUrl(*more + *it).path();
94             parseEffectFile(audioEffectList, videoEffectList, itemName, filtersList, producersList);
95             // kDebug()<<"//  FOUND EFFECT FILE: "<<itemName<<endl;
96         }
97     }
98     foreach(QString filtername, filtersList) {
99         QDomDocument doc = createDescriptionFromMlt(repository, "filters", filtername);
100         if (!doc.isNull())
101             videoEffectList->append(doc.documentElement());
102     }
103     return repository;
104 }
105
106 // static
107 void initEffects::parseEffectFile(EffectsList *audioEffectList, EffectsList *videoEffectList, QString name, QStringList filtersList, QStringList producersList) {
108     QDomDocument doc;
109     QFile file(name);
110     doc.setContent(&file, false);
111     QDomElement documentElement = doc.documentElement();
112     QDomNodeList effects = doc.elementsByTagName("effect");
113
114     if (effects.count() == 0) {
115         kDebug() << "// EFFECT FILET: " << name << " IS BROKEN" << endl;
116         return;
117     }
118     QString groupName;
119     if (doc.elementsByTagName("effectgroup").item(0).toElement().tagName() == "effectgroup") {
120         groupName = documentElement.attribute("name", QString::null);
121     }
122
123     int i = 0;
124
125     while (!effects.item(i).isNull()) {
126         documentElement = effects.item(i).toElement();
127         QString tag = documentElement.attribute("tag", QString::null);
128         bool ladspaOk = true;
129         if (tag == "ladspa") {
130             QString library = documentElement.attribute("library", QString::null);
131             if (KStandardDirs::locate("ladspa_plugin", library).isEmpty()) ladspaOk = false;
132         }
133
134         // Parse effect file
135         if ((filtersList.contains(tag) || producersList.contains(tag)) && ladspaOk) {
136             bool isAudioEffect = false;
137             QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
138             if (!propsnode.isNull()) {
139                 QDomElement propselement = propsnode.toElement();
140 //     id = propselement.attribute("id", QString::null);
141 //     effectTag = propselement.attribute("tag", QString::null);
142                 if (propselement.attribute("type", QString::null) == "audio") isAudioEffect = true;
143                 //else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
144                 //else type = VIDEOEFFECT;
145             }
146             if (isAudioEffect) audioEffectList->append(documentElement);
147             else videoEffectList->append(documentElement);
148         }
149
150         /*
151              QDomNode n = documentElement.firstChild();
152          QString id, effectName, effectTag, paramType;
153          int paramCount = 0;
154          EFFECTTYPE type;
155
156                 // Create Effect
157                 EffectParamDescFactory effectDescParamFactory;
158                 EffectDesc *effect = NULL;
159
160          // parse effect file
161          QDomNode namenode = documentElement.elementsByTagName("name").item(0);
162          if (!namenode.isNull()) effectName = i18n(namenode.toElement().text());
163          if (!groupName.isEmpty()) effectName.prepend("_" + groupName + "_");
164
165          QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
166          if (!propsnode.isNull()) {
167              QDomElement propselement = propsnode.toElement();
168              id = propselement.attribute("id", QString::null);
169              effectTag = propselement.attribute("tag", QString::null);
170              if (propselement.attribute("type", QString::null) == "audio") type = AUDIOEFFECT;
171              else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
172              else type = VIDEOEFFECT;
173          }
174
175          QString effectDescription;
176          QDomNode descnode = documentElement.elementsByTagName("description").item(0);
177          if (!descnode.isNull()) effectDescription = descnode.toElement().text() + "<br />";
178
179          QString effectAuthor;
180          QDomNode authnode = documentElement.elementsByTagName("author").item(0);
181          if (!authnode.isNull()) effectAuthor = authnode.toElement().text() + "<br />";
182
183          if (effectName.isEmpty() || id.isEmpty() || effectTag.isEmpty()) return;
184
185          effect = new EffectDesc(effectName, id, effectTag, effectDescription, effectAuthor, type);
186
187          QDomNodeList paramList = documentElement.elementsByTagName("parameter");
188          if (paramList.count() == 0) {
189              QDomElement fixed = doc.createElement("parameter");
190              fixed.setAttribute("type", "fixed");
191              effect->addParameter(effectDescParamFactory.createParameter(fixed));
192          }
193          else for (int i = 0; i < paramList.count(); i++) {
194              QDomElement e = paramList.item(i).toElement();
195              if (!e.isNull()) {
196           paramCount++;
197            QDomNamedNodeMap attrs = e.attributes();
198           int i = 0;
199           QString value;
200           while (!attrs.item(i).isNull()) {
201               QDomNode n = attrs.item(i);
202               value = n.nodeValue();
203               if (value.find("MAX_WIDTH") != -1)
204            value.replace("MAX_WIDTH", QString::number(KdenliveSettings::defaultwidth()));
205               if (value.find("MID_WIDTH") != -1)
206            value.replace("MID_WIDTH", QString::number(KdenliveSettings::defaultwidth() / 2));
207               if (value.find("MAX_HEIGHT") != -1)
208            value.replace("MAX_HEIGHT", QString::number(KdenliveSettings::defaultheight()));
209               if (value.find("MID_HEIGHT") != -1)
210            value.replace("MID_HEIGHT", QString::number(KdenliveSettings::defaultheight() / 2));
211               n.setNodeValue(value);
212               i++;
213           }
214           effect->addParameter(effectDescParamFactory.createParameter(e));
215              }
216          }
217                 effectList->append(effect);
218          }*/
219         i++;
220     }
221 }
222
223 //static
224 char* initEffects::ladspaEffectString(int ladspaId, QStringList params) {
225     if (ladspaId == 1433)  //Pitch
226         return ladspaPitchEffectString(params);
227     else if (ladspaId == 1216)  //Room Reverb
228         return ladspaRoomReverbEffectString(params);
229     else if (ladspaId == 1423)  //Reverb
230         return ladspaReverbEffectString(params);
231     else if (ladspaId == 1901)  //Reverb
232         return ladspaEqualizerEffectString(params);
233     else {
234         kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
235         return("<jackrack></jackrack>");
236     }
237 }
238
239 //static
240 void initEffects::ladspaEffectFile(const QString & fname, int ladspaId, QStringList params) {
241     char *filterString;
242     switch (ladspaId) {
243     case 1433: //Pitch
244         filterString = ladspaPitchEffectString(params);
245         break;
246     case 1905: //Vinyl
247         filterString = ladspaVinylEffectString(params);
248         break;
249     case 1216 : //Room Reverb
250         filterString = ladspaRoomReverbEffectString(params);
251         break;
252     case 1423: //Reverb
253         filterString = ladspaReverbEffectString(params);
254         break;
255     case 1195: //Declipper
256         filterString = ladspaDeclipEffectString(params);
257         break;
258     case 1901:  //Reverb
259         filterString = ladspaEqualizerEffectString(params);
260         break;
261     case 1913: // Limiter
262         filterString = ladspaLimiterEffectString(params);
263         break;
264     case 1193: // Pitch Shifter
265         filterString = ladspaPitchShifterEffectString(params);
266         break;
267     case 1417: // Rate Scaler
268         filterString = ladspaRateScalerEffectString(params);
269         break;
270     case 1217: // Phaser
271         filterString = ladspaPhaserEffectString(params);
272         break;
273     default:
274         kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
275         return;
276         break;
277     }
278
279     QFile f(fname);
280     if (f.open(QIODevice::WriteOnly)) {
281         QTextStream stream(&f);
282         stream << filterString;
283         f.close();
284     } else kDebug() << "++++++++++  ERROR CANNOT WRITE TO: " << KdenliveSettings::currenttmpfolder() +  fname << endl;
285     delete filterString;
286 }
287
288 QString jackString = "<?xml version=\"1.0\"?><!DOCTYPE jackrack SYSTEM \"http://purge.bash.sh/~rah/jack_rack_1.2.dtd\"><jackrack><channels>2</channels><samplerate>48000</samplerate><plugin><id>";
289
290
291 char* initEffects::ladspaDeclipEffectString(QStringList) {
292     return qstrdup(QString(jackString + "1195</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall></plugin></jackrack>").toUtf8());
293 }
294
295 /*
296 char* initEffects::ladspaVocoderEffectString(QStringList params)
297 {
298  return qstrdup( QString(jackString + "1441</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>0.000000</value><value>0.000000</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]));
299 }*/
300
301 char* initEffects::ladspaVinylEffectString(QStringList params) {
302     return qstrdup(QString(jackString + "1905</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow><controlrow><value>%3</value></controlrow><controlrow><value>%4</value></controlrow><controlrow><value>%5</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]).arg(params[4]).toUtf8());
303 }
304
305 char* initEffects::ladspaPitchEffectString(QStringList params) {
306     return qstrdup(QString(jackString + "1433</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.0</value><value>1.0</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>4.000000</value><value>4.000000</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
307 }
308
309 char* initEffects::ladspaRoomReverbEffectString(QStringList params) {
310     return qstrdup(QString(jackString + "1216</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>0.750000</value><value>0.750000</value></controlrow><controlrow><lock>true</lock><value>-70.000000</value><value>-70.000000</value></controlrow><controlrow><lock>true</lock><value>0.000000</value><value>0.000000</value></controlrow><controlrow><lock>true</lock><value>-17.500000</value><value>-17.500000</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
311 }
312
313 char* initEffects::ladspaReverbEffectString(QStringList params) {
314     return qstrdup(QString(jackString + "1423</id><enabled>true</enabled>  <wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked>    <wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values>    <lockall>true</lockall><controlrow><lock>true</lock><value>%1</value>      <value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>0.250000</value><value>0.250000</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).toUtf8());
315 }
316
317 char* initEffects::ladspaEqualizerEffectString(QStringList params) {
318     return qstrdup(QString(jackString + "1901</id><enabled>true</enabled>    <wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked>    <wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow>    <controlrow><value>%3</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
319 }
320
321 char* initEffects::ladspaLimiterEffectString(QStringList params) {
322     return qstrdup(QString(jackString + "1913</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow><controlrow><value>%3</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
323 }
324
325 char* initEffects::ladspaPitchShifterEffectString(QStringList params) {
326     return qstrdup(QString(jackString + "1193</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
327 }
328
329 char* initEffects::ladspaRateScalerEffectString(QStringList params) {
330     return qstrdup(QString(jackString + "1417</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
331 }
332
333 char* initEffects::ladspaPhaserEffectString(QStringList params) {
334     return qstrdup(QString(jackString + "1217</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]).toUtf8());
335 }
336
337
338 QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository* repository, const QString& type, const QString& filtername) {
339
340     QDomDocument ret;
341     Mlt::Properties *metadata = repository->metadata(filter_type, filtername.toAscii().data());
342     //kDebug() << filtername;
343     if (metadata && metadata->is_valid()) {
344         if (metadata->get("title") && metadata->get("identifier")) {
345             QDomElement eff = ret.createElement("effect");
346             eff.setAttribute("tag", metadata->get("identifier"));
347
348             QDomElement name = ret.createElement("name");
349             name.appendChild(ret.createTextNode(metadata->get("title")));
350
351             QDomElement desc = ret.createElement("description");
352             desc.appendChild(ret.createTextNode(metadata->get("description")));
353
354             QDomElement author = ret.createElement("author");
355             author.appendChild(ret.createTextNode(metadata->get("creator")));
356
357             QDomElement prop = ret.createElement("properties");
358             prop.setAttribute("id", metadata->get("identifier"));
359             prop.setAttribute("tag", metadata->get("identifier"));
360             eff.appendChild(name);
361             eff.appendChild(author);
362             eff.appendChild(desc);
363             eff.appendChild(prop);
364
365             Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
366             for (int j = 0; param_props.is_valid() && j < param_props.count();j++) {
367                 QDomElement params = ret.createElement("parameter");
368
369                 Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(j)));
370
371                 params.setAttribute("name", paramdesc.get("identifier"));
372
373                 if (paramdesc.get("maximum")) params.setAttribute("max", paramdesc.get("maximum"));
374                 if (paramdesc.get("minimum")) params.setAttribute("min", paramdesc.get("minimum"));
375                 if (QString(paramdesc.get("type")) == "integer")
376                     params.setAttribute("type", "constant");
377                 if (QString(paramdesc.get("type")) == "boolean")
378                     params.setAttribute("type", "bool");
379                 if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) != "geometry") {
380                     params.setAttribute("type", "complex");
381                     params.setAttribute("format", paramdesc.get("format"));
382                 }
383                 if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) == "geometry") {
384                     params.setAttribute("type", "geometry");
385                     //params.setAttribute("format", paramdesc.get("format"));
386                 }
387                 if (paramdesc.get("default")) params.setAttribute("default", paramdesc.get("default"));
388                 if (paramdesc.get("value")) {
389                     params.setAttribute("value", paramdesc.get("value"));
390                 } else {
391                     params.setAttribute("value", paramdesc.get("default"));
392                 }
393
394
395                 QDomElement pname = ret.createElement("name");
396                 pname.appendChild(ret.createTextNode(paramdesc.get("title")));
397                 params.appendChild(pname);
398
399                 eff.appendChild(params);
400             }
401             ret.appendChild(eff);
402         }
403     }
404     /* QString outstr;
405      QTextStream str(&outstr);
406      ret.save(str, 2);
407      kDebug() << outstr;*/
408     return ret;
409 }
410
411 void initEffects::fillTransitionsList(Mlt::Repository * repository, EffectsList* transitions, QStringList names) {
412     foreach(QString name, names) {
413         QDomDocument ret;
414         QDomElement ktrans = ret.createElement("ktransition");
415         ret.appendChild(ktrans);
416         ktrans.setAttribute("tag", name);
417         QDomElement tname = ret.createElement("name");
418         QList<QDomElement> paramList;
419         Mlt::Properties *metadata = repository->metadata(transition_type, name.toAscii().data());
420         //kDebug() << filtername;
421         if (metadata && metadata->is_valid()) {
422             Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
423             for (int j = 0; param_props.is_valid() && j < param_props.count();j++) {
424                 QDomElement params = ret.createElement("parameter");
425
426                 Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(j)));
427
428                 params.setAttribute("name", paramdesc.get("identifier"));
429
430                 if (paramdesc.get("maximum")) params.setAttribute("max", paramdesc.get("maximum"));
431                 if (paramdesc.get("minimum")) params.setAttribute("min", paramdesc.get("minimum"));
432                 if (QString(paramdesc.get("type")) == "integer") {
433                     params.setAttribute("type", "constant");
434                     params.setAttribute("factor", "100");
435                 }
436                 if (QString(paramdesc.get("type")) == "boolean")
437                     params.setAttribute("type", "bool");
438                 if (!QString(paramdesc.get("format")).isEmpty()) {
439                     params.setAttribute("type", "complex");
440                     params.setAttribute("format", paramdesc.get("format"));
441
442                 }
443                 if (paramdesc.get("default")) params.setAttribute("default", paramdesc.get("default"));
444                 if (paramdesc.get("value")) {
445                     params.setAttribute("value", paramdesc.get("value"));
446                 } else {
447                     params.setAttribute("value", paramdesc.get("default"));
448                 }
449
450
451                 QDomElement pname = ret.createElement("name");
452                 pname.appendChild(ret.createTextNode(paramdesc.get("title")));
453                 params.appendChild(pname);
454
455                 ktrans.appendChild(params);
456             }
457
458             ret.appendChild(ktrans);
459             if (metadata->get("title") && metadata->get("identifier")) {
460                 ktrans.setAttribute("tag", name);
461                 QDomElement tname = ret.createElement("name");
462                 tname.appendChild(ret.createTextNode(metadata->get("title")));
463                 ktrans.appendChild(tname);
464             }
465
466             //kDebug() << ret.toString();
467         } else {
468
469
470             if (name == "luma") {
471
472                 tname.appendChild(ret.createTextNode("Luma"));
473
474                 QString path(mlt_environment("MLT_DATA"));
475                 path.append("/lumas/").append(mlt_environment("MLT_NORMALISATION"));
476                 Mlt::Properties entries;
477                 mlt_properties_dir_list(entries.get_properties(), path.toAscii().data(), "*.*", 1);
478                 kDebug() << path << entries.count();
479                 QString imagefiles;
480                 for (int i = 0;i < entries.count();i++) {
481                     //if (!imagefiles.isEmpty()) // add empty entry too
482                     imagefiles.append(",");
483                     imagefiles.append(entries.get(i));
484                 }
485                 paramList.append(quickParameterFill(ret, "Softness", "softness", "double", "0", "0", "100", "", "100"));
486                 paramList.append(quickParameterFill(ret, "Invert", "invert", "bool", "0", "0", "1"));
487                 paramList.append(quickParameterFill(ret, "ImageFile", "resource", "list", "", "", "", imagefiles));
488
489
490             } else if (name == "composite") {
491                 paramList.append(quickParameterFill(ret, "Geometry", "geometry", "geometry", "0%,0%:100%x100%", "0%,0%:100%x100%", "0%,0%:100%x100%"));
492                 tname.appendChild(ret.createTextNode("Composite"));
493
494                 QDomDocument ret1;
495                 QDomElement ktrans1 = ret1.createElement("ktransition");
496                 ret1.appendChild(ktrans1);
497                 ktrans1.setAttribute("tag", name);
498                 QDomElement tname1 = ret.createElement("name");
499                 tname1.appendChild(ret1.createTextNode("PIP"));
500
501             } else if (name == "mix") {
502                 tname.appendChild(ret.createTextNode("Mix"));
503             } else if (name == "affine") {
504                 tname.appendChild(ret.createTextNode("Affine"));
505                 paramList.append(quickParameterFill(ret, "Rotate Y", "rotate_y", "double", "0", "0", "360"));
506                 paramList.append(quickParameterFill(ret, "Rotate X", "rotate_x", "double", "0", "0", "360"));
507                 paramList.append(quickParameterFill(ret, "Rotate Z", "rotate_z", "double", "0", "0", "360"));
508                 paramList.append(quickParameterFill(ret, "Fix Rotate Y", "fix_rotate_y", "double", "0", "0", "360"));
509                 paramList.append(quickParameterFill(ret, "Fix Rotate X", "fix_rotate_x", "double", "0", "0", "360"));
510                 paramList.append(quickParameterFill(ret, "Fix Rotate Z", "fix_rotate_z", "double", "0", "0", "360"));
511                 paramList.append(quickParameterFill(ret, "Shear Y", "shear_y", "double", "0", "0", "360"));
512                 paramList.append(quickParameterFill(ret, "Shear X", "shear_x", "double", "0", "0", "360"));
513                 paramList.append(quickParameterFill(ret, "Shear Z", "shear_z", "double", "0", "0", "360"));
514                 paramList.append(quickParameterFill(ret, "Fix Shear Y", "fix_shear_y", "double", "0", "0", "360"));
515                 paramList.append(quickParameterFill(ret, "Fix Shear X", "fix_shear_x", "double", "0", "0", "360"));
516                 paramList.append(quickParameterFill(ret, "Fix Shear Z", "fix_shear_z", "double", "0", "0", "360"));
517                 paramList.append(quickParameterFill(ret, "Mirror", "mirror_off", "bool", "0", "0", "1"));
518                 paramList.append(quickParameterFill(ret, "Repeat", "repeat_off", "bool", "0", "0", "1"));
519                 paramList.append(quickParameterFill(ret, "Geometry", "geometry", "geometry", "0%,0%:100%x100%", "0%,0%:100%x100%", "0%,0%:100%x100%"));
520                 tname.appendChild(ret.createTextNode("Composite"));
521             } else if (name == "region") {
522                 tname.appendChild(ret.createTextNode("Region"));
523             }
524
525
526         }
527         paramList.append(quickParameterFill(ret, "Reverse Transition", "reverse", "bool", "1", "0", "1"));
528         ktrans.appendChild(tname);
529
530         foreach(QDomElement e, paramList) {
531             ktrans.appendChild(e);
532         }
533
534
535         transitions->append(ret.documentElement());
536         /*
537
538          <transition fill="1" in="11" a_track="1" out="73" mlt_service="luma" b_track="2" softness="0" resource="/home/marco/Projekte/kdenlive/install_cmake/share/apps/kdenlive/pgm/PAL/square2.pgm" />
539         */
540     }
541 }
542 QDomElement initEffects::quickParameterFill(QDomDocument & doc, QString name, QString tag, QString type, QString def, QString min, QString max, QString list, QString factor, QString namedesc, QString format) {
543     QDomElement parameter = doc.createElement("parameter");
544     parameter.setAttribute("tag", tag);
545     parameter.setAttribute("default", def);
546     parameter.setAttribute("type", type);
547     parameter.setAttribute("name", tag);
548     parameter.setAttribute("max", max);
549     parameter.setAttribute("min", min);
550     if (!list.isEmpty())
551         parameter.setAttribute("paramlist", list);
552     if (!factor.isEmpty())
553         parameter.setAttribute("factor", factor);
554     if (!namedesc.isEmpty())
555         parameter.setAttribute("namedesc", namedesc);
556     if (!format.isEmpty())
557         parameter.setAttribute("format", format);
558     QDomElement pname = doc.createElement("name");
559     pname.appendChild(doc.createTextNode(name));
560     parameter.appendChild(pname);
561
562     return parameter;
563 }