]> git.sesse.net Git - kdenlive/commitdiff
Implement reset effect in new effect stack
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 20 Mar 2012 23:12:56 +0000 (00:12 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 20 Mar 2012 23:12:56 +0000 (00:12 +0100)
src/effectstack/collapsibleeffect.cpp
src/effectstack/collapsibleeffect.h
src/effectstack/effectstackview2.cpp
src/effectstack/effectstackview2.h
src/widgets/collapsiblewidget_ui.ui

index 767cc630d1351b98ad4f8ff20d6583b4d77a27b2..766c927fce8324bd07a40a93ed90391de27ac1e9 100644 (file)
 #include "rotoscoping/rotowidget.h"
 #endif
 
-
+#include <QInputDialog>
 #include <QDialog>
+#include <QMenu>
 #include <QVBoxLayout>
 #include <KDebug>
 #include <KGlobalSettings>
 #include <KLocale>
+#include <KMessageBox>
+#include <KStandardDirs>
 #include <KFileDialog>
 #include <KUrlRequester>
 
@@ -142,12 +145,9 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
     }
     buttonDel->setIcon(KIcon("edit-delete"));
     buttonDel->setToolTip(i18n("Delete effect"));
-    buttonSave->setIcon(KIcon("document-save"));
-    buttonSave->setToolTip(i18n("Save effect"));
 
     buttonUp->setVisible(false);
     buttonDown->setVisible(false);
-    buttonSave->setVisible(false);
     buttonDel->setVisible(false);
     
     /*buttonReset->setIcon(KIcon("view-refresh"));
@@ -157,10 +157,12 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
     //buttonShowComments->setToolTip(i18n("Show additional information for the parameters"));
             
     title->setText(i18n(namenode.text().toUtf8().data()));
-    effectIcon->setPixmap(icon.pixmap(QSize(16,16)));
+    title->setIcon(icon);
+    QMenu *menu = new QMenu;
+    menu->addAction(KIcon("view-refresh"), i18n("Reset effect"), this, SLOT(slotResetEffect()));
+    menu->addAction(KIcon("document-save"), i18n("Save effect"), this, SLOT(slotSaveEffect()));
+    title->setMenu(menu);
     
-    //QLabel *lab = new QLabel("HEllo", widgetFrame);
-    //m_vbox->addWidget(lab);
     if (m_effect.attribute("disable") == "1") {
         enabledBox->setCheckState(Qt::Unchecked);
         title->setEnabled(false);
@@ -174,6 +176,7 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
     connect(buttonUp, SIGNAL(clicked()), this, SLOT(slotEffectUp()));
     connect(buttonDown, SIGNAL(clicked()), this, SLOT(slotEffectDown()));
     connect(buttonDel, SIGNAL(clicked()), this, SLOT(slotDeleteEffect()));
+
     setupWidget(info, ix, metaInfo);
     Q_FOREACH( QSpinBox * sp, findChildren<QSpinBox*>() ) {
         sp->installEventFilter( this );
@@ -262,7 +265,6 @@ void CollapsibleEffect::enterEvent ( QEvent * event )
 {
     if (m_paramWidget->index() > 0) buttonUp->setVisible(true);
     if (!m_lastEffect) buttonDown->setVisible(true);
-    buttonSave->setVisible(true);
     buttonDel->setVisible(true);
     if (!m_active) frame->setBackgroundRole(QPalette::Midlight);
     frame->setAutoFillBackground(true);
@@ -273,7 +275,6 @@ void CollapsibleEffect::leaveEvent ( QEvent * event )
 {
     buttonUp->setVisible(false);
     buttonDown->setVisible(false);
-    buttonSave->setVisible(false);
     buttonDel->setVisible(false);
     if (!m_active) frame->setAutoFillBackground(false);
     QWidget::leaveEvent(event);
@@ -304,6 +305,45 @@ void CollapsibleEffect::slotEffectDown()
     emit changeEffectPosition(m_paramWidget->index(), false);
 }
 
+void CollapsibleEffect::slotSaveEffect()
+{
+    QString name = QInputDialog::getText(this, i18n("Save Effect"), i18n("Name for saved effect: "));
+    if (name.isEmpty()) return;
+    QString path = KStandardDirs::locateLocal("appdata", "effects/", true);
+    path = path + name + ".xml";
+    if (QFile::exists(path)) if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", path)) == KMessageBox::No) return;
+
+    QDomDocument doc;
+    QDomElement effect = m_effect.cloneNode().toElement();
+    doc.appendChild(doc.importNode(effect, true));
+    effect = doc.firstChild().toElement();
+    effect.removeAttribute("kdenlive_ix");
+    effect.setAttribute("id", name);
+    effect.setAttribute("type", "custom");
+    QDomElement effectname = effect.firstChildElement("name");
+    effect.removeChild(effectname);
+    effectname = doc.createElement("name");
+    QDomText nametext = doc.createTextNode(name);
+    effectname.appendChild(nametext);
+    effect.insertBefore(effectname, QDomNode());
+    QDomElement effectprops = effect.firstChildElement("properties");
+    effectprops.setAttribute("id", name);
+    effectprops.setAttribute("type", "custom");
+
+    QFile file(path);
+    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+        QTextStream out(&file);
+        out << doc.toString();
+    }
+    file.close();
+    emit reloadEffects();
+}
+
+void CollapsibleEffect::slotResetEffect()
+{
+    emit resetEffect(m_paramWidget->index());
+}
+
 void CollapsibleEffect::slotSwitch()
 {
     bool enable = !widgetFrame->isVisible();
@@ -323,6 +363,16 @@ void CollapsibleEffect::slotShow(bool show)
     }
 }
 
+void CollapsibleEffect::updateWidget(ItemInfo info, int index, QDomElement effect, EffectMetaInfo *metaInfo)
+{
+    if (m_paramWidget) {
+       // cleanup
+       delete m_paramWidget;
+       m_paramWidget = NULL;
+    }
+    m_effect = effect;
+    setupWidget(info, index, metaInfo);
+}
 
 void CollapsibleEffect::setupWidget(ItemInfo info, int index, EffectMetaInfo *metaInfo)
 {
@@ -330,6 +380,7 @@ void CollapsibleEffect::setupWidget(ItemInfo info, int index, EffectMetaInfo *me
 //         kDebug() << "// EMPTY EFFECT STACK";
         return;
     }
+
     if (m_effect.attribute("tag") == "region") {
         QVBoxLayout *vbox = new QVBoxLayout(widgetFrame);
         vbox->setContentsMargins(0, 0, 0, 0);
@@ -870,8 +921,8 @@ void ParameterContainer::slotCollectAllParameters()
     QLocale locale;
     locale.setNumberOptions(QLocale::OmitGroupSeparator);
     const QDomElement oldparam = m_effect.cloneNode().toElement();
-    QDomElement newparam = oldparam.cloneNode().toElement();
-    QDomNodeList namenode = newparam.elementsByTagName("parameter");
+    //QDomElement newparam = oldparam.cloneNode().toElement();
+    QDomNodeList namenode = m_effect.elementsByTagName("parameter");
 
     for (int i = 0; i < namenode.count() ; i++) {
         QDomNode pa = namenode.item(i);
@@ -920,23 +971,23 @@ void ParameterContainer::slotCollectAllParameters()
             PositionEdit *pedit = ((PositionEdit*)m_valueItems.value(paramName));
             int pos = pedit->getPosition();
             setValue = QString::number(pos);
-            if (newparam.attribute("id") == "fadein" || newparam.attribute("id") == "fade_from_black") {
+            if (m_effect.attribute("id") == "fadein" || m_effect.attribute("id") == "fade_from_black") {
                 // Make sure duration is not longer than clip
                 /*if (pos > m_out) {
                     pos = m_out;
                     pedit->setPosition(pos);
                 }*/
