initeffects.cpp 48.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/***************************************************************************
                          initeffects.cpp  -  description
                             -------------------
    begin                :  Jul 2006
    copyright            : (C) 2006 by Jean-Baptiste Mardelle
    email                : jb@ader.ch
    copyright            : (C) 2008 Marco Gittler
    email                : g.marco@freenet.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "initeffects.h"
21
22
#include "kdenlivesettings.h"
#include "effectslist.h"
23
#include "effectstackedit.h"
Marco Gittler's avatar
Marco Gittler committed
24
#include "mainwindow.h"
25

26
27
28
29
30
31
32
33
34
#include <KDebug>
#include <kglobal.h>
#include <KStandardDirs>

#include <QFile>
#include <qregexp.h>
#include <QDir>
#include <QIcon>

35
initEffectsThumbnailer::initEffectsThumbnailer() :
36
    QThread()
37
{
38
39
}

40
41
void initEffectsThumbnailer::prepareThumbnailsCall(const QStringList& list)
{
42
43
44
45
46
    m_list = list;
    start();
    kDebug() << "done";
}

47
48
void initEffectsThumbnailer::run()
{
49
    foreach(const QString & entry, m_list) {
50
51
52
53
54
55
56
57
58
59
60
61
62
        kDebug() << entry;
        if (!entry.isEmpty() && (entry.endsWith(".png") || entry.endsWith(".pgm"))) {
            if (!EffectStackEdit::iconCache.contains(entry)) {
                QImage pix(entry);
                //if (!pix.isNull())
                EffectStackEdit::iconCache[entry] = pix.scaled(30, 30);
                kDebug() << "stored";
            }
        }
    }
}

initEffectsThumbnailer initEffects::thumbnailer;
63

64
// static
65
66
void initEffects::refreshLumas()
{
67
68
69
    // Check for Kdenlive installed luma files, add empty string at start for no luma
    QStringList imagenamelist = QStringList() << i18n("None");
    QStringList imagefiles = QStringList() << QString();
70
71
72
73
    QStringList filters;
    filters << "*.pgm" << "*.png";

    QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
74
    foreach(const QString & folder, customLumas) {
75
        QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
76
        foreach(const QString & fname, filesnames) {
77
            imagenamelist.append(fname);
78
            imagefiles.append(KUrl(folder).path(KUrl::AddTrailingSlash) + fname);
79
80
81
82
        }
    }

    // Check for MLT lumas
Dan Dennedy's avatar
Dan Dennedy committed
83
84
85
86
    KUrl folder(mlt_environment("MLT_DATA"));
    folder.addPath("lumas");
    folder.addPath(mlt_environment("MLT_NORMALISATION"));
    QDir lumafolder(folder.path());
87
    QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
88
    foreach(const QString & fname, filesnames) {
89
        imagenamelist.append(fname);
Dan Dennedy's avatar
Dan Dennedy committed
90
91
92
        KUrl path(folder);
        path.addPath(fname);
        imagefiles.append(path.toLocalFile());
93
    }
94
    QDomElement lumaTransition = MainWindow::transitions.getEffectByTag("luma", "luma");
95
96
97
98
99
100
101
102
103
104
    QDomNodeList params = lumaTransition.elementsByTagName("parameter");
    for (int i = 0; i < params.count(); i++) {
        QDomElement e = params.item(i).toElement();
        if (e.attribute("tag") == "resource") {
            e.setAttribute("paramlistdisplay", imagenamelist.join(","));
            e.setAttribute("paramlist", imagefiles.join(","));
            break;
        }
    }

105
106
107
108
109
110
111
112
113
114
    QDomElement compositeTransition = MainWindow::transitions.getEffectByTag("composite", "composite");
    params = compositeTransition.elementsByTagName("parameter");
    for (int i = 0; i < params.count(); i++) {
        QDomElement e = params.item(i).toElement();
        if (e.attribute("tag") == "luma") {
            e.setAttribute("paramlistdisplay", imagenamelist.join(","));
            e.setAttribute("paramlist", imagefiles.join(","));
            break;
        }
    }
115
116
}

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// static
QDomDocument initEffects::getUsedCustomEffects(QMap <QString, QString> effectids)
{
    QMapIterator<QString, QString> i(effectids);
    int ix;
    QDomDocument doc;
    QDomElement list = doc.createElement("customeffects");
    doc.appendChild(list);
    while (i.hasNext()) {
        i.next();
        ix = MainWindow::customEffects.hasEffect(i.value(), i.key());
        if (ix > -1) {
            QDomElement e = MainWindow::customEffects.at(ix);
            list.appendChild(doc.importNode(e, true));
        }
    }
    return doc;
}

136
//static
137
138
Mlt::Repository *initEffects::parseEffectFiles()
{
139
140
141
142
143
144
    QStringList::Iterator more;
    QStringList::Iterator it;
    QStringList fileList;
    QString itemName;

    Mlt::Repository *repository = Mlt::Factory::init();
145
    if (!repository) {
146
        kDebug() << "Repository didn't finish initialisation" ;
147
        return NULL;
148
    }
149
150

    // Retrieve the list of MLT's available effects.
151
152
    Mlt::Properties *filters = repository->filters();
    QStringList filtersList;
153
    for (int i = 0; i < filters->count(); ++i)
154
        filtersList << filters->get_name(i);
155
    delete filters;
156

157
    // Retrieve the list of available producers.
158
159
    Mlt::Properties *producers = repository->producers();
    QStringList producersList;
160
    for (int i = 0; i < producers->count(); ++i)
161
        producersList << producers->get_name(i);
162
    KdenliveSettings::setProducerslist(producersList);
163
164
    delete producers;

165
    // Retrieve the list of available transitions.
166
167
    Mlt::Properties *transitions = repository->transitions();
    QStringList transitionsItemList;
168
    for (int i = 0; i < transitions->count(); ++i)
169
170
        transitionsItemList << transitions->get_name(i);
    delete transitions;
171

172
173
174
175
176
177
178
179
180
181
182
    // Remove blacklisted transitions from the list.
    QFile file(KStandardDirs::locate("appdata", "blacklisted_transitions.txt"));
    if (file.open(QIODevice::ReadOnly)) {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString black = in.readLine().simplified();
            if (!black.isEmpty() && !black.startsWith('#') &&
                    transitionsItemList.contains(black))
                transitionsItemList.removeAll(black);
        }
        file.close();
183
    }
184
185

    // Fill transitions list.
Marco Gittler's avatar
Marco Gittler committed
186
    fillTransitionsList(repository, &MainWindow::transitions, transitionsItemList);
187

188
189
    //WARNING: deprecated, we now use MLT to detect LADSPA filters
    /*
190
    // Set the directories to look into for ladspa plugins.
191
    KGlobal::dirs()->addResourceType("ladspa_plugin", 0, "lib/ladspa");
192
193
194
195
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/lib/ladspa");
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/local/lib/ladspa");
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/lib/ladspa");
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/local/lib/ladspa");
196
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/lib64/ladspa");
197
    KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/local/lib64/ladspa");*/
