Logo Search packages:      
Sourcecode: kdenlive version File versions  Download package

effectstackdialog.cpp

/***************************************************************************
                          effectstackdialog  -  description
                             -------------------
    begin                : Mon Jan 12 2004
    copyright            : (C) 2004 by Jason Wood
    email                : jasonwood@blueyonder.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "effectstackdialog.h"

#include <qspinbox.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qfont.h>
#include <qtabwidget.h>
#include <qtooltip.h>
#include <qslider.h>
#include <qlayout.h>
#include <qobjectlist.h>

#include <kdebug.h>
#include <kiconloader.h>
#include <kpushbutton.h>
#include <klocale.h>
#include <kcombobox.h>
#include <kcolorbutton.h>
#include <kinputdialog.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>

#include <effectstacklistview.h>

#include "docclipref.h"
#include "effect.h"
#include "effectdesc.h"
#include "effectparamdesc.h"
#include "effectparameter.h"
#include "effectkeyframe.h"
#include "effectdoublekeyframe.h"
#include "effectcomplexkeyframe.h"
#include "kdenlivesettings.h"
#include "kdenlivedoc.h"

namespace Gui {

    EffectStackDialog::EffectStackDialog(KdenliveApp * app,
      KdenliveDoc * doc, QWidget * parent, const char *name)
    :EffectStackDialog_UI(parent, name), m_container(NULL), m_frame(NULL), m_app(app) {
      // Use a smaller font for that dialog, it has many infos on it. Maybe it's not a good idea?
      QFont dialogFont = font();
       dialogFont.setPointSize(dialogFont.pointSize() - 1);
       setFont(dialogFont);
      KIconLoader loader;

       m_upButton->setIconSet(QIconSet(loader.loadIcon("1uparrow",
                KIcon::Toolbar)));
       m_downButton->setIconSet(QIconSet(loader.loadIcon("1downarrow",
                KIcon::Toolbar)));
       m_resetButton->setIconSet(QIconSet(loader.loadIcon("reload",
                KIcon::Toolbar)));
       m_deleteButton->setIconSet(QIconSet(loader.loadIcon("editdelete",
                KIcon::Toolbar)));
       m_saveButton->setIconSet(QIconSet(loader.loadIcon("filesave",
                KIcon::Toolbar)));
       m_groupButton->setIconSet(QIconSet(loader.loadIcon("attach",
                KIcon::Toolbar)));

       QToolTip::add(m_upButton, i18n("Move effect up"));
       QToolTip::add(m_downButton, i18n("Move effect down"));
       QToolTip::add(m_resetButton, i18n("Reset all parameters to default values"));
       QToolTip::add(m_deleteButton, i18n("Remove effect"));
       QToolTip::add(m_saveButton, i18n("Save effect"));
       QToolTip::add(m_groupButton, i18n("Group effects"));
       QToolTip::add(m_ungroupButton, i18n("Ungroup effects"));

       QHBoxLayout *viewLayout = new QHBoxLayout( frame );
         viewLayout->setAutoAdd( TRUE );

       m_effectList = new EffectStackListView(frame, app, doc);

       m_parameter->setOrientation(Qt::Vertical);
       m_parameter->setColumns(5);
       m_blockUpdate = false;
       m_effecttype = "";
       m_hasKeyFrames = false;

       tabWidget2->setTabEnabled(tabWidget2->page(1), false);

       connect(m_upButton, SIGNAL(clicked()), m_effectList,
          SLOT(slotMoveEffectUp()));
       connect(m_downButton, SIGNAL(clicked()), m_effectList,
          SLOT(slotMoveEffectDown()));
       connect(m_resetButton, SIGNAL(clicked()), this,
          SLOT(resetParameters()));
       connect(m_deleteButton, SIGNAL(clicked()), this,
          SLOT(slotDeleteEffect()));
       connect(m_saveButton, SIGNAL(clicked()), this,
          SLOT(slotSaveEffect()));
       connect(m_groupButton, SIGNAL(clicked()), this,
          SLOT(slotGroupEffects()));
       connect(m_ungroupButton, SIGNAL(clicked()), this,
          SLOT(slotUngroupEffects()));

       connect(spinIndex, SIGNAL(valueChanged(int)), this,
          SLOT(selectKeyFrame(int)));
       connect(m_effectList, SIGNAL(effectSelected(DocClipRef *,
                Effect *)), this, SLOT(addParameters(DocClipRef *,
                Effect *)));
       connect(m_effectList, SIGNAL(effectToggled()), this, SLOT(slotSwitchEffect()));

       connect(m_effectList, SIGNAL(doubleClicked ( QListViewItem *, const QPoint &, int )), this,
          SLOT(slotRenameGroup()));


       connect(sliderPosition, SIGNAL(valueChanged(int)), spinPosition,
          SLOT(setValue(int)));
       connect(spinPosition, SIGNAL(valueChanged(int)), sliderPosition,
          SLOT(setValue(int)));
       connect(spinPosition, SIGNAL(valueChanged(int)), this,
          SLOT(changeKeyFramePosition(int)));
      disableButtons();

      /*connect(spinValue, SIGNAL(valueChanged(int)), sliderValue, SLOT(setValue(int)));
         connect(sliderValue, SIGNAL(valueChanged(int)), spinValue, SLOT(setValue(int)));
         connect(spinValue, SIGNAL(valueChanged(int)), this, SLOT(changeKeyFrameValue(int))); */
    } 

    EffectStackDialog::~EffectStackDialog() {
      delete m_effectList;
    }

    void EffectStackDialog::disableButtons()
    {
      m_upButton->setEnabled(false);
      m_downButton->setEnabled(false);
      m_resetButton->setEnabled(false);
      m_deleteButton->setEnabled(false);
      m_saveButton->setEnabled(false);
      m_groupButton->setEnabled(false);
      m_ungroupButton->setEnabled(false);
    }

    void EffectStackDialog::enableButtons()
    {
      m_upButton->setEnabled(true);
      m_downButton->setEnabled(true);
      m_resetButton->setEnabled(true);
      m_deleteButton->setEnabled(true);
      m_saveButton->setEnabled(true);
      m_groupButton->setEnabled(true);
      m_ungroupButton->setEnabled(true);
    }

    void EffectStackDialog::cleanWidgets()
    {
      if (m_container) delete m_container;
      if (m_frame) delete m_frame;
      m_container = 0;
      m_frame = 0;
    }



    void EffectStackDialog::addParameters(DocClipRef * clip, Effect * effect) {
      // Rebuild the effect parameters dialog
      //kdDebug()<<"++++++++++++  REBUILD PARAMETER DIALOG FOR CLIP: "<<clip->name()<<endl;
      uint parameterNum = 0;
      m_hasKeyFrames = false;

      if (effect == NULL) {
          cleanWidgets();
          return;
      }
      tabWidget2->setEnabled(effect->isEnabled());
        if (!effect->parameter(parameterNum)) {
            disableButtons();
            return;
      }
      enableButtons();

      m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
      spinIndex->setValue(0);
      updateKeyFrames();
      clip->setEffectStackSelectedItem(m_effectList->selectedEffectIndex());

      // remove all previous params
      cleanWidgets();

      m_container = new QGrid(3, Qt::Horizontal, m_parameter, "container");
      m_container->setSpacing(5);
      m_container->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum));

      while (effect->parameter(parameterNum)) {
          m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
          // for each constant parameter, build a QSpinBox with its value
            if (m_effecttype == "constant") {
            int maxValue =(int)
                effect->effectDescription().parameter(parameterNum)->
                max();
            int minValue =(int)
                effect->effectDescription().parameter(parameterNum)->
                min();
                if (maxValue != minValue) {
              (void) new QLabel(effect->effectDescription().parameter(parameterNum)->description(), m_container);
              QString widgetName = QString("param");
              widgetName.append(QString::number(parameterNum));
              QSlider *sliderParam = new QSlider(Qt::Horizontal, m_container);
              sliderParam->setRange(minValue, maxValue);
              QSpinBox *spinParam = new QSpinBox(m_container, widgetName.ascii());
              spinParam->setMaxValue(maxValue);
              spinParam->setMinValue(minValue);
            connect(sliderParam, SIGNAL(valueChanged(int)), spinParam,
                SLOT(setValue(int)));
            connect(spinParam, SIGNAL(valueChanged(int)), sliderParam,
                SLOT(setValue(int)));
              spinParam->setValue(effect->effectDescription().parameter(parameterNum)->value().toInt());
              connect(spinParam, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));
                }
          }
          else if (m_effecttype == "position") {
            int minValue = 1; //clip->cropStartTime().frames(KdenliveSettings::defaultfps());
            int maxValue = clip->duration().frames(KdenliveSettings::defaultfps());
            // cropDuration().frames(KdenliveSettings::defaultfps()) + minValue;
            if (minValue == 0) minValue = 1; // Currently, MLT does not support freeze at frame 0.
                if (maxValue != minValue) {
              (void) new QLabel(effect->effectDescription().parameter(parameterNum)->description(), m_container);
              QString widgetName = QString("param");
              widgetName.append(QString::number(parameterNum));
              QPushButton *buttonParam = new QPushButton(i18n("Get Current Frame"), m_container);
              QSpinBox *spinParam = new QSpinBox(m_container, widgetName.ascii());
              spinParam->setMaxValue(maxValue);
              spinParam->setMinValue(minValue);
              spinParam->setValue(effect->effectDescription().parameter(parameterNum)->value().toInt());
              connect(m_app->getDocument(), SIGNAL(currentClipPosition(int)), spinParam, SLOT(setValue(int)));
              connect(buttonParam, SIGNAL(clicked()), m_app->getDocument(), SLOT(emitCurrentClipPosition()));
              connect(spinParam, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));
                }
          }
            else if (m_effecttype == "bool") {
              (void) new QLabel(effect->effectDescription().parameter(parameterNum)->description(), m_container);
              //#HACK: Grid has 3 columns, so insert empty widget in the middle when line only has 2 widgets
              (void) new QWidget(m_container);
              QString widgetName = QString("param");
              widgetName.append(QString::number(parameterNum));
              QCheckBox *checkParam = new QCheckBox(m_container, widgetName.ascii());
              int value = effect->effectDescription().parameter(parameterNum)->value().toInt();
              kdDebug()<<" ++++  VALUE FOR BOOL PARAM: "<<effect->effectDescription().parameter(parameterNum)->description()<<" IS: "<<value<<endl;
              if (value == 1) checkParam->setChecked(true);
              else checkParam->setChecked(false);
              connect(checkParam, SIGNAL(toggled(bool)), this, SLOT(parameterChanged()));
          }
          else if (m_effecttype == "list") {
            QStringList list = QStringList::split(",", 
                effect->effectDescription().parameter(parameterNum)->
                list());

              // build combobox

              (void) new QLabel(effect->effectDescription().parameter(parameterNum)->description(), m_container);
              //#HACK: Grid has 3 columns, so insert empty widget in the middle when line only has 2 widgets 
              (void) new QWidget(m_container);
              QString widgetName = QString("param");
              widgetName.append(QString::number(parameterNum));
              KComboBox *comboParam = new KComboBox(m_container, widgetName.ascii());
              comboParam->insertStringList(list);
              comboParam->setCurrentItem(effect->effectDescription().parameter(parameterNum)->value());
              connect(comboParam, SIGNAL(activated(int)), this, SLOT(parameterChanged()));
                
          }
          else if (m_effecttype == "double") {
            m_frame = new QFrame(k_container, "container2");
            m_frame->setSizePolicy(QSizePolicy::MinimumExpanding,
                QSizePolicy::MinimumExpanding);
            QGridLayout *grid = new QGridLayout(m_frame, 3, 0, 0, 5);
            spinIndex->setMaxValue(effect->parameter(parameterNum)->
                numKeyFrames() - 1);
            int ix =
                effect->parameter(parameterNum)->selectedKeyFrame();
            uint maxVal = effect->effectDescription().parameter(parameterNum)->
                max();
            uint minVal = effect->effectDescription().parameter(parameterNum)->
                min();
            uint currVal =(uint)
                effect->parameter(parameterNum)->keyframe(ix)->
                toDoubleKeyFrame()->value();
            QLabel *label =
                new QLabel(effect->effectDescription().
                parameter(parameterNum)->description(), m_frame);
            QSlider *sliderParam = new QSlider(Qt::Horizontal, m_frame);
            sliderParam->setRange(minVal, maxVal);
            QSpinBox *spinParam = new QSpinBox(m_frame, "value");

            grid->addWidget(label, 0, 0);
            grid->addWidget(sliderParam, 0, 1);
            grid->addWidget(spinParam, 0, 2);

            connect(sliderParam, SIGNAL(valueChanged(int)), spinParam,
                SLOT(setValue(int)));
            connect(spinParam, SIGNAL(valueChanged(int)), sliderParam,
                SLOT(setValue(int)));
            spinParam->setMaxValue(maxVal);
            spinParam->setMinValue(minVal);
            spinParam->setValue(currVal);

            connect(spinParam, SIGNAL(valueChanged(int)), this,
                SLOT(changeKeyFrameValue(int)));
            m_frame->adjustSize();
            m_frame->show();
            m_hasKeyFrames = true;
          }
          else if (m_effecttype == "color") {
              (void) new QLabel(effect->effectDescription().parameter(parameterNum)->description(), m_container);
              //#HACK: Grid has 3 columns, so insert empty widget in the middle when line only has 2 widgets
              (void) new QWidget(m_container);
              QString widgetName = QString("param");
              widgetName.append(QString::number(parameterNum));
              QString value = effect->effectDescription().parameter(parameterNum)->value();
              kdDebug()<<" ++++  COLOR PARAM: "<<value<<endl;
                    value = value.replace(0, 2, "#");
                    //value = value.left(7);
              KColorButton *colorParam = new KColorButton(QColor(value), m_container, widgetName.ascii());
              kdDebug()<<" ++++  VALUE FOR COLOR PARAM: "<<effect->effectDescription().parameter(parameterNum)->description()<<" IS: "<<value<<endl;
              connect(colorParam, SIGNAL(changed(const QColor &)), this, SLOT(parameterChanged()));

          }
          else if (m_effecttype == "geometry") {
            QString val = effect->effectDescription().parameter(parameterNum)->value();
            QString valx = val.section(",", 0, 0);
            QString valy = val.section(",", 1).section(":", 0, 0);
            QString valw = val.section(":", 1).section("x", 0, 0);
            QString valh = val.section(":", 1).section("x", 1);

            // x widget
            int maxValue = KdenliveSettings::defaultwidth();
            int minValue = 0;
            (void) new QLabel(i18n("X"), m_container);
            QString widgetName = QString("param0");
            QSlider *sliderParam = new QSlider(Qt::Horizontal, m_container);
            sliderParam->setRange(minValue, maxValue);
            QSpinBox *spinParam = new QSpinBox(m_container, widgetName.ascii());
            spinParam->setMaxValue(maxValue);
            spinParam->setMinValue(minValue);
            connect(sliderParam, SIGNAL(valueChanged(int)), spinParam, SLOT(setValue(int)));
            connect(spinParam, SIGNAL(valueChanged(int)), sliderParam, SLOT(setValue(int)));
            spinParam->setValue(valx.toInt());
            connect(spinParam, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));

            // y widget
            maxValue = KdenliveSettings::defaultheight();
            minValue = 0;
            (void) new QLabel(i18n("Y"), m_container);
            widgetName = QString("param1");
            QSlider *sliderParamy = new QSlider(Qt::Horizontal, m_container);
            sliderParamy->setRange(minValue, maxValue);
            QSpinBox *spinParamy = new QSpinBox(m_container, widgetName.ascii());
            spinParamy->setMaxValue(maxValue);
            spinParamy->setMinValue(minValue);
            connect(sliderParamy, SIGNAL(valueChanged(int)), spinParamy, SLOT(setValue(int)));
            connect(spinParamy, SIGNAL(valueChanged(int)), sliderParamy, SLOT(setValue(int)));
            spinParamy->setValue(valy.toInt());
            connect(spinParamy, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));

            // w widget
            maxValue = KdenliveSettings::defaultwidth();
            minValue = 3;
            (void) new QLabel(i18n("Width"), m_container);
            widgetName = QString("param2");
            QSlider *sliderParamw = new QSlider(Qt::Horizontal, m_container);
            sliderParamw->setRange(minValue, maxValue);
            QSpinBox *spinParamw = new QSpinBox(m_container, widgetName.ascii());
            spinParamw->setMaxValue(maxValue);
            spinParamw->setMinValue(minValue);
            connect(sliderParamw, SIGNAL(valueChanged(int)), spinParamw, SLOT(setValue(int)));
            connect(spinParamw, SIGNAL(valueChanged(int)), sliderParamw, SLOT(setValue(int)));
            spinParamw->setValue(valw.toInt());
            connect(spinParamw, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));

            // h widget
            maxValue = KdenliveSettings::defaultheight();
            minValue = 3;
            (void) new QLabel(i18n("Height"), m_container);
            widgetName = QString("param3");
            QSlider *sliderParamh = new QSlider(Qt::Horizontal, m_container);
            sliderParamh->setRange(minValue, maxValue);
            QSpinBox *spinParamh = new QSpinBox(m_container, widgetName.ascii());
            spinParamh->setMaxValue(maxValue);
            spinParamh->setMinValue(minValue);
            connect(sliderParamh, SIGNAL(valueChanged(int)), spinParamh, SLOT(setValue(int)));
            connect(spinParamh, SIGNAL(valueChanged(int)), sliderParamh, SLOT(setValue(int)));
            spinParamh->setValue(valh.toInt());
            connect(spinParamh, SIGNAL(valueChanged(int)), this, SLOT(parameterChanged()));


          }
          else if (m_effecttype == "complex") {
            kdWarning()<<"/////  BIUILDING CPLX PARAM DLG"<<endl;
            m_frame = new QFrame(k_container, "container2");
            m_frame->setSizePolicy(QSizePolicy::MinimumExpanding,
                QSizePolicy::MinimumExpanding);
            QGridLayout *grid = new QGridLayout(m_frame, 3, 0, 0, 5);
            spinIndex->setMaxValue(effect->parameter(parameterNum)->
                numKeyFrames() - 1);

            uint paramNum =
                effect->effectDescription().parameter(parameterNum)->
                complexParamNum();
            for (uint i = 0; i < paramNum; i++) {
                int ix =
                  effect->parameter(parameterNum)->
                  selectedKeyFrame();
                   uint maxVal =(uint)
                  effect->effectDescription().
                  parameter(parameterNum)->max(i);
                   uint minVal =(uint)
                  effect->effectDescription().
                  parameter(parameterNum)->min(i);
                   uint currVal =
                  effect->parameter(parameterNum)->keyframe(ix)->
                  toComplexKeyFrame()->value(i);
                QLabel *label =
                  new QLabel(effect->effectDescription().
                  parameter(parameterNum)->complexParamName(i),
                  m_frame);
                QString widgetName = QString("param");
                widgetName.append(QString::number(i));
                QSlider *sliderParam =
                  new QSlider(Qt::Horizontal, m_frame);
                sliderParam->setRange(minVal, maxVal);
                QSpinBox *spinParam =
                  new QSpinBox(m_frame, widgetName.ascii());



                grid->addWidget(label, i, 0);
                grid->addWidget(sliderParam, i, 1);
                grid->addWidget(spinParam, i, 2);

                connect(sliderParam, SIGNAL(valueChanged(int)),
                  spinParam, SLOT(setValue(int)));
                connect(spinParam, SIGNAL(valueChanged(int)),
                  sliderParam, SLOT(setValue(int)));

                spinParam->setMaxValue(maxVal);
                spinParam->setMinValue(minVal);
                spinParam->setValue(currVal);

                connect(spinParam, SIGNAL(valueChanged(int)), this,
                  SLOT(changeKeyFrameValue(int)));
            }
            m_frame->adjustSize();
            m_frame->show();
            m_hasKeyFrames = true;
          }

          parameterNum++;
      }

      tabWidget2->setTabEnabled(tabWidget2->page(1), m_hasKeyFrames);
      if (m_hasKeyFrames) tabWidget2->setCurrentPage(1);
      else tabWidget2->setCurrentPage(0);
      m_container->adjustSize();
      m_container->show();
      emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
    }

    void EffectStackDialog::parameterChanged() {
      // A parameter was changed, sync the clip's effect with the spin box values
      uint parameterNum = 0;
      Effect *effect = m_effectList->clip()->effectAt(m_effectList->selectedEffectIndex());
      if (!effect) return;
      while (effect->parameter(parameterNum)) {
          m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
          QString widgetName = QString("param");
          widgetName.append(QString::number(parameterNum));
          if (m_effecttype == "constant" || m_effecttype == "position") {
            QSpinBox *sbox =
                dynamic_cast <
                QSpinBox * >(m_parameter->child(widgetName.ascii(),
                  "QSpinBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum << endl;
            else {
                effect->effectDescription().parameter(parameterNum)->
                  setValue(QString::number(sbox->value()));
            }
          }
          else if (m_effecttype == "geometry") {
            QString value;
            widgetName = "param0";
            QSpinBox *sbox =
                dynamic_cast < QSpinBox * >(m_parameter->child(widgetName.ascii(), "QSpinBox"));
            if (!sbox) kdWarning() << "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER " 
                  << parameterNum << endl;
            else {
                value = QString::number(sbox->value());
                widgetName = "param1";
                sbox = dynamic_cast < QSpinBox * >(m_parameter->child(widgetName.ascii(), "QSpinBox"));
                if (sbox) value.append("," + QString::number(sbox->value()));
                widgetName = "param2";
                sbox = dynamic_cast < QSpinBox * >(m_parameter->child(widgetName.ascii(), "QSpinBox"));
                if (sbox) value.append(":" + QString::number(sbox->value()));
                widgetName = "param3";
                sbox = dynamic_cast < QSpinBox * >(m_parameter->child(widgetName.ascii(), "QSpinBox"));
                if (sbox) value.append("x" + QString::number(sbox->value()));

                effect->effectDescription().parameter(parameterNum)->setValue(value);
            }
          }
          else if (m_effecttype == "bool") {
            QCheckBox *sbox =
                dynamic_cast <
                QCheckBox * >(m_parameter->child(widgetName.ascii(),
                  "QCheckBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum <<", "<<widgetName.ascii()<< endl;
            else {
                int value = sbox->isChecked() ? 1 : 0;
                effect->effectDescription().parameter(parameterNum)->
                  setValue(QString::number(value));
            }
          }
          else if (m_effecttype == "color") {
            KColorButton *sbox =
                dynamic_cast <
                KColorButton * >(m_parameter->child(widgetName.ascii(),
                  "KColorButton"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum <<", "<<widgetName.ascii()<< endl;
            else {
                QString value = sbox->color().name();
                value = value.replace(0, 1, "0x");
                kdDebug()<<"///  SETTING COLOR: "<<value<<endl;
                effect->effectDescription().parameter(parameterNum)->
                  setValue(value);
            }
          }
          else if (m_effecttype == "list") {
            KComboBox *sbox =
                dynamic_cast <
                KComboBox * >(m_parameter->child(widgetName.ascii(),
                  "KComboBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum << endl;
            else
                effect->effectDescription().parameter(parameterNum)->
                  setValue(sbox->currentText());
          }       
          parameterNum++;
      }

      QString tag = effect->effectDescription().tag();

      if (tag == "framebuffer") {
          if (effect->effectDescription().name() == i18n("Speed")) m_effectList->clip()->setSpeed(effect->effectDescription().parameter(0)->value().toDouble() / 100.0);
          else m_effectList->clip()->setSpeed(1.0);

      }

      if (!m_blockUpdate) {
          //emit generateSceneList();
          QMap <QString, QString> params = effect->getParameters(m_effectList->clip());

          if (tag != QString("framebuffer") && tag != QString("affine"))
            m_app->getDocument()->renderer()->mltEditEffect(m_effectList->clip()->playlistTrackNum(), m_effectList->clip()->trackMiddleTime(), m_effectList->selectedEffectIndex(), effect->effectDescription().stringId(), tag, params);
          else emit generateSceneList();
          m_app->focusTimelineWidget();
      }
    }


    void EffectStackDialog::slotDeleteEffect() {
      // remove all previous params
      cleanWidgets();
      m_effectList->slotDeleteEffect();
    }

    void EffectStackDialog::slotRenameGroup() {
      DocClipRef *clip = m_effectList->clip();
      if (m_effectList->selectedEffectIndex() != -1 || !clip) return;
      QString oldName = m_effectList->currentItem()->text(0);
      QString groupName = KInputDialog::getText(i18n("Edit Effect Group"), i18n("Rename group"), oldName);
      if (groupName.isEmpty()) return;
      clip->renameEffectGroup(oldName, groupName);
      slotSetEffectStack(clip);
    }

    void EffectStackDialog::slotGroupEffects() {
      DocClipRef *clip = m_effectList->clip();
      if (m_effectList->selectedEffectIndex() == -1 || !clip) return;
      QString groupName = KInputDialog::getText(i18n("Create Effect Group"), i18n("New group name"));
      if (groupName.isEmpty()) return;
      int cnt = 0;

        QListViewItemIterator it( m_effectList );
        while ( it.current() ) {
            QListViewItem *item = it.current();
            if (item->isSelected()) {
            Effect *effect = clip->effectAt(cnt);
            effect->setGroup(groupName);
          }
          if (((QCheckListItem *) item)->type() == QCheckListItem::CheckBox) cnt++;
            ++it;
        }

      slotSetEffectStack(clip);
    }

    void EffectStackDialog::slotUngroupEffects() {
      DocClipRef *clip = m_effectList->clip();
      if (!clip) return;
      int ix = m_effectList->selectedEffectIndex();
      Effect *effect;
      QString group;
      if (ix == -1) {
          group = m_effectList->currentItem()->text(0);
      }
      else {
          effect = clip->effectAt(ix);
          if (!effect) return;
          group = effect->group();
      }

      int cnt = 0;
      effect = clip->effectAt(cnt);
      while (effect) {
          if (effect->group() == group) effect->setGroup(QString::null);
          cnt++;
          effect = clip->effectAt(cnt);
      }
      slotSetEffectStack(clip);
    }

    void EffectStackDialog::slotSaveEffect() {
      DocClipRef *clip = m_effectList->clip();
      if (!clip) return;
      QDomDocument doc;
      QString name = KInputDialog::getText(i18n("Save Custom Effect"), i18n("Effect name:"));
      if (!name.isEmpty()) {
      if (m_effectList->groupSelected()) {
          QDomElement group = doc.createElement("effectgroup");
          doc.appendChild(group);
          QString groupName = m_effectList->currentItem()->text(0);
          group.setAttribute("name", groupName);
          QListViewItem *child = m_effectList->currentItem()->firstChild();
          while (child) {
            Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex(child));
            if (effect) {
                QDomNode eff = effect->toFullXML(groupName, true).firstChild();
                group.appendChild(doc.importNode(eff, true));
            }
            else kdWarning()<<"// TRYING TO SAVE EFFECT BUT FAILED.........."<<child->text(0)<<endl;
            child = child->nextSibling();
          }
      }
      else {
          Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
          if (!effect) return;
          doc = effect->toFullXML(name);
      }
          QString direc = locateLocal("appdata", "effects/");
          QFile file(direc + name + ".xml");
          file.open( IO_WriteOnly );
          QCString save = doc.toString().utf8();
          if (file.writeBlock(save, save.length()) == -1) KMessageBox::sorry(this, i18n("Cannot save file %1, check your permissions").arg(file.name()));
          file.close();
          m_app->refreshEffects();
      }
    }

    void EffectStackDialog::slotSwitchEffect() {
      DocClipRef *clip = m_effectList->clip();
      Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
      if (!effect) return;

      tabWidget2->setEnabled(effect->isEnabled());
      if (effect->name() == i18n("Speed")) {
          // If we disable speed effect, reset clip speed to normal
          if (!effect->isEnabled()) clip->setSpeed( 1.0);
          else clip->setSpeed(effect->effectDescription().parameter(0)->value().toDouble() / 100.0);
      }

      if (effect->isEnabled()) {
          QMap <QString, QString> params = effect->getParameters(clip);
          QString tag = effect->effectDescription().tag();

          if (tag != QString("framebuffer") && tag != QString("affine"))
            m_app->getDocument()->renderer()->mltAddEffect(clip->playlistTrackNum(), clip->trackMiddleTime(), effect->effectDescription().stringId(), tag, params);
          else emit generateSceneList();
      }
      else {
          QString tag = effect->effectDescription().tag();
          int index = 0;
          if (effect->effectDescription().parameter(0)->type() == "complex" || effect->effectDescription().parameter(0)->type() == "double") index = -1;
          m_app->getDocument()->renderer()->mltRemoveEffect(clip->playlistTrackNum(), clip->trackMiddleTime(), effect->effectDescription().stringId(), tag, index);
      }


      //emit generateSceneList();
      emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
    }

    void EffectStackDialog::resetParameters() {
      m_blockUpdate = true;
      uint parameterNum = 0;
      spinIndex->setValue(0);
      DocClipRef *clip = m_effectList->clip();
      Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
      if (!effect) return;
      while (effect->parameter(parameterNum)) {
          m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
          QString widgetName = QString("param");
          widgetName.append(QString::number(parameterNum));

          if (m_effecttype == "double" || m_effecttype == "complex") {
            uint ix = effect->parameter(parameterNum)->numKeyFrames();
            while (ix > 0) {
                effect->parameter(parameterNum)->deleteKeyFrame(ix -
                  1);
                ix--;
            }
            effect->addInitialKeyFrames(parameterNum);
            effect->parameter(parameterNum)->setSelectedKeyFrame(0);
            updateKeyFrames();
          } else if (effect->effectDescription().
            parameter(parameterNum)->type() == "constant" || effect->effectDescription().
            parameter(parameterNum)->type() == "position") {
            QSpinBox *sbox =
                dynamic_cast <
                QSpinBox * >(m_parameter->child(widgetName.ascii(),
                  "QSpinBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum << endl;
            else
                sbox->setValue(effect->effectDescription().
                  parameter(parameterNum)->defaultValue().toInt());
          } else if (effect->effectDescription().
            parameter(parameterNum)->type() == "bool") {
            QCheckBox *sbox =
                dynamic_cast <
                QCheckBox * >(m_parameter->child(widgetName.ascii(),
                  "QCheckBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum << endl;
            else
                sbox->setChecked(effect->effectDescription().
                  parameter(parameterNum)->defaultValue().toInt());
          }
          else if (effect->effectDescription().parameter(parameterNum)->type() == "list") {
            KComboBox *sbox =
                dynamic_cast <
                KComboBox * >(m_parameter->child(widgetName.ascii(),
                  "KComboBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX FOR PARAMETER "
                  << parameterNum << endl;
            else
                sbox->setCurrentText(effect->effectDescription().
                  parameter(parameterNum)->defaultValue());
          }
          parameterNum++;
      }
      m_blockUpdate = false;
      parameterChanged();
      emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
    }


    void EffectStackDialog::updateKeyFrames() {
      Effect *effect = m_effectList->clip()->effectAt(m_effectList->selectedEffectIndex());
      if (!effect) return;
      uint parameterNum = 0;
      uint numKeyFrames = effect->parameter(parameterNum)->numKeyFrames();
      if (numKeyFrames == 0 || !m_hasKeyFrames)
          return;
      int ix = effect->parameter(parameterNum)->selectedKeyFrame();
      spinIndex->setValue(ix);
      spinIndex->setMaxValue(numKeyFrames - 1);
      selectKeyFrame(ix);
    }


    void EffectStackDialog::selectKeyFrame(int ix) {
      // User selected a keyframe
      if (ix == -1 || !m_hasKeyFrames)
          return;
      m_blockUpdate = true;
      uint parameterNum = 0;
      uint previousTime, nextTime, currentTime;
      uint currentValue;
      DocClipRef *clip = m_effectList->clip();
      Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
        if (!effect || !effect->parameter(parameterNum)) return;
      effect->parameter(parameterNum)->setSelectedKeyFrame(ix);

      m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
      // Find the keyframe value & position
      if (m_effecttype == "double") {
            currentValue =(uint)
            effect->parameter(parameterNum)->keyframe(ix)->
            toDoubleKeyFrame()->value();
          QSpinBox *sbox =
            dynamic_cast < QSpinBox * >(k_container->child("value",
                "QSpinBox"));
          sbox->setValue(currentValue);
      } else if (m_effecttype == "complex") {
          uint paramNum =
            effect->effectDescription().parameter(parameterNum)->
            complexParamNum();
          for (uint i = 0; i < paramNum; i++) {
            QString widgetName = QString("param");
            widgetName.append(QString::number(i));
            QSpinBox *sbox =
                dynamic_cast <
                QSpinBox * >(k_container->child(widgetName.ascii(),
                  "QSpinBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX: " << i
                  << endl;
            else {
                disconnect(sbox, SIGNAL(valueChanged(int)), this, SLOT(changeKeyFrameValue(int)));
                sbox->setMaxValue((int)effect->effectDescription().parameter(parameterNum)->max(i));
                sbox->setMinValue((int)effect->effectDescription().parameter(parameterNum)->min(i));
                sbox->setValue(effect->parameter(parameterNum)->keyframe(ix)->toComplexKeyFrame()->value(i));
                connect(sbox, SIGNAL(valueChanged(int)), this, SLOT(changeKeyFrameValue(int)));
            }
          }
      }

      currentTime = (uint)(
          effect->parameter(parameterNum)->keyframe(ix)->time() *
                  clip->cropDuration().frames(KdenliveSettings::defaultfps()));

      // Find the previous keyframe position to make sure the current keyframe cannot be moved before the previous one
      if (ix == 0)
          previousTime = 0;
      else
            previousTime = (uint)(
            effect->parameter(parameterNum)->keyframe(ix -
            1)->time() *
            clip->cropDuration().frames(KdenliveSettings::defaultfps()) + 1);

      // Find the next keyframe position to make sure the current keyframe cannot be moved after the next one
      if (ix == effect->parameter(parameterNum)->numKeyFrames() - 1)
            nextTime = (uint)(clip->cropDuration().frames(KdenliveSettings::defaultfps()));
      else
            nextTime =(uint)(
            effect->parameter(parameterNum)->keyframe(ix +
            1)->time() *
            clip->cropDuration().frames(KdenliveSettings::defaultfps()) - 1);

      spinPosition->setMinValue(previousTime);
      spinPosition->setMaxValue(nextTime);
      sliderPosition->setMinValue(previousTime);
      sliderPosition->setMaxValue(nextTime);
      spinPosition->setValue(currentTime);
      m_blockUpdate = false;
      emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
    }


    void EffectStackDialog::changeKeyFramePosition(int newTime) {
      uint parameterNum = 0;
      double currentTime;
      DocClipRef *clip = m_effectList->clip();

      currentTime =
          newTime / clip->cropDuration().frames(KdenliveSettings::defaultfps());
      Effect *effect =
          clip->effectAt(m_effectList->
          selectedEffectIndex());
      if (!effect) return;
      int ix = effect->parameter(parameterNum)->selectedKeyFrame();
      effect->parameter(parameterNum)->keyframe(ix)->
          setTime(currentTime);

      if (!m_blockUpdate) {
            emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());

          QMap <QString, QString> params = effect->getParameters(m_effectList->clip());
          QString tag = effect->effectDescription().tag();

          kdDebug()<<" / / INSERTING EFFECT- "<<tag<<endl;
          if (tag != QString("framebuffer") && tag != QString("affine"))
            m_app->getDocument()->renderer()->mltEditEffect(m_effectList->clip()->playlistTrackNum(), m_effectList->clip()->trackMiddleTime(), m_effectList->selectedEffectIndex(), effect->effectDescription().stringId(), tag, params);
          else emit generateSceneList();
      }
    }


    void EffectStackDialog::changeKeyFrameValue(int newValue) {
      uint parameterNum = 0;
      //double currentTime;
      DocClipRef *clip = m_effectList->clip();
      Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
        if (!effect || !effect->parameter(parameterNum)) return;
      int ix = effect->parameter(parameterNum)->selectedKeyFrame();
      m_effecttype = effect->effectDescription().parameter(parameterNum)->type();
      if (m_effecttype == "double")
          effect->parameter(parameterNum)->keyframe(ix)->
            toDoubleKeyFrame()->setValue(newValue);
      else if (m_effecttype == "complex") {
          uint paramNum = effect->effectDescription().parameter(parameterNum)->complexParamNum();
          for (uint i = 0; i < paramNum; i++) {
            QString widgetName = QString("param");
            widgetName.append(QString::number(i));
            QSpinBox *sbox =
                dynamic_cast <
                QSpinBox * >(k_container->child(widgetName.ascii(),
                  "QSpinBox"));
            if (!sbox)
                kdWarning() <<
                  "EFFECTSTACKDIALOG ERROR, CANNOT FIND BOX: " << i
                  << endl;
            else {
                effect->parameter(parameterNum)->keyframe(ix)->
                  toComplexKeyFrame()->setValue(i,
                  QString::number(sbox->value()));
            }

          }
      }

      if (!m_blockUpdate) {
          emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
          QMap <QString, QString> params = effect->getParameters(m_effectList->clip());
          QString tag = effect->effectDescription().tag();

          kdDebug()<<" / / INSERTING EFFECT- "<<tag<<endl;
          if (tag != QString("framebuffer") && tag != QString("affine"))
            m_app->getDocument()->renderer()->mltEditEffect(m_effectList->clip()->playlistTrackNum(), m_effectList->clip()->trackMiddleTime(), m_effectList->selectedEffectIndex(), effect->effectDescription().stringId(), tag, params);
          else emit generateSceneList();
          m_app->focusTimelineWidget();
      }
    }


00962     void EffectStackDialog::slotSetEffectStack(DocClipRef * clip) {
      // remove all previous params
      cleanWidgets();
      disableButtons();
      tabWidget2->setTabEnabled(tabWidget2->page(1), false);
      m_effectList->setEffectStack(clip);
      if (m_effectList->childCount() > 0) enableButtons();
      if (!clip) return;
      
      //Effect *effect = clip->effectAt(m_effectList->selectedEffectIndex());
      emit redrawTrack(clip->trackNum(), clip->trackStart(), clip->trackEnd());
    }

}                       // namespace Gui

Generated by  Doxygen 1.6.0   Back to index