-                EffectsList::setParameter(newparam, "in", QString::number(m_in));
-                EffectsList::setParameter(newparam, "out", QString::number(m_in + pos));
+                EffectsList::setParameter(m_effect, "in", QString::number(m_in));
+                EffectsList::setParameter(m_effect, "out", QString::number(m_in + pos));
                 setValue.clear();
-            } else if (newparam.attribute("id") == "fadeout" || newparam.attribute("id") == "fade_to_black") {
+            } else if (m_effect.attribute("id") == "fadeout" || m_effect.attribute("id") == "fade_to_black") {
                 // Make sure duration is not longer than clip
                 /*if (pos > m_out) {
                     pos = m_out;
                     pedit->setPosition(pos);
                 }*/
-                EffectsList::setParameter(newparam, "in", QString::number(m_out - pos));
-                EffectsList::setParameter(newparam, "out", QString::number(m_out));
+                EffectsList::setParameter(m_effect, "in", QString::number(m_out - pos));
+                EffectsList::setParameter(m_effect, "out", QString::number(m_out));
                 setValue.clear();
             }
         } else if (type == "curve") {
@@ -947,24 +998,24 @@ void ParameterContainer::slotCollectAllParameters()
             QString outName = pa.attributes().namedItem("outpoints").nodeValue();
             int off = pa.attributes().namedItem("min").nodeValue().toInt();
             int end = pa.attributes().namedItem("max").nodeValue().toInt();
-            EffectsList::setParameter(newparam, number, QString::number(points.count()));
+            EffectsList::setParameter(m_effect, number, QString::number(points.count()));
             for (int j = 0; (j < points.count() && j + off <= end); j++) {
                 QString in = inName;
                 in.replace("%i", QString::number(j + off));
                 QString out = outName;
                 out.replace("%i", QString::number(j + off));
-                EffectsList::setParameter(newparam, in, locale.toString(points.at(j).x()));
-                EffectsList::setParameter(newparam, out, locale.toString(points.at(j).y()));
+                EffectsList::setParameter(m_effect, in, locale.toString(points.at(j).x()));
+                EffectsList::setParameter(m_effect, out, locale.toString(points.at(j).y()));
             }
             QString depends = pa.attributes().namedItem("depends").nodeValue();
             if (!depends.isEmpty())
-                meetDependency(paramName, type, EffectsList::parameter(newparam, depends));
+                meetDependency(paramName, type, EffectsList::parameter(m_effect, depends));
         } else if (type == "bezier_spline") {
             BezierSplineWidget *widget = (BezierSplineWidget*)m_valueItems.value(paramName);
             setValue = widget->spline();
             QString depends = pa.attributes().namedItem("depends").nodeValue();
             if (!depends.isEmpty())
-                meetDependency(paramName, type, EffectsList::parameter(newparam, depends));
+                meetDependency(paramName, type, EffectsList::parameter(m_effect, depends));
 #ifdef USE_QJSON
         } else if (type == "roto-spline") {
             RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems.value(paramName));