198

199
    // Set the directories to look into for effects.
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
200
    QStringList direc = KGlobal::dirs()->findDirs("appdata", "effects");
201

202
203
204
    // Iterate through effects directories to parse all XML files.
    for (more = direc.begin(); more != direc.end(); ++more) {
        QDir directory(*more);
205
206
        QStringList filter;
        filter << "*.xml";
207
        fileList = directory.entryList(filter, QDir::Files);
208
        for (it = fileList.begin(); it != fileList.end(); ++it) {
209
            itemName = KUrl(*more + *it).path();
210
211
212
            parseEffectFile(&MainWindow::customEffects,
                            &MainWindow::audioEffects,
                            &MainWindow::videoEffects,
213
                            itemName, filtersList, producersList, repository);
214
215
        }
    }
216

217
218
219
220
221
222
223
224
225
226
227
    // Remove blacklisted effects from the filters list.
    QFile file2(KStandardDirs::locate("appdata", "blacklisted_effects.txt"));
    if (file2.open(QIODevice::ReadOnly)) {
        QTextStream in(&file2);
        while (!in.atEnd()) {
            QString black = in.readLine().simplified();
            if (!black.isEmpty() && !black.startsWith('#') &&
                    filtersList.contains(black))
                filtersList.removeAll(black);
        }
        file2.close();
228
229
    }

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    /*
     * Cleanup the global lists. We use QMap because of its automatic sorting
     * (by key) and key uniqueness (using insert() instead of insertMulti()).
     * This introduces some more cycles (while removing them from other parts of
     * the code and centralising them), but due to the way this methods, QMap
     * and EffectsList are implemented, there's no easy way to make it
     * differently without reinplementing something (which should really be
     * done).
     */
    QDomElement effectInfo;
    QMap<QString, QDomElement> effectsMap;
    for (int i = 0; i < MainWindow::transitions.count(); ++i) {
        effectInfo = MainWindow::transitions.at(i);
        effectsMap.insert(effectInfo.elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), effectInfo);
    }
    MainWindow::transitions.clearList();
246
    foreach(const QDomElement & effect, effectsMap)
247
248
249
250
251
252
253
    MainWindow::transitions.append(effect);
    effectsMap.clear();
    for (int i = 0; i < MainWindow::customEffects.count(); ++i) {
        effectInfo = MainWindow::customEffects.at(i);
        effectsMap.insert(effectInfo.elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), effectInfo);
    }
    MainWindow::customEffects.clearList();
254
    foreach(const QDomElement & effect, effectsMap)
255
256
257
258
259
260
261
    MainWindow::customEffects.append(effect);
    effectsMap.clear();
    for (int i = 0; i < MainWindow::audioEffects.count(); ++i) {
        effectInfo = MainWindow::audioEffects.at(i);
        effectsMap.insert(effectInfo.elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), effectInfo);
    }
    MainWindow::audioEffects.clearList();
