]> git.sesse.net Git - kdenlive/commitdiff
First steps for the incredible filter region
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 9 Apr 2012 21:56:27 +0000 (23:56 +0200)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 9 Apr 2012 21:56:27 +0000 (23:56 +0200)
14 files changed:
data/blacklisted_effects.txt
effects/CMakeLists.txt
effects/README
effects/region.xml [new file with mode: 0644]
src/customtrackview.cpp
src/customtrackview.h
src/effectslist.cpp
src/effectstack/collapsibleeffect.cpp
src/effectstack/collapsibleeffect.h
src/effectstack/effectstackview2.cpp
src/effectstack/effectstackview2.h
src/trackview.cpp
src/trackview.h
src/widgets/urlval_ui.ui

index 3b3d11d2c59e35e2149cb5d410fd1b41e5bdf1e6..c553ba9477aaa615123417e2ad6bdbb46ec3a3e5 100644 (file)
@@ -93,7 +93,7 @@ luma
 data_show
 gtkrescale
 watermark
-region
+#region
 resize
 resample
 mono
index 8aa6c04d59fe14b128e7febdba59e704aeeb0662..2fe9e11591f8e2e5a9c510b04151f6e40cb49176 100644 (file)
@@ -22,6 +22,7 @@ normalise.xml
 oldfilm.xml
 pan_zoom.xml
 obscure.xml
+region.xml
 rotation.xml
 rotation_keyframable.xml
 scratchlines.xml
index b19bba359646e952d539051ba95c7901ce468814..7cc34eb76d72f009dc6c06afec232c32b64ee00b 100644 (file)
@@ -49,6 +49,7 @@ The rest:
         - tag "name": visible name of the parameter (depending on the GUI this parameter uses)
         - tag "comment": (optional) description of the parameter (support HTML formatting) (not yet supported by all widgets)
         - attribute "name": MLT filter parameter name
+        - attribute "paramprefix": a string to be prepended to the parameter value before passing it to MLT
         - attribute "default": initial value, format depends on parameter type
         - attribute "type": widget (GUI) to use
             - "fixed":
diff --git a/effects/region.xml b/effects/region.xml
new file mode 100644 (file)
index 0000000..9f76c09
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE kpartgui>
+<effect tag="region" id="region">
+       <name>Regionalize</name>
+       <description>Apply sub-effects to a region defined by a clip's alpha channel</description>
+       <author>Charles Yates</author>
+       <parameter type="url" name="resource" default="">
+               <name>Url</name>
+       </parameter>
+       <parameter type="fixed" name="filter_only" min="1" max="1" default="1" />
+</effect>
index ace533d4eb30321c155a83f63d61f5ac457a6e09..4651997e78b6dd999c84f5562f3878cb4b0a0858 100644 (file)
@@ -6691,7 +6691,7 @@ EffectsParameterList CustomTrackView::getEffectArgs(const QDomElement &effect)
     EffectsParameterList parameters;
     QLocale locale;
     parameters.addParam("tag", effect.attribute("tag"));
-    if (effect.hasAttribute("region")) parameters.addParam("region", effect.attribute("region"));
+    //if (effect.hasAttribute("region")) parameters.addParam("region", effect.attribute("region"));
     parameters.addParam("kdenlive_ix", effect.attribute("kdenlive_ix"));
     parameters.addParam("kdenlive_info", effect.attribute("kdenlive_info"));
     parameters.addParam("id", effect.attribute("id"));
@@ -6699,16 +6699,37 @@ EffectsParameterList CustomTrackView::getEffectArgs(const QDomElement &effect)
     if (effect.hasAttribute("disable")) parameters.addParam("disable", effect.attribute("disable"));
     if (effect.hasAttribute("in")) parameters.addParam("in", effect.attribute("in"));
     if (effect.hasAttribute("out")) parameters.addParam("out", effect.attribute("out"));