@@ -1033,7 +1084,7 @@ void ParameterContainer::slotCollectAllParameters()
             pa.attributes().namedItem("value").setNodeValue(setValue);
 
     }
-    emit parameterChanged(oldparam, newparam, m_index);
+    emit parameterChanged(oldparam, m_effect, m_index);
 }
 
 QString ParameterContainer::getWipeString(wipeInfo info)
index 97bbbcce57d78f9f373dcadef3bff3705af44225..818853471efd58f5ed7b86895ef4c7c8f927e18c 100644 (file)
@@ -120,6 +120,8 @@ public:
     void updateTimecodeFormat();
     void setActive(bool activate);
     virtual bool eventFilter( QObject * o, QEvent * e );
+    /** @brief Update effect GUI to reflect parameted changes. */
+    void updateWidget(ItemInfo info, int index, QDomElement effect, EffectMetaInfo *metaInfo);
 
 public slots:
     void slotSyncEffectsPos(int pos);
@@ -131,6 +133,8 @@ private slots:
     void slotDeleteEffect();
     void slotEffectUp();
     void slotEffectDown();
+    void slotSaveEffect();
+    void slotResetEffect();
 
 private:
     ParameterContainer *m_paramWidget;
@@ -159,6 +163,9 @@ signals:
     void seekTimeline(int);
     /** @brief Start an MLT filter job on this clip. */
     void startFilterJob(QString filterName, QString filterParams, QString finalFilterName, QString consumer, QString consumerParams, QString properties);
+    /** @brief An effect was saved, trigger effect list reload. */
+    void reloadEffects();
+    void resetEffect(int ix);
 };
 
 
index e2ea33099cb66000b2eb2907466e782996994ae4..3ef46cad6d5410297518ba84d297964c17485f00 100644 (file)
@@ -206,6 +206,8 @@ void EffectStackView2::setupListView(int ix)
         connect(currentEffect, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement, int)));
        connect(currentEffect, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString)), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,QString,QString)));
         connect(currentEffect, SIGNAL(deleteEffect(const QDomElement, int)), this , SLOT(slotDeleteEffect(const QDomElement, int)));
+       connect(currentEffect, SIGNAL(reloadEffects()), this , SIGNAL(reloadEffects()));
+       connect(currentEffect, SIGNAL(resetEffect(int)), this , SLOT(slotResetEffect(int)));
         connect(currentEffect, SIGNAL(changeEffectPosition(int,bool)), this , SLOT(slotMoveEffect(int , bool)));
         connect(currentEffect, SIGNAL(effectStateChanged(bool, int)), this, SLOT(slotUpdateEffectState(bool, int)));
         connect(currentEffect, SIGNAL(activateEffect(int)), this, SLOT(slotSetCurrentEffect(int)));
@@ -339,4 +341,45 @@ void EffectStackView2::slotStartFilterJob(const QString&filterName, const QStrin
     emit startFilterJob(m_clipref->info(), m_clipref->clipProducer(), filterName, filterParams, finalFilterName, consumer, consumerParams, properties);
 }
 