262
    foreach(const QDomElement & effect, effectsMap)
263
264
265
266
267
268
    MainWindow::audioEffects.append(effect);
    effectsMap.clear();
    for (int i = 0; i < MainWindow::videoEffects.count(); ++i) {
        effectInfo = MainWindow::videoEffects.at(i);
        effectsMap.insert(effectInfo.elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), effectInfo);
    }
269
    // Add remaining filters
270
    foreach(const QString & filtername, filtersList) {
271
272
        QDomDocument doc = createDescriptionFromMlt(repository, "filters", filtername);
        if (!doc.isNull())
273
            effectsMap.insert(doc.documentElement().elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), doc.documentElement());
274
    }
275
    MainWindow::videoEffects.clearList();
276
277
278
279
280
281
    foreach(const QDomElement & effect, effectsMap) {
        if (effect.attribute("type") == "audio")
            MainWindow::audioEffects.append(effect);
        else
            MainWindow::videoEffects.append(effect);
    }
282

283
284
285
286
    return repository;
}

// static
287
288
void initEffects::parseCustomEffectsFile()
{
289
    MainWindow::customEffects.clearList();
290
291
292
293
294
    /*
     * Why a QMap? See parseEffectFiles(). It's probably useless here, but we
     * cannot be sure about it.
     */
    QMap<QString, QDomElement> effectsMap;
295
    QString path = KStandardDirs::locateLocal("appdata", "effects/", true);
296
    QDir directory = QDir(path);
297
298
299
    QStringList filter;
    filter << "*.xml";
    const QStringList fileList = directory.entryList(filter, QDir::Files);
300
301
302
303
304
305
306
307
    /*
     * We need to declare these variables outside the foreach, or the QMap will
     * refer to non existing variables (QMap::insert() takes references as
     * parameters).
     */
    QDomDocument doc;
    QDomNodeList effects;
    QDomElement e;
308
    foreach(const QString & filename, fileList) {
309
        QString itemName = KUrl(path + filename).path();
310
311
312
        QFile file(itemName);
        doc.setContent(&file, false);
        file.close();
313
        effects = doc.elementsByTagName("effect");
314
        if (effects.count() != 1) {
315
            kDebug() << "More than one effect in file " << itemName << ", not supported yet";
316
        } else {
317
318
            e = effects.item(0).toElement();
            effectsMap.insert(e.elementsByTagName("name").item(0).toElement().text().toLower().toUtf8().data(), e);
319
320
        }
    }
321
322
    foreach(const QDomElement & effect, effectsMap)
    MainWindow::customEffects.append(effect);
323
324
325
}