+    if (effect.attribute("id") == "region") {
+       QDomNodeList subeffects = effect.elementsByTagName("effect");
+       for (int i = 0; i < subeffects.count(); i++) {
+           QDomElement subeffect = subeffects.at(i).toElement();
+           int subeffectix = subeffect.attribute("region_ix").toInt();
+           parameters.addParam(QString("filter%1").arg(subeffectix), subeffect.attribute("id"));
+           parameters.addParam(QString("filter%1.tag").arg(subeffectix), subeffect.attribute("tag"));
+           parameters.addParam(QString("filter%1.kdenlive_info").arg(subeffectix), subeffect.attribute("kdenlive_info"));
+           QDomNodeList subparams = subeffect.elementsByTagName("parameter");
+           adjustEffectParameters(parameters, subparams, QString("filter%1.").arg(subeffectix));
+       }
+    }
 
     QDomNodeList params = effect.elementsByTagName("parameter");
-    for (int i = 0; i < params.count(); i++) {
+    adjustEffectParameters(parameters, params);
+    
+    return parameters;
+}
+
+
+void CustomTrackView::adjustEffectParameters(EffectsParameterList &parameters, QDomNodeList params, const QString &prefix)
+{
+  QLocale locale;
+  for (int i = 0; i < params.count(); i++) {
         QDomElement e = params.item(i).toElement();
+       QString paramname = prefix + e.attribute("name");
         if (e.attribute("type") == "geometry" && !e.hasAttribute("fixed")) {
             // effects with geometry param need in / out synced with the clip, request it...
             parameters.addParam("_sync_in_out", "1");
         }
         if (e.attribute("type") == "simplekeyframe") {
-
             QStringList values = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
             double factor = e.attribute("factor", "1").toDouble();
             double offset = e.attribute("offset", "0").toDouble();
@@ -6718,7 +6739,7 @@ EffectsParameterList CustomTrackView::getEffectArgs(const QDomElement &effect)
                 values[j] = pos + "=" + locale.toString(val);
             }
             // kDebug() << "/ / / /SENDING KEYFR:" << values;
-            parameters.addParam(e.attribute("name"), values.join(";"));
+            parameters.addParam(paramname, values.join(";"));
             /*parameters.addParam(e.attribute("name"), e.attribute("keyframes").replace(":", "="));
             parameters.addParam("max", e.attribute("max"));
             parameters.addParam("min", e.attribute("min"));
@@ -6754,15 +6775,15 @@ EffectsParameterList CustomTrackView::getEffectArgs(const QDomElement &effect)
                     fact = e.attribute("factor", "1").toDouble();
                 }
                 double offset = e.attribute("offset", "0").toDouble();
-                parameters.addParam(e.attribute("name"), locale.toString((e.attribute("value").toDouble() - offset) / fact));
+                parameters.addParam(paramname, locale.toString((e.attribute("value").toDouble() - offset) / fact));
             } else {
-                parameters.addParam(e.attribute("name"), e.attribute("value"));
+                parameters.addParam(paramname, e.attribute("value"));
             }
         }
     }
-    return parameters;
 }
 
+
 void CustomTrackView::updateTrackNames(int track, bool added)
 {
     QList <TrackInfo> tracks = m_document->tracksList();
index f4175ab3f3d9ba96018652a7751ae63e4090ca96..e419dedfad0cca40a78e06156c4e94d83f9357ed 100644 (file)
@@ -445,6 +445,9 @@ private:
     
     /** @brief Prepare an add clip command for an effect */
     void processEffect(ClipItem *item, QDomElement effect, QUndoCommand *effectCommand);
+    
+    /** @brief Get effect parameters ready for MLT*/
+    void adjustEffectParameters(EffectsParameterList &parameters, QDomNodeList params, const QString &prefix = QString());
 
 private slots:
     void slotRefreshGuides();
index 407c51b858f50ba8d1da6d9a7d9c97702758d1a6..af064380b8658094ae91d9756f617254f0a2ad2e 100644 (file)
@@ -203,13 +203,24 @@ void EffectsList::clearList()
 void EffectsList::setParameter(QDomElement effect, const QString &name, const QString &value)
 {
     QDomNodeList params = effect.elementsByTagName("parameter");
+    bool found = false;
     for (int i = 0; i < params.count(); i++) {
         QDomElement e = params.item(i).toElement();
         if (e.attribute("name") == name) {
             e.setAttribute("value", value);
+           found = true;
             break;
         }
     }
+    if (!found) {
+       // create property
+       QDomDocument doc = effect.ownerDocument();
+       QDomElement e = doc.createElement("parameter");
+       e.setAttribute("name", name);
+       QDomText val = doc.createTextNode(value);
+       e.appendChild(val);
+       effect.appendChild(e);
+    }
 }
 
 // static
index 9f2af1f582e54db74ca74846cd2d5ec3f599d552..0bf2bb2e0bf6b4f961713714e7b4d349901e1523 100644 (file)
@@ -60,6 +60,7 @@
 #include <KUrlRequester>
 #include <KColorScheme>
 #include <KColorUtils>
+#include <KApplication>
 
 class Boolval: public QWidget, public Ui::Boolval_UI
 {
@@ -126,9 +127,14 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
         m_paramWidget(NULL),
         m_effect(effect),
         m_original_effect(original_effect),
-        m_lastEffect(lastEffect)
+        m_lastEffect(lastEffect),
+        m_regionEffect(false)
 {
     setupUi(this);
+    if (m_effect.attribute("tag") == "region") {
+       m_regionEffect = true;
+       decoframe->setObjectName("decoframegroup");
+    }
     filterWheelEvent = true;
     m_info.fromString(effect.attribute("kdenlive_info"));
     setFont(KGlobalSettings::smallestReadableFont());
@@ -151,12 +157,15 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
     //buttonShowComments->setIcon(KIcon("help-about"));
     //buttonShowComments->setToolTip(i18n("Show additional information for the parameters"));
     m_menu = new QMenu;
+    if (m_regionEffect) m_menu->addAction(KIcon("document-new"), i18n("Change Region"), this, SLOT(slotResetEffect()));
     m_menu->addAction(KIcon("view-refresh"), i18n("Reset Effect"), this, SLOT(slotResetEffect()));
     m_menu->addAction(KIcon("document-save"), i18n("Save Effect"), this, SLOT(slotSaveEffect()));
     
     QDomElement namenode = m_effect.firstChildElement("name");
     if (namenode.isNull()) return;
-    title->setText(i18n(namenode.text().toUtf8().data()));
+    QString effectname = i18n(namenode.text().toUtf8().data());
+    if (m_regionEffect) effectname.append(":" + KUrl(EffectsList::parameter(m_effect, "resource")).fileName());
+    title->setText(effectname);
     /*
      * Do not show icon, makes too much visual noise
     QString type = m_effect.attribute("type", QString());
@@ -167,7 +176,10 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
     else icon = KIcon("kdenlive-show-video");
     effecticon->setPixmap(icon.pixmap(16,16));*/
     
-    m_menu->addAction(KIcon("folder-new"), i18n("Create Group"), this, SLOT(slotCreateGroup()));
+    if (!m_regionEffect) {
+       m_menu->addAction(KIcon("folder-new"), i18n("Create Group"), this, SLOT(slotCreateGroup()));
+       m_menu->addAction(KIcon("folder-new"), i18n("Create Region"), this, SLOT(slotCreateRegion()));
+    }
     setupWidget(info, metaInfo);
     setAcceptDrops(true);
     menuButton->setIcon(KIcon("kdenlive-menu"));
@@ -256,6 +268,20 @@ void CollapsibleEffect::slotCreateGroup()
     emit createGroup(effectIndex());
 }
 
+void CollapsibleEffect::slotCreateRegion()
+{
+    QString allExtensions = ProjectList::getExtensions();
+    const QString dialogFilter = allExtensions + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files");
+    KFileDialog *d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, kapp->activeWindow());
+    d->setOperationMode(KFileDialog::Opening);
+    d->setMode(KFile::File);
+    if (d->exec() == QDialog::Accepted) {
+       KUrl url = d->selectedUrl();
+       if (!url.isEmpty()) emit createRegion(effectIndex(), url);
+    }
+    delete d;
+}
+
 void CollapsibleEffect::slotUnGroup()
 {
     emit unGroup(this);
@@ -487,6 +513,7 @@ void CollapsibleEffect::setupWidget(ItemInfo info, EffectMetaInfo *metaInfo)
     }
 
     if (m_effect.attribute("tag") == "region") {
+       m_regionEffect = true;
         QVBoxLayout *vbox = new QVBoxLayout(widgetFrame);
         vbox->setContentsMargins(0, 0, 0, 0);
         vbox->setSpacing(2);
@@ -494,10 +521,11 @@ void CollapsibleEffect::setupWidget(ItemInfo info, EffectMetaInfo *metaInfo)
         QDomNodeList origin_effects =  m_original_effect.elementsByTagName("effect");
         QWidget *container = new QWidget(widgetFrame);
         vbox->addWidget(container);
-        m_paramWidget = new ParameterContainer(m_effect.toElement(), info, metaInfo, container);
+       // m_paramWidget = new ParameterContainer(m_effect.toElement(), info, metaInfo, container);
         for (int i = 0; i < effects.count(); i++) {
             CollapsibleEffect *coll = new CollapsibleEffect(effects.at(i).toElement(), origin_effects.at(i).toElement(), info, metaInfo, container);
             m_subParamWidgets.append(coll);
+           connect(coll, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateRegionEffectParams(const QDomElement, const QDomElement, int)));
             //container = new QWidget(widgetFrame);
             vbox->addWidget(coll);
             //p = new ParameterContainer(effects.at(i).toElement(), info, isEffect, container);
@@ -545,6 +573,12 @@ void CollapsibleEffect::updateTimecodeFormat()
     }
 }
 
+void CollapsibleEffect::slotUpdateRegionEffectParams(const QDomElement /*old*/, const QDomElement /*e*/, int /*ix*/)
+{
+    kDebug()<<"// EMIT CHANGE SUBEFFECT.....:";
+    emit parameterChanged(m_original_effect, m_effect, effectIndex());
+}
+
 void CollapsibleEffect::slotSyncEffectsPos(int pos)
 {
     emit syncEffectsPos(pos);
index 530a53e56305a0bb29190558e93e2c7c56845758..07132f1a131ada748aa1f2f9bf7d878062169cbb 100644 (file)
@@ -160,7 +160,10 @@ private slots:
     void slotEffectDown();
     void slotSaveEffect();
     void slotCreateGroup();
+    void slotCreateRegion();
     void slotUnGroup();
+    /** @brief A sub effect parameter was changed */
+    void slotUpdateRegionEffectParams(const QDomElement /*old*/, const QDomElement /*e*/, int /*ix*/);
 
 private:
     ParameterContainer *m_paramWidget;
@@ -174,6 +177,8 @@ private:
     QMenu *m_menu;
     QPoint m_clickPoint;
     EffectInfo m_info;
+    /** @brief True if this is a region effect, which behaves in a special way, like a group. */
+    bool m_regionEffect;
     
 protected:
     virtual void mouseDoubleClickEvent ( QMouseEvent * event );
@@ -202,6 +207,7 @@ signals:
     void moveEffect(int current_pos, int new_pos, int groupIndex, QString groupName);
     void unGroup(CollapsibleEffect *);
     void addEffect(QDomElement e);
+    void createRegion(int, KUrl);
 };
 
 
index e5984ee0f253321ae2f4660672a4663f1a50274c..dc09c99ebb5ecea1bbbd320f14b382570fed742c 100644 (file)
@@ -172,8 +172,7 @@ void EffectStackView2::setupListView()
        EffectInfo effectInfo;
        effectInfo.fromString(d.attribute("kdenlive_info"));
        if (effectInfo.groupIndex >= 0) {
-           // effect is in a group
-           
+           // effect is in a group    
            for (int j = 0; j < vbox1->count(); j++) {
                CollapsibleGroup *eff = static_cast<CollapsibleGroup *>(vbox1->itemAt(j)->widget());
                if (eff->isGroup() &&  eff->groupIndex() == effectInfo.groupIndex) {
@@ -243,6 +242,7 @@ void EffectStackView2::setupListView()
        connect(currentEffect, SIGNAL(createGroup(int)), this , SLOT(slotCreateGroup(int)));
        connect(currentEffect, SIGNAL(moveEffect(int,int,int,QString)), this , SLOT(slotMoveEffect(int,int,int,QString)));
        connect(currentEffect, SIGNAL(addEffect(QDomElement)), this , SLOT(slotAddEffect(QDomElement)));
+       connect(currentEffect, SIGNAL(createRegion(int,KUrl)), this, SLOT(slotCreateRegion(int,KUrl)));
        
         //ui.title->setPixmap(icon.pixmap(QSize(12, 12)));
     }
@@ -625,6 +625,65 @@ void EffectStackView2::slotShowComments()
     emit showComments(m_ui.buttonShowComments->isChecked());
 }
 
+void EffectStackView2::slotCreateRegion(int ix, KUrl url)
+{
+    QDomElement oldeffect = m_currentEffectList.itemFromIndex(ix);
+    QDomElement neweffect = oldeffect.cloneNode().toElement();
+    QDomElement region = MainWindow::videoEffects.getEffectByTag("region", "region").cloneNode().toElement();
+    region.appendChild(region.ownerDocument().importNode(neweffect, true));
+    region.setAttribute("kdenlive_ix", ix);
+    EffectsList::setParameter(region, "resource", url.path());
+    if (m_effectMetaInfo.trackMode)
+        emit updateEffect(NULL, m_trackindex, oldeffect, region, ix,false);
+    else if (m_clipref) {
+        emit updateEffect(m_clipref, -1, oldeffect, region, ix, false);
+        // Make sure the changed effect is currently displayed
+        //slotSetCurrentEffect(ix);
+    }
+    // refresh effect stack
+    ItemInfo info;
+    bool isSelected = false;
+    if (m_effectMetaInfo.trackMode) { 
+       info.track = m_trackInfo.type;
+        info.cropDuration = GenTime(m_trackInfo.duration, KdenliveSettings::project_fps());
+        info.cropStart = GenTime(0);
+        info.startPos = GenTime(-1);
+        info.track = 0;
+    }
+    else {
+       info = m_clipref->info();
+    }
+    CollapsibleEffect *current = getEffectByIndex(ix);
+    m_effects.removeAll(current);
+    current->setEnabled(false);
+    m_currentEffectList.removeAt(ix);
+    m_currentEffectList.insert(region);
+    current->deleteLater();
+    CollapsibleEffect *currentEffect = new CollapsibleEffect(region, m_currentEffectList.itemFromIndex(ix), info, &m_effectMetaInfo, ix == m_currentEffectList.count() - 1, m_ui.container->widget());
+    connect(currentEffect, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement, int)));
+    if (m_effectMetaInfo.trackMode) {
+       isSelected = currentEffect->effectIndex() == 1;
+    }
+    else {
+       isSelected = currentEffect->effectIndex() == m_clipref->selectedEffectIndex();
+    }
+    if (isSelected) currentEffect->setActive(true);
+    m_effects.append(currentEffect);
+    // TODO: region in group?
+    //if (group) {
+    // group->addGroupEffect(currentEffect);
+    //} else {
+    QVBoxLayout *vbox = static_cast <QVBoxLayout *> (m_ui.container->widget()->layout());
+    vbox->insertWidget(ix, currentEffect);
+    //}
+
+    // Check drag & drop
+    currentEffect->installEventFilter( this );
+       
+    QTimer::singleShot(200, this, SLOT(slotCheckWheelEventFilter()));    
+    
+}
+
 void EffectStackView2::slotCreateGroup(int ix)
 {
     QDomElement oldeffect = m_currentEffectList.itemFromIndex(ix);
index 48fa4f42196f3685639aa85dd07688ca7d6411fb..1c4b5e680e83df2c72c572281ccdb474cf90fe14 100644 (file)
@@ -160,6 +160,9 @@ private slots:
     /** @brief Create a group containing effect with ix index. */
     void slotCreateGroup(int ix);
     
+    /** @brief Create a region effect with ix index. */
+    void slotCreateRegion(int ix, KUrl url);
+    
     /** @brief Move an effect into a group.
       ** @param ix the index of effect to move in stack layout
       ** @param group the effect on which the effect was dropped
index 5e5892314844569d1f6a06549d86d43c34d76e53..ea8802b0cf7f783b88c8e6d551278c61588321b4 100644 (file)
@@ -793,13 +793,7 @@ void TrackView::slotAddProjectEffects(QDomNodeList effects, QDomElement parentNo
         }
         //kDebug() << "+ + CLIP EFF FND: " << effecttag << ", " << effectid << ", " << effectindex;
         // get effect standard tags
-        QDomElement clipeffect = MainWindow::customEffects.getEffectByTag(QString(), effectid);
-        if (clipeffect.isNull()) {
-            clipeffect = MainWindow::videoEffects.getEffectByTag(effecttag, effectid);
-        }
-        if (clipeffect.isNull()) {
-            clipeffect = MainWindow::audioEffects.getEffectByTag(effecttag, effectid);
-        }
+        QDomElement clipeffect = getEffectByTag(effecttag, effectid);
         if (clipeffect.isNull()) {
             kDebug() << "///  WARNING, EFFECT: " << effecttag << ": " << effectid << " not found, removing it from project";
             m_documentErrors.append(i18n("Effect %1:%2 not found in MLT, it was removed from this project\n", effecttag, effectid));
@@ -899,50 +893,50 @@ void TrackView::slotAddProjectEffects(QDomNodeList effects, QDomElement parentNo
                     EffectsList::setParameter(currenteffect, "out",  effect.attribute("out"));
                 }
             }
-
+            
+            // Special case, region filter embeds other effects
+           bool regionFilter = effecttag == "region";
+           QMap <QString, QString> regionEffects;
+           
             // adjust effect parameters
             for (QDomNode n3 = effect.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
                 // parse effect parameters
                 QDomElement effectparam = n3.toElement();
                 QString paramname = effectparam.attribute("name");
                 QString paramvalue = effectparam.text();
-
-                // try to find this parameter in the effect xml
-                QDomElement e;
-                for (int k = 0; k < clipeffectparams.count(); k++) {
-                    e = clipeffectparams.item(k).toElement();
-                    if (!e.isNull() && e.tagName() == "parameter" && e.attribute("name") == paramname) {
-                        QString type = e.attribute("type");
-                        QString factor = e.attribute("factor", "1");
-                        double fact;
-                        if (factor.contains('%')) {
-                            fact = ProfilesDialog::getStringEval(m_doc->mltProfile(), factor);
-                        } else {
-                            fact = factor.toDouble();
-                        }
-                        double offset = e.attribute("offset", "0").toDouble();
-                        if (type == "simplekeyframe") {
-                            QStringList kfrs = paramvalue.split(";");
-                            for (int l = 0; l < kfrs.count(); l++) {
-                                QString fr = kfrs.at(l).section('=', 0, 0);
-                                double val = locale.toDouble(kfrs.at(l).section('=', 1, 1));
-                                //kfrs[l] = fr + ":" + locale.toString((int)(val * fact));
-                                kfrs[l] = fr + ":" + QString::number((int) (offset + val * fact));
-                            }
-                            e.setAttribute("keyframes", kfrs.join(";"));
-                        } else if (type == "double" || type == "constant") {
-                            bool ok;
-                            e.setAttribute("value", offset + locale.toDouble(paramvalue, &ok) * fact);
-                            if (!ok)
-                                e.setAttribute("value", paramvalue);
-                        } else {
-                            e.setAttribute("value", paramvalue);
-                        }
-                        break;
-                    }
-                }
+               
+               if (regionFilter && paramname.startsWith("filter")) {
+                   regionEffects.insert(paramname, paramvalue);
+                   continue;
+               }
+
+                // try to find this parameter in the effect xml and set its value
+                adjustparameterValue(clipeffectparams, paramname, paramvalue);
+                
             }
             
+            if (regionFilter && !regionEffects.isEmpty()) {
+               // insert region sub-effects
+               int i = 0;
+               while (regionEffects.contains(QString("filter%1").arg(i))) {
+                   QString filterid = regionEffects.value(QString("filter%1.kdenlive_id").arg(i));
+                   QString filtertag = regionEffects.value(QString("filter%1.tag").arg(i));
+                   QDomElement subclipeffect = getEffectByTag(filtertag, filterid).cloneNode().toElement();
+                   QDomNodeList subclipeffectparams = subclipeffect.childNodes();
+                   subclipeffect.setAttribute("region_ix", i);
+                   QMap<QString, QString>::const_iterator j = regionEffects.constBegin();
+                   while (j != regionEffects.constEnd()) {
+                       if (j.key().startsWith(QString("filter%1.").arg(i))) {
+                           QString pname = j.key().section('.', 1, -1);
+                           adjustparameterValue(subclipeffectparams, pname, j.value());
+                       }
+                       ++j;
+                   }
+                   currenteffect.appendChild(currenteffect.ownerDocument().importNode(subclipeffect, true));
+                   i++;
+               }
+           }
+            
             if (disableeffect) currenteffect.setAttribute("disable", "1");
             if (clip)
                 clip->addEffect(currenteffect, false);
@@ -953,6 +947,58 @@ void TrackView::slotAddProjectEffects(QDomNodeList effects, QDomElement parentNo
 }
 
 
+void TrackView::adjustparameterValue(QDomNodeList clipeffectparams, const QString &paramname, const QString &paramvalue)
+{
+    QDomElement e;
+    QLocale locale;
+    for (int k = 0; k < clipeffectparams.count(); k++) {
+       e = clipeffectparams.item(k).toElement();
+        if (!e.isNull() && e.tagName() == "parameter" && e.attribute("name") == paramname) {
+           QString type = e.attribute("type");
+            QString factor = e.attribute("factor", "1");
+            double fact;
+            if (factor.contains('%')) {
+               fact = ProfilesDialog::getStringEval(m_doc->mltProfile(), factor);
+            } else {
+               fact = factor.toDouble();
+            }
+            double offset = e.attribute("offset", "0").toDouble();
+            if (type == "simplekeyframe") {
+               QStringList kfrs = paramvalue.split(";");
+                for (int l = 0; l < kfrs.count(); l++) {
+                   QString fr = kfrs.at(l).section('=', 0, 0);
+                    double val = locale.toDouble(kfrs.at(l).section('=', 1, 1));
+                    //kfrs[l] = fr + ":" + locale.toString((int)(val * fact));
+                    kfrs[l] = fr + ":" + QString::number((int) (offset + val * fact));
+                }
+                e.setAttribute("keyframes", kfrs.join(";"));
+            } else if (type == "double" || type == "constant") {
+               bool ok;
+                e.setAttribute("value", offset + locale.toDouble(paramvalue, &ok) * fact);
+                if (!ok)
+                   e.setAttribute("value", paramvalue);
+            } else {
+               e.setAttribute("value", paramvalue);
+            }
+            break;
+        }
+    }  
+}
+
+
+QDomElement TrackView::getEffectByTag(const QString &effecttag, const QString &effectid)
+{
+    QDomElement clipeffect = MainWindow::customEffects.getEffectByTag(QString(), effectid);
+    if (clipeffect.isNull()) {
+       clipeffect = MainWindow::videoEffects.getEffectByTag(effecttag, effectid);
+    }
+    if (clipeffect.isNull()) {
+       clipeffect = MainWindow::audioEffects.getEffectByTag(effecttag, effectid);
+    }
+    return clipeffect;
+}
+
+
 DocClipBase *TrackView::getMissingProducer(const QString id) const
 {
     QDomElement missingXml;
index 8d3ff11d5991db3692834b7cfc1a1d6d90ef45ea..c5992e98b25be755a27e883b742d2c6dad6d43ec 100644 (file)
@@ -112,6 +112,12 @@ private:
     void adjustTrackHeaders();
     /** @brief Add effects from the xml. Returns true if some effect was upgraded, false if everything went fine.*/
     void slotAddProjectEffects(QDomNodeList effects, QDomElement parentNode, ClipItem *clip, int trackIndex);
+    
+    /** @brief Returns a kdenlive effect xml description from an effect tag / id */
+    QDomElement getEffectByTag(const QString &effecttag, const QString &effectid);
+    
+    /** @brief Adjust kdenlive effect xml parameters to the MLT value*/
+    void adjustparameterValue(QDomNodeList clipeffectparams, const QString &paramname, const QString &paramvalue);
 
 private slots:
     void setCursorPos(int pos);
index 32445baea2d5644b27f9f2a4a4b86240956966e6..68901f492597624e5ca9d19b8a67fcaa218475c2 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>194</width>
-    <height>42</height>
+    <width>159</width>
+    <height>23</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <property name="margin">
     <number>0</number>
    </property>
-   <item row="0" column="0" colspan="2">
+   <item row="1" column="1">
+    <widget class="KUrlRequester" name="urlwidget"/>
+   </item>
+   <item row="1" column="0">
     <widget class="QLabel" name="label">
      <property name="text">
       <string>Param</string>
@@ -27,9 +30,6 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="KUrlRequester" name="urlwidget"/>
-   </item>
   </layout>
  </widget>
  <customwidgets>