+void EffectStackView2::slotResetEffect(int ix)
+{
+    QDomElement old = m_currentEffectList.at(ix);
+    QDomElement dom;
+    QString effectId = old.attribute("id");
+    QMap<QString, EffectsList*> effectLists;
+    effectLists["audio"] = &MainWindow::audioEffects;
+    effectLists["video"] = &MainWindow::videoEffects;
+    effectLists["custom"] = &MainWindow::customEffects;
+    foreach(const QString &type, effectLists.keys()) {
+        EffectsList *list = effectLists[type];
+        dom = list->getEffectByTag(QString(), effectId).cloneNode().toElement();
+        if (!dom.isNull()) break;
+    }
+    if (!dom.isNull()) {
+        dom.setAttribute("kdenlive_ix", old.attribute("kdenlive_ix"));
+       //TODO: Track mode
+        /*if (m_trackMode) {
+            EffectsList::setParameter(dom, "in", QString::number(0));
+            EffectsList::setParameter(dom, "out", QString::number(m_trackInfo.duration));
+            ItemInfo info;
+            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;
+            m_effectedit->transferParamDesc(dom, info);
+            emit updateEffect(NULL, m_trackindex, old, dom, activeRow);
+        } else*/ {
+            m_clipref->initEffect(dom);
+           m_effects.at(ix)->updateWidget(m_clipref->info(), ix, dom, &m_effectMetaInfo);
+            //m_effectedit->transferParamDesc(dom, m_clipref->info());
+            //m_ui.region_url->setUrl(KUrl(dom.attribute("region")));
+            emit updateEffect(m_clipref, -1, old, dom, ix);
+        }
+    }
+
+    /*emit showComments(m_ui.buttonShowComments->isChecked());
+    m_ui.labelComment->setHidden(!m_ui.buttonShowComments->isChecked() || !m_ui.labelComment->text().count());*/
+}
+
 #include "effectstackview2.moc"
index ba08fac9be422a811bfa067599ba011e9588586a..152cda4cb4bc427abc30964cd97d74746b2484d0 100644 (file)
@@ -124,6 +124,9 @@ private slots:
     
     /** @brief Triggers a filter job on this clip. */
     void slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QString&properties);
+    
+    /** @brief Reset an effect to its default values. */
+    void slotResetEffect(int ix);
 
 
 signals:
index ee80f759d5923507edbe8681a03c6d3ba1d02d65..503a977f9c8b91872f7da54287d9e603a240b81c 100644 (file)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>236</width>
+    <width>176</width>
     <height>38</height>
    </rect>
   </property>
       <property name="margin">
        <number>0</number>
       </property>
-      <item row="0" column="0">
-       <widget class="QToolButton" name="collapseButton">
+      <item row="0" column="2">
+       <widget class="QToolButton" name="title">
         <property name="text">
-         <string>...</string>
+         <string/>
+        </property>
+        <property name="popupMode">
+         <enum>QToolButton::MenuButtonPopup</enum>
+        </property>
+        <property name="toolButtonStyle">
+         <enum>Qt::ToolButtonTextBesideIcon</enum>
         </property>
         <property name="autoRaise">
          <bool>true</bool>
         </property>
         <property name="arrowType">
-         <enum>Qt::DownArrow</enum>
+         <enum>Qt::NoArrow</enum>
         </property>
        </widget>
       </item>
         </property>
        </widget>
       </item>
-      <item row="0" column="2">
-       <widget class="QLabel" name="effectIcon">
+      <item row="0" column="4">
+       <widget class="QToolButton" name="buttonUp">
         <property name="text">
-         <string/>
+         <string>...</string>
         </property>
-       </widget>
-      </item>
-      <item row="0" column="3">
-       <widget class="QLabel" name="title">
-        <property name="text">
-         <string>TextLabel</string>
+        <property name="autoRaise">
+         <bool>true</bool>
         </property>
        </widget>
       </item>
-      <item row="0" column="4">
+      <item row="0" column="3">
        <spacer name="horizontalSpacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
        </spacer>
       </item>
       <item row="0" column="5">
-       <widget class="QToolButton" name="buttonUp">
-        <property name="text">
-         <string>...</string>
-        </property>
-        <property name="autoRaise">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="6">
        <widget class="QToolButton" name="buttonDown">
         <property name="text">
          <string>...</string>
         </property>
        </widget>
       </item>
-      <item row="0" column="7">
-       <widget class="QToolButton" name="buttonDel">
+      <item row="0" column="0">
+       <widget class="QToolButton" name="collapseButton">
         <property name="text">
          <string>...</string>
         </property>
         <property name="autoRaise">
          <bool>true</bool>
         </property>
+        <property name="arrowType">
+         <enum>Qt::DownArrow</enum>
+        </property>
        </widget>
       </item>
-      <item row="0" column="8">
-       <widget class="QToolButton" name="buttonSave">
+      <item row="0" column="6">
+       <widget class="QToolButton" name="buttonDel">
         <property name="text">
          <string>...</string>
         </property>