// static
326
void initEffects::parseEffectFile(EffectsList *customEffectList, EffectsList *audioEffectList, EffectsList *videoEffectList, QString name, QStringList filtersList, QStringList producersList, Mlt::Repository *repository)
327
{
328
329
330
    QDomDocument doc;
    QFile file(name);
    doc.setContent(&file, false);
331
    file.close();
332
333
334
335
    QDomElement documentElement = doc.documentElement();
    QDomNodeList effects = doc.elementsByTagName("effect");

    if (effects.count() == 0) {
336
        kDebug() << "Effect broken: " << name;
337
        return;
338
339
    }

340
    for (int i = 0; !effects.item(i).isNull(); ++i) {
341
        documentElement = effects.item(i).toElement();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
342
        QString tag = documentElement.attribute("tag", QString());
343
344
345
346
347

        if (documentElement.hasAttribute("version")) {
            // a specific version of the filter is required
            Mlt::Properties *metadata = repository->metadata(filter_type, tag.toUtf8().data());
            if (metadata && metadata->is_valid()) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
348
                double version = metadata->get_double("version");
Till Theato's avatar
Till Theato committed
349
350
                if (documentElement.attribute("version").toDouble() > version) {
                    delete metadata;
351
                    return;
Till Theato's avatar
Till Theato committed
352
                }
353
354
355
356
            }
            delete metadata;
        }

357
358
        bool ladspaOk = true;
        if (tag == "ladspa") {
359
360
361
362
            //WARNING: old LADSPA xml effects are deprecated, so hide them
            /*QString library = documentElement.attribute("library", QString());
            if (KStandardDirs::locate("ladspa_plugin", library).isEmpty()) ladspaOk = false;*/
            ladspaOk = false;
363
364
        }

365
        // Parse effect information.
366
        if ((filtersList.contains(tag) || producersList.contains(tag)) && ladspaOk) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
367
            QString type = documentElement.attribute("type", QString());
368
369
370
371
372
373
            if (type == "audio")
                audioEffectList->append(documentElement);
            else if (type == "custom")
                customEffectList->append(documentElement);
            else
                videoEffectList->append(documentElement);
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
        }

        /*
             QDomNode n = documentElement.firstChild();
         QString id, effectName, effectTag, paramType;
         int paramCount = 0;
         EFFECTTYPE type;

                // Create Effect
                EffectParamDescFactory effectDescParamFactory;
                EffectDesc *effect = NULL;

         // parse effect file
         QDomNode namenode = documentElement.elementsByTagName("name").item(0);
         if (!namenode.isNull()) effectName = i18n(namenode.toElement().text());
         if (!groupName.isEmpty()) effectName.prepend("_" + groupName + "_");

         QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
         if (!propsnode.isNull()) {
             QDomElement propselement = propsnode.toElement();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
394
395
396
397
             id = propselement.attribute("id", QString());
             effectTag = propselement.attribute("tag", QString());
             if (propselement.attribute("type", QString()) == "audio") type = AUDIOEFFECT;
             else if (propselement.attribute("type", QString()) == "custom") type = CUSTOMEFFECT;
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
             else type = VIDEOEFFECT;
         }

         QString effectDescription;
         QDomNode descnode = documentElement.elementsByTagName("description").item(0);
         if (!descnode.isNull()) effectDescription = descnode.toElement().text() + "<br />";

         QString effectAuthor;
         QDomNode authnode = documentElement.elementsByTagName("author").item(0);
         if (!authnode.isNull()) effectAuthor = authnode.toElement().text() + "<br />";

         if (effectName.isEmpty() || id.isEmpty() || effectTag.isEmpty()) return;

         effect = new EffectDesc(effectName, id, effectTag, effectDescription, effectAuthor, type);

         QDomNodeList paramList = documentElement.elementsByTagName("parameter");
         if (paramList.count() == 0) {
             QDomElement fixed = doc.createElement("parameter");
             fixed.setAttribute("type", "fixed");
             effect->addParameter(effectDescParamFactory.createParameter(fixed));
         }
         else for (int i = 0; i < paramList.count(); i++) {
             QDomElement e = paramList.item(i).toElement();
             if (!e.isNull()) {
          paramCount++;
           QDomNamedNodeMap attrs = e.attributes();
          int i = 0;
          QString value;
          while (!attrs.item(i).isNull()) {
              QDomNode n = attrs.item(i);
              value = n.nodeValue();
              if (value.find("MAX_WIDTH") != -1)
           value.replace("MAX_WIDTH", QString::number(KdenliveSettings::defaultwidth()));
              if (value.find("MID_WIDTH") != -1)
           value.replace("MID_WIDTH", QString::number(KdenliveSettings::defaultwidth() / 2));
              if (value.find("MAX_HEIGHT") != -1)
           value.replace("MAX_HEIGHT", QString::number(KdenliveSettings::defaultheight()));
              if (value.find("MID_HEIGHT") != -1)
           value.replace("MID_HEIGHT", QString::number(KdenliveSettings::defaultheight() / 2));
              n.setNodeValue(value);
              i++;
          }
          effect->addParameter(effectDescParamFactory.createParameter(e));
             }
         }
                effectList->append(effect);
         }*/
445
446
447
    }
}

448
//static
449
450
const char* initEffects::ladspaEffectString(int ladspaId, QStringList params)
{
451
452
453
454
455
456
457
458
    if (ladspaId == 1433)  //Pitch
        return ladspaPitchEffectString(params);
    else if (ladspaId == 1216)  //Room Reverb
        return ladspaRoomReverbEffectString(params);
    else if (ladspaId == 1423)  //Reverb
        return ladspaReverbEffectString(params);
    else if (ladspaId == 1901)  //Reverb
        return ladspaEqualizerEffectString(params);
459
    else {
460
        kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
461
        return "<jackrack></jackrack>";
462
463
464
    }
}

465
//static
466
467
void initEffects::ladspaEffectFile(const QString & fname, int ladspaId, QStringList params)
{
468
    const char *filterString;
469
470
    switch (ladspaId) {
    case 1433: //Pitch
471
472
        filterString = ladspaPitchEffectString(params);
        break;
473
    case 1905: //Vinyl
474
475
        filterString = ladspaVinylEffectString(params);
        break;
476
    case 1216 : //Room Reverb
477
478
        filterString = ladspaRoomReverbEffectString(params);
        break;
479
    case 1423: //Reverb
480
481
        filterString = ladspaReverbEffectString(params);
        break;
482
    case 1195: //Declipper
483
484
        filterString = ladspaDeclipEffectString(params);
        break;
485
    case 1901:  //Reverb
486
487
        filterString = ladspaEqualizerEffectString(params);
        break;
488
    case 1913: // Limiter
489
490
        filterString = ladspaLimiterEffectString(params);
        break;
491
    case 1193: // Pitch Shifter
492
493
        filterString = ladspaPitchShifterEffectString(params);
        break;
494
    case 1417: // Rate Scaler
495
496
        filterString = ladspaRateScalerEffectString(params);
        break;
497
    case 1217: // Phaser
498
499
        filterString = ladspaPhaserEffectString(params);
        break;
500
501
502
    case 1197: // 15 Band Equalizer
        filterString = ladspaEqualizer15EffectString(params);
        break;
503
504
505
506
    default:
        kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
        return;
        break;
507
508
    }

509
510
511
512
513
514
    QFile f(fname);
    if (f.open(QIODevice::WriteOnly)) {
        QTextStream stream(&f);
        stream << filterString;
        f.close();
    } else kDebug() << "++++++++++  ERROR CANNOT WRITE TO: " << KdenliveSettings::currenttmpfolder() +  fname << endl;
515
    delete [] filterString;
516
517
}

