+#include <QTextStream>
+#include <QFile>
+#include <QInputDialog>
+
+
+EffectStackView::EffectStackView(Monitor *monitor, QWidget *parent) :
+ QWidget(parent),
+ m_monitor(monitor),
+ m_clipref(NULL),
+ m_trackMode(false),
+ m_trackindex(-1)
+{
+ m_ui.setupUi(this);
+ QVBoxLayout *vbox1 = new QVBoxLayout(m_ui.frame);
+ m_effectedit = new EffectStackEdit(monitor, m_ui.frame);
+ vbox1->setContentsMargins(0, 0, 0, 0);
+ vbox1->setSpacing(0);
+ vbox1->addWidget(m_effectedit);
+ m_ui.frame->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
+ //m_ui.region_url->fileDialog()->setFilter(ProjectList::getExtensions());
+ //m_ui.effectlist->horizontalHeader()->setVisible(false);
+ //m_ui.effectlist->verticalHeader()->setVisible(false);
+
+ m_ui.buttonNew->setIcon(KIcon("document-new"));
+ m_ui.buttonNew->setToolTip(i18n("Add new effect"));
+ m_ui.buttonUp->setIcon(KIcon("go-up"));
+ m_ui.buttonUp->setToolTip(i18n("Move effect up"));
+ m_ui.buttonDown->setIcon(KIcon("go-down"));
+ m_ui.buttonDown->setToolTip(i18n("Move effect down"));
+ m_ui.buttonDel->setIcon(KIcon("edit-delete"));
+ m_ui.buttonDel->setToolTip(i18n("Delete effect"));
+ m_ui.buttonSave->setIcon(KIcon("document-save"));
+ m_ui.buttonSave->setToolTip(i18n("Save effect"));
+ m_ui.buttonReset->setIcon(KIcon("view-refresh"));
+ m_ui.buttonReset->setToolTip(i18n("Reset effect"));
+ m_ui.checkAll->setToolTip(i18n("Enable/Disable all effects"));
+
+
+ m_ui.effectlist->setDragDropMode(QAbstractItemView::NoDragDrop); //use internal if drop is recognised right
+
+ //connect(m_ui.region_url, SIGNAL(urlSelected(const KUrl &)), this , SLOT(slotRegionChanged()));
+ //connect(m_ui.region_url, SIGNAL(returnPressed()), this , SLOT(slotRegionChanged()));
+ connect(m_ui.effectlist, SIGNAL(itemSelectionChanged()), this , SLOT(slotItemSelectionChanged()));
+ connect(m_ui.effectlist, SIGNAL(itemChanged(QListWidgetItem *)), this , SLOT(slotItemChanged(QListWidgetItem *)));
+ connect(m_ui.buttonUp, SIGNAL(clicked()), this, SLOT(slotItemUp()));
+ connect(m_ui.buttonDown, SIGNAL(clicked()), this, SLOT(slotItemDown()));
+ connect(m_ui.buttonDel, SIGNAL(clicked()), this, SLOT(slotItemDel()));
+ connect(m_ui.buttonSave, SIGNAL(clicked()), this, SLOT(slotSaveEffect()));
+ connect(m_ui.buttonReset, SIGNAL(clicked()), this, SLOT(slotResetEffect()));
+ connect(m_ui.checkAll, SIGNAL(stateChanged(int)), this, SLOT(slotCheckAll(int)));
+ connect(m_effectedit, SIGNAL(parameterChanged(const QDomElement, const QDomElement)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement)));
+ connect(m_effectedit, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int)));
+ connect(m_effectedit, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
+ connect(m_effectedit, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
+ connect(monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
+ m_effectLists["audio"] = &MainWindow::audioEffects;
+ m_effectLists["video"] = &MainWindow::videoEffects;
+ m_effectLists["custom"] = &MainWindow::customEffects;
+ m_ui.splitter->setStretchFactor(1, 10);
+ m_ui.splitter->setStretchFactor(0, 1);
+ setEnabled(false);
+}
+
+EffectStackView::~EffectStackView()
+{
+ m_effectLists.clear();
+ delete m_effectedit;
+}
+
+void EffectStackView::updateTimecodeFormat()
+{
+ m_effectedit->updateTimecodeFormat();
+}
+
+void EffectStackView::setMenu(QMenu *menu)
+{
+ m_ui.buttonNew->setMenu(menu);
+}
+
+void EffectStackView::updateProjectFormat(MltVideoProfile profile, Timecode t)
+{
+ m_effectedit->updateProjectFormat(profile, t);
+}
+
+void EffectStackView::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;
+
+ int i = m_ui.effectlist->currentRow();
+ QDomDocument doc;
+ QDomElement effect = m_currentEffectList.at(i).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 EffectStackView::slotUpdateEffectParams(const QDomElement old, const QDomElement e)
+{
+ if (m_trackMode)
+ emit updateEffect(NULL, m_trackindex, old, e, m_ui.effectlist->currentRow());
+ else if (m_clipref)
+ emit updateEffect(m_clipref, -1, old, e, m_ui.effectlist->currentRow());
+}
+
+void EffectStackView::slotClipItemSelected(ClipItem* c, int ix)
+{
+ if (c && !c->isEnabled()) return;
+ if (c && c == m_clipref) {
+ if (ix == -1) ix = m_ui.effectlist->currentRow();
+ //if (ix == -1 || ix == m_ui.effectlist->currentRow()) return;
+ } else {
+ m_clipref = c;
+ if (c) {
+ QString cname = m_clipref->clipName();
+ if (cname.length() > 20) {
+ m_ui.checkAll->setToolTip(i18n("Effects for %1").arg(cname));
+ cname.truncate(17);
+ m_ui.checkAll->setText(i18n("Effects for %1").arg(cname) + "...");
+ } else {
+ m_ui.checkAll->setToolTip(QString());
+ m_ui.checkAll->setText(i18n("Effects for %1").arg(cname));
+ }
+ ix = c->selectedEffectIndex();
+ QString size = c->baseClip()->getProperty("frame_size");
+ double factor = c->baseClip()->getProperty("aspect_ratio").toDouble();
+ QPoint p((int)(size.section('x', 0, 0).toInt() * factor + 0.5), size.section('x', 1, 1).toInt());
+ m_effectedit->setFrameSize(p);
+ m_effectedit->setFrameSize(p);
+ } else ix = 0;
+ }
+ if (m_clipref == NULL) {
+ m_ui.effectlist->blockSignals(true);
+ m_ui.effectlist->clear();
+ m_effectedit->transferParamDesc(QDomElement(), 0, 0, 0);
+ //m_ui.region_url->clear();
+ m_ui.effectlist->blockSignals(false);
+ m_ui.checkAll->setToolTip(QString());
+ m_ui.checkAll->setText(QString());
+ setEnabled(false);
+ return;
+ }
+ setEnabled(true);
+ m_trackMode = false;
+ m_currentEffectList = m_clipref->effectList();
+ setupListView(ix);
+}
+
+void EffectStackView::slotTrackItemSelected(int ix, const TrackInfo info)
+{
+ m_clipref = NULL;
+ m_trackMode = true;
+ m_currentEffectList = info.effectsList;
+ kDebug() << "// TRACK; " << ix << ", EFFECTS: " << m_currentEffectList.count();
+ setEnabled(true);
+ m_ui.checkAll->setToolTip(QString());
+ m_ui.checkAll->setText(i18n("Effects for track %1").arg(info.trackName.isEmpty() ? QString::number(ix) : info.trackName));
+ m_trackindex = ix;
+ setupListView(0);
+}
+
+void EffectStackView::slotItemChanged(QListWidgetItem *item)
+{
+ bool disable = true;
+ if (item->checkState() == Qt::Checked) disable = false;
+ m_ui.frame_layout->setEnabled(!disable);
+ m_ui.buttonReset->setEnabled(!disable);
+ int activeRow = m_ui.effectlist->currentRow();
+ if (activeRow >= 0) {
+ m_effectedit->updateParameter("disable", QString::number((int) disable));
+ if (m_trackMode) emit changeEffectState(NULL, m_trackindex, activeRow, disable);
+ else emit changeEffectState(m_clipref, -1, activeRow, disable);
+ }
+ slotUpdateCheckAllButton();
+}
+
+
+void EffectStackView::setupListView(int ix)
+{
+ m_ui.effectlist->blockSignals(true);
+ m_ui.effectlist->clear();