518
const 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>";
519
520


521
522
const char* initEffects::ladspaDeclipEffectString(QStringList)
{
523
    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());
524
525
526
}

/*
527
const char* initEffects::ladspaVocoderEffectString(QStringList params)
528
{
529
 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]));
530
531
}*/

532
533
const char* initEffects::ladspaVinylEffectString(QStringList params)
{
534
    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());
535
536
}

537
538
const char* initEffects::ladspaPitchEffectString(QStringList params)
{
539
    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());
540
541
}

542
543
const char* initEffects::ladspaRoomReverbEffectString(QStringList params)
{
544
    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());
545
546
}

547
548
const char* initEffects::ladspaReverbEffectString(QStringList params)
{
549
    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());
550
551
}

552
553
const char* initEffects::ladspaEqualizerEffectString(QStringList params)
{
554
    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());
555
556
}

557
558
const char* initEffects::ladspaLimiterEffectString(QStringList params)
{
559
    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());
560
561
}

562
563
const char* initEffects::ladspaPitchShifterEffectString(QStringList params)
{
564
    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());
565
566
}

567
568
const char* initEffects::ladspaRateScalerEffectString(QStringList params)
{
569
    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());
570
571
}

572
573
const char* initEffects::ladspaPhaserEffectString(QStringList params)
{
574
    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());
575
}
576
577
578
579
const char* initEffects::ladspaEqualizer15EffectString(QStringList params)
{
    return qstrdup(QString(jackString + "1197</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><controlrow><lock>true</lock><value>%5</value><value>%5</value></controlrow><controlrow><lock>true</lock><value>%6</value><value>%6</value></controlrow><controlrow><lock>true</lock><value>%7</value><value>%7</value></controlrow><controlrow><lock>true</lock><value>%8</value><value>%8</value></controlrow><controlrow><lock>true</lock><value>%9</value><value>%9</value></controlrow><controlrow><lock>true</lock><value>%10</value><value>%10</value></controlrow><controlrow><lock>true</lock><value>%11</value><value>%11</value></controlrow><controlrow><lock>true</lock><value>%12</value><value>%12</value></controlrow><controlrow><lock>true</lock><value>%13</value><value>%13</value></controlrow><controlrow><lock>true</lock><value>%14</value><value>%14</value></controlrow><controlrow><lock>true</lock><value>%15</value><value>%15</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]).arg(params[4]).arg(params[5]).arg(params[6]).arg(params[7]).arg(params[8]).arg(params[9]).arg(params[10]).arg(params[11]).arg(params[12]).arg(params[13]).arg(params[14]).toUtf8());
}
580
581


582
583
QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository* repository, const QString& /*type*/, const QString& filtername)
{
584
585
586

    QDomDocument ret;
    Mlt::Properties *metadata = repository->metadata(filter_type, filtername.toAscii().data());
587
    //kDebug() << filtername;
588
589
590
    if (metadata && metadata->is_valid()) {
        if (metadata->get("title") && metadata->get("identifier")) {
            QDomElement eff = ret.createElement("effect");
591
592
593
            QString id = metadata->get("identifier");
            eff.setAttribute("tag", id);
            eff.setAttribute("id", id);
594
            //kDebug()<<"Effect: "<<id;
595
596
597
598
599
600
601
602
603
604
605
606
607
608

            QDomElement name = ret.createElement("name");
            name.appendChild(ret.createTextNode(metadata->get("title")));

            QDomElement desc = ret.createElement("description");
            desc.appendChild(ret.createTextNode(metadata->get("description")));

            QDomElement author = ret.createElement("author");
            author.appendChild(ret.createTextNode(metadata->get("creator")));

            eff.appendChild(name);
            eff.appendChild(author);
            eff.appendChild(desc);

609
610
611
612
613
            Mlt::Properties tags((mlt_properties) metadata->get_data("tags"));
            if (QString(tags.get(0)) == "Audio") eff.setAttribute("type", "audio");
            /*for (int i = 0; i < tags.count(); i++)
                kDebug()<<tags.get_name(i)<<"="<<tags.get(i);*/

614
            Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
Alberto Villa's avatar
Alberto Villa committed
615
            for (int j = 0; param_props.is_valid() && j < param_props.count(); j++) {
616
617
618
619
620
621
622
623
624
625
                QDomElement params = ret.createElement("parameter");

                Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(j)));

                params.setAttribute("name", paramdesc.get("identifier"));

                if (paramdesc.get("maximum")) params.setAttribute("max", paramdesc.get("maximum"));
                if (paramdesc.get("minimum")) params.setAttribute("min", paramdesc.get("minimum"));
                if (QString(paramdesc.get("type")) == "integer")
                    params.setAttribute("type", "constant");
626
627
                if (QString(paramdesc.get("type")) == "float") {
                    params.setAttribute("type", "constant");
628
629
                    // param type is float, set default decimals to 3
                    params.setAttribute("decimals", "3");
630
                }
631
632
                if (QString(paramdesc.get("type")) == "boolean")
                    params.setAttribute("type", "bool");
633
                if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) != "geometry") {
634
                    params.setAttribute("type", "geometry");
635
636
                    params.setAttribute("format", paramdesc.get("format"));
                }
637
638
639
640
                if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) == "geometry") {
                    params.setAttribute("type", "geometry");
                    //params.setAttribute("format", paramdesc.get("format"));
                }
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
                if (paramdesc.get("default")) params.setAttribute("default", paramdesc.get("default"));
                if (paramdesc.get("value")) {
                    params.setAttribute("value", paramdesc.get("value"));
                } else {
                    params.setAttribute("value", paramdesc.get("default"));
                }


                QDomElement pname = ret.createElement("name");
                pname.appendChild(ret.createTextNode(paramdesc.get("title")));
                params.appendChild(pname);

                eff.appendChild(params);
            }
            ret.appendChild(eff);
        }
    }
Ray Lehtiniemi's avatar
Ray Lehtiniemi committed
658
659
    delete metadata;
    metadata = 0;
660
661
662
663
    /* QString outstr;
     QTextStream str(&outstr);
     ret.save(str, 2);
     kDebug() << outstr;*/
664
    return ret;
665
}
666

667
void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *transitions, QStringList names)
668
{
669
    // Remove transitions that are not implemented.
670
    int pos = names.indexOf("mix");
671
672
    if (pos != -1)
        names.takeAt(pos);
673
674
675
676
677
678
679
680
681
682

    QStringList imagenamelist = QStringList() << i18n("None");
    QStringList imagefiles = QStringList() << QString();
    QStringList filters;
    filters << "*.pgm" << "*.png";
    QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
    foreach(QString folder, customLumas) {
        if (!folder.endsWith('/'))
            folder.append('/');
        QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
683
        foreach(const QString & fname, filesnames) {
684
685
686
687
688
689
690
691
692
693
694
            imagenamelist.append(fname);
            imagefiles.append(folder + fname);
        }
    }

    // Check for MLT luma files.
    KUrl folder(mlt_environment("MLT_DATA"));
    folder.addPath("lumas");
    folder.addPath(mlt_environment("MLT_NORMALISATION"));
    QDir lumafolder(folder.path());
    QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
695
    foreach(const QString & fname, filesnames) {
696
697
698
699
700
        imagenamelist.append(fname);
        KUrl path(folder);
        path.addPath(fname);
        imagefiles.append(path.toLocalFile());
    }
701

702
    foreach(const QString & name, names) {
703
        QDomDocument ret;
Marco Gittler's avatar
Marco Gittler committed
704
705
706
        QDomElement ktrans = ret.createElement("ktransition");
        ret.appendChild(ktrans);
        ktrans.setAttribute("tag", name);
707

708
        QDomElement tname = ret.createElement("name");
709
        QDomElement desc = ret.createElement("description");
710
711
712
        ktrans.appendChild(tname);
        ktrans.appendChild(desc);
        Mlt::Properties *metadata = repository->metadata(transition_type, name.toUtf8().data());
713
        if (metadata && metadata->is_valid()) {
714
715
716
            // If possible, set name and description.
            if (metadata->get("title") && metadata->get("identifier"))
                tname.appendChild(ret.createTextNode(metadata->get("title")));
717
718
            desc.appendChild(ret.createTextNode(metadata->get("description")));

719
            Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
720
            for (int i = 0; param_props.is_valid() && i < param_props.count(); ++i) {
721
722
                QDomElement params = ret.createElement("parameter");

723
                Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(i)));
724
725
726

                params.setAttribute("name", paramdesc.get("identifier"));

727
728
729
730
                if (paramdesc.get("maximum"))
                    params.setAttribute("max", paramdesc.get("maximum"));
                if (paramdesc.get("minimum"))
                    params.setAttribute("min", paramdesc.get("minimum"));
731
732
733
734
735
736
737
738
739
740
                if (QString(paramdesc.get("type")) == "integer") {
                    params.setAttribute("type", "constant");
                    params.setAttribute("factor", "100");
                }
                if (QString(paramdesc.get("type")) == "boolean")
                    params.setAttribute("type", "bool");
                if (!QString(paramdesc.get("format")).isEmpty()) {
                    params.setAttribute("type", "complex");
                    params.setAttribute("format", paramdesc.get("format"));
                }
741
742
743
                if (paramdesc.get("default"))
                    params.setAttribute("default", paramdesc.get("default"));
                if (paramdesc.get("value"))
744
                    params.setAttribute("value", paramdesc.get("value"));
745
                else
746
747
748
749
750
751
752
                    params.setAttribute("value", paramdesc.get("default"));

                QDomElement pname = ret.createElement("name");
                pname.appendChild(ret.createTextNode(paramdesc.get("title")));
                params.appendChild(pname);
                ktrans.appendChild(params);
            }
Ray Lehtiniemi's avatar
Ray Lehtiniemi committed
753
754
            delete metadata;
            metadata = 0;
755
        } else {
756
757
758
759
            /*
             * Check for Kdenlive installed luma files, add empty string at
             * start for no luma file.
             */
760

761
762
            // Implement default transitions.
            QList<QDomElement> paramList;
763
            if (name == "luma") {
764
                ktrans.setAttribute("id", name);
765
766
                tname.appendChild(ret.createTextNode(i18n("Wipe")));
                desc.appendChild(ret.createTextNode(i18n("Applies a stationary transition between the current and next frames.")));
767

768
                paramList.append(quickParameterFill(ret, i18n("Softness"), "softness", "double", "0", "0", "100", "", "", "100"));
Yuri Chornoivan's avatar
Yuri Chornoivan committed
769
                paramList.append(quickParameterFill(ret, i18nc("@property: means that the image is inverted", "Invert"), "invert", "bool", "0", "0", "1"));
770
771
                paramList.append(quickParameterFill(ret, i18n("Image File"), "resource", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
                paramList.append(quickParameterFill(ret, i18n("Reverse Transition"), "reverse", "bool", "0", "0", "1"));
Marco Gittler's avatar
Marco Gittler committed
772
                //thumbnailer.prepareThumbnailsCall(imagelist);
773
            } else if (name == "composite") {
774
775
776
777
                ktrans.setAttribute("id", name);
                tname.appendChild(ret.createTextNode(i18n("Composite")));
                desc.appendChild(ret.createTextNode(i18n("A key-framable alpha-channel compositor for two frames.")));
                paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry", "0%,0%:100%x100%:100", "-500;-500;-500;-500;0", "500;500;500;500;100"));
778
                paramList.append(quickParameterFill(ret, i18n("Alpha Channel Operation"), "operator", "list", "over", "", "", "over,and,or,xor", i18n("Over,And,Or,Xor")));
779
780
781
782
783
784
785
786
                paramList.append(quickParameterFill(ret, i18n("Align"), "aligned", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Fill"), "fill", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Distort"), "distort", "bool", "0", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Wipe File"), "luma", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
                paramList.append(quickParameterFill(ret, i18n("Wipe Softness"), "softness", "double", "0", "0", "100", "", "", "100"));
                paramList.append(quickParameterFill(ret, i18n("Wipe Invert"), "luma_invert", "bool", "0", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Force Progressive Rendering"), "progressive", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Force Deinterlace Overlay"), "deinterlace", "bool", "0", "0", "1"));
787
            } else if (name == "affine") {
788
                tname.appendChild(ret.createTextNode(i18n("Affine")));
789
790
                ret.documentElement().setAttribute("showrotation", "1");
                /*paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "double", "0", "0", "360"));
791
792
793
794
795
796
797
                paramList.append(quickParameterFill(ret, i18n("Rotate X"), "rotate_x", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Rotate Y"), "fix_rotate_y", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Rotate X"), "fix_rotate_x", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Rotate Z"), "fix_rotate_z", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Shear Y"), "shear_y", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Shear X"), "shear_x", "double", "0", "0", "360"));
798
799
800
801
802
803
804
805
806
807
808
809
810
811
                paramList.append(quickParameterFill(ret, i18n("Shear Z"), "shear_z", "double", "0", "0", "360"));*/
                /*paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), "fix_shear_y", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), "fix_shear_x", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), "fix_shear_z", "double", "0", "0", "360"));*/

                paramList.append(quickParameterFill(ret, "keyed", "keyed", "fixed", "1", "1", "1"));
                paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry",  "0,0,100%,100%,100%", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "", "", "", "", "", "true"));

                paramList.append(quickParameterFill(ret, i18n("Rotate X"), "rotate_x", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
                paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
                paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
                /*paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));
                paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));*/
                
812
813
814
815
816
                paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), "fix_shear_y", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), "fix_shear_x", "double", "0", "0", "360"));
                paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), "fix_shear_z", "double", "0", "0", "360"));
            } else if (name == "mix") {
                tname.appendChild(ret.createTextNode(i18n("Mix")));
817
            } else if (name == "region") {
818
                ktrans.setAttribute("id", name);
819
                tname.appendChild(ret.createTextNode(i18n("Region")));
820
821
822
                desc.appendChild(ret.createTextNode(i18n("Use alpha channel of another clip to create a transition.")));
                paramList.append(quickParameterFill(ret, i18n("Transparency clip"), "resource", "url", "", "", "", "", "", ""));
                paramList.append(quickParameterFill(ret, i18n("Geometry"), "composite.geometry", "geometry", "0%,0%:100%x100%:100", "-500;-500;-500;-500;0", "500;500;500;500;100"));
823
                paramList.append(quickParameterFill(ret, i18n("Alpha Channel Operation"), "composite.operator", "list", "over", "", "", "over,and,or,xor", i18n("Over,And,Or,Xor")));
824
825
826
827
828
829
830
831
                paramList.append(quickParameterFill(ret, i18n("Align"), "composite.aligned", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Fill"), "composite.fill", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Distort"), "composite.distort", "bool", "0", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Wipe File"), "composite.luma", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
                paramList.append(quickParameterFill(ret, i18n("Wipe Softness"), "composite.softness", "double", "0", "0", "100", "", "", "100"));
                paramList.append(quickParameterFill(ret, i18n("Wipe Invert"), "composite.luma_invert", "bool", "0", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Force Progressive Rendering"), "composite.progressive", "bool", "1", "0", "1"));
                paramList.append(quickParameterFill(ret, i18n("Force Deinterlace Overlay"), "composite.deinterlace", "bool", "0", "0", "1"));
832
            }
833
            foreach(const QDomElement & e, paramList)
834
835
836
            ktrans.appendChild(e);
        }

837
        // Add the transition to the global list.
Marco Gittler's avatar
Marco Gittler committed
838
        transitions->append(ret.documentElement());
839
        //kDebug() << ret.toString();
840
    }
841

842
    // Add some virtual transitions.
Yuri Chornoivan's avatar
Yuri Chornoivan committed
843
    QString slidetrans = "<ktransition tag=\"composite\" id=\"slide\"><name>" + i18n("Slide") + "</name><description>" + i18n("Slide image from one side to another.") + "</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name>                                               </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter><parameter tag=\"progressive\" default=\"1\" type=\"bool\" name=\"progressive\" ><name>" + i18n("Force Progressive Rendering") + "</name></parameter><parameter tag=\"deinterlace\" default=\"0\" type=\"bool\" name=\"deinterlace\" ><name>" + i18n("Force Deinterlace Overlay") + "</name></parameter><parameter tag=\"invert\" default=\"0\" type=\"bool\" name=\"invert\" ><name>" + i18nc("@property: means that the image is inverted", "Invert") + "</name></parameter></ktransition>";
844
    QDomDocument ret;
845
    ret.setContent(slidetrans);
846
    transitions->append(ret.documentElement());
847

848
849
850
    QString dissolve = "<ktransition tag=\"luma\" id=\"dissolve\"><name>" + i18n("Dissolve") + "</name><description>" + i18n("Fade out one video while fading in the other video.") + "</description><parameter tag=\"reverse\" default=\"0\" type=\"bool\" name=\"reverse\" ><name>" + i18n("Reverse") + "</name></parameter></ktransition>";
    ret.setContent(dissolve);
    transitions->append(ret.documentElement());
851

852
853
854
    /*QString alphatrans = "<ktransition tag=\"composite\" id=\"alphatransparency\" ><name>" + i18n("Alpha Transparency") + "</name><description>" + i18n("Make alpha channel transparent.") + "</description><parameter tag=\"geometry\" type=\"fixed\" default=\"0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name></parameter><parameter tag=\"fill\" default=\"0\" type=\"bool\" name=\"fill\" ><name>" + i18n("Rescale") + "</name></parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter></ktransition>";
    ret.setContent(alphatrans);
    transitions->append(ret.documentElement());*/
855
}
856

857
QDomElement initEffects::quickParameterFill(QDomDocument & doc, QString name, QString tag, QString type, QString def, QString min, QString max, QString list, QString listdisplaynames, QString factor, QString namedesc, QString format, QString opacity)
858
{
859
860
861
862
863
864
865
    QDomElement parameter = doc.createElement("parameter");
    parameter.setAttribute("tag", tag);
    parameter.setAttribute("default", def);
    parameter.setAttribute("type", type);
    parameter.setAttribute("name", tag);
    parameter.setAttribute("max", max);
    parameter.setAttribute("min", min);
866
867
    if (!list.isEmpty())
        parameter.setAttribute("paramlist", list);
868
869
    if (!listdisplaynames.isEmpty())
        parameter.setAttribute("paramlistdisplay", listdisplaynames);
870
871
    if (!factor.isEmpty())
        parameter.setAttribute("factor", factor);
872
873
874
875
    if (!namedesc.isEmpty())
        parameter.setAttribute("namedesc", namedesc);
    if (!format.isEmpty())
        parameter.setAttribute("format", format);
876
877
    if (!opacity.isEmpty())
        parameter.setAttribute("opacity", opacity);
878
879
880
881
882
883
    QDomElement pname = doc.createElement("name");
    pname.appendChild(doc.createTextNode(name));
    parameter.appendChild(pname);

    return parameter;
}