<parameter type="url" name="resource" default="">
<name>Url</name>
</parameter>
+ <parameter type="geometry" name="composite.geometry" default="0%,0%:100%x100%" fixed="1" opacity="false">
+ <name>Pan and Zoom</name>
+ </parameter>
<parameter type="fixed" name="filter_only" min="1" max="1" default="1" />
</effect>
QString profile = args.takeFirst();
QString rendermodule = args.takeFirst();
QString player = args.takeFirst();
- QString src = args.takeFirst();
+ QUrl srcurl = QUrl::fromEncoded(args.takeFirst().toUtf8());
+ QString src = srcurl.path();
QUrl desturl = QUrl::fromEncoded(args.takeFirst().toUtf8());
QString dest = desturl.path();
bool dualpass = false;
widgets/clipproperties_ui.ui
widgets/cliptranscode_ui.ui
widgets/collapsiblewidget_ui.ui
- widgets/collapsiblegroup_ui.ui
widgets/clipstabilize_ui.ui
widgets/colorclip_ui.ui
widgets/colorplaneexport_ui.ui
}
}
+void ClipItem::enableEffects(QList <int> indexes, bool disable)
+{
+ m_effectList.enableEffects(indexes, disable);
+}
+
bool ClipItem::moveEffect(QDomElement effect, int ix)
{
if (ix <= 0 || ix > (m_effectList.count()) || effect.isNull()) {
* @param ix The effect's index in effectlist
* @param effect The new effect */
void updateEffect(QDomElement effect);
+ /** @brief Enable / disable a list of effect from their indexes. */
+ void enableEffects(QList <int> indexes, bool disable);
bool moveEffect(QDomElement effect, int ix);
void flashClip();
void addTransition(Transition*);
commands/addtrackcommand.cpp
commands/addtransitioncommand.cpp
commands/changecliptypecommand.cpp
+ commands/changeeffectstatecommand.cpp
commands/changespeedcommand.cpp
commands/configtrackscommand.cpp
commands/editclipcommand.cpp
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * *
+ * 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. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#include "changeeffectstatecommand.h"
+#include "customtrackview.h"
+
+#include <KLocale>
+
+ChangeEffectStateCommand::ChangeEffectStateCommand(CustomTrackView *view, const int track, GenTime pos, QList <int> effectIndexes, bool disable, bool refreshEffectStack, bool doIt, QUndoCommand *parent) :
+ QUndoCommand(parent),
+ m_view(view),
+ m_track(track),
+ m_effectIndexes(effectIndexes),
+ m_pos(pos),
+ m_disable(disable),
+ m_doIt(doIt),
+ m_refreshEffectStack(refreshEffectStack)
+{
+ if (disable)
+ setText(i18np("Disable effect", "Disable effects", effectIndexes.count()));
+ else
+ setText(i18np("Enable effect", "Enable effects", effectIndexes.count()));
+}
+
+// virtual
+void ChangeEffectStateCommand::undo()
+{
+ m_view->updateEffectState(m_track, m_pos, m_effectIndexes, !m_disable, true);
+}
+// virtual
+void ChangeEffectStateCommand::redo()
+{
+ if (m_doIt) m_view->updateEffectState(m_track, m_pos, m_effectIndexes, m_disable, m_refreshEffectStack);
+ m_doIt = true;
+ m_refreshEffectStack = true;
+}
+
+
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * *
+ * 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. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#ifndef CHANGEEFFECTSTATECOMMAND_H
+#define CHANGEEFFECTSTATECOMMAND_H
+
+#include <QUndoCommand>
+#include <KDebug>
+#include <gentime.h>
+#include <QDomElement>
+
+class CustomTrackView;
+
+class ChangeEffectStateCommand : public QUndoCommand
+{
+public:
+ ChangeEffectStateCommand(CustomTrackView *view, const int track, GenTime pos, QList <int> effectIndexes, bool disable, bool refreshEffectStack, bool doIt, QUndoCommand *parent = 0);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ CustomTrackView *m_view;
+ const int m_track;
+ QList <int> m_effectIndexes;
+ const GenTime m_pos;
+ bool m_disable;
+ bool m_doIt;
+ bool m_refreshEffectStack;
+};
+
+#endif
+
// virtual
void EditEffectCommand::undo()
{
- m_view->updateEffect(m_track, m_pos, m_oldeffect, m_stackPos, true);
+ m_view->updateEffect(m_track, m_pos, m_oldeffect, true);
}
// virtual
void EditEffectCommand::redo()
{
- if (m_doIt) m_view->updateEffect(m_track, m_pos, m_effect, m_stackPos, m_refreshEffectStack);
+ if (m_doIt) m_view->updateEffect(m_track, m_pos, m_effect, m_refreshEffectStack);
m_doIt = true;
m_refreshEffectStack = true;
}
m_pos(0)
{
MonitorEditWidget *edit = monitor->getEffectEdit();
- edit->showVisibilityButton(true);
m_scene = edit->getScene();
m_scene->cleanup();
edit->addCustomButton(KIcon("insert-horizontal-rule"), i18n("Show/Hide the lines connecting the corners"), this, SLOT(slotShowLines(bool)),
true, KdenliveSettings::onmonitoreffects_cornersshowlines());
- connect(edit, SIGNAL(showEdit(bool)), this, SLOT(slotShowScene(bool)));
- connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateProperties()));
connect(m_scene, SIGNAL(addKeyframe()), this, SLOT(slotInsertKeyframe()));
delete m_item;
if (m_monitor) {
MonitorEditWidget *edit = m_monitor->getEffectEdit();
- edit->showVisibilityButton(false);
edit->removeCustomControls();
- m_monitor->slotEffectScene(false);
}
}
return points;
}
-void CornersWidget::slotCheckMonitorPosition(int renderPos)
-{
- if (m_showScene)
- emit checkMonitorPosition(renderPos);
-}
-
-void CornersWidget::slotShowScene(bool show)
-{
- m_showScene = show;
- if (!m_showScene)
- m_monitor->slotEffectScene(false);
- else
- slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
-}
void CornersWidget::slotShowLines(bool show)
{
virtual void addParameter(QDomElement e, int activeKeyframe = -1);
public slots:
- /** @brief Switches from normal monitor to monitor scene according to @param show. */
- void slotShowScene(bool show = true);
/** @brief Updates the on-monitor item. */
void slotSyncPosition(int relTimelinePos);
QList <QPointF> getPoints(QTableWidgetItem *keyframe);
private slots:
- /** @brief Makes sure the monitor effect scene is only visible if the clip this geometry belongs to is visible.
- * @param renderPos Postion of the Monitor / Timeline cursor */
- void slotCheckMonitorPosition(int renderPos);
/** @brief Updates the on-monitor item according to the current timeline position. */
void slotUpdateItem();
/** @brief Shows/Hides additional controls on the monitor according to @param show. */
void slotShowControls(bool show = true);
-
-signals:
- void checkMonitorPosition(int);
};
#endif
#include "commands/insertspacecommand.h"
#include "spacerdialog.h"
#include "commands/addtrackcommand.h"
+#include "commands/changeeffectstatecommand.h"
#include "commands/movegroupcommand.h"
#include "ui_addtrack_ui.h"
#include "initeffects.h"
EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false, false);
//EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false);
m_commandStack->push(command);
- updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
+ updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect());
emit clipItemSelected(item, item->selectedEffectIndex());
}
} else if (m_dragItem && !m_dragItem->isItemLocked()) {
setDocumentModified();
}
-void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement insertedEffect, int ix, bool updateEffectStack)
+void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement insertedEffect, bool updateEffectStack)
{
if (insertedEffect.isNull()) {
+ kDebug()<<"// Trying to add null effect";
emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
return;
}
+ int ix = insertedEffect.attribute("kdenlive_ix").toInt();
QDomElement effect = insertedEffect.cloneNode().toElement();
//kDebug() << "// update effect ix: " << effect.attribute("kdenlive_ix")<<", GAIN: "<<EffectsList::parameter(effect, "gain");
if (pos < GenTime()) {
clip->initEffect(effect);
effectParams = getEffectArgs(effect);
}*/
- if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - track, pos, effectParams))
+ if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - track, pos, effectParams)) {
emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+ }
m_document->setTrackEffect(m_document->tracksCount() - track - 1, ix, effect);
emit updateTrackEffectState(track);
setDocumentModified();
if (ix == clip->selectedEffectIndex()) {
// make sure to update display of clip keyframes
clip->setSelectedEffect(ix);
- } else emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+ }
return;
}
setDocumentModified();
}
+void CustomTrackView::updateEffectState(int track, GenTime pos, QList <int> effectIndexes, bool disable, bool updateEffectStack)
+{
+ if (pos < GenTime()) {
+ // editing a track effect
+ if (!m_document->renderer()->mltEnableEffects(m_document->tracksCount() - track, pos, effectIndexes, disable)) {
+ emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+ return;
+ }
+ m_document->enableTrackEffects(m_document->tracksCount() - track - 1, effectIndexes, disable);
+ emit updateTrackEffectState(track);
+ setDocumentModified();
+ return;
+ }
+ // editing a clip effect
+ ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
+ if (clip) {
+ bool success = m_document->renderer()->mltEnableEffects(m_document->tracksCount() - clip->track(), clip->startPos(), effectIndexes, disable);
+ if (success) {
+ clip->enableEffects(effectIndexes, disable);
+ if (updateEffectStack && clip->isSelected()) {
+ emit clipItemSelected(clip);
+ }
+ if (effectIndexes.contains(clip->selectedEffectIndex())) {
+ // make sure to update display of clip keyframes
+ clip->setSelectedEffect(clip->selectedEffectIndex());
+ }
+ }
+ else emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+ }
+ else emit displayMessage(i18n("Cannot find clip to update effect"), ErrorMessage);
+}
+
void CustomTrackView::moveEffect(int track, GenTime pos, QList <int> oldPos, QList <int> newPos)
{
if (pos < GenTime()) {
} else emit displayMessage(i18n("Cannot move effect"), ErrorMessage);
}
-void CustomTrackView::slotChangeEffectState(ClipItem *clip, int track, int effectPos, bool disable)
+void CustomTrackView::slotChangeEffectState(ClipItem *clip, int track, QList <int> effectIndexes, bool disable)
{
- EditEffectCommand *command;
- QDomElement effect;
- if (clip == NULL) effect = m_document->getTrackEffect(track - 1, effectPos);
- else effect = clip->effectAt(effectPos);
- QDomElement oldEffect = effect.cloneNode().toElement();
- effect.setAttribute("disable", (int) disable);
-
-
+ ChangeEffectStateCommand *command;
if (clip == NULL) {
// editing track effect
- command = new EditEffectCommand(this, m_document->tracksCount() - track, GenTime(-1), oldEffect, effect, effectPos, false, true);
+ command = new ChangeEffectStateCommand(this, m_document->tracksCount() - track, GenTime(-1), effectIndexes, disable, false, true);
} else {
- command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, false, true);
+ // Check if we have a speed effect, disabling / enabling it needs a special procedure since it is a pseudoo effect
+ QList <int> speedEffectIndexes;
+ for (int i = 0; i < effectIndexes.count(); i++) {
+ QDomElement effect = clip->effectAt(effectIndexes.at(i));
+ if (effect.attribute("id") == "speed") {
+ // speed effect
+ speedEffectIndexes << effectIndexes.at(i);
+ QDomElement newEffect = effect.cloneNode().toElement();
+ newEffect.setAttribute("disable", (int) disable);
+ EditEffectCommand *editcommand = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effect, newEffect, effectIndexes.at(i), false, true);
+ m_commandStack->push(editcommand);
+ }
+ }
+ for (int j = 0; j < speedEffectIndexes.count(); j++) {
+ effectIndexes.removeAll(speedEffectIndexes.at(j));
+ }
+ command = new ChangeEffectStateCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effectIndexes, disable, false, true);
}
m_commandStack->push(command);
- setDocumentModified();;
+ setDocumentModified();
}
void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int track, QList <int> currentPos, int newPos)
EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false, false);
m_commandStack->push(command);
- updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
+ updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect());
emit clipItemSelected(item);
}
if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET && m_dragItem->isSelected()) {
void slotAddGroupEffect(QDomElement effect, AbstractGroupItem *group);
void addEffect(int track, GenTime pos, QDomElement effect);
void deleteEffect(int track, GenTime pos, QDomElement effect);
- void updateEffect(int track, GenTime pos, QDomElement insertedEffect, int ix, bool refreshEffectStack = false);
+ void updateEffect(int track, GenTime pos, QDomElement insertedEffect, bool refreshEffectStack = false);
+ /** @brief Enable / disable a list of effects */
+ void updateEffectState(int track, GenTime pos, QList <int> effectIndexes, bool disable, bool updateEffectStack);
void moveEffect(int track, GenTime pos, QList <int> oldPos, QList <int> newPos);
void addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params, bool refresh);
void deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params, bool refresh);
void moveCursorPos(int delta);
void updateCursorPos();
void slotDeleteEffect(ClipItem *clip, int track, QDomElement effect, bool affectGroup = true);
- void slotChangeEffectState(ClipItem *clip, int track, int effectPos, bool disable);
+ void slotChangeEffectState(ClipItem *clip, int track, QList <int> effectIndexes, bool disable);
void slotChangeEffectPosition(ClipItem *clip, int track, QList <int> currentPos, int newPos);
void slotUpdateClipEffect(ClipItem *clip, int track, QDomElement oldeffect, QDomElement effect, int ix, bool refreshEffectStack = true);
void slotUpdateClipRegion(ClipItem *clip, int ix, QString region);
}
}
+void EffectsList::enableEffects(QList <int> indexes, bool disable)
+{
+ QDomNodeList effects = m_baseElement.childNodes();
+ QDomElement effect;
+ for (int i = 0; i < indexes.count(); i++) {
+ effect = effectFromIndex(effects, indexes.at(i));
+ effect.setAttribute("disable", (int) disable);
+ }
+}
+
QDomElement EffectsList::effectFromIndex(QDomNodeList effects, int ix)
{
if (ix <= 0 || ix > effects.count()) return QDomElement();
QDomElement effectFromIndex(QDomNodeList effects, int ix);
/** @brief Update all effects indexes to make sure they are 1, 2, 3, ... */
void updateIndexes(QDomNodeList effects, int startIndex);
+ /** @brief Enable / disable a list of effects */
+ void enableEffects(QList <int> indexes, bool disable);
private:
QDomElement m_baseElement;
set(kdenlive_SRCS
${kdenlive_SRCS}
+ effectstack/parametercontainer.cpp
effectstack/abstractcollapsiblewidget.cpp
effectstack/collapsibleeffect.cpp
effectstack/collapsiblegroup.cpp
AbstractCollapsibleWidget::AbstractCollapsibleWidget(QWidget * parent) :
QWidget(parent)
{
-
-}
\ No newline at end of file
+ setupUi(this);
+}
#ifndef ABSTRACTCOLLAPSIBLEWIDGET_H
#define ABSTRACTCOLLAPSIBLEWIDGET_H
+#include "ui_collapsiblewidget_ui.h"
+
#include <QWidget>
+#include <QDomElement>
-class AbstractCollapsibleWidget : public QWidget
+class AbstractCollapsibleWidget : public QWidget, public Ui::CollapsibleWidget_UI
{
Q_OBJECT
AbstractCollapsibleWidget(QWidget * parent = 0);
virtual void setActive(bool activate) = 0;
virtual bool isGroup() const = 0;
+
+signals:
+ void addEffect(QDomElement e);
+ /** @brief Move effects in the stack one step up or down. */
+ void changeEffectPosition(QList <int>, bool upwards);
+ /** @brief Move effects in the stack. */
+ void moveEffect(QList <int> current_pos, int new_pos, int groupIndex, QString groupName);
+ /** @brief An effect was saved, trigger effect list reload. */
+ void reloadEffects();
};
#include "collapsibleeffect.h"
-
-#include "ui_listval_ui.h"
-#include "ui_boolval_ui.h"
-#include "ui_wipeval_ui.h"
-#include "ui_urlval_ui.h"
-#include "ui_keywordval_ui.h"
-#include "ui_fontval_ui.h"
-#include "complexparameter.h"
-#include "geometryval.h"
-#include "positionedit.h"
-#include "projectlist.h"
#include "effectslist.h"
#include "kdenlivesettings.h"
-#include "profilesdialog.h"
-#include "kis_curve_widget.h"
-#include "kis_cubic_curve.h"
-#include "choosecolorwidget.h"
-#include "geometrywidget.h"
-#include "colortools.h"
-#include "doubleparameterwidget.h"
-#include "cornerswidget.h"
-#include "dragvalue.h"
-#include "beziercurve/beziersplinewidget.h"
-#ifdef USE_QJSON
-#include "rotoscoping/rotowidget.h"
-#endif
+#include "projectlist.h"
#include <QInputDialog>
#include <QDialog>
#include <QMenu>
#include <QVBoxLayout>
+#include <QLabel>
+#include <QProgressBar>
+#include <QWheelEvent>
#include <KDebug>
+#include <KComboBox>
#include <KGlobalSettings>
#include <KLocale>
#include <KMessageBox>
#include <KStandardDirs>
#include <KFileDialog>
-#include <KUrlRequester>
-#include <KColorScheme>
-#include <KColorUtils>
#include <KApplication>
-class Boolval: public QWidget, public Ui::Boolval_UI
-{
-};
-
-class Listval: public QWidget, public Ui::Listval_UI
-{
-};
-
-class Wipeval: public QWidget, public Ui::Wipeval_UI
-{
-};
-
-class Urlval: public QWidget, public Ui::Urlval_UI
-{
-};
-
-class Keywordval: public QWidget, public Ui::Keywordval_UI
-{
-};
-
-class Fontval: public QWidget, public Ui::Fontval_UI
-{
-};
-
-QMap<QString, QImage> CollapsibleEffect::iconCache;
-
-void clearLayout(QLayout *layout)
-{
- QLayoutItem *item;
- while((item = layout->takeAt(0))) {
- if (item->layout()) {
- clearLayout(item->layout());
- delete item->layout();
- }
- if (item->widget()) {
- delete item->widget();
- }
- delete item;
- }
-}
-
-MySpinBox::MySpinBox(QWidget * parent):
- QSpinBox(parent)
-{
- setFocusPolicy(Qt::StrongFocus);
-}
-
-void MySpinBox::focusInEvent(QFocusEvent *e)
-{
- setFocusPolicy(Qt::WheelFocus);
- e->accept();
-}
-
-void MySpinBox::focusOutEvent(QFocusEvent *e)
-{
- setFocusPolicy(Qt::StrongFocus);
- e->accept();
-}
-
CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_effect, ItemInfo info, EffectMetaInfo *metaInfo, bool lastEffect, QWidget * parent) :
AbstractCollapsibleWidget(parent),
m_lastEffect(lastEffect),
m_regionEffect(false)
{
- setupUi(this);
if (m_effect.attribute("tag") == "region") {
m_regionEffect = true;
decoframe->setObjectName("decoframegroup");
//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()));
if (namenode.isNull()) return;
QString effectname = i18n(namenode.text().toUtf8().data());
if (m_regionEffect) effectname.append(":" + KUrl(EffectsList::parameter(m_effect, "resource")).fileName());
+
+ QHBoxLayout *l = static_cast <QHBoxLayout *>(frame->layout());
+ title = new QLabel(this);
+ l->insertWidget(2, title);
+
title->setText(effectname);
/*
* Do not show icon, makes too much visual noise
else if (type == "custom") icon = KIcon("kdenlive-custom-effect");
else icon = KIcon("kdenlive-show-video");
effecticon->setPixmap(icon.pixmap(16,16));*/
-
+ m_groupAction = new QAction(KIcon("folder-new"), i18n("Create Group"), this);
+ connect(m_groupAction, SIGNAL(triggered(bool)), this, SLOT(slotCreateGroup()));
if (!m_regionEffect) {
- m_menu->addAction(KIcon("folder-new"), i18n("Create Group"), this, SLOT(slotCreateGroup()));
+ if (m_info.groupIndex == -1) m_menu->addAction(m_groupAction);
m_menu->addAction(KIcon("folder-new"), i18n("Create Region"), this, SLOT(slotCreateRegion()));
}
setupWidget(info, metaInfo);
delete m_menu;
}
-//static
-const QString CollapsibleEffect::getStyleSheet()
-{
- KColorScheme scheme(QApplication::palette().currentColorGroup(), KColorScheme::View, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
- QColor selected_bg = scheme.decoration(KColorScheme::FocusColor).color();
- QColor hgh = KColorUtils::mix(QApplication::palette().window().color(), selected_bg, 0.2);
- QColor hover_bg = scheme.decoration(KColorScheme::HoverColor).color();
- QColor light_bg = scheme.shade(KColorScheme::LightShade);
- QColor alt_bg = scheme.background(KColorScheme::NormalBackground).color();
-
- QString stylesheet;
-
- // group editable labels
- stylesheet.append(QString("MyEditableLabel { background-color: transparent;color: palette(bright-text);} "));
-
- // effect background
- stylesheet.append(QString("QFrame#decoframe {border-top-left-radius:5px;border-top-right-radius:5px;border-bottom:2px solid palette(mid);border-top:1px solid palette(light);} QFrame#decoframe[active=\"true\"] {background: %1;}").arg(hgh.name()));
-
- // effect in group background
- stylesheet.append(QString("QFrame#decoframesub {border-top:1px solid palette(light);} QFrame#decoframesub[active=\"true\"] {background: %1;}").arg(hgh.name()));
-
- // group background
- stylesheet.append(QString("QFrame#decoframegroup {border-top-left-radius:5px;border-top-right-radius:5px;border:2px solid palette(dark);margin:0px;margin-top:2px;} "));
-
- // effect title bar
- stylesheet.append(QString("QFrame#frame {margin-bottom:2px;border-top-left-radius:5px;border-top-right-radius:5px;} QFrame#frame[target=\"true\"] {background: palette(highlight);}"));
-
- // group effect title bar
- stylesheet.append(QString("QFrame#framegroup {border-top-left-radius:2px;border-top-right-radius:2px;background: palette(dark);} QFrame#framegroup[target=\"true\"] {background: palette(highlight);} "));
-
- // draggable effect bar content
- stylesheet.append(QString("QProgressBar::chunk:horizontal {background: palette(button);border-top-left-radius: 4px;border-bottom-left-radius: 4px;} QProgressBar::chunk:horizontal#dragOnly {background: %1;border-top-left-radius: 4px;border-bottom-left-radius: 4px;} QProgressBar::chunk:horizontal:hover {background: %2;}").arg(alt_bg.name()).arg(selected_bg.name()));
-
- // draggable effect bar
- stylesheet.append(QString("QProgressBar:horizontal {border: 1px solid palette(dark);border-top-left-radius: 4px;border-bottom-left-radius: 4px;border-right:0px;background:%3;padding: 0px;text-align:left center} QProgressBar:horizontal:disabled {border: 1px solid palette(button)} QProgressBar:horizontal#dragOnly {background: %3} QProgressBar:horizontal[inTimeline=\"true\"] { border: 1px solid %1;border-right: 0px;background: %2;padding: 0px;text-align:left center } QProgressBar::chunk:horizontal[inTimeline=\"true\"] {background: %1;}").arg(hover_bg.name()).arg(light_bg.name()).arg(alt_bg.name()));
-
- // spin box for draggable widget
- stylesheet.append(QString("QAbstractSpinBox#dragBox {border: 1px solid palette(dark);border-top-right-radius: 4px;border-bottom-right-radius: 4px;padding-right:0px;} QAbstractSpinBox::down-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox:disabled#dragBox {border: 1px solid palette(button);} QAbstractSpinBox::up-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox[inTimeline=\"true\"]#dragBox { border: 1px solid %1;} QAbstractSpinBox:hover#dragBox {border: 1px solid %2;} ").arg(hover_bg.name()).arg(selected_bg.name()));
-
- return stylesheet;
-}
-
void CollapsibleEffect::slotCreateGroup()
{
emit createGroup(effectIndex());
QWidget::mouseReleaseEvent(event);
}
-void CollapsibleEffect::slotEnable(bool disable, bool updateMainStatus)
+void CollapsibleEffect::slotEnable(bool disable, bool emitInfo)
{
title->setEnabled(!disable);
enabledButton->blockSignals(true);
if (!disable || KdenliveSettings::disable_effect_parameters()) {
widgetFrame->setEnabled(!disable);
}
- emit effectStateChanged(disable, effectIndex(), updateMainStatus);
+ if (emitInfo) emit effectStateChanged(disable, effectIndex(), isActive() && needsMonitorEffectScene());
}
void CollapsibleEffect::slotDeleteEffect()
void CollapsibleEffect::slotEffectUp()
{
- emit changeEffectPosition(effectIndex(), true);
+ emit changeEffectPosition(QList <int>() <<effectIndex(), true);
}
void CollapsibleEffect::slotEffectDown()
{
- emit changeEffectPosition(effectIndex(), false);
+ emit changeEffectPosition(QList <int>() <<effectIndex(), false);
}
void CollapsibleEffect::slotSaveEffect()
void CollapsibleEffect::setGroupIndex(int ix)
{
+ if (m_info.groupIndex == -1 && ix != -1) {
+ m_menu->removeAction(m_groupAction);
+ }
+ else if (m_info.groupIndex != -1 && ix == -1) {
+ m_menu->addAction(m_groupAction);
+ }
m_info.groupIndex = ix;
m_effect.setAttribute("kdenlive_info", m_info.toString());
}
void CollapsibleEffect::removeFromGroup()
{
+ if (m_info.groupIndex != -1) {
+ m_menu->addAction(m_groupAction);
+ }
m_info.groupIndex = -1;
m_info.groupName.clear();
m_effect.setAttribute("kdenlive_info", m_info.toString());
if (m_effect.attribute("tag") == "region") {
m_regionEffect = true;
- QVBoxLayout *vbox = new QVBoxLayout(widgetFrame);
- vbox->setContentsMargins(0, 0, 0, 0);
- vbox->setSpacing(2);
QDomNodeList effects = m_effect.elementsByTagName("effect");
QDomNodeList origin_effects = m_original_effect.elementsByTagName("effect");
+ m_paramWidget = new ParameterContainer(m_effect, info, metaInfo, widgetFrame);
QWidget *container = new QWidget(widgetFrame);
+ QVBoxLayout *vbox = static_cast<QVBoxLayout *> (widgetFrame->layout());
vbox->addWidget(container);
// m_paramWidget = new ParameterContainer(m_effect.toElement(), info, metaInfo, container);
for (int i = 0; i < effects.count(); i++) {
connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString)));
connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int)));
- connect (this, SIGNAL(effectStateChanged(bool)), m_paramWidget, SIGNAL(effectStateChanged(bool)));
connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
connect (m_paramWidget, SIGNAL(seekTimeline(int)), this, SIGNAL(seekTimeline(int)));
event->accept();
}
-ParameterContainer::ParameterContainer(QDomElement effect, ItemInfo info, EffectMetaInfo *metaInfo, QWidget * parent) :
- m_keyframeEditor(NULL),
- m_geometryWidget(NULL),
- m_metaInfo(metaInfo),
- m_effect(effect)
-{
- m_in = info.cropStart.frames(KdenliveSettings::project_fps());
- m_out = (info.cropStart + info.cropDuration).frames(KdenliveSettings::project_fps()) - 1;
-
- QDomNodeList namenode = effect.childNodes(); //elementsByTagName("parameter");
-
- QDomElement e = effect.toElement();
- int minFrame = e.attribute("start").toInt();
- int maxFrame = e.attribute("end").toInt();
- // In transitions, maxFrame is in fact one frame after the end of transition
- if (maxFrame > 0) maxFrame --;
-
- bool disable = effect.attribute("disable") == "1" && KdenliveSettings::disable_effect_parameters();
- parent->setEnabled(!disable);
-
- bool stretch = true;
- m_vbox = new QVBoxLayout(parent);
- m_vbox->setContentsMargins(4, 0, 4, 0);
- m_vbox->setSpacing(2);
-
- for (int i = 0; i < namenode.count() ; i++) {
- QDomElement pa = namenode.item(i).toElement();
- if (pa.tagName() != "parameter") continue;
- QDomElement na = pa.firstChildElement("name");
- QDomElement commentElem = pa.firstChildElement("comment");
- QString type = pa.attribute("type");
- QString paramName = na.isNull() ? pa.attribute("name") : i18n(na.text().toUtf8().data());
- QString comment;
- if (!commentElem.isNull())
- comment = i18n(commentElem.text().toUtf8().data());
- QWidget * toFillin = new QWidget(parent);
- QString value = pa.attribute("value").isNull() ?
- pa.attribute("default") : pa.attribute("value");
-
- /** See effects/README for info on the different types */
-
- if (type == "double" || type == "constant") {
- double min;
- double max;
- if (pa.attribute("min").contains('%'))
- min = ProfilesDialog::getStringEval(m_metaInfo->profile, pa.attribute("min"), m_metaInfo->frameSize);
- else
- min = pa.attribute("min").toDouble();
- if (pa.attribute("max").contains('%'))
- max = ProfilesDialog::getStringEval(m_metaInfo->profile, pa.attribute("max"), m_metaInfo->frameSize);
- else
- max = pa.attribute("max").toDouble();
-
- DoubleParameterWidget *doubleparam = new DoubleParameterWidget(paramName, value.toDouble(), min, max,
- pa.attribute("default").toDouble(), comment, -1, pa.attribute("suffix"), pa.attribute("decimals").toInt(), parent);
- doubleparam->setFocusPolicy(Qt::StrongFocus);
- m_vbox->addWidget(doubleparam);
- m_valueItems[paramName] = doubleparam;
- connect(doubleparam, SIGNAL(valueChanged(double)), this, SLOT(slotCollectAllParameters()));
- connect(this, SIGNAL(showComments(bool)), doubleparam, SLOT(slotShowComment(bool)));
- } else if (type == "list") {
- Listval *lsval = new Listval;
- lsval->setupUi(toFillin);
- lsval->list->setFocusPolicy(Qt::StrongFocus);
- QStringList listitems = pa.attribute("paramlist").split(';');
- if (listitems.count() == 1) {
- // probably custom effect created before change to ';' as separator
- listitems = pa.attribute("paramlist").split(",");
- }
- QDomElement list = pa.firstChildElement("paramlistdisplay");
- QStringList listitemsdisplay;
- if (!list.isNull()) {
- listitemsdisplay = i18n(list.text().toUtf8().data()).split(',');
- } else {
- listitemsdisplay = i18n(pa.attribute("paramlistdisplay").toUtf8().data()).split(',');
- }
- if (listitemsdisplay.count() != listitems.count())
- listitemsdisplay = listitems;
- lsval->list->setIconSize(QSize(30, 30));
- for (int i = 0; i < listitems.count(); i++) {
- lsval->list->addItem(listitemsdisplay.at(i), listitems.at(i));
- QString entry = listitems.at(i);
- if (!entry.isEmpty() && (entry.endsWith(".png") || entry.endsWith(".pgm"))) {
- if (!CollapsibleEffect::iconCache.contains(entry)) {
- QImage pix(entry);
- CollapsibleEffect::iconCache[entry] = pix.scaled(30, 30);
- }
- lsval->list->setItemIcon(i, QPixmap::fromImage(CollapsibleEffect::iconCache[entry]));
- }
- }
- if (!value.isEmpty()) lsval->list->setCurrentIndex(listitems.indexOf(value));
- lsval->name->setText(paramName);
- lsval->labelComment->setText(comment);
- lsval->widgetComment->setHidden(true);
- m_valueItems[paramName] = lsval;
- connect(lsval->list, SIGNAL(currentIndexChanged(int)) , this, SLOT(slotCollectAllParameters()));
- if (!comment.isEmpty())
- connect(this, SIGNAL(showComments(bool)), lsval->widgetComment, SLOT(setVisible(bool)));
- m_uiItems.append(lsval);
- } else if (type == "bool") {
- Boolval *bval = new Boolval;
- bval->setupUi(toFillin);
- bval->checkBox->setCheckState(value == "0" ? Qt::Unchecked : Qt::Checked);
- bval->name->setText(paramName);
- bval->labelComment->setText(comment);
- bval->widgetComment->setHidden(true);
- m_valueItems[paramName] = bval;
- connect(bval->checkBox, SIGNAL(stateChanged(int)) , this, SLOT(slotCollectAllParameters()));
- if (!comment.isEmpty())
- connect(this, SIGNAL(showComments(bool)), bval->widgetComment, SLOT(setVisible(bool)));
- m_uiItems.append(bval);
- } else if (type == "complex") {
- ComplexParameter *pl = new ComplexParameter;
- pl->setupParam(effect, pa.attribute("name"), 0, 100);
- m_vbox->addWidget(pl);
- m_valueItems[paramName+"complex"] = pl;
- connect(pl, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- } else if (type == "geometry") {
- if (KdenliveSettings::on_monitor_effects()) {
- m_geometryWidget = new GeometryWidget(m_metaInfo->monitor, m_metaInfo->timecode, 0, true, effect.hasAttribute("showrotation"), parent);
- m_geometryWidget->setFrameSize(m_metaInfo->frameSize);
- m_geometryWidget->slotShowScene(!disable);
- // connect this before setupParam to make sure the monitor scene shows up at startup
- connect(m_geometryWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(m_geometryWidget, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- if (minFrame == maxFrame)
- m_geometryWidget->setupParam(pa, m_in, m_out);
- else
- m_geometryWidget->setupParam(pa, minFrame, maxFrame);
- m_vbox->addWidget(m_geometryWidget);
- m_valueItems[paramName+"geometry"] = m_geometryWidget;
- connect(m_geometryWidget, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), m_geometryWidget, SLOT(slotShowScene(bool)));
- } else {
- Geometryval *geo = new Geometryval(m_metaInfo->profile, m_metaInfo->timecode, m_metaInfo->frameSize, 0);
- if (minFrame == maxFrame)
- geo->setupParam(pa, m_in, m_out);
- else
- geo->setupParam(pa, minFrame, maxFrame);
- m_vbox->addWidget(geo);
- m_valueItems[paramName+"geometry"] = geo;
- connect(geo, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), geo, SLOT(slotSyncPosition(int)));
- }
- } else if (type == "addedgeometry") {
- // this is a parameter that should be linked to the geometry widget, for example rotation, shear, ...
- if (m_geometryWidget) m_geometryWidget->addParameter(pa);
- } else if (type == "keyframe" || type == "simplekeyframe") {
- // keyframe editor widget
- if (m_keyframeEditor == NULL) {
- KeyframeEdit *geo;
- if (pa.attribute("widget") == "corners") {
- // we want a corners-keyframe-widget
- CornersWidget *corners = new CornersWidget(m_metaInfo->monitor, pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt(), parent);
- corners->slotShowScene(!disable);
- connect(corners, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), corners, SLOT(slotShowScene(bool)));
- connect(this, SIGNAL(syncEffectsPos(int)), corners, SLOT(slotSyncPosition(int)));
- geo = static_cast<KeyframeEdit *>(corners);
- } else {
- geo = new KeyframeEdit(pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt());
- }
- m_vbox->addWidget(geo);
- m_valueItems[paramName+"keyframe"] = geo;
- m_keyframeEditor = geo;
- connect(geo, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(showComments(bool)), geo, SIGNAL(showComments(bool)));
- } else {
- // we already have a keyframe editor, so just add another column for the new param
- m_keyframeEditor->addParameter(pa);
- }
- } else if (type == "color") {
- if (pa.hasAttribute("paramprefix")) value.remove(0, pa.attribute("paramprefix").size());
- if (value.startsWith('#'))
- value = value.replace('#', "0x");
- ChooseColorWidget *choosecolor = new ChooseColorWidget(paramName, value, parent);
- choosecolor->setAlphaChannelEnabled(true);
- m_vbox->addWidget(choosecolor);
- m_valueItems[paramName] = choosecolor;
- connect(choosecolor, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
- connect(choosecolor, SIGNAL(modified()) , this, SLOT(slotCollectAllParameters()));
- } else if (type == "position") {
- int pos = value.toInt();
- if (effect.attribute("id") == "fadein" || effect.attribute("id") == "fade_from_black") {
- pos = pos - m_in;
- } else if (effect.attribute("id") == "fadeout" || effect.attribute("id") == "fade_to_black") {
- // fadeout position starts from clip end
- pos = m_out - pos;
- }
- PositionEdit *posedit = new PositionEdit(paramName, pos, 0, m_out - m_in, m_metaInfo->timecode);
- m_vbox->addWidget(posedit);
- m_valueItems[paramName+"position"] = posedit;
- connect(posedit, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- } else if (type == "curve") {
- KisCurveWidget *curve = new KisCurveWidget(parent);
- curve->setMaxPoints(pa.attribute("max").toInt());
- QList<QPointF> points;
- int number;
- if (e.attribute("version").toDouble() > 0.2) {
- // Rounding gives really weird results. (int) (10 * 0.3) gives 2! So for now, add 0.5 to get correct result
- number = EffectsList::parameter(e, pa.attribute("number")).toDouble() * 10 + 0.5;
- } else {
- number = EffectsList::parameter(e, pa.attribute("number")).toInt();
- }
- QString inName = pa.attribute("inpoints");
- QString outName = pa.attribute("outpoints");
- int start = pa.attribute("min").toInt();
- for (int j = start; j <= number; j++) {
- QString in = inName;
- in.replace("%i", QString::number(j));
- QString out = outName;
- out.replace("%i", QString::number(j));
- points << QPointF(EffectsList::parameter(e, in).toDouble(), EffectsList::parameter(e, out).toDouble());
- }
- if (!points.isEmpty())
- curve->setCurve(KisCubicCurve(points));
- MySpinBox *spinin = new MySpinBox();
- spinin->setRange(0, 1000);
- MySpinBox *spinout = new MySpinBox();
- spinout->setRange(0, 1000);
- curve->setupInOutControls(spinin, spinout, 0, 1000);
- m_vbox->addWidget(curve);
- m_vbox->addWidget(spinin);
- m_vbox->addWidget(spinout);
-
- connect(curve, SIGNAL(modified()), this, SLOT(slotCollectAllParameters()));
- m_valueItems[paramName] = curve;
-
- QString depends = pa.attribute("depends");
- if (!depends.isEmpty())
- meetDependency(paramName, type, EffectsList::parameter(e, depends));
- } else if (type == "bezier_spline") {
- BezierSplineWidget *widget = new BezierSplineWidget(value, parent);
- stretch = false;
- m_vbox->addWidget(widget);
- m_valueItems[paramName] = widget;
- connect(widget, SIGNAL(modified()), this, SLOT(slotCollectAllParameters()));
- QString depends = pa.attribute("depends");
- if (!depends.isEmpty())
- meetDependency(paramName, type, EffectsList::parameter(e, depends));
-#ifdef USE_QJSON
- } else if (type == "roto-spline") {
- RotoWidget *roto = new RotoWidget(value, m_metaInfo->monitor, info, m_metaInfo->timecode, parent);
- roto->slotShowScene(!disable);
- connect(roto, SIGNAL(valueChanged()), this, SLOT(slotCollectAllParameters()));
- connect(roto, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(roto, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), roto, SLOT(slotSyncPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), roto, SLOT(slotShowScene(bool)));
- m_vbox->addWidget(roto);
- m_valueItems[paramName] = roto;
-#endif
- } else if (type == "wipe") {
- Wipeval *wpval = new Wipeval;
- wpval->setupUi(toFillin);
- wipeInfo w = getWipeInfo(value);
- switch (w.start) {
- case UP:
- wpval->start_up->setChecked(true);
- break;
- case DOWN:
- wpval->start_down->setChecked(true);
- break;
- case RIGHT:
- wpval->start_right->setChecked(true);
- break;
- case LEFT:
- wpval->start_left->setChecked(true);
- break;
- default:
- wpval->start_center->setChecked(true);
- break;
- }
- switch (w.end) {
- case UP:
- wpval->end_up->setChecked(true);
- break;
- case DOWN:
- wpval->end_down->setChecked(true);
- break;
- case RIGHT:
- wpval->end_right->setChecked(true);
- break;
- case LEFT:
- wpval->end_left->setChecked(true);
- break;
- default:
- wpval->end_center->setChecked(true);
- break;
- }
- wpval->start_transp->setValue(w.startTransparency);
- wpval->end_transp->setValue(w.endTransparency);
- m_valueItems[paramName] = wpval;
- connect(wpval->end_up, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->end_down, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->end_left, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->end_right, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->end_center, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_up, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_down, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_left, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_right, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_center, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
- connect(wpval->start_transp, SIGNAL(valueChanged(int)), this, SLOT(slotCollectAllParameters()));
- connect(wpval->end_transp, SIGNAL(valueChanged(int)), this, SLOT(slotCollectAllParameters()));
- //wpval->title->setTitle(na.toElement().text());
- m_uiItems.append(wpval);
- } else if (type == "url") {
- Urlval *cval = new Urlval;
- cval->setupUi(toFillin);
- cval->label->setText(paramName);
- cval->urlwidget->fileDialog()->setFilter(ProjectList::getExtensions());
- m_valueItems[paramName] = cval;
- cval->urlwidget->setUrl(KUrl(value));
- connect(cval->urlwidget, SIGNAL(returnPressed()) , this, SLOT(slotCollectAllParameters()));
- connect(cval->urlwidget, SIGNAL(urlSelected(const KUrl&)) , this, SLOT(slotCollectAllParameters()));
- m_uiItems.append(cval);
- } else if (type == "keywords") {
- Keywordval* kval = new Keywordval;
- kval->setupUi(toFillin);
- kval->label->setText(paramName);
- kval->lineeditwidget->setText(value);
- QDomElement klistelem = pa.firstChildElement("keywords");
- QDomElement kdisplaylistelem = pa.firstChildElement("keywordsdisplay");
- QStringList keywordlist;
- QStringList keyworddisplaylist;
- if (!klistelem.isNull()) {
- keywordlist = klistelem.text().split(';');
- keyworddisplaylist = i18n(kdisplaylistelem.text().toUtf8().data()).split(';');
- }
- if (keyworddisplaylist.count() != keywordlist.count()) {
- keyworddisplaylist = keywordlist;
- }
- for (int i = 0; i < keywordlist.count(); i++) {
- kval->comboboxwidget->addItem(keyworddisplaylist.at(i), keywordlist.at(i));
- }
- // Add disabled user prompt at index 0
- kval->comboboxwidget->insertItem(0, i18n("<select a keyword>"), "");
- kval->comboboxwidget->model()->setData( kval->comboboxwidget->model()->index(0,0), QVariant(Qt::NoItemFlags), Qt::UserRole -1);
- kval->comboboxwidget->setCurrentIndex(0);
- m_valueItems[paramName] = kval;
- connect(kval->lineeditwidget, SIGNAL(editingFinished()) , this, SLOT(collectAllParameters()));
- connect(kval->comboboxwidget, SIGNAL(activated (const QString&)), this, SLOT(collectAllParameters()));
- m_uiItems.append(kval);
- } else if (type == "fontfamily") {
- Fontval* fval = new Fontval;
- fval->setupUi(toFillin);
- fval->name->setText(paramName);
- fval->fontfamilywidget->setCurrentFont(QFont(value));
- m_valueItems[paramName] = fval;
- connect(fval->fontfamilywidget, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(collectAllParameters())) ;
- m_uiItems.append(fval);
- } else if (type == "filterjob") {
- QVBoxLayout *l= new QVBoxLayout(toFillin);
- QPushButton *button = new QPushButton(paramName, toFillin);
- l->addWidget(button);
- m_valueItems[paramName] = button;
- connect(button, SIGNAL(pressed()), this, SLOT(slotStartFilterJobAction()));
- } else {
- delete toFillin;
- toFillin = NULL;
- }
-
- if (toFillin)
- m_vbox->addWidget(toFillin);
- }
-
- if (stretch)
- m_vbox->addStretch();
-
- if (m_keyframeEditor)
- m_keyframeEditor->checkVisibleParam();
-
- // Make sure all doubleparam spinboxes have the same width, looks much better
- QList<DoubleParameterWidget *> allWidgets = findChildren<DoubleParameterWidget *>();
- int minSize = 0;
- for (int i = 0; i < allWidgets.count(); i++) {
- if (minSize < allWidgets.at(i)->spinSize()) minSize = allWidgets.at(i)->spinSize();
- }
- for (int i = 0; i < allWidgets.count(); i++) {
- allWidgets.at(i)->setSpinSize(minSize);
- }
-}
-
-ParameterContainer::~ParameterContainer()
+void CollapsibleEffect::adjustButtons(int ix, int max)
{
- clearLayout(m_vbox);
- delete m_vbox;
+ buttonUp->setVisible(ix > 0);
+ buttonDown->setVisible(ix < max - 1);
}
-void ParameterContainer::meetDependency(const QString& name, QString type, QString value)
+bool CollapsibleEffect::needsMonitorEffectScene() const
{
- if (type == "curve") {
- KisCurveWidget *curve = (KisCurveWidget*)m_valueItems[name];
- if (curve) {
- int color = value.toInt();
- curve->setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(curve->size(), (ColorTools::ColorsRGB)(color == 3 ? 4 : color), 0.8)));
- }
- } else if (type == "bezier_spline") {
- BezierSplineWidget *widget = (BezierSplineWidget*)m_valueItems[name];
- if (widget) {
- widget->setMode((BezierSplineWidget::CurveModes)((int)(value.toDouble() * 10 + 0.5)));
- }
- }
-}
-
-wipeInfo ParameterContainer::getWipeInfo(QString value)
-{
- wipeInfo info;
- // Convert old geometry values that used a comma as separator
- if (value.contains(',')) value.replace(',','/');
- QString start = value.section(';', 0, 0);
- QString end = value.section(';', 1, 1).section('=', 1, 1);
- if (start.startsWith("-100%/0"))
- info.start = LEFT;
- else if (start.startsWith("100%/0"))
- info.start = RIGHT;
- else if (start.startsWith("0%/100%"))
- info.start = DOWN;
- else if (start.startsWith("0%/-100%"))
- info.start = UP;
- else
- info.start = CENTER;
-
- if (start.count(':') == 2)
- info.startTransparency = start.section(':', -1).toInt();
- else
- info.startTransparency = 100;
-
- if (end.startsWith("-100%/0"))
- info.end = LEFT;
- else if (end.startsWith("100%/0"))
- info.end = RIGHT;
- else if (end.startsWith("0%/100%"))
- info.end = DOWN;
- else if (end.startsWith("0%/-100%"))
- info.end = UP;
- else
- info.end = CENTER;
-
- if (end.count(':') == 2)
- info.endTransparency = end.section(':', -1).toInt();
- else
- info.endTransparency = 100;
-
- return info;
+ return m_paramWidget->needsMonitorEffectScene();
}
-void ParameterContainer::updateTimecodeFormat()
-{
- if (m_keyframeEditor)
- m_keyframeEditor->updateTimecodeFormat();
-
- QDomNodeList namenode = m_effect.elementsByTagName("parameter");
- for (int i = 0; i < namenode.count() ; i++) {
- QDomNode pa = namenode.item(i);
- QDomElement na = pa.firstChildElement("name");
- QString type = pa.attributes().namedItem("type").nodeValue();
- QString paramName = na.isNull() ? pa.attributes().namedItem("name").nodeValue() : i18n(na.text().toUtf8().data());
- if (type == "geometry") {
- if (KdenliveSettings::on_monitor_effects()) {
- if (m_geometryWidget) m_geometryWidget->updateTimecodeFormat();
- } else {
- Geometryval *geom = ((Geometryval*)m_valueItems[paramName+"geometry"]);
- geom->updateTimecodeFormat();
- }
- break;
- } else if (type == "position") {
- PositionEdit *posi = ((PositionEdit*)m_valueItems[paramName+"position"]);
- posi->updateTimecodeFormat();
- break;
-#ifdef USE_QJSON
- } else if (type == "roto-spline") {
- RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems[paramName]);
- widget->updateTimecodeFormat();
-#endif
- }
- }
-}
-
-void ParameterContainer::slotCollectAllParameters()
-{
- if (m_valueItems.isEmpty() || m_effect.isNull()) return;
- QLocale locale;
- locale.setNumberOptions(QLocale::OmitGroupSeparator);
- const QDomElement oldparam = m_effect.cloneNode().toElement();
- //QDomElement newparam = oldparam.cloneNode().toElement();
- QDomNodeList namenode = m_effect.elementsByTagName("parameter");
-
- for (int i = 0; i < namenode.count() ; i++) {
- QDomElement pa = namenode.item(i).toElement();
- QDomElement na = pa.firstChildElement("name");
- QString type = pa.attribute("type");
- QString paramName = na.isNull() ? pa.attribute("name") : i18n(na.text().toUtf8().data());
- if (type == "complex")
- paramName.append("complex");
- else if (type == "position")
- paramName.append("position");
- else if (type == "geometry")
- paramName.append("geometry");
- else if (type == "keyframe")
- paramName.append("keyframe");
- if (type != "simplekeyframe" && type != "fixed" && type != "addedgeometry" && !m_valueItems.contains(paramName)) {
- kDebug() << "// Param: " << paramName << " NOT FOUND";
- continue;
- }
-
- QString setValue;
- if (type == "double" || type == "constant") {
- DoubleParameterWidget *doubleparam = (DoubleParameterWidget*)m_valueItems.value(paramName);
- setValue = locale.toString(doubleparam->getValue());
- } else if (type == "list") {
- KComboBox *box = ((Listval*)m_valueItems.value(paramName))->list;
- setValue = box->itemData(box->currentIndex()).toString();
- } else if (type == "bool") {
- QCheckBox *box = ((Boolval*)m_valueItems.value(paramName))->checkBox;
- setValue = box->checkState() == Qt::Checked ? "1" : "0" ;
- } else if (type == "color") {
- ChooseColorWidget *choosecolor = ((ChooseColorWidget*)m_valueItems.value(paramName));
- setValue = choosecolor->getColor();
- if (pa.hasAttribute("paramprefix")) setValue.prepend(pa.attribute("paramprefix"));
- } else if (type == "complex") {
- ComplexParameter *complex = ((ComplexParameter*)m_valueItems.value(paramName));
- namenode.item(i) = complex->getParamDesc();
- } else if (type == "geometry") {
- if (KdenliveSettings::on_monitor_effects()) {
- if (m_geometryWidget) namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getValue());
- } else {
- Geometryval *geom = ((Geometryval*)m_valueItems.value(paramName));
- namenode.item(i).toElement().setAttribute("value", geom->getValue());
- }
- } else if (type == "addedgeometry") {
- namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getExtraValue(namenode.item(i).toElement().attribute("name")));
- } else if (type == "position") {
- PositionEdit *pedit = ((PositionEdit*)m_valueItems.value(paramName));
- int pos = pedit->getPosition();
- setValue = QString::number(pos);
- 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(m_effect, "in", QString::number(m_in));
- EffectsList::setParameter(m_effect, "out", QString::number(m_in + pos));
- setValue.clear();
- } 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(m_effect, "in", QString::number(m_out - pos));
- EffectsList::setParameter(m_effect, "out", QString::number(m_out));
- setValue.clear();
- }
- } else if (type == "curve") {
- KisCurveWidget *curve = ((KisCurveWidget*)m_valueItems.value(paramName));
- QList<QPointF> points = curve->curve().points();
- QString number = pa.attribute("number");
- QString inName = pa.attribute("inpoints");
- QString outName = pa.attribute("outpoints");
- int off = pa.attribute("min").toInt();
- int end = pa.attribute("max").toInt();
- if (oldparam.attribute("version").toDouble() > 0.2) {
- EffectsList::setParameter(m_effect, number, locale.toString(points.count() / 10.));
- } else {
- 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(m_effect, in, locale.toString(points.at(j).x()));
- EffectsList::setParameter(m_effect, out, locale.toString(points.at(j).y()));
- }
- QString depends = pa.attribute("depends");
- if (!depends.isEmpty())
- 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.attribute("depends");
- if (!depends.isEmpty())
- 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));
- setValue = widget->getSpline();
-#endif
- } else if (type == "wipe") {
- Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
- wipeInfo info;
- if (wp->start_left->isChecked())
- info.start = LEFT;
- else if (wp->start_right->isChecked())
- info.start = RIGHT;
- else if (wp->start_up->isChecked())
- info.start = UP;
- else if (wp->start_down->isChecked())
- info.start = DOWN;
- else if (wp->start_center->isChecked())
- info.start = CENTER;
- else
- info.start = LEFT;
- info.startTransparency = wp->start_transp->value();
-
- if (wp->end_left->isChecked())
- info.end = LEFT;
- else if (wp->end_right->isChecked())
- info.end = RIGHT;
- else if (wp->end_up->isChecked())
- info.end = UP;
- else if (wp->end_down->isChecked())
- info.end = DOWN;
- else if (wp->end_center->isChecked())
- info.end = CENTER;
- else
- info.end = RIGHT;
- info.endTransparency = wp->end_transp->value();
-
- setValue = getWipeString(info);
- } else if ((type == "simplekeyframe" || type == "keyframe") && m_keyframeEditor) {
- QString realName = i18n(na.toElement().text().toUtf8().data());
- QString val = m_keyframeEditor->getValue(realName);
- pa.setAttribute("keyframes", val);
-
- if (m_keyframeEditor->isVisibleParam(realName)) {
- pa.setAttribute("intimeline", "1");
- }
- else if (pa.hasAttribute("intimeline"))
- pa.removeAttribute("intimeline");
- } else if (type == "url") {
- KUrlRequester *req = ((Urlval*)m_valueItems.value(paramName))->urlwidget;
- setValue = req->url().path();
- } else if (type == "keywords"){
- QLineEdit *line = ((Keywordval*)m_valueItems.value(paramName))->lineeditwidget;
- QComboBox *combo = ((Keywordval*)m_valueItems.value(paramName))->comboboxwidget;
- if(combo->currentIndex())
- {
- QString comboval = combo->itemData(combo->currentIndex()).toString();
- line->insert(comboval);
- combo->setCurrentIndex(0);
- }
- setValue = line->text();
- } else if (type == "fontfamily") {
- QFontComboBox* fontfamily = ((Fontval*)m_valueItems.value(paramName))->fontfamilywidget;
- setValue = fontfamily->currentFont().family();
- }
- if (!setValue.isNull())
- pa.setAttribute("value", setValue);
-
- }
- emit parameterChanged(oldparam, m_effect, m_effect.attribute("kdenlive_ix").toInt());
-}
-
-QString ParameterContainer::getWipeString(wipeInfo info)
-{
-
- QString start;
- QString end;
- switch (info.start) {
- case LEFT:
- start = "-100%/0%:100%x100%";
- break;
- case RIGHT:
- start = "100%/0%:100%x100%";
- break;
- case DOWN:
- start = "0%/100%:100%x100%";
- break;
- case UP:
- start = "0%/-100%:100%x100%";
- break;
- default:
- start = "0%/0%:100%x100%";
- break;
- }
- start.append(':' + QString::number(info.startTransparency));
-
- switch (info.end) {
- case LEFT:
- end = "-100%/0%:100%x100%";
- break;
- case RIGHT:
- end = "100%/0%:100%x100%";
- break;
- case DOWN:
- end = "0%/100%:100%x100%";
- break;
- case UP:
- end = "0%/-100%:100%x100%";
- break;
- default:
- end = "0%/0%:100%x100%";
- break;
- }
- end.append(':' + QString::number(info.endTransparency));
- return QString(start + ";-1=" + end);
-}
-
-void ParameterContainer::updateParameter(const QString &key, const QString &value)
-{
- m_effect.setAttribute(key, value);
-}
-
-void ParameterContainer::slotStartFilterJobAction()
-{
- QDomNodeList namenode = m_effect.elementsByTagName("parameter");
- for (int i = 0; i < namenode.count() ; i++) {
- QDomElement pa = namenode.item(i).toElement();
- QString type = pa.attribute("type");
- if (type == "filterjob") {
- emit startFilterJob(pa.attribute("filtertag"), pa.attribute("filterparams"), pa.attribute("finalfilter"), pa.attribute("consumer"), pa.attribute("consumerparams"), pa.attribute("wantedproperties"));
- kDebug()<<" - - -PROPS:\n"<<pa.attribute("filtertag")<<"-"<< pa.attribute("filterparams")<<"-"<< pa.attribute("consumer")<<"-"<< pa.attribute("consumerparams")<<"-"<< pa.attribute("wantedproperties");
- break;
- }
- }
-}
#ifndef COLLAPSIBLEEFFECT_H
#define COLLAPSIBLEEFFECT_H
-
-#include "ui_collapsiblewidget_ui.h"
-
+#include "parametercontainer.h"
#include "abstractcollapsiblewidget.h"
#include "timecode.h"
-#include "keyframeedit.h"
+
#include <QDomElement>
#include <QToolButton>
class QFrame;
-class Monitor;
-class GeometryWidget;
-
-struct EffectMetaInfo {
- MltVideoProfile profile;
- Timecode timecode;
- Monitor *monitor;
- QPoint frameSize;
- bool trackMode;
-};
-
-enum WIPE_DIRECTON { UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, CENTER = 4 };
-
-struct wipeInfo {
- WIPE_DIRECTON start;
- WIPE_DIRECTON end;
- int startTransparency;
- int endTransparency;
-};
-
-class MySpinBox : public QSpinBox
-{
- Q_OBJECT
-
-public:
- MySpinBox(QWidget * parent = 0);
-
-protected:
- virtual void focusInEvent(QFocusEvent*);
- virtual void focusOutEvent(QFocusEvent*);
-};
-
-class ParameterContainer : public QObject
-{
- Q_OBJECT
-
-public:
- ParameterContainer(QDomElement effect, ItemInfo info, EffectMetaInfo *metaInfo, QWidget * parent = 0);
- ~ParameterContainer();
- void updateTimecodeFormat();
- void updateProjectFormat(MltVideoProfile profile, Timecode t);
- void updateParameter(const QString &key, const QString &value);
-
-private slots:
- void slotCollectAllParameters();
- void slotStartFilterJobAction();
-
-private:
- /** @brief Updates parameter @param name according to new value of dependency.
- * @param name Name of the parameter which will be updated
- * @param type Type of the parameter which will be updated
- * @param value Value of the dependency parameter */
- void meetDependency(const QString& name, QString type, QString value);
- wipeInfo getWipeInfo(QString value);
- QString getWipeString(wipeInfo info);
-
- int m_in;
- int m_out;
- QList<QWidget*> m_uiItems;
- QMap<QString, QWidget*> m_valueItems;
- Timecode m_timecode;
- KeyframeEdit *m_keyframeEditor;
- GeometryWidget *m_geometryWidget;
- EffectMetaInfo *m_metaInfo;
- QDomElement m_effect;
- QVBoxLayout *m_vbox;
+class QLabel;
-signals:
- void parameterChanged(const QDomElement, const QDomElement, int);
- void syncEffectsPos(int);
- void effectStateChanged(bool);
- void checkMonitorPosition(int);
- void seekTimeline(int);
- void showComments(bool);
- /** @brief Start an MLT filter job on this clip. */
- void startFilterJob(QString filterName, QString filterParams, QString finalFilterName, QString consumer, QString consumerParams, QString properties);
-
-};
/**)
* @class CollapsibleEffect
* @author Jean-Baptiste Mardelle
*/
-class CollapsibleEffect : public AbstractCollapsibleWidget, public Ui::CollapsibleWidget_UI
+class CollapsibleEffect : public AbstractCollapsibleWidget
{
Q_OBJECT
public:
CollapsibleEffect(QDomElement effect, QDomElement original_effect, ItemInfo info, EffectMetaInfo *metaInfo, bool lastEffect, QWidget * parent = 0);
~CollapsibleEffect();
- static QMap<QString, QImage> iconCache;
+ QLabel *title;
+
void setupWidget(ItemInfo info, EffectMetaInfo *metaInfo);
void updateTimecodeFormat();
void setActive(bool activate);
bool isActive() const;
/** @brief Should the wheel event be sent to parent widget for scrolling. */
bool filterWheelEvent;
- /** @brief Return the stylesheet required for effect parameters. */
- static const QString getStyleSheet();
/** @brief Parent group was collapsed, update. */
void groupStateChanged(bool collapsed);
+ /** @brief Show / hide up / down buttons. */
+ void adjustButtons(int ix, int max);
+ /** @brief Returns true of this effect requires an on monitor adjustable effect scene. */
+ bool needsMonitorEffectScene() const;
public slots:
void slotSyncEffectsPos(int pos);
- void slotEnable(bool enable, bool updateMainStatus = true);
+ void slotEnable(bool enable, bool emitInfo = true);
void slotResetEffect();
private slots:
EffectInfo m_info;
/** @brief True if this is a region effect, which behaves in a special way, like a group. */
bool m_regionEffect;
+ /** @brief The add group action. */
+ QAction *m_groupAction;
/** @brief Check if collapsed state changed and inform MLT. */
void updateCollapsedState();
signals:
void parameterChanged(const QDomElement, const QDomElement, int);
void syncEffectsPos(int);
- void effectStateChanged(bool, int ix = -1, bool updateMainStatus = true);
+ void effectStateChanged(bool, int ix, bool effectNeedsMonitorScene);
void deleteEffect(const QDomElement);
- void changeEffectPosition(int, bool);
void activateEffect(int);
void checkMonitorPosition(int);
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();
/** @brief An effect was reset, trigger param reload. */
void resetEffect(int ix);
/** @brief Ask for creation of a group. */
void createGroup(int ix);
- void moveEffect(QList <int> current_pos, int new_pos, int groupIndex, QString groupName);
void unGroup(CollapsibleEffect *);
- void addEffect(QDomElement e);
void createRegion(int, KUrl);
void deleteGroup(QDomDocument);
};
{
setFrame(false);
setReadOnly(true);
- setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
void MyEditableLabel::mouseDoubleClickEvent ( QMouseEvent * e )
CollapsibleGroup::CollapsibleGroup(int ix, bool firstGroup, bool lastGroup, EffectInfo info, QWidget * parent) :
AbstractCollapsibleWidget(parent)
{
- setupUi(this);
m_info.groupIndex = ix;
m_subWidgets = QList <CollapsibleEffect *> ();
setFont(KGlobalSettings::smallestReadableFont());
- QHBoxLayout *l = static_cast <QHBoxLayout *>(framegroup->layout());
+ frame->setObjectName("framegroup");
+ decoframe->setObjectName("decoframegroup");
+ QHBoxLayout *l = static_cast <QHBoxLayout *>(frame->layout());
m_title = new MyEditableLabel(this);
- l->insertWidget(3, m_title);
+ l->insertWidget(2, m_title);
m_title->setText(info.groupName.isEmpty() ? i18n("Effect Group") : info.groupName);
m_info.groupName = m_title->text();
connect(m_title, SIGNAL(editingFinished()), this, SLOT(slotRenameGroup()));
bool CollapsibleGroup::isActive() const
{
- return decoframegroup->property("active").toBool();
+ return decoframe->property("active").toBool();
}
void CollapsibleGroup::setActive(bool activate)
{
- decoframegroup->setProperty("active", activate);
- decoframegroup->setStyleSheet(decoframegroup->styleSheet());
+ decoframe->setProperty("active", activate);
+ decoframe->setStyleSheet(decoframe->styleSheet());
}
void CollapsibleGroup::mouseDoubleClickEvent ( QMouseEvent * event )
{
- if (framegroup->underMouse() && collapseButton->isEnabled()) slotSwitch();
+ if (frame->underMouse() && collapseButton->isEnabled()) slotSwitch();
QWidget::mouseDoubleClickEvent(event);
}
-void CollapsibleGroup::slotEnable(bool disable)
+void CollapsibleGroup::slotEnable(bool disable, bool emitInfo)
{
m_title->setEnabled(!disable);
enabledButton->blockSignals(true);
enabledButton->setIcon(disable ? KIcon("novisible") : KIcon("visible"));
enabledButton->blockSignals(false);
for (int i = 0; i < m_subWidgets.count(); i++)
- m_subWidgets.at(i)->slotEnable(disable);
+ m_subWidgets.at(i)->slotEnable(disable, emitInfo);
}
void CollapsibleGroup::slotDeleteGroup()
void CollapsibleGroup::slotEffectUp()
{
- emit changeGroupPosition(groupIndex(), true);
+ QList <int> indexes;
+ for (int i = 0; i < m_subWidgets.count(); i++)
+ indexes << m_subWidgets.at(i)->effectIndex();
+ emit changeEffectPosition(indexes, true);
}
void CollapsibleGroup::slotEffectDown()
{
- emit changeGroupPosition(groupIndex(), false);
+ QList <int> indexes;
+ for (int i = 0; i < m_subWidgets.count(); i++)
+ indexes << m_subWidgets.at(i)->effectIndex();
+ emit changeEffectPosition(indexes, false);
}
void CollapsibleGroup::slotSaveGroup()
void CollapsibleGroup::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("kdenlive/effectslist")) {
- framegroup->setProperty("target", true);
- framegroup->setStyleSheet(framegroup->styleSheet());
+ frame->setProperty("target", true);
+ frame->setStyleSheet(frame->styleSheet());
event->acceptProposedAction();
}
}
void CollapsibleGroup::dragLeaveEvent(QDragLeaveEvent */*event*/)
{
- framegroup->setProperty("target", false);
- framegroup->setStyleSheet(framegroup->styleSheet());
+ frame->setProperty("target", false);
+ frame->setStyleSheet(frame->styleSheet());
}
void CollapsibleGroup::dropEvent(QDropEvent *event)
{
- framegroup->setProperty("target", false);
- framegroup->setStyleSheet(framegroup->styleSheet());
+ frame->setProperty("target", false);
+ frame->setStyleSheet(frame->styleSheet());
const QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
//event->acceptProposedAction();
QDomDocument doc;
return doc;
}
+void CollapsibleGroup::adjustEffects()
+{
+ for (int i = 0; i < m_subWidgets.count(); i++) {
+ m_subWidgets.at(i)->adjustButtons(i, m_subWidgets.count());
+ }
+}
+
#define COLLAPSIBLEGROUP_H
-#include "ui_collapsiblegroup_ui.h"
-
#include "abstractcollapsiblewidget.h"
#include "collapsibleeffect.h"
#include "timecode.h"
* @author Jean-Baptiste Mardelle
*/
-class CollapsibleGroup : public AbstractCollapsibleWidget, public Ui::CollapsibleGroup_UI
+class CollapsibleGroup : public AbstractCollapsibleWidget
{
Q_OBJECT
QWidget *title() const;
/** @brief Return the XML data describing all effects in group. */
QDomDocument effectsData();
+ /** @brief Adjust sub effects buttons. */
+ void adjustEffects();
public slots:
- void slotEnable(bool enable);
+ void slotEnable(bool enable, bool emitInfo = true);
private slots:
void slotSwitch();
virtual void dropEvent(QDropEvent *event);
signals:
- void syncEffectsPos(int);
- void effectStateChanged(bool, int ix = -1);
void deleteGroup(QDomDocument);
- void changeGroupPosition(int, bool);
- void activateEffect(int);
- void moveEffect(QList <int> current_pos, int new_pos, int groupIndex, QString groupName);
- void addEffect(QDomElement e);
void unGroup(CollapsibleGroup *);
void groupRenamed(CollapsibleGroup *);
- void reloadEffects();
+
};
#include <KStandardDirs>
#include <KFileDialog>
#include <KColorScheme>
+#include <KColorUtils>
#include <QMenu>
#include <QTextStream>
m_trackindex(-1),
m_draggedEffect(NULL),
m_draggedGroup(NULL),
- m_groupIndex(0)
+ m_groupIndex(0),
+ m_monitorSceneWanted(false)
{
m_effectMetaInfo.trackMode = false;
m_effectMetaInfo.monitor = monitor;
setEnabled(false);
- setStyleSheet(CollapsibleEffect::getStyleSheet());
+ setStyleSheet(getStyleSheet());
}
EffectStackView2::~EffectStackView2()
void EffectStackView2::updatePalette()
{
- setStyleSheet(CollapsibleEffect::getStyleSheet());
+ setStyleSheet(getStyleSheet());
}
void EffectStackView2::slotRenderPos(int pos)
{
if (m_effects.isEmpty()) return;
+ if (m_monitorSceneWanted) slotCheckMonitorPosition(pos);
if (!m_effectMetaInfo.trackMode && m_clipref) pos = pos - m_clipref->startPos().frames(KdenliveSettings::project_fps());
for (int i = 0; i< m_effects.count(); i++)
}
if (m_clipref == NULL) {
//TODO: clear list, reset paramdesc and info
- //ItemInfo info;
- //m_effectedit->transferParamDesc(QDomElement(), info);
+ // If monitor scene is displayed, hide it
+ if (m_monitorSceneWanted) {
+ m_effectMetaInfo.monitor->slotShowEffectScene(false);
+ }
+ m_monitorSceneWanted = false;
clear();
return;
}
void EffectStackView2::setupListView()
{
blockSignals(true);
+ bool previousMonitorScene = m_monitorSceneWanted;
+ m_monitorSceneWanted = false;
m_draggedEffect = NULL;
m_draggedGroup = NULL;
disconnect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
QVBoxLayout *vbox1 = new QVBoxLayout(view);
vbox1->setContentsMargins(0, 0, 0, 0);
vbox1->setSpacing(0);
-
- if (m_currentEffectList.isEmpty()) m_ui.labelComment->setHidden(true);
- for (int i = 0; i < m_currentEffectList.count(); i++) {
+ int effectsCount = m_currentEffectList.count();
+
+ // Make sure we always have one effect selected
+ int selectedEffect = m_clipref->selectedEffectIndex();
+ if (selectedEffect < 1 && effectsCount > 0) m_clipref->setSelectedEffect(1);
+ else if (selectedEffect > effectsCount) m_clipref->setSelectedEffect(effectsCount);
+
+ for (int i = 0; i < effectsCount; i++) {
QDomElement d = m_currentEffectList.at(i).cloneNode().toElement();
if (d.isNull()) {
kDebug() << " . . . . WARNING, NULL EFFECT IN STACK!!!!!!!!!";
}
if (group == NULL) {
- group = new CollapsibleGroup(effectInfo.groupIndex, i == 0, i == m_currentEffectList.count() - 1, effectInfo, m_ui.container->widget());
+ group = new CollapsibleGroup(effectInfo.groupIndex, i == 0, i == effectsCount - 1, effectInfo, m_ui.container->widget());
connectGroup(group);
vbox1->addWidget(group);
group->installEventFilter( this );
info = m_clipref->info();
}
- CollapsibleEffect *currentEffect = new CollapsibleEffect(d, m_currentEffectList.at(i), info, &m_effectMetaInfo, i == m_currentEffectList.count() - 1, view);
+ CollapsibleEffect *currentEffect = new CollapsibleEffect(d, m_currentEffectList.at(i), info, &m_effectMetaInfo, i == effectsCount - 1, view);
if (m_effectMetaInfo.trackMode) {
isSelected = currentEffect->effectIndex() == 1;
}
else {
isSelected = currentEffect->effectIndex() == m_clipref->selectedEffectIndex();
}
- if (isSelected) currentEffect->setActive(true);
+ if (isSelected) {
+ currentEffect->setActive(true);
+ if (currentEffect->needsMonitorEffectScene()) m_monitorSceneWanted = true;
+ }
m_effects.append(currentEffect);
if (group) {
group->addGroupEffect(currentEffect);
}
connectEffect(currentEffect);
}
+
+ if (m_currentEffectList.isEmpty()) {
+ m_ui.labelComment->setHidden(true);
+ }
+ else {
+ // Adjust group effects (up / down buttons)
+ QList<CollapsibleGroup *> allGroups = m_ui.container->widget()->findChildren<CollapsibleGroup *>();
+ for (int i = 0; i < allGroups.count(); i++) {
+ allGroups.at(i)->adjustEffects();
+ }
+ connect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
+ }
+
vbox1->addStretch(10);
slotUpdateCheckAllButton();
- connect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
+ if (previousMonitorScene && !m_monitorSceneWanted) {
+ // monitor scene was displayed, not wanted anymore
+ m_effectMetaInfo.monitor->slotShowEffectScene(false);
+ }
// Wait a little bit for the new layout to be ready, then check if we have a scrollbar
QTimer::singleShot(200, this, SLOT(slotCheckWheelEventFilter()));
connect(currentEffect, SIGNAL(deleteEffect(const QDomElement)), this , SLOT(slotDeleteEffect(const QDomElement)));
connect(currentEffect, SIGNAL(reloadEffects()), this , SIGNAL(reloadEffects()));
connect(currentEffect, SIGNAL(resetEffect(int)), this , SLOT(slotResetEffect(int)));
- connect(currentEffect, SIGNAL(changeEffectPosition(int,bool)), this , SLOT(slotMoveEffectUp(int , bool)));
+ connect(currentEffect, SIGNAL(changeEffectPosition(QList <int>,bool)), this , SLOT(slotMoveEffectUp(QList <int>,bool)));
connect(currentEffect, SIGNAL(effectStateChanged(bool,int,bool)), this, SLOT(slotUpdateEffectState(bool,int,bool)));
connect(currentEffect, SIGNAL(activateEffect(int)), this, SLOT(slotSetCurrentEffect(int)));
- connect(currentEffect, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
connect(currentEffect, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int)));
connect(currentEffect, SIGNAL(createGroup(int)), this , SLOT(slotCreateGroup(int)));
connect(currentEffect, SIGNAL(moveEffect(QList<int>,int,int,QString)), this , SLOT(slotMoveEffect(QList<int>,int,int,QString)));
m_draggedGroup = qobject_cast<CollapsibleGroup*>(o);
if (m_draggedGroup) {
QMouseEvent *me = static_cast<QMouseEvent *>(e);
- if (me->button() == Qt::LeftButton && (m_draggedGroup->framegroup->underMouse() || m_draggedGroup->title()->underMouse()))
+ if (me->button() == Qt::LeftButton && (m_draggedGroup->frame->underMouse() || m_draggedGroup->title()->underMouse()))
m_clickPoint = me->globalPos();
else {
m_clickPoint = QPoint();
}
-void EffectStackView2::slotUpdateEffectState(bool disable, int index, bool updateMainStatus)
+void EffectStackView2::slotUpdateEffectState(bool disable, int index, bool needsMonitorEffectScene)
{
+ if (m_monitorSceneWanted && disable) {
+ m_effectMetaInfo.monitor->slotShowEffectScene(false);
+ m_monitorSceneWanted = false;
+ }
+ else if (!disable && !m_monitorSceneWanted && needsMonitorEffectScene) {
+ m_effectMetaInfo.monitor->slotShowEffectScene(true);
+ m_monitorSceneWanted = true;
+ }
if (m_effectMetaInfo.trackMode)
- emit changeEffectState(NULL, m_trackindex, index, disable);
+ emit changeEffectState(NULL, m_trackindex, QList <int>() << index, disable);
else
- emit changeEffectState(m_clipref, -1, index, disable);
- if (updateMainStatus) slotUpdateCheckAllButton();
+ emit changeEffectState(m_clipref, -1, QList <int>() <<index, disable);
+ slotUpdateCheckAllButton();
}
void EffectStackView2::slotCheckMonitorPosition(int renderPos)
{
- if (m_effectMetaInfo.trackMode || (m_clipref && renderPos >= m_clipref->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_clipref->endPos().frames(KdenliveSettings::project_fps()))) {
- if (!m_effectMetaInfo.monitor->getEffectEdit()->getScene()->views().at(0)->isVisible())
- m_effectMetaInfo.monitor->slotEffectScene(true);
- } else {
- m_effectMetaInfo.monitor->slotEffectScene(false);
+ if (m_monitorSceneWanted) {
+ if (m_effectMetaInfo.trackMode || (m_clipref && renderPos >= m_clipref->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_clipref->endPos().frames(KdenliveSettings::project_fps()))) {
+ if (!m_effectMetaInfo.monitor->effectSceneDisplayed()) {
+ m_effectMetaInfo.monitor->slotShowEffectScene(true);
+ }
+ } else {
+ m_effectMetaInfo.monitor->slotShowEffectScene(false);
+ }
+ }
+ else {
+ m_effectMetaInfo.monitor->slotShowEffectScene(false);
}
}
void EffectStackView2::clear()
{
m_effects.clear();
+ m_monitorSceneWanted = false;
QWidget *view = m_ui.container->takeWidget();
if (view) {
delete view;
}
bool disabled = state == Qt::Unchecked;
+ // Disable all effects
+ QList <int> indexes;
for (int i = 0; i < m_effects.count(); i++) {
- if (!m_effects.at(i)->isGroup()) {
- m_effects.at(i)->slotEnable(disabled, false);
- }
+ m_effects.at(i)->slotEnable(disabled, false);
+ indexes << m_effects.at(i)->effectIndex();
+ }
+ // Take care of groups
+ QList<CollapsibleGroup *> allGroups = m_ui.container->widget()->findChildren<CollapsibleGroup *>();
+ for (int i = 0; i < allGroups.count(); i++) {
+ allGroups.at(i)->slotEnable(disabled, false);
}
+
+ if (m_effectMetaInfo.trackMode)
+ emit changeEffectState(NULL, m_trackindex, indexes, disabled);
+ else
+ emit changeEffectState(m_clipref, -1, indexes, disabled);
}
void EffectStackView2::slotUpdateCheckAllButton()
m_clipref->setSelectedEffect(ix);
for (int i = 0; i < m_effects.count(); i++) {
if (m_effects.at(i)->effectIndex() == ix) {
+ if (m_effects.at(i)->isActive()) return;
m_effects.at(i)->setActive(true);
+ m_monitorSceneWanted = m_effects.at(i)->needsMonitorEffectScene();
+ slotCheckMonitorPosition(m_effectMetaInfo.monitor->render->seekFramePosition());
m_ui.labelComment->setText(i18n(m_effects.at(i)->effect().firstChildElement("description").firstChildElement("full").text().toUtf8().data()));
m_ui.labelComment->setHidden(!m_ui.buttonShowComments->isChecked() || m_ui.labelComment->text().isEmpty());
}
emit addEffect(m_clipref, effect);
}
-void EffectStackView2::slotMoveEffectUp(int index, bool up)
+void EffectStackView2::slotMoveEffectUp(QList <int> indexes, bool up)
{
- if (up && index <= 1) return;
- if (!up && index >= m_currentEffectList.count()) return;
+ if (up && indexes.first() <= 1) return;
+ if (!up && indexes.last() >= m_currentEffectList.count()) return;
int endPos;
if (up) {
- endPos = index - 1;
+ endPos = indexes.first() - 1;
}
else {
- endPos = index + 1;
+ endPos = indexes.last() + 1;
}
- if (m_effectMetaInfo.trackMode) emit changeEffectPosition(NULL, m_trackindex, QList <int>() <<index, endPos);
- else emit changeEffectPosition(m_clipref, -1, QList <int>() <<index, endPos);
+ if (m_effectMetaInfo.trackMode) emit changeEffectPosition(NULL, m_trackindex, indexes, endPos);
+ else emit changeEffectPosition(m_clipref, -1, indexes, endPos);
}
void EffectStackView2::slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QString&properties)
connect(group, SIGNAL(groupRenamed(CollapsibleGroup *)), this , SLOT(slotRenameGroup(CollapsibleGroup*)));
connect(group, SIGNAL(reloadEffects()), this , SIGNAL(reloadEffects()));
connect(group, SIGNAL(deleteGroup(QDomDocument)), this , SLOT(slotDeleteGroup(QDomDocument)));
+ connect(group, SIGNAL(changeEffectPosition(QList <int>,bool)), this , SLOT(slotMoveEffectUp(QList <int>,bool)));
}
void EffectStackView2::slotMoveEffect(QList <int> currentIndexes, int newIndex, int groupIndex, QString groupName)
processDroppedEffect(doc.documentElement(), event);
}
+//static
+const QString EffectStackView2::getStyleSheet()
+{
+ KColorScheme scheme(QApplication::palette().currentColorGroup(), KColorScheme::View, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
+ QColor selected_bg = scheme.decoration(KColorScheme::FocusColor).color();
+ QColor hgh = KColorUtils::mix(QApplication::palette().window().color(), selected_bg, 0.2);
+ QColor hover_bg = scheme.decoration(KColorScheme::HoverColor).color();
+ QColor light_bg = scheme.shade(KColorScheme::LightShade);
+ QColor alt_bg = scheme.background(KColorScheme::NormalBackground).color();
+
+ QString stylesheet;
+
+ // effect background
+ stylesheet.append(QString("QFrame#decoframe {border-top-left-radius:5px;border-top-right-radius:5px;border-bottom:2px solid palette(mid);border-top:1px solid palette(light);} QFrame#decoframe[active=\"true\"] {background: %1;}").arg(hgh.name()));
+
+ // effect in group background
+ stylesheet.append(QString("QFrame#decoframesub {border-top:1px solid palette(light);} QFrame#decoframesub[active=\"true\"] {background: %1;}").arg(hgh.name()));
+
+ // group background
+ stylesheet.append(QString("QFrame#decoframegroup {border-top-left-radius:5px;border-top-right-radius:5px;border:2px solid palette(dark);margin:0px;margin-top:2px;} "));
+
+ // effect title bar
+ stylesheet.append(QString("QFrame#frame {margin-bottom:2px;border-top-left-radius:5px;border-top-right-radius:5px;} QFrame#frame[target=\"true\"] {background: palette(highlight);}"));
+
+ // group effect title bar
+ stylesheet.append(QString("QFrame#framegroup {border-top-left-radius:2px;border-top-right-radius:2px;background: palette(dark);} QFrame#framegroup[target=\"true\"] {background: palette(highlight);} "));
+
+ // draggable effect bar content
+ stylesheet.append(QString("QProgressBar::chunk:horizontal {background: palette(button);border-top-left-radius: 4px;border-bottom-left-radius: 4px;} QProgressBar::chunk:horizontal#dragOnly {background: %1;border-top-left-radius: 4px;border-bottom-left-radius: 4px;} QProgressBar::chunk:horizontal:hover {background: %2;}").arg(alt_bg.name()).arg(selected_bg.name()));
+
+ // draggable effect bar
+ stylesheet.append(QString("QProgressBar:horizontal {border: 1px solid palette(dark);border-top-left-radius: 4px;border-bottom-left-radius: 4px;border-right:0px;background:%3;padding: 0px;text-align:left center} QProgressBar:horizontal:disabled {border: 1px solid palette(button)} QProgressBar:horizontal#dragOnly {background: %3} QProgressBar:horizontal[inTimeline=\"true\"] { border: 1px solid %1;border-right: 0px;background: %2;padding: 0px;text-align:left center } QProgressBar::chunk:horizontal[inTimeline=\"true\"] {background: %1;}").arg(hover_bg.name()).arg(light_bg.name()).arg(alt_bg.name()));
+
+ // spin box for draggable widget
+ stylesheet.append(QString("QAbstractSpinBox#dragBox {border: 1px solid palette(dark);border-top-right-radius: 4px;border-bottom-right-radius: 4px;padding-right:0px;} QAbstractSpinBox::down-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox:disabled#dragBox {border: 1px solid palette(button);} QAbstractSpinBox::up-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox[inTimeline=\"true\"]#dragBox { border: 1px solid %1;} QAbstractSpinBox:hover#dragBox {border: 1px solid %2;} ").arg(hover_bg.name()).arg(selected_bg.name()));
+
+ // group editable labels
+ stylesheet.append(QString("MyEditableLabel { background-color: transparent; color: palette(bright-text); border-radius: 2px;border: 1px solid transparent;} MyEditableLabel:hover {border: 1px solid palette(highlight);} "));
+
+ return stylesheet;
+}
+
#include "effectstackview2.moc"
#define EFFECTSTACKVIEW2_H
#include "ui_effectstack2_ui.h"
-#include "effectstackedit.h"
#include "collapsibleeffect.h"
#include "collapsiblegroup.h"
/** @brief Process dropped xml effect. */
void processDroppedEffect(QDomElement e, QDropEvent *event);
+
+ /** @brief Return the stylesheet required for effect parameters. */
+ static const QString getStyleSheet();
protected:
virtual void mouseMoveEvent(QMouseEvent * event);
/** @brief The current number of groups. */
int m_groupIndex;
+
+ /** @brief The current effect may require an on monitor scene. */
+ bool m_monitorSceneWanted;
/** @brief Sets the list of effects according to the clip's effect list. */
void setupListView();
void slotUpdateEffectParams(const QDomElement old, const QDomElement e, int ix);
/** @brief Move an effect in the stack.
- * @param index The effect index in the stack
+ * @param indexes The list of effect index in the stack
* @param up true if we want to move effect up, false for down */
- void slotMoveEffectUp(int index, bool up);
+ void slotMoveEffectUp(QList <int> indexes, bool up);
/** @brief Delete an effect in the stack. */
void slotDeleteEffect(const QDomElement effect);
void slotRenderPos(int pos);
/** @brief Called whenever an effect is enabled / disabled by user. */
- void slotUpdateEffectState(bool disable, int index, bool updateMainStatus);
+ void slotUpdateEffectState(bool disable, int index, bool needsMonitorEffectScene);
void slotSetCurrentEffect(int ix);
all effects for this clip in the playlist */
void refreshEffectStack(ClipItem *);
/** Enable or disable an effect */
- void changeEffectState(ClipItem*, int, int, bool);
+ void changeEffectState(ClipItem*, int, QList <int>, bool);
/** An effect in stack was moved */
void changeEffectPosition(ClipItem*, int, QList <int>, int);
/** an effect was saved, reload list */
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * *
+ * 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. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "ui_listval_ui.h"
+#include "ui_boolval_ui.h"
+#include "ui_wipeval_ui.h"
+#include "ui_urlval_ui.h"
+#include "ui_keywordval_ui.h"
+#include "ui_fontval_ui.h"
+#include "complexparameter.h"
+#include "geometryval.h"
+#include "positionedit.h"
+#include "kis_curve_widget.h"
+#include "kis_cubic_curve.h"
+#include "choosecolorwidget.h"
+#include "geometrywidget.h"
+#include "colortools.h"
+#include "doubleparameterwidget.h"
+#include "cornerswidget.h"
+#include "dragvalue.h"
+#include "beziercurve/beziersplinewidget.h"
+#ifdef USE_QJSON
+#include "rotoscoping/rotowidget.h"
+#endif
+#include "kdenlivesettings.h"
+#include "profilesdialog.h"
+#include "projectlist.h"
+#include "mainwindow.h"
+#include "parametercontainer.h"
+
+#include <KUrlRequester>
+#include <KFileDialog>
+
+#include <QMap>
+#include <QString>
+#include <QImage>
+
+MySpinBox::MySpinBox(QWidget * parent):
+ QSpinBox(parent)
+{
+ setFocusPolicy(Qt::StrongFocus);
+}
+
+void MySpinBox::focusInEvent(QFocusEvent *e)
+{
+ setFocusPolicy(Qt::WheelFocus);
+ e->accept();
+}
+
+void MySpinBox::focusOutEvent(QFocusEvent *e)
+{
+ setFocusPolicy(Qt::StrongFocus);
+ e->accept();
+}
+
+class Boolval: public QWidget, public Ui::Boolval_UI
+{
+};
+
+class Listval: public QWidget, public Ui::Listval_UI
+{
+};
+
+class Wipeval: public QWidget, public Ui::Wipeval_UI
+{
+};
+
+class Urlval: public QWidget, public Ui::Urlval_UI
+{
+};
+
+class Keywordval: public QWidget, public Ui::Keywordval_UI
+{
+};
+
+class Fontval: public QWidget, public Ui::Fontval_UI
+{
+};
+
+
+ParameterContainer::ParameterContainer(QDomElement effect, ItemInfo info, EffectMetaInfo *metaInfo, QWidget * parent) :
+ m_keyframeEditor(NULL),
+ m_geometryWidget(NULL),
+ m_metaInfo(metaInfo),
+ m_effect(effect),
+ m_needsMonitorEffectScene(false)
+{
+ m_in = info.cropStart.frames(KdenliveSettings::project_fps());
+ m_out = (info.cropStart + info.cropDuration).frames(KdenliveSettings::project_fps()) - 1;
+
+ QDomNodeList namenode = effect.childNodes(); //elementsByTagName("parameter");
+
+ QDomElement e = effect.toElement();
+ int minFrame = e.attribute("start").toInt();
+ int maxFrame = e.attribute("end").toInt();
+ // In transitions, maxFrame is in fact one frame after the end of transition
+ if (maxFrame > 0) maxFrame --;
+
+ bool disable = effect.attribute("disable") == "1" && KdenliveSettings::disable_effect_parameters();
+ parent->setEnabled(!disable);
+
+ bool stretch = true;
+ m_vbox = new QVBoxLayout(parent);
+ m_vbox->setContentsMargins(4, 0, 4, 0);
+ m_vbox->setSpacing(2);
+
+ for (int i = 0; i < namenode.count() ; i++) {
+ QDomElement pa = namenode.item(i).toElement();
+ if (pa.tagName() != "parameter") continue;
+ QDomElement na = pa.firstChildElement("name");
+ QDomElement commentElem = pa.firstChildElement("comment");
+ QString type = pa.attribute("type");
+ QString paramName = na.isNull() ? pa.attribute("name") : i18n(na.text().toUtf8().data());
+ QString comment;
+ if (!commentElem.isNull())
+ comment = i18n(commentElem.text().toUtf8().data());
+ QWidget * toFillin = new QWidget(parent);
+ QString value = pa.attribute("value").isNull() ?
+ pa.attribute("default") : pa.attribute("value");
+
+
+ /** See effects/README for info on the different types */
+
+ if (type == "double" || type == "constant") {
+ double min;
+ double max;
+ if (pa.attribute("min").contains('%'))
+ min = ProfilesDialog::getStringEval(m_metaInfo->profile, pa.attribute("min"), m_metaInfo->frameSize);
+ else
+ min = pa.attribute("min").toDouble();
+ if (pa.attribute("max").contains('%'))
+ max = ProfilesDialog::getStringEval(m_metaInfo->profile, pa.attribute("max"), m_metaInfo->frameSize);
+ else
+ max = pa.attribute("max").toDouble();
+
+ DoubleParameterWidget *doubleparam = new DoubleParameterWidget(paramName, value.toDouble(), min, max,
+ pa.attribute("default").toDouble(), comment, -1, pa.attribute("suffix"), pa.attribute("decimals").toInt(), parent);
+ doubleparam->setFocusPolicy(Qt::StrongFocus);
+ m_vbox->addWidget(doubleparam);
+ m_valueItems[paramName] = doubleparam;
+ connect(doubleparam, SIGNAL(valueChanged(double)), this, SLOT(slotCollectAllParameters()));
+ connect(this, SIGNAL(showComments(bool)), doubleparam, SLOT(slotShowComment(bool)));
+ } else if (type == "list") {
+ Listval *lsval = new Listval;
+ lsval->setupUi(toFillin);
+ lsval->list->setFocusPolicy(Qt::StrongFocus);
+ QStringList listitems = pa.attribute("paramlist").split(';');
+ if (listitems.count() == 1) {
+ // probably custom effect created before change to ';' as separator
+ listitems = pa.attribute("paramlist").split(",");
+ }
+ QDomElement list = pa.firstChildElement("paramlistdisplay");
+ QStringList listitemsdisplay;
+ if (!list.isNull()) {
+ listitemsdisplay = i18n(list.text().toUtf8().data()).split(',');
+ } else {
+ listitemsdisplay = i18n(pa.attribute("paramlistdisplay").toUtf8().data()).split(',');
+ }
+ if (listitemsdisplay.count() != listitems.count())
+ listitemsdisplay = listitems;
+ lsval->list->setIconSize(QSize(30, 30));
+ for (int i = 0; i < listitems.count(); i++) {
+ lsval->list->addItem(listitemsdisplay.at(i), listitems.at(i));
+ QString entry = listitems.at(i);
+ if (!entry.isEmpty() && (entry.endsWith(".png") || entry.endsWith(".pgm"))) {
+ if (!MainWindow::m_lumacache.contains(entry)) {
+ QImage pix(entry);
+ MainWindow::m_lumacache.insert(entry, pix.scaled(30, 30, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ }
+ lsval->list->setItemIcon(i, QPixmap::fromImage(MainWindow::m_lumacache.value(entry)));
+ }
+ }
+ if (!value.isEmpty()) lsval->list->setCurrentIndex(listitems.indexOf(value));
+ lsval->name->setText(paramName);
+ lsval->labelComment->setText(comment);
+ lsval->widgetComment->setHidden(true);
+ m_valueItems[paramName] = lsval;
+ connect(lsval->list, SIGNAL(currentIndexChanged(int)) , this, SLOT(slotCollectAllParameters()));
+ if (!comment.isEmpty())
+ connect(this, SIGNAL(showComments(bool)), lsval->widgetComment, SLOT(setVisible(bool)));
+ m_uiItems.append(lsval);
+ } else if (type == "bool") {
+ Boolval *bval = new Boolval;
+ bval->setupUi(toFillin);
+ bval->checkBox->setCheckState(value == "0" ? Qt::Unchecked : Qt::Checked);
+ bval->name->setText(paramName);
+ bval->labelComment->setText(comment);
+ bval->widgetComment->setHidden(true);
+ m_valueItems[paramName] = bval;
+ connect(bval->checkBox, SIGNAL(stateChanged(int)) , this, SLOT(slotCollectAllParameters()));
+ if (!comment.isEmpty())
+ connect(this, SIGNAL(showComments(bool)), bval->widgetComment, SLOT(setVisible(bool)));
+ m_uiItems.append(bval);
+ } else if (type == "complex") {
+ ComplexParameter *pl = new ComplexParameter;
+ pl->setupParam(effect, pa.attribute("name"), 0, 100);
+ m_vbox->addWidget(pl);
+ m_valueItems[paramName+"complex"] = pl;
+ connect(pl, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
+ } else if (type == "geometry") {
+ if (KdenliveSettings::on_monitor_effects()) {
+ m_needsMonitorEffectScene = true;
+ m_geometryWidget = new GeometryWidget(m_metaInfo->monitor, m_metaInfo->timecode, 0, true, effect.hasAttribute("showrotation"), parent);
+ m_geometryWidget->setFrameSize(m_metaInfo->frameSize);
+ connect(m_geometryWidget, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
+ if (minFrame == maxFrame)
+ m_geometryWidget->setupParam(pa, m_in, m_out);
+ else
+ m_geometryWidget->setupParam(pa, minFrame, maxFrame);
+ m_vbox->addWidget(m_geometryWidget);
+ m_valueItems[paramName+"geometry"] = m_geometryWidget;
+ connect(m_geometryWidget, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+ connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int)));
+ } else {
+ Geometryval *geo = new Geometryval(m_metaInfo->profile, m_metaInfo->timecode, m_metaInfo->frameSize, 0);
+ if (minFrame == maxFrame)
+ geo->setupParam(pa, m_in, m_out);
+ else
+ geo->setupParam(pa, minFrame, maxFrame);
+ m_vbox->addWidget(geo);
+ m_valueItems[paramName+"geometry"] = geo;
+ connect(geo, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
+ connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+ connect(this, SIGNAL(syncEffectsPos(int)), geo, SLOT(slotSyncPosition(int)));
+ }
+ } else if (type == "addedgeometry") {
+ // this is a parameter that should be linked to the geometry widget, for example rotation, shear, ...
+ if (m_geometryWidget) m_geometryWidget->addParameter(pa);
+ } else if (type == "keyframe" || type == "simplekeyframe") {
+ // keyframe editor widget
+ if (m_keyframeEditor == NULL) {
+ KeyframeEdit *geo;
+ if (pa.attribute("widget") == "corners") {
+ // we want a corners-keyframe-widget
+ CornersWidget *corners = new CornersWidget(m_metaInfo->monitor, pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt(), parent);
+ m_needsMonitorEffectScene = true;
+ connect(this, SIGNAL(syncEffectsPos(int)), corners, SLOT(slotSyncPosition(int)));
+ geo = static_cast<KeyframeEdit *>(corners);
+ } else {
+ geo = new KeyframeEdit(pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt());
+ }
+ m_vbox->addWidget(geo);
+ m_valueItems[paramName+"keyframe"] = geo;
+ m_keyframeEditor = geo;
+ connect(geo, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
+ connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+ connect(this, SIGNAL(showComments(bool)), geo, SIGNAL(showComments(bool)));
+ } else {
+ // we already have a keyframe editor, so just add another column for the new param
+ m_keyframeEditor->addParameter(pa);
+ }
+ } else if (type == "color") {
+ if (pa.hasAttribute("paramprefix")) value.remove(0, pa.attribute("paramprefix").size());
+ if (value.startsWith('#'))
+ value = value.replace('#', "0x");
+ ChooseColorWidget *choosecolor = new ChooseColorWidget(paramName, value, parent);
+ choosecolor->setAlphaChannelEnabled(true);
+ m_vbox->addWidget(choosecolor);
+ m_valueItems[paramName] = choosecolor;
+ connect(choosecolor, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
+ connect(choosecolor, SIGNAL(modified()) , this, SLOT(slotCollectAllParameters()));
+ } else if (type == "position") {
+ int pos = value.toInt();
+ if (effect.attribute("id") == "fadein" || effect.attribute("id") == "fade_from_black") {
+ pos = pos - m_in;
+ } else if (effect.attribute("id") == "fadeout" || effect.attribute("id") == "fade_to_black") {
+ // fadeout position starts from clip end
+ pos = m_out - pos;
+ }
+ PositionEdit *posedit = new PositionEdit(paramName, pos, 0, m_out - m_in, m_metaInfo->timecode);
+ m_vbox->addWidget(posedit);
+ m_valueItems[paramName+"position"] = posedit;
+ connect(posedit, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
+ } else if (type == "curve") {
+ KisCurveWidget *curve = new KisCurveWidget(parent);
+ curve->setMaxPoints(pa.attribute("max").toInt());
+ QList<QPointF> points;
+ int number;
+ if (e.attribute("version").toDouble() > 0.2) {
+ // Rounding gives really weird results. (int) (10 * 0.3) gives 2! So for now, add 0.5 to get correct result
+ number = EffectsList::parameter(e, pa.attribute("number")).toDouble() * 10 + 0.5;
+ } else {
+ number = EffectsList::parameter(e, pa.attribute("number")).toInt();
+ }
+ QString inName = pa.attribute("inpoints");
+ QString outName = pa.attribute("outpoints");
+ int start = pa.attribute("min").toInt();
+ for (int j = start; j <= number; j++) {
+ QString in = inName;
+ in.replace("%i", QString::number(j));
+ QString out = outName;
+ out.replace("%i", QString::number(j));
+ points << QPointF(EffectsList::parameter(e, in).toDouble(), EffectsList::parameter(e, out).toDouble());
+ }
+ if (!points.isEmpty())
+ curve->setCurve(KisCubicCurve(points));
+ MySpinBox *spinin = new MySpinBox();
+ spinin->setRange(0, 1000);
+ MySpinBox *spinout = new MySpinBox();
+ spinout->setRange(0, 1000);
+ curve->setupInOutControls(spinin, spinout, 0, 1000);
+ m_vbox->addWidget(curve);
+ m_vbox->addWidget(spinin);
+ m_vbox->addWidget(spinout);
+
+ connect(curve, SIGNAL(modified()), this, SLOT(slotCollectAllParameters()));
+ m_valueItems[paramName] = curve;
+
+ QString depends = pa.attribute("depends");
+ if (!depends.isEmpty())
+ meetDependency(paramName, type, EffectsList::parameter(e, depends));
+ } else if (type == "bezier_spline") {
+ BezierSplineWidget *widget = new BezierSplineWidget(value, parent);
+ stretch = false;
+ m_vbox->addWidget(widget);
+ m_valueItems[paramName] = widget;
+ connect(widget, SIGNAL(modified()), this, SLOT(slotCollectAllParameters()));
+ QString depends = pa.attribute("depends");
+ if (!depends.isEmpty())
+ meetDependency(paramName, type, EffectsList::parameter(e, depends));
+#ifdef USE_QJSON
+ } else if (type == "roto-spline") {
+ m_needsMonitorEffectScene = true;
+ RotoWidget *roto = new RotoWidget(value, m_metaInfo->monitor, info, m_metaInfo->timecode, parent);
+ connect(roto, SIGNAL(valueChanged()), this, SLOT(slotCollectAllParameters()));
+ connect(roto, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+ connect(this, SIGNAL(syncEffectsPos(int)), roto, SLOT(slotSyncPosition(int)));
+ m_vbox->addWidget(roto);
+ m_valueItems[paramName] = roto;
+#endif
+ } else if (type == "wipe") {
+ Wipeval *wpval = new Wipeval;
+ wpval->setupUi(toFillin);
+ wipeInfo w = getWipeInfo(value);
+ switch (w.start) {
+ case UP:
+ wpval->start_up->setChecked(true);
+ break;
+ case DOWN:
+ wpval->start_down->setChecked(true);
+ break;
+ case RIGHT:
+ wpval->start_right->setChecked(true);
+ break;
+ case LEFT:
+ wpval->start_left->setChecked(true);
+ break;
+ default:
+ wpval->start_center->setChecked(true);
+ break;
+ }
+ switch (w.end) {
+ case UP:
+ wpval->end_up->setChecked(true);
+ break;
+ case DOWN:
+ wpval->end_down->setChecked(true);
+ break;
+ case RIGHT:
+ wpval->end_right->setChecked(true);
+ break;
+ case LEFT:
+ wpval->end_left->setChecked(true);
+ break;
+ default:
+ wpval->end_center->setChecked(true);
+ break;
+ }
+ wpval->start_transp->setValue(w.startTransparency);
+ wpval->end_transp->setValue(w.endTransparency);
+ m_valueItems[paramName] = wpval;
+ connect(wpval->end_up, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->end_down, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->end_left, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->end_right, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->end_center, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_up, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_down, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_left, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_right, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_center, SIGNAL(clicked()), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->start_transp, SIGNAL(valueChanged(int)), this, SLOT(slotCollectAllParameters()));
+ connect(wpval->end_transp, SIGNAL(valueChanged(int)), this, SLOT(slotCollectAllParameters()));
+ //wpval->title->setTitle(na.toElement().text());
+ m_uiItems.append(wpval);
+ } else if (type == "url") {
+ Urlval *cval = new Urlval;
+ cval->setupUi(toFillin);
+ cval->label->setText(paramName);
+ cval->urlwidget->fileDialog()->setFilter(ProjectList::getExtensions());
+ m_valueItems[paramName] = cval;
+ cval->urlwidget->setUrl(KUrl(value));
+ connect(cval->urlwidget, SIGNAL(returnPressed()) , this, SLOT(slotCollectAllParameters()));
+ connect(cval->urlwidget, SIGNAL(urlSelected(const KUrl&)) , this, SLOT(slotCollectAllParameters()));
+ m_uiItems.append(cval);
+ } else if (type == "keywords") {
+ Keywordval* kval = new Keywordval;
+ kval->setupUi(toFillin);
+ kval->label->setText(paramName);
+ kval->lineeditwidget->setText(value);
+ QDomElement klistelem = pa.firstChildElement("keywords");
+ QDomElement kdisplaylistelem = pa.firstChildElement("keywordsdisplay");
+ QStringList keywordlist;
+ QStringList keyworddisplaylist;
+ if (!klistelem.isNull()) {
+ keywordlist = klistelem.text().split(';');
+ keyworddisplaylist = i18n(kdisplaylistelem.text().toUtf8().data()).split(';');
+ }
+ if (keyworddisplaylist.count() != keywordlist.count()) {
+ keyworddisplaylist = keywordlist;
+ }
+ for (int i = 0; i < keywordlist.count(); i++) {
+ kval->comboboxwidget->addItem(keyworddisplaylist.at(i), keywordlist.at(i));
+ }
+ // Add disabled user prompt at index 0
+ kval->comboboxwidget->insertItem(0, i18n("<select a keyword>"), "");
+ kval->comboboxwidget->model()->setData( kval->comboboxwidget->model()->index(0,0), QVariant(Qt::NoItemFlags), Qt::UserRole -1);
+ kval->comboboxwidget->setCurrentIndex(0);
+ m_valueItems[paramName] = kval;
+ connect(kval->lineeditwidget, SIGNAL(editingFinished()) , this, SLOT(collectAllParameters()));
+ connect(kval->comboboxwidget, SIGNAL(activated (const QString&)), this, SLOT(collectAllParameters()));
+ m_uiItems.append(kval);
+ } else if (type == "fontfamily") {
+ Fontval* fval = new Fontval;
+ fval->setupUi(toFillin);
+ fval->name->setText(paramName);
+ fval->fontfamilywidget->setCurrentFont(QFont(value));
+ m_valueItems[paramName] = fval;
+ connect(fval->fontfamilywidget, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(collectAllParameters())) ;
+ m_uiItems.append(fval);
+ } else if (type == "filterjob") {
+ QVBoxLayout *l= new QVBoxLayout(toFillin);
+ QPushButton *button = new QPushButton(paramName, toFillin);
+ l->addWidget(button);
+ m_valueItems[paramName] = button;
+ connect(button, SIGNAL(pressed()), this, SLOT(slotStartFilterJobAction()));
+ } else {
+ delete toFillin;
+ toFillin = NULL;
+ }
+
+ if (toFillin)
+ m_vbox->addWidget(toFillin);
+ }
+
+ if (stretch)
+ m_vbox->addStretch();
+
+ if (m_keyframeEditor)
+ m_keyframeEditor->checkVisibleParam();
+
+ // Make sure all doubleparam spinboxes have the same width, looks much better
+ QList<DoubleParameterWidget *> allWidgets = findChildren<DoubleParameterWidget *>();
+ int minSize = 0;
+ for (int i = 0; i < allWidgets.count(); i++) {
+ if (minSize < allWidgets.at(i)->spinSize()) minSize = allWidgets.at(i)->spinSize();
+ }
+ for (int i = 0; i < allWidgets.count(); i++) {
+ allWidgets.at(i)->setSpinSize(minSize);
+ }
+}
+
+ParameterContainer::~ParameterContainer()
+{
+ clearLayout(m_vbox);
+ delete m_vbox;
+}
+
+void ParameterContainer::meetDependency(const QString& name, QString type, QString value)
+{
+ if (type == "curve") {
+ KisCurveWidget *curve = (KisCurveWidget*)m_valueItems[name];
+ if (curve) {
+ int color = value.toInt();
+ curve->setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(curve->size(), (ColorTools::ColorsRGB)(color == 3 ? 4 : color), 0.8)));
+ }
+ } else if (type == "bezier_spline") {
+ BezierSplineWidget *widget = (BezierSplineWidget*)m_valueItems[name];
+ if (widget) {
+ widget->setMode((BezierSplineWidget::CurveModes)((int)(value.toDouble() * 10 + 0.5)));
+ }
+ }
+}
+
+wipeInfo ParameterContainer::getWipeInfo(QString value)
+{
+ wipeInfo info;
+ // Convert old geometry values that used a comma as separator
+ if (value.contains(',')) value.replace(',','/');
+ QString start = value.section(';', 0, 0);
+ QString end = value.section(';', 1, 1).section('=', 1, 1);
+ if (start.startsWith("-100%/0"))
+ info.start = LEFT;
+ else if (start.startsWith("100%/0"))
+ info.start = RIGHT;
+ else if (start.startsWith("0%/100%"))
+ info.start = DOWN;
+ else if (start.startsWith("0%/-100%"))
+ info.start = UP;
+ else
+ info.start = CENTER;
+
+ if (start.count(':') == 2)
+ info.startTransparency = start.section(':', -1).toInt();
+ else
+ info.startTransparency = 100;
+
+ if (end.startsWith("-100%/0"))
+ info.end = LEFT;
+ else if (end.startsWith("100%/0"))
+ info.end = RIGHT;
+ else if (end.startsWith("0%/100%"))
+ info.end = DOWN;
+ else if (end.startsWith("0%/-100%"))
+ info.end = UP;
+ else
+ info.end = CENTER;
+
+ if (end.count(':') == 2)
+ info.endTransparency = end.section(':', -1).toInt();
+ else
+ info.endTransparency = 100;
+
+ return info;
+}
+
+void ParameterContainer::updateTimecodeFormat()
+{
+ if (m_keyframeEditor)
+ m_keyframeEditor->updateTimecodeFormat();
+
+ QDomNodeList namenode = m_effect.elementsByTagName("parameter");
+ for (int i = 0; i < namenode.count() ; i++) {
+ QDomNode pa = namenode.item(i);
+ QDomElement na = pa.firstChildElement("name");
+ QString type = pa.attributes().namedItem("type").nodeValue();
+ QString paramName = na.isNull() ? pa.attributes().namedItem("name").nodeValue() : i18n(na.text().toUtf8().data());
+
+ if (type == "geometry") {
+ if (KdenliveSettings::on_monitor_effects()) {
+ if (m_geometryWidget) m_geometryWidget->updateTimecodeFormat();
+ } else {
+ Geometryval *geom = ((Geometryval*)m_valueItems[paramName+"geometry"]);
+ geom->updateTimecodeFormat();
+ }
+ break;
+ } else if (type == "position") {
+ PositionEdit *posi = ((PositionEdit*)m_valueItems[paramName+"position"]);
+ posi->updateTimecodeFormat();
+ break;
+#ifdef USE_QJSON
+ } else if (type == "roto-spline") {
+ RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems[paramName]);
+ widget->updateTimecodeFormat();
+#endif
+ }
+ }
+}
+
+void ParameterContainer::slotCollectAllParameters()
+{
+ if (m_valueItems.isEmpty() || m_effect.isNull()) return;
+ QLocale locale;
+ locale.setNumberOptions(QLocale::OmitGroupSeparator);
+ const QDomElement oldparam = m_effect.cloneNode().toElement();
+ //QDomElement newparam = oldparam.cloneNode().toElement();
+ QDomNodeList namenode = m_effect.elementsByTagName("parameter");
+
+ for (int i = 0; i < namenode.count() ; i++) {
+ QDomElement pa = namenode.item(i).toElement();
+ QDomElement na = pa.firstChildElement("name");
+ QString type = pa.attribute("type");
+ QString paramName = na.isNull() ? pa.attribute("name") : i18n(na.text().toUtf8().data());
+ if (type == "complex")
+ paramName.append("complex");
+ else if (type == "position")
+ paramName.append("position");
+ else if (type == "geometry")
+ paramName.append("geometry");
+ else if (type == "keyframe")
+ paramName.append("keyframe");
+ if (type != "simplekeyframe" && type != "fixed" && type != "addedgeometry" && !m_valueItems.contains(paramName)) {
+ kDebug() << "// Param: " << paramName << " NOT FOUND";
+ continue;
+ }
+
+ QString setValue;
+ if (type == "double" || type == "constant") {
+ DoubleParameterWidget *doubleparam = (DoubleParameterWidget*)m_valueItems.value(paramName);
+ setValue = locale.toString(doubleparam->getValue());
+ } else if (type == "list") {
+ KComboBox *box = ((Listval*)m_valueItems.value(paramName))->list;
+ setValue = box->itemData(box->currentIndex()).toString();
+ } else if (type == "bool") {
+ QCheckBox *box = ((Boolval*)m_valueItems.value(paramName))->checkBox;
+ setValue = box->checkState() == Qt::Checked ? "1" : "0" ;
+ } else if (type == "color") {
+ ChooseColorWidget *choosecolor = ((ChooseColorWidget*)m_valueItems.value(paramName));
+ setValue = choosecolor->getColor();
+ if (pa.hasAttribute("paramprefix")) setValue.prepend(pa.attribute("paramprefix"));
+ } else if (type == "complex") {
+ ComplexParameter *complex = ((ComplexParameter*)m_valueItems.value(paramName));
+ namenode.item(i) = complex->getParamDesc();
+ } else if (type == "geometry") {
+ if (KdenliveSettings::on_monitor_effects()) {
+ if (m_geometryWidget) namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getValue());
+ } else {
+ Geometryval *geom = ((Geometryval*)m_valueItems.value(paramName));
+ namenode.item(i).toElement().setAttribute("value", geom->getValue());
+ }
+ } else if (type == "addedgeometry") {
+ namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getExtraValue(namenode.item(i).toElement().attribute("name")));
+ } else if (type == "position") {
+ PositionEdit *pedit = ((PositionEdit*)m_valueItems.value(paramName));
+ int pos = pedit->getPosition();
+ setValue = QString::number(pos);
+ 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(m_effect, "in", QString::number(m_in));
+ EffectsList::setParameter(m_effect, "out", QString::number(m_in + pos));
+ setValue.clear();
+ } 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(m_effect, "in", QString::number(m_out - pos));
+ EffectsList::setParameter(m_effect, "out", QString::number(m_out));
+ setValue.clear();
+ }
+ } else if (type == "curve") {
+ KisCurveWidget *curve = ((KisCurveWidget*)m_valueItems.value(paramName));
+ QList<QPointF> points = curve->curve().points();
+ QString number = pa.attribute("number");
+ QString inName = pa.attribute("inpoints");
+ QString outName = pa.attribute("outpoints");
+ int off = pa.attribute("min").toInt();
+ int end = pa.attribute("max").toInt();
+ if (oldparam.attribute("version").toDouble() > 0.2) {
+ EffectsList::setParameter(m_effect, number, locale.toString(points.count() / 10.));
+ } else {
+ 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(m_effect, in, locale.toString(points.at(j).x()));
+ EffectsList::setParameter(m_effect, out, locale.toString(points.at(j).y()));
+ }
+ QString depends = pa.attribute("depends");
+ if (!depends.isEmpty())
+ 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.attribute("depends");
+ if (!depends.isEmpty())
+ 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));
+ setValue = widget->getSpline();
+#endif
+ } else if (type == "wipe") {
+ Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
+ wipeInfo info;
+ if (wp->start_left->isChecked())
+ info.start = LEFT;
+ else if (wp->start_right->isChecked())
+ info.start = RIGHT;
+ else if (wp->start_up->isChecked())
+ info.start = UP;
+ else if (wp->start_down->isChecked())
+ info.start = DOWN;
+ else if (wp->start_center->isChecked())
+ info.start = CENTER;
+ else
+ info.start = LEFT;
+ info.startTransparency = wp->start_transp->value();
+
+ if (wp->end_left->isChecked())
+ info.end = LEFT;
+ else if (wp->end_right->isChecked())
+ info.end = RIGHT;
+ else if (wp->end_up->isChecked())
+ info.end = UP;
+ else if (wp->end_down->isChecked())
+ info.end = DOWN;
+ else if (wp->end_center->isChecked())
+ info.end = CENTER;
+ else
+ info.end = RIGHT;
+ info.endTransparency = wp->end_transp->value();
+
+ setValue = getWipeString(info);
+ } else if ((type == "simplekeyframe" || type == "keyframe") && m_keyframeEditor) {
+ QString realName = i18n(na.toElement().text().toUtf8().data());
+ QString val = m_keyframeEditor->getValue(realName);
+ pa.setAttribute("keyframes", val);
+
+ if (m_keyframeEditor->isVisibleParam(realName)) {
+ pa.setAttribute("intimeline", "1");
+ }
+ else if (pa.hasAttribute("intimeline"))
+ pa.removeAttribute("intimeline");
+ } else if (type == "url") {
+ KUrlRequester *req = ((Urlval*)m_valueItems.value(paramName))->urlwidget;
+ setValue = req->url().path();
+ } else if (type == "keywords"){
+ QLineEdit *line = ((Keywordval*)m_valueItems.value(paramName))->lineeditwidget;
+ QComboBox *combo = ((Keywordval*)m_valueItems.value(paramName))->comboboxwidget;
+ if(combo->currentIndex())
+ {
+ QString comboval = combo->itemData(combo->currentIndex()).toString();
+ line->insert(comboval);
+ combo->setCurrentIndex(0);
+ }
+ setValue = line->text();
+ } else if (type == "fontfamily") {
+ QFontComboBox* fontfamily = ((Fontval*)m_valueItems.value(paramName))->fontfamilywidget;
+ setValue = fontfamily->currentFont().family();
+ }
+ if (!setValue.isNull())
+ pa.setAttribute("value", setValue);
+
+ }
+ emit parameterChanged(oldparam, m_effect, m_effect.attribute("kdenlive_ix").toInt());
+}
+
+QString ParameterContainer::getWipeString(wipeInfo info)
+{
+
+ QString start;
+ QString end;
+ switch (info.start) {
+ case LEFT:
+ start = "-100%/0%:100%x100%";
+ break;
+ case RIGHT:
+ start = "100%/0%:100%x100%";
+ break;
+ case DOWN:
+ start = "0%/100%:100%x100%";
+ break;
+ case UP:
+ start = "0%/-100%:100%x100%";
+ break;
+ default:
+ start = "0%/0%:100%x100%";
+ break;
+ }
+ start.append(':' + QString::number(info.startTransparency));
+
+ switch (info.end) {
+ case LEFT:
+ end = "-100%/0%:100%x100%";
+ break;
+ case RIGHT:
+ end = "100%/0%:100%x100%";
+ break;
+ case DOWN:
+ end = "0%/100%:100%x100%";
+ break;
+ case UP:
+ end = "0%/-100%:100%x100%";
+ break;
+ default:
+ end = "0%/0%:100%x100%";
+ break;
+ }
+ end.append(':' + QString::number(info.endTransparency));
+ return QString(start + ";-1=" + end);
+}
+
+void ParameterContainer::updateParameter(const QString &key, const QString &value)
+{
+ m_effect.setAttribute(key, value);
+}
+
+void ParameterContainer::slotStartFilterJobAction()
+{
+ QDomNodeList namenode = m_effect.elementsByTagName("parameter");
+ for (int i = 0; i < namenode.count() ; i++) {
+ QDomElement pa = namenode.item(i).toElement();
+ QString type = pa.attribute("type");
+ if (type == "filterjob") {
+ emit startFilterJob(pa.attribute("filtertag"), pa.attribute("filterparams"), pa.attribute("finalfilter"), pa.attribute("consumer"), pa.attribute("consumerparams"), pa.attribute("wantedproperties"));
+ kDebug()<<" - - -PROPS:\n"<<pa.attribute("filtertag")<<"-"<< pa.attribute("filterparams")<<"-"<< pa.attribute("consumer")<<"-"<< pa.attribute("consumerparams")<<"-"<< pa.attribute("wantedproperties");
+ break;
+ }
+ }
+}
+
+
+void ParameterContainer::clearLayout(QLayout *layout)
+{
+ QLayoutItem *item;
+ while((item = layout->takeAt(0))) {
+ if (item->layout()) {
+ clearLayout(item->layout());
+ delete item->layout();
+ }
+ if (item->widget()) {
+ delete item->widget();
+ }
+ delete item;
+ }
+}
+
+bool ParameterContainer::needsMonitorEffectScene() const
+{
+ return m_needsMonitorEffectScene;
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2012 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * *
+ * 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. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef PARAMETERCONTAINER_H
+#define PARAMETERCONTAINER_H
+
+#include "keyframeedit.h"
+
+class GeometryWidget;
+class Monitor;
+
+struct EffectMetaInfo {
+ MltVideoProfile profile;
+ Timecode timecode;
+ Monitor *monitor;
+ QPoint frameSize;
+ bool trackMode;
+};
+
+enum WIPE_DIRECTON { UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, CENTER = 4 };
+
+struct wipeInfo {
+ WIPE_DIRECTON start;
+ WIPE_DIRECTON end;
+ int startTransparency;
+ int endTransparency;
+};
+
+class MySpinBox : public QSpinBox
+{
+ Q_OBJECT
+
+public:
+ MySpinBox(QWidget * parent = 0);
+
+protected:
+ virtual void focusInEvent(QFocusEvent*);
+ virtual void focusOutEvent(QFocusEvent*);
+};
+
+class ParameterContainer : public QObject
+{
+ Q_OBJECT
+
+public:
+ ParameterContainer(QDomElement effect, ItemInfo info, EffectMetaInfo *metaInfo, QWidget * parent = 0);
+ ~ParameterContainer();
+ void updateTimecodeFormat();
+ void updateProjectFormat(MltVideoProfile profile, Timecode t);
+ void updateParameter(const QString &key, const QString &value);
+ /** @brief Returns true of this effect requires an on monitor adjustable effect scene. */
+ bool needsMonitorEffectScene() const;
+
+private slots:
+ void slotCollectAllParameters();
+ void slotStartFilterJobAction();
+
+private:
+ /** @brief Updates parameter @param name according to new value of dependency.
+ * @param name Name of the parameter which will be updated
+ * @param type Type of the parameter which will be updated
+ * @param value Value of the dependency parameter */
+ void meetDependency(const QString& name, QString type, QString value);
+ wipeInfo getWipeInfo(QString value);
+ QString getWipeString(wipeInfo info);
+ /** @brief Delete all child widgets */
+ void clearLayout(QLayout *layout);
+
+ int m_in;
+ int m_out;
+ QList<QWidget*> m_uiItems;
+ QMap<QString, QWidget*> m_valueItems;
+ Timecode m_timecode;
+ KeyframeEdit *m_keyframeEditor;
+ GeometryWidget *m_geometryWidget;
+ EffectMetaInfo *m_metaInfo;
+ QDomElement m_effect;
+ QVBoxLayout *m_vbox;
+ bool m_needsMonitorEffectScene;
+
+signals:
+ void parameterChanged(const QDomElement, const QDomElement, int);
+ void syncEffectsPos(int);
+ void effectStateChanged(bool);
+ void checkMonitorPosition(int);
+ void seekTimeline(int);
+ void showComments(bool);
+ /** @brief Start an MLT filter job on this clip. */
+ void startFilterJob(QString filterName, QString filterParams, QString finalFilterName, QString consumer, QString consumerParams, QString properties);
+
+};
+
+#endif
+
***************************************************************************/
#include "effectstackedit.h"
-#include "ui_listval_ui.h"
-#include "ui_boolval_ui.h"
-#include "ui_wipeval_ui.h"
-#include "ui_urlval_ui.h"
-#include "ui_keywordval_ui.h"
-#include "ui_fontval_ui.h"
-#include "complexparameter.h"
-#include "geometryval.h"
-#include "positionedit.h"
-#include "projectlist.h"
+#include "effectstack/effectstackview2.h"
#include "effectslist.h"
+#include "monitor.h"
#include "kdenlivesettings.h"
-#include "profilesdialog.h"
-#include "kis_curve_widget.h"
-#include "kis_cubic_curve.h"
-#include "choosecolorwidget.h"
-#include "geometrywidget.h"
-#include "colortools.h"
-#include "doubleparameterwidget.h"
-#include "cornerswidget.h"
-#include "beziercurve/beziersplinewidget.h"
-#ifdef USE_QJSON
-#include "rotoscoping/rotowidget.h"
-#endif
#include <KDebug>
#include <KLocale>
#include <KFileDialog>
+#include <KComboBox>
#include <QVBoxLayout>
#include <QLabel>
#include <QScrollArea>
#include <QScrollBar>
#include <QProgressBar>
+#include <QWheelEvent>
// For QDomNode debugging (output into files); leaving here as sample code.
//#define DEBUG_ESE
-class Boolval: public QWidget, public Ui::Boolval_UI
-{
-};
-
-class Listval: public QWidget, public Ui::Listval_UI
-{
-};
-
-class Wipeval: public QWidget, public Ui::Wipeval_UI
-{
-};
-
-class Urlval: public QWidget, public Ui::Urlval_UI
-{
-};
-
-class Keywordval: public QWidget, public Ui::Keywordval_UI
-{
-};
-
-class Fontval: public QWidget, public Ui::Fontval_UI
-{
-};
-
-QMap<QString, QImage> EffectStackEdit::iconCache;
-
EffectStackEdit::EffectStackEdit(Monitor *monitor, QWidget *parent) :
QScrollArea(parent),
- m_in(0),
- m_out(0),
- m_keyframeEditor(NULL),
- m_monitor(monitor),
- m_geometryWidget(NULL),
m_paramWidget(NULL)
{
m_baseWidget = new QWidget(this);
setFrameStyle(QFrame::NoFrame);
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding));
- setStyleSheet(CollapsibleEffect::getStyleSheet());
+ setStyleSheet(EffectStackView2::getStyleSheet());
setWidget(m_baseWidget);
/*m_vbox = new QVBoxLayout(m_baseWidget);
m_vbox->setContentsMargins(0, 0, 0, 0);
EffectStackEdit::~EffectStackEdit()
{
- iconCache.clear();
delete m_baseWidget;
}
void EffectStackEdit::setFrameSize(QPoint p)
{
m_metaInfo.frameSize = p;
- /*
- m_frameSize = p;
- QDomNodeList namenode = m_params.elementsByTagName("parameter");
- for (int i = 0; i < namenode.count() ; i++) {
- QDomNode pa = namenode.item(i);
- QDomElement na = pa.firstChildElement("name");
- QString type = pa.attributes().namedItem("type").nodeValue();
- QString paramName = na.isNull() ? pa.attributes().namedItem("name").nodeValue() : i18n(na.text().toUtf8().data());
-
- if (type == "geometry") {
- if (!KdenliveSettings::on_monitor_effects()) {
- Geometryval *geom = ((Geometryval*)m_valueItems[paramName+"geometry"]);
- geom->setFrameSize(m_frameSize);
- break;
- }
- else {
- if (m_geometryWidget) m_geometryWidget->setFrameSize(m_frameSize);
- break;
- }
- }
- }*/
}
void EffectStackEdit::updateTimecodeFormat()
if (m_paramWidget) m_paramWidget->updateTimecodeFormat();
}
-void EffectStackEdit::meetDependency(const QString& name, QString type, QString value)
-{
- if (type == "curve") {
- KisCurveWidget *curve = (KisCurveWidget*)m_valueItems[name];
- if (curve) {
- int color = value.toInt();
- curve->setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(curve->size(), (ColorTools::ColorsRGB)(color == 3 ? 4 : color), 0.8)));
- }
- } else if (type == "bezier_spline") {
- BezierSplineWidget *widget = (BezierSplineWidget*)m_valueItems[name];
- if (widget) {
- widget->setMode((BezierSplineWidget::CurveModes)((int)(value.toDouble() * 10)));
- }
- }
-}
-
void EffectStackEdit::updateParameter(const QString &name, const QString &value)
{
m_paramWidget->updateParameter(name, value);
connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
connect (m_paramWidget, SIGNAL(seekTimeline(int)), this, SIGNAL(seekTimeline(int)));
-
Q_FOREACH( QSpinBox * sp, m_baseWidget->findChildren<QSpinBox*>() ) {
sp->installEventFilter( this );
sp->setFocusPolicy( Qt::StrongFocus );
cb->installEventFilter( this );
cb->setFocusPolicy( Qt::StrongFocus );
}
-
- return;
- /*
- //clearAllItems();
- if (m_keyframeEditor) delete m_keyframeEditor;
- m_keyframeEditor = NULL;
- m_params = d;
- m_in = isEffect ? info.cropStart.frames(KdenliveSettings::project_fps()) : info.startPos.frames(KdenliveSettings::project_fps());
- m_out = isEffect ? (info.cropStart + info.cropDuration).frames(KdenliveSettings::project_fps()) - 1 : info.endPos.frames(KdenliveSettings::project_fps());
- if (m_params.isNull()) {
-// kDebug() << "// EMPTY EFFECT STACK";
- return;
- }
-
- QDomNodeList namenode = m_params.elementsByTagName("parameter");
-#ifdef DEBUG_ESE
- QFile debugFile("/tmp/namenodes.txt");
- if (debugFile.open(QFile::WriteOnly | QFile::Truncate)) {
- QTextStream out(&debugFile);
- QTextStream out2(stdout);
- for (int i = 0; i < namenode.size(); i++) {
- out << i << ": \n";
- namenode.at(i).save(out, 2);
- out2 << i << ": \n";
- namenode.at(i).save(out2, 2);
- }
- }
-#endif
- int minFrame = d.attribute("start").toInt();
- int maxFrame = d.attribute("end").toInt();
- // In transitions, maxFrame is in fact one frame after the end of transition
- if (maxFrame > 0) maxFrame --;
-
- bool disable = d.attribute("disable") == "1" && KdenliveSettings::disable_effect_parameters();
- setEnabled(!disable);
-
- bool stretch = true;
-
-
- for (int i = 0; i < namenode.count() ; i++) {
- QDomElement pa = namenode.item(i).toElement();
- QDomElement na = pa.firstChildElement("name");
- QDomElement commentElem = pa.firstChildElement("comment");
- QString type = pa.attribute("type");
- QString paramName = na.isNull() ? pa.attribute("name") : i18n(na.text().toUtf8().data());
- QString comment;
- if (!commentElem.isNull())
- comment = i18n(commentElem.text().toUtf8().data());
- QString value = pa.attribute("value").isNull() ?
- pa.attribute("default") : pa.attribute("value");
-
-
-
-
- if (type == "double" || type == "constant") {
- double min;
- double max;
- if (pa.attribute("min").contains('%'))
- min = ProfilesDialog::getStringEval(m_profile, pa.attribute("min"), m_frameSize);
- else
- min = pa.attribute("min").toDouble();
- if (pa.attribute("max").contains('%'))
- max = ProfilesDialog::getStringEval(m_profile, pa.attribute("max"), m_frameSize);
- else
- max = pa.attribute("max").toDouble();
-
- DoubleParameterWidget *doubleparam = new DoubleParameterWidget(paramName, value.toDouble(), min, max,
- pa.attribute("default").toDouble(), comment, -1, pa.attribute("suffix"), pa.attribute("decimals").toInt(), this);
- m_vbox->addWidget(doubleparam);
- m_valueItems[paramName] = doubleparam;
- connect(doubleparam, SIGNAL(valueChanged(double)), this, SLOT(collectAllParameters()));
- connect(this, SIGNAL(showComments(bool)), doubleparam, SLOT(slotShowComment(bool)));
- } else if (type == "list") {
- Listval *lsval = new Listval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- lsval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- QStringList listitems = pa.attribute("paramlist").split(';');
- if (listitems.count() == 1) {
- // probably custom effect created before change to ';' as separator
- listitems = pa.attribute("paramlist").split(',');
- }
- QDomElement list = pa.firstChildElement("paramlistdisplay");
- QStringList listitemsdisplay;
- if (!list.isNull()) {
- listitemsdisplay = i18n(list.text().toUtf8().data()).split(',');
- } else {
- listitemsdisplay = i18n(pa.attribute("paramlistdisplay").toUtf8().data()).split(',');
- }
- if (listitemsdisplay.count() != listitems.count())
- listitemsdisplay = listitems;
- lsval->list->setIconSize(QSize(30, 30));
- for (int i = 0; i < listitems.count(); i++) {
- lsval->list->addItem(listitemsdisplay.at(i), listitems.at(i));
- QString entry = listitems.at(i);
- if (!entry.isEmpty() && (entry.endsWith(".png") || entry.endsWith(".pgm"))) {
- if (!EffectStackEdit::iconCache.contains(entry)) {
- QImage pix(entry);
- EffectStackEdit::iconCache[entry] = pix.scaled(30, 30);
- }
- lsval->list->setItemIcon(i, QPixmap::fromImage(iconCache[entry]));
- }
- }
- if (!value.isEmpty()) lsval->list->setCurrentIndex(listitems.indexOf(value));
- lsval->name->setText(paramName);
- lsval->labelComment->setText(comment);
- lsval->widgetComment->setHidden(true);
- m_valueItems[paramName] = lsval;
- connect(lsval->list, SIGNAL(currentIndexChanged(int)) , this, SLOT(collectAllParameters()));
- if (!comment.isEmpty())
- connect(this, SIGNAL(showComments(bool)), lsval->widgetComment, SLOT(setVisible(bool)));
- m_uiItems.append(lsval);
- } else if (type == "bool") {
- Boolval *bval = new Boolval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- bval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- bval->checkBox->setCheckState(value == "0" ? Qt::Unchecked : Qt::Checked);
- bval->name->setText(paramName);
- bval->labelComment->setText(comment);
- bval->widgetComment->setHidden(true);
- m_valueItems[paramName] = bval;
- connect(bval->checkBox, SIGNAL(stateChanged(int)) , this, SLOT(collectAllParameters()));
- if (!comment.isEmpty())
- connect(this, SIGNAL(showComments(bool)), bval->widgetComment, SLOT(setVisible(bool)));
- m_uiItems.append(bval);
- } else if (type == "complex") {
- ComplexParameter *pl = new ComplexParameter;
- pl->setupParam(d, pa.attribute("name"), 0, 100);
- m_vbox->addWidget(pl);
- m_valueItems[paramName+"complex"] = pl;
- connect(pl, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
- } else if (type == "geometry") {
- if (KdenliveSettings::on_monitor_effects()) {
- m_geometryWidget = new GeometryWidget(m_monitor, m_timecode, isEffect ? 0 : qMax(0, (int)info.startPos.frames(KdenliveSettings::project_fps())), isEffect, m_params.hasAttribute("showrotation"), this);
- m_geometryWidget->setFrameSize(m_frameSize);
- m_geometryWidget->slotShowScene(!disable);
- // connect this before setupParam to make sure the monitor scene shows up at startup
- connect(m_geometryWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(m_geometryWidget, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
- if (minFrame == maxFrame)
- m_geometryWidget->setupParam(pa, m_in, m_out);
- else
- m_geometryWidget->setupParam(pa, minFrame, maxFrame);
- m_vbox->addWidget(m_geometryWidget);
- m_valueItems[paramName+"geometry"] = m_geometryWidget;
- connect(m_geometryWidget, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), m_geometryWidget, SLOT(slotShowScene(bool)));
- } else {
- Geometryval *geo = new Geometryval(m_profile, m_timecode, m_frameSize, isEffect ? 0 : qMax(0, (int)info.startPos.frames(KdenliveSettings::project_fps())));
- if (minFrame == maxFrame)
- geo->setupParam(pa, m_in, m_out);
- else
- geo->setupParam(pa, minFrame, maxFrame);
- m_vbox->addWidget(geo);
- m_valueItems[paramName+"geometry"] = geo;
- connect(geo, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
- connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), geo, SLOT(slotSyncPosition(int)));
- }
- } else if (type == "addedgeometry") {
- // this is a parameter that should be linked to the geometry widget, for example rotation, shear, ...
- if (m_geometryWidget) m_geometryWidget->addParameter(pa);
- } else if (type == "keyframe" || type == "simplekeyframe") {
- // keyframe editor widget
- if (m_keyframeEditor == NULL) {
- KeyframeEdit *geo;
- if (pa.attribute("widget") == "corners") {
- // we want a corners-keyframe-widget
- CornersWidget *corners = new CornersWidget(m_monitor, pa, m_in, m_out, m_timecode, d.attribute("active_keyframe", "-1").toInt(), this);
- corners->slotShowScene(!disable);
- connect(corners, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), corners, SLOT(slotShowScene(bool)));
- connect(this, SIGNAL(syncEffectsPos(int)), corners, SLOT(slotSyncPosition(int)));
- geo = static_cast<KeyframeEdit *>(corners);
- } else {
- geo = new KeyframeEdit(pa, m_in, m_out, m_timecode, d.attribute("active_keyframe", "-1").toInt());
- }
- m_vbox->addWidget(geo);
- m_valueItems[paramName+"keyframe"] = geo;
- m_keyframeEditor = geo;
- connect(geo, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
- connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(showComments(bool)), geo, SIGNAL(showComments(bool)));
- } else {
- // we already have a keyframe editor, so just add another column for the new param
- m_keyframeEditor->addParameter(pa);
- }
- } else if (type == "color") {
- ChooseColorWidget *choosecolor = new ChooseColorWidget(paramName, value, this);
- choosecolor->setAlphaChannelEnabled(pa.attribute("alpha") == "1");
- m_vbox->addWidget(choosecolor);
- m_valueItems[paramName] = choosecolor;
- connect(choosecolor, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
- connect(choosecolor, SIGNAL(modified()) , this, SLOT(collectAllParameters()));
- } else if (type == "position") {
- int pos = value.toInt();
- if (d.attribute("id") == "fadein" || d.attribute("id") == "fade_from_black") {
- pos = pos - m_in;
- } else if (d.attribute("id") == "fadeout" || d.attribute("id") == "fade_to_black") {
- // fadeout position starts from clip end
- pos = m_out - pos;
- }
- PositionEdit *posedit = new PositionEdit(paramName, pos, 0, m_out - m_in, m_timecode);
- m_vbox->addWidget(posedit);
- m_valueItems[paramName+"position"] = posedit;
- connect(posedit, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
- } else if (type == "curve") {
- KisCurveWidget *curve = new KisCurveWidget(this);
- curve->setMaxPoints(pa.attribute("max").toInt());
- QList<QPointF> points;
- int number;
- if (d.attribute("version").toDouble() > 0.2) {
- number = EffectsList::parameter(d, pa.attribute("number")).toDouble() * 10;
- } else {
- number = EffectsList::parameter(d, pa.attribute("number")).toInt();
- }
- QString inName = pa.attribute("inpoints");
- QString outName = pa.attribute("outpoints");
- int start = pa.attribute("min").toInt();
- for (int j = start; j <= number; j++) {
- QString in = inName;
- in.replace("%i", QString::number(j));
- QString out = outName;
- out.replace("%i", QString::number(j));
- points << QPointF(EffectsList::parameter(d, in).toDouble(), EffectsList::parameter(d, out).toDouble());
- }
- if (!points.isEmpty())
- curve->setCurve(KisCubicCurve(points));
- QSpinBox *spinin = new QSpinBox();
- spinin->setRange(0, 1000);
- QSpinBox *spinout = new QSpinBox();
- spinout->setRange(0, 1000);
- curve->setupInOutControls(spinin, spinout, 0, 1000);
- m_vbox->addWidget(curve);
- m_vbox->addWidget(spinin);
- m_vbox->addWidget(spinout);
-
- connect(curve, SIGNAL(modified()), this, SLOT(collectAllParameters()));
- m_valueItems[paramName] = curve;
-
- QString depends = pa.attribute("depends");
- if (!depends.isEmpty())
- meetDependency(paramName, type, EffectsList::parameter(d, depends));
- } else if (type == "bezier_spline") {
- BezierSplineWidget *widget = new BezierSplineWidget(value, this);
- stretch = false;
- m_vbox->addWidget(widget);
- m_valueItems[paramName] = widget;
- connect(widget, SIGNAL(modified()), this, SLOT(collectAllParameters()));
- QString depends = pa.attribute("depends");
- if (!depends.isEmpty())
- meetDependency(paramName, type, EffectsList::parameter(d, depends));
-#ifdef USE_QJSON
- } else if (type == "roto-spline") {
- RotoWidget *roto = new RotoWidget(value, m_monitor, info, m_timecode, this);
- roto->slotShowScene(!disable);
- connect(roto, SIGNAL(valueChanged()), this, SLOT(collectAllParameters()));
- connect(roto, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(roto, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), roto, SLOT(slotSyncPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), roto, SLOT(slotShowScene(bool)));
- m_vbox->addWidget(roto);
- m_valueItems[paramName] = roto;
-#endif
- } else if (type == "wipe") {
- Wipeval *wpval = new Wipeval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- wpval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- wipeInfo w = getWipeInfo(value);
- switch (w.start) {
- case UP:
- wpval->start_up->setChecked(true);
- break;
- case DOWN:
- wpval->start_down->setChecked(true);
- break;
- case RIGHT:
- wpval->start_right->setChecked(true);
- break;
- case LEFT:
- wpval->start_left->setChecked(true);
- break;
- default:
- wpval->start_center->setChecked(true);
- break;
- }
- switch (w.end) {
- case UP:
- wpval->end_up->setChecked(true);
- break;
- case DOWN:
- wpval->end_down->setChecked(true);
- break;
- case RIGHT:
- wpval->end_right->setChecked(true);
- break;
- case LEFT:
- wpval->end_left->setChecked(true);
- break;
- default:
- wpval->end_center->setChecked(true);
- break;
- }
- wpval->start_transp->setValue(w.startTransparency);
- wpval->end_transp->setValue(w.endTransparency);
- m_valueItems[paramName] = wpval;
- connect(wpval->end_up, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->end_down, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->end_left, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->end_right, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->end_center, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_up, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_down, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_left, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_right, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_center, SIGNAL(clicked()), this, SLOT(collectAllParameters()));
- connect(wpval->start_transp, SIGNAL(valueChanged(int)), this, SLOT(collectAllParameters()));
- connect(wpval->end_transp, SIGNAL(valueChanged(int)), this, SLOT(collectAllParameters()));
- //wpval->title->setTitle(na.toElement().text());
- m_uiItems.append(wpval);
- } else if (type == "url") {
- Urlval *cval = new Urlval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- cval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- cval->label->setText(paramName);
- cval->urlwidget->fileDialog()->setFilter(ProjectList::getExtensions());
- m_valueItems[paramName] = cval;
- cval->urlwidget->setUrl(KUrl(value));
- connect(cval->urlwidget, SIGNAL(returnPressed()) , this, SLOT(collectAllParameters()));
- connect(cval->urlwidget, SIGNAL(urlSelected(const KUrl&)) , this, SLOT(collectAllParameters()));
- m_uiItems.append(cval);
- } else if (type == "keywords") {
- Keywordval* kval = new Keywordval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- kval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- kval->label->setText(paramName);
- kval->lineeditwidget->setText(value);
- QDomElement klistelem = pa.firstChildElement("keywords");
- QDomElement kdisplaylistelem = pa.firstChildElement("keywordsdisplay");
- QStringList keywordlist;
- QStringList keyworddisplaylist;
- if (!klistelem.isNull()) {
- keywordlist = klistelem.text().split(';');
- keyworddisplaylist = i18n(kdisplaylistelem.text().toUtf8().data()).split(';');
- }
- if (keyworddisplaylist.count() != keywordlist.count()) {
- keyworddisplaylist = keywordlist;
- }
- for (int i = 0; i < keywordlist.count(); i++) {
- kval->comboboxwidget->addItem(keyworddisplaylist.at(i), keywordlist.at(i));
- }
- // Add disabled user prompt at index 0
- kval->comboboxwidget->insertItem(0, i18n("<select a keyword>"), "");
- kval->comboboxwidget->model()->setData( kval->comboboxwidget->model()->index(0,0), QVariant(Qt::NoItemFlags), Qt::UserRole -1);
- kval->comboboxwidget->setCurrentIndex(0);
- m_valueItems[paramName] = kval;
- connect(kval->lineeditwidget, SIGNAL(editingFinished()) , this, SLOT(collectAllParameters()));
- connect(kval->comboboxwidget, SIGNAL(activated (const QString&)), this, SLOT(collectAllParameters()));
- m_uiItems.append(kval);
- } else if (type == "fontfamily") {
- Fontval* fval = new Fontval;
- QWidget * toFillin = new QWidget(m_baseWidget);
- fval->setupUi(toFillin);
- m_vbox->addWidget(toFillin);
- fval->name->setText(paramName);
- fval->fontfamilywidget->setCurrentFont(QFont(value));
- m_valueItems[paramName] = fval;
- connect(fval->fontfamilywidget, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(collectAllParameters())) ;
- m_uiItems.append(fval);
- } else if (type == "filterjob") {
- QPushButton *button = new QPushButton(paramName, m_baseWidget);
- m_vbox->addWidget(button);
- m_valueItems[paramName] = button;
- connect(button, SIGNAL(pressed()), this, SLOT(slotStartFilterJobAction()));
- }
- }
-
- if (stretch)
- m_vbox->addStretch();
-
- if (m_keyframeEditor)
- m_keyframeEditor->checkVisibleParam();
-
- // Make sure all doubleparam spinboxes have the same width, looks much better
- QList<DoubleParameterWidget *> allWidgets = findChildren<DoubleParameterWidget *>();
- int minSize = 0;
- for (int i = 0; i < allWidgets.count(); i++) {
- if (minSize < allWidgets.at(i)->spinSize()) minSize = allWidgets.at(i)->spinSize();
- }
- for (int i = 0; i < allWidgets.count(); i++) {
- allWidgets.at(i)->setSpinSize(minSize);
- }*/
-}
-
-void EffectStackEdit::collectAllParameters()
-{
- /*
- if (m_valueItems.isEmpty() || m_params.isNull()) return;
- const QDomElement oldparam = m_params.cloneNode().toElement();
- QDomElement newparam = oldparam.cloneNode().toElement();
- QDomNodeList namenode = newparam.elementsByTagName("parameter");
- QLocale locale;
-
- for (int i = 0; i < namenode.count() ; i++) {
- QDomNode pa = namenode.item(i);
- QDomElement na = pa.firstChildElement("name");
- QString type = pa.attributes().namedItem("type").nodeValue();
- QString paramName = na.isNull() ? pa.attributes().namedItem("name").nodeValue() : i18n(na.text().toUtf8().data());
- if (type == "complex")
- paramName.append("complex");
- else if (type == "position")
- paramName.append("position");
- else if (type == "geometry")
- paramName.append("geometry");
- else if (type == "keyframe")
- paramName.append("keyframe");
- if (type != "simplekeyframe" && type != "fixed" && type != "addedgeometry" && !m_valueItems.contains(paramName)) {
- kDebug() << "// Param: " << paramName << " NOT FOUND";
- continue;
- }
-
- QString setValue;
- if (type == "double" || type == "constant") {
- DoubleParameterWidget *doubleparam = (DoubleParameterWidget*)m_valueItems.value(paramName);
- setValue = locale.toString(doubleparam->getValue());
- } else if (type == "list") {
- KComboBox *box = ((Listval*)m_valueItems.value(paramName))->list;
- setValue = box->itemData(box->currentIndex()).toString();
- } else if (type == "bool") {
- QCheckBox *box = ((Boolval*)m_valueItems.value(paramName))->checkBox;
- setValue = box->checkState() == Qt::Checked ? "1" : "0" ;
- } else if (type == "color") {
- ChooseColorWidget *choosecolor = ((ChooseColorWidget*)m_valueItems.value(paramName));
- setValue = choosecolor->getColor();
- } else if (type == "complex") {
- ComplexParameter *complex = ((ComplexParameter*)m_valueItems.value(paramName));
- namenode.item(i) = complex->getParamDesc();
- } else if (type == "geometry") {
- if (KdenliveSettings::on_monitor_effects()) {
- if (m_geometryWidget) namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getValue());
- } else {
- Geometryval *geom = ((Geometryval*)m_valueItems.value(paramName));
- namenode.item(i).toElement().setAttribute("value", geom->getValue());
- }
- } else if (type == "addedgeometry") {
- namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getExtraValue(namenode.item(i).toElement().attribute("name")));
- } else if (type == "position") {
- 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") {
- // Make sure duration is not longer than clip
-
- EffectsList::setParameter(newparam, "in", QString::number(m_in));
- EffectsList::setParameter(newparam, "out", QString::number(m_in + pos));
- setValue.clear();
- } else if (newparam.attribute("id") == "fadeout" || newparam.attribute("id") == "fade_to_black") {
- // Make sure duration is not longer than clip
-
- EffectsList::setParameter(newparam, "in", QString::number(m_out - pos));
- EffectsList::setParameter(newparam, "out", QString::number(m_out));
- setValue.clear();
- }
- } else if (type == "curve") {
- KisCurveWidget *curve = ((KisCurveWidget*)m_valueItems.value(paramName));
- QList<QPointF> points = curve->curve().points();
- QString number = pa.attributes().namedItem("number").nodeValue();
- QString inName = pa.attributes().namedItem("inpoints").nodeValue();
- QString outName = pa.attributes().namedItem("outpoints").nodeValue();
- int off = pa.attributes().namedItem("min").nodeValue().toInt();
- int end = pa.attributes().namedItem("max").nodeValue().toInt();
- if (oldparam.attribute("version").toDouble() > 0.2) {
- EffectsList::setParameter(newparam, number, locale.toString(points.count() / 10.));
- } else {
- EffectsList::setParameter(newparam, 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()));
- }
- QString depends = pa.attributes().namedItem("depends").nodeValue();
- if (!depends.isEmpty())
- meetDependency(paramName, type, EffectsList::parameter(newparam, 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));
-#ifdef USE_QJSON
- } else if (type == "roto-spline") {
- RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems.value(paramName));
- setValue = widget->getSpline();
-#endif
- } else if (type == "wipe") {
- Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
- wipeInfo info;
- if (wp->start_left->isChecked())
- info.start = LEFT;
- else if (wp->start_right->isChecked())
- info.start = RIGHT;
- else if (wp->start_up->isChecked())
- info.start = UP;
- else if (wp->start_down->isChecked())
- info.start = DOWN;
- else if (wp->start_center->isChecked())
- info.start = CENTER;
- else
- info.start = LEFT;
- info.startTransparency = wp->start_transp->value();
-
- if (wp->end_left->isChecked())
- info.end = LEFT;
- else if (wp->end_right->isChecked())
- info.end = RIGHT;
- else if (wp->end_up->isChecked())
- info.end = UP;
- else if (wp->end_down->isChecked())
- info.end = DOWN;
- else if (wp->end_center->isChecked())
- info.end = CENTER;
- else
- info.end = RIGHT;
- info.endTransparency = wp->end_transp->value();
-
- setValue = getWipeString(info);
- } else if ((type == "simplekeyframe" || type == "keyframe") && m_keyframeEditor) {
- QDomElement elem = pa.toElement();
- QString realName = i18n(na.toElement().text().toUtf8().data());
- QString val = m_keyframeEditor->getValue(realName);
- elem.setAttribute("keyframes", val);
-
- if (m_keyframeEditor->isVisibleParam(realName))
- elem.setAttribute("intimeline", "1");
- else if (elem.hasAttribute("intimeline"))
- elem.removeAttribute("intimeline");
- } else if (type == "url") {
- KUrlRequester *req = ((Urlval*)m_valueItems.value(paramName))->urlwidget;
- setValue = req->url().path();
- } else if (type == "keywords"){
- QLineEdit *line = ((Keywordval*)m_valueItems.value(paramName))->lineeditwidget;
- QComboBox *combo = ((Keywordval*)m_valueItems.value(paramName))->comboboxwidget;
- if(combo->currentIndex())
- {
- QString comboval = combo->itemData(combo->currentIndex()).toString();
- line->insert(comboval);
- combo->setCurrentIndex(0);
- }
- setValue = line->text();
- } else if (type == "fontfamily") {
- QFontComboBox* fontfamily = ((Fontval*)m_valueItems.value(paramName))->fontfamilywidget;
- setValue = fontfamily->currentFont().family();
- }
-
- if (!setValue.isNull())
- pa.attributes().namedItem("value").setNodeValue(setValue);
-
- }
- emit parameterChanged(oldparam, newparam);*/
-}
-
-void EffectStackEdit::clearAllItems()
-{
- blockSignals(true);
- m_valueItems.clear();
- m_uiItems.clear();
- /*while (!m_items.isEmpty()) {
- QWidget *die = m_items.takeFirst();
- die->disconnect();
- delete die;
- }*/
- //qDeleteAll(m_uiItems);
- QLayoutItem *child;
- while ((child = m_vbox->takeAt(0)) != 0) {
- QWidget *wid = child->widget();
- delete child;
- if (wid) delete wid;
- }
- m_keyframeEditor = NULL;
- m_geometryWidget = NULL;
- blockSignals(false);
}
void EffectStackEdit::slotSyncEffectsPos(int pos)
emit syncEffectsPos(pos);
}
+bool EffectStackEdit::needsMonitorEffectScene() const
+{
+ if (!m_paramWidget) return false;
+ return m_paramWidget->needsMonitorEffectScene();
+}
#include "definitions.h"
#include "timecode.h"
#include "keyframeedit.h"
-#include "effectstack/collapsibleeffect.h"
+#include "effectstack/parametercontainer.h"
#include <QWidget>
#include <QDomElement>
Monitor *monitor();
/** @brief Install event filter so that scrolling with mouse wheel does not change parameter value. */
virtual bool eventFilter( QObject * o, QEvent * e );
+ /** @brief Returns true if this transition requires an on monitor scene. */
+ bool needsMonitorEffectScene() const;
private:
- /** @brief Deletes all parameter widgets. */
- void clearAllItems();
- /** @brief Updates parameter @param name according to new value of dependency.
- * @param name Name of the parameter which will be updated
- * @param type Type of the parameter which will be updated
- * @param value Value of the dependency parameter */
- void meetDependency(const QString& name, QString type, QString value);
-
- QVBoxLayout *m_vbox;
- QList<QWidget*> m_uiItems;
- QMap<QString, QWidget*> m_valueItems;
- int m_in;
- int m_out;
- KeyframeEdit *m_keyframeEditor;
Monitor *m_monitor;
- GeometryWidget *m_geometryWidget;
EffectMetaInfo m_metaInfo;
QWidget *m_baseWidget;
ParameterContainer *m_paramWidget;
/** @brief Called when an effect is selected, builds the UIÂ for this effect. */
void transferParamDesc(const QDomElement &d, ItemInfo info, bool isEffect = true);
- /** @brief Called whenever(?) some parameter is changed in the gui.
- *
- * Transfers all Dynamic gui parameter settings into m_params(??) */
- void collectAllParameters();
-
/** @brief Pass position changes of the timeline cursor to the effects to keep their local timelines in sync. */
void slotSyncEffectsPos(int pos);
{
if (m_trackMode || (m_clipref && renderPos >= m_clipref->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_clipref->endPos().frames(KdenliveSettings::project_fps()))) {
if (!m_monitor->getEffectEdit()->getScene()->views().at(0)->isVisible())
- m_monitor->slotEffectScene(true);
+ m_monitor->slotShowEffectScene(true);
} else {
- m_monitor->slotEffectScene(false);
+ m_monitor->slotShowEffectScene(false);
}
}
MonitorEditWidget *edit = monitor->getEffectEdit();
edit->removeCustomControls();
edit->addCustomButton(KIcon("transform-crop"), i18n("Show previous keyframe"), this, SLOT(slotShowPreviousKeyFrame(bool)), true, KdenliveSettings::onmonitoreffects_geometryshowprevious());
- edit->showVisibilityButton(true);
m_scene = edit->getScene();
connect(m_ui.buttonSync, SIGNAL(toggled(bool)), this, SLOT(slotSetSynchronize(bool)));
m_spinX = new DragValue(i18nc("x axis position", "X"), 0, 0, -99000, 99000, -1, QString(), false, this);
- m_ui.horizontalLayout->addWidget(m_spinX);
+ m_ui.horizontalLayout->addWidget(m_spinX, 0, 0);
m_spinY = new DragValue(i18nc("y axis position", "Y"), 0, 0, -99000, 99000, -1, QString(), false, this);
- m_ui.horizontalLayout->addWidget(m_spinY);
+ m_ui.horizontalLayout->addWidget(m_spinY, 0, 1);
m_spinWidth = new DragValue(i18nc("Frame width", "W"), m_monitor->render->frameRenderWidth(), 0, 1, 99000, -1, QString(), false, this);
- m_ui.horizontalLayout->addWidget(m_spinWidth);
+ m_ui.horizontalLayout->addWidget(m_spinWidth, 0, 2);
m_spinHeight = new DragValue(i18nc("Frame height", "H"), m_monitor->render->renderHeight(), 0, 1, 99000, -1, QString(), false, this);
- m_ui.horizontalLayout->addWidget(m_spinHeight);
+ m_ui.horizontalLayout->addWidget(m_spinHeight, 0, 3);
QMenu *menu = new QMenu(this);
QAction *adjustSize = new QAction(i18n("Adjust to original size"), this);
alignButton->setDefaultAction(alignbottom);
alignButton->setAutoRaise(true);
alignLayout->addWidget(alignButton);
+ alignLayout->addStretch(10);
- m_ui.horizontalLayout->addLayout(alignLayout);
- m_ui.horizontalLayout->addStretch(10);
+ m_ui.horizontalLayout->addLayout(alignLayout, 1, 0, 1, 4);
+ //m_ui.horizontalLayout->addStretch(10);
m_spinSize = new DragValue(i18n("Size"), 100, 2, 1, 99000, -1, i18n("%"), false, this);
m_ui.horizontalLayout2->addWidget(m_spinSize);
Setup of configuration controls
*/
- connect(edit, SIGNAL(showEdit(bool)), this, SLOT(slotShowScene(bool)));
-
connect(m_scene, SIGNAL(addKeyframe()), this, SLOT(slotAddKeyframe()));
- connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
connect(this, SIGNAL(parameterChanged()), this, SLOT(slotUpdateProperties()));
}
Mlt::Geometry *g = m_extraGeometries.takeFirst();
delete g;
}
- if (m_monitor) {
- m_monitor->getEffectEdit()->showVisibilityButton(false);
- m_monitor->slotEffectScene(false);
- }
}
void GeometryWidget::slotShowPreviousKeyFrame(bool show)
connect(m_rect, SIGNAL(changed()), this, SLOT(slotUpdateGeometry()));
m_scene->centerView();
slotPositionChanged(0, false);
- slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
}
void GeometryWidget::addParameter(const QDomElement elem)
}
-void GeometryWidget::slotCheckMonitorPosition(int renderPos)
-{
- if (m_showScene) {
- /*
- We do only get the position in timeline if this geometry belongs to a transition,
- therefore we need two ways here.
- */
- if (m_isEffect) {
- emit checkMonitorPosition(renderPos);
- } else {
- if (renderPos >= m_clipPos && renderPos <= m_clipPos + m_outPoint - m_inPoint) {
- if (!m_scene->views().at(0)->isVisible())
- m_monitor->slotEffectScene(true);
- } else {
- m_monitor->slotEffectScene(false);
- }
- }
- }
-}
-
void GeometryWidget::slotUpdateGeometry()
{
emit seekToPos(m_clipPos + m_timePos->getValue());
}
-void GeometryWidget::slotShowScene(bool show)
-{
- m_showScene = show;
- if (!m_showScene)
- m_monitor->slotEffectScene(false);
- else
- slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
-}
-
void GeometryWidget::setFrameSize(QPoint size)
{
m_frameSize = size;
void setupParam(const QDomElement elem, int minframe, int maxframe);
/** @brief Updates position of the local timeline to @param relTimelinePos. */
void slotSyncPosition(int relTimelinePos);
- /** @brief Switches from normal monitor to monitor scene according to @param show. */
- void slotShowScene(bool show = true);
private:
Ui::GeometryWidget_UI m_ui;
/** @brief Adds or deletes a keyframe depending on whether there is already a keyframe at the current position. */
void slotAddDeleteKeyframe();
- /** @brief Makes sure the monitor effect scene is only visible if the clip this geometry belongs to is visible.
- * @param renderPos Postion of the Monitor / Timeline cursor */
- void slotCheckMonitorPosition(int renderPos);
-
/** @brief Updates the Mlt::Geometry object. */
void slotUpdateGeometry();
/** @brief Updates the spinBoxes according to the rect. */
signals:
void parameterChanged();
- void checkMonitorPosition(int);
void seekToPos(int);
};
#include "initeffects.h"
#include "kdenlivesettings.h"
#include "effectslist.h"
-#include "effectstackedit.h"
#include "mainwindow.h"
#include <KDebug>
foreach(const QString & entry, m_list) {
kDebug() << entry;
if (!entry.isEmpty() && (entry.endsWith(".png") || entry.endsWith(".pgm"))) {
- if (!EffectStackEdit::iconCache.contains(entry)) {
+ if (!MainWindow::m_lumacache.contains(entry)) {
QImage pix(entry);
//if (!pix.isNull())
- EffectStackEdit::iconCache[entry] = pix.scaled(30, 30);
+ MainWindow::m_lumacache.insert(entry, pix.scaled(30, 30, Qt::KeepAspectRatio, Qt::SmoothTransformation));
kDebug() << "stored";
}
}
for (int i = 0; i < max; ++i) {
effectInfo = MainWindow::customEffects.at(i);
if (effectInfo.tagName() == "effectgroup") {
- effectsMap.insert(effectInfo.attribute("name").toLower().toUtf8().data(), effectInfo);
+ effectsMap.insert(effectInfo.attribute("name").toUtf8().data(), effectInfo);
}
- else effectsMap.insert(effectInfo.firstChildElement("name").text().toLower().toUtf8().data(), effectInfo);
+ else effectsMap.insert(effectInfo.firstChildElement("name").text().toUtf8().data(), effectInfo);
}
MainWindow::customEffects.clearList();
foreach(const QDomElement & effect, effectsMap)
//m_tracksList[trackIndex].effectsList.updateEffect(effect);
}
+void KdenliveDoc::enableTrackEffects(int trackIndex, QList <int> effectIndexes, bool disable)
+{
+ if (trackIndex < 0 || trackIndex >= m_tracksList.count()) {
+ kWarning() << "Set Track effect outisde of range";
+ return;
+ }
+ EffectsList list = m_tracksList.at(trackIndex).effectsList;
+ QDomElement effect;
+ for (int i = 0; i < effectIndexes.count(); i++) {
+ effect = list.itemFromIndex(effectIndexes.at(i));
+ if (!effect.isNull()) effect.setAttribute("disable", (int) disable);
+ }
+}
+
const EffectsList KdenliveDoc::getTrackEffects(int ix)
{
if (ix < 0 || ix >= m_tracksList.count()) {
void removeTrackEffect(int ix, QDomElement effect);
void setTrackEffect(int trackIndex, int effectIndex, QDomElement effect);
const EffectsList getTrackEffects(int ix);
+ /** @brief Enable / disable an effect in Kdenlive's xml list. */
+ void enableTrackEffects(int trackIndex, QList <int> effectIndexes, bool disable);
QDomElement getTrackEffect(int trackIndex, int effectIndex) const;
/** @brief Check if a track already contains a specific effect. */
int hasTrackEffect(int trackIndex, const QString &tag, const QString &id) const;
<label>Show overlay info on monitor (in / out points, markers,...).</label>
<default>true</default>
</entry>
+
+ <entry name="showOnMonitorScene" type="Bool">
+ <label>Show on monitor adjustable effect parameter (geometry, ..).</label>
+ <default>true</default>
+ </entry>
<entry name="autoaudiodrivername" type="String">
<label>Audio driver selected automatically.</label>
EffectsList MainWindow::customEffects;
EffectsList MainWindow::transitions;
+QMap <QString,QImage> MainWindow::m_lumacache;
+
MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & clipsToLoad, QWidget *parent) :
KXmlGuiWindow(parent),
m_activeDocument(NULL),
// FIXME: the next call returns a newly allocated object, which leaks
initEffects::parseEffectFiles();
//initEffects::parseCustomEffectsFile();
-
+
m_monitorManager = new MonitorManager();
m_shortcutRemoveFocus = new QShortcut(QKeySequence("Esc"), this);
disconnect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int,bool)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int,bool)));
disconnect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
disconnect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement)));
- disconnect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
+ disconnect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, QList <int>, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, QList <int>, bool)));
disconnect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList<int>, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList <int>, int)));
disconnect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
disconnect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
connect(m_effectStack, SIGNAL(updateClipRegion(ClipItem*, int, QString)), trackView->projectView(), SLOT(slotUpdateClipRegion(ClipItem*, int, QString)));
connect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
connect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement)));
- connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
+ connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, QList <int>, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, QList <int>, bool)));
connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList <int>, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList <int>, int)));
connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
#include <QEvent>
#include <QTimer>
#include <QShortcut>
+#include <QMap>
+#include <QString>
+#include <QImage>
#include <KXmlGuiWindow>
#include <KTextEdit>
#include <KComboBox>
#include <kautosavefile.h>
#include <KActionCategory>
+#include <KImageCache>
#include "effectslist.h"
#include "gentime.h"
static EffectsList audioEffects;
static EffectsList customEffects;
static EffectsList transitions;
+
+ /** @brief Cache for luma files thumbnails. */
+ static QMap <QString,QImage> m_lumacache;
+
protected:
/** @brief Closes the window.
if (id == Kdenlive::projectMonitor) {
m_effectWidget = new MonitorEditWidget(render, videoBox);
+ connect(m_effectWidget, SIGNAL(showEdit(bool)), this, SLOT(slotShowEffectScene(bool)));
m_toolbar->addAction(m_effectWidget->getVisibilityAction());
videoBox->layout()->addWidget(m_effectWidget);
m_effectWidget->hide();
}
-void Monitor::slotEffectScene(bool show)
+void Monitor::slotShowEffectScene(bool show)
{
if (m_id == Kdenlive::projectMonitor) {
- if (videoSurface) {
- videoSurface->setVisible(!show);
- } else {
+ if (!m_effectWidget->getVisibilityAction()->isChecked()) show = false;
+ if (m_effectWidget->isVisible() == show) return;
+ setUpdatesEnabled(false);
+ if (show) {
+ if (videoSurface) {
+ videoSurface->setVisible(!show);
+ // Preview is handeled internally through the Render::showFrame method
+ render->disablePreview(show);
+ } else {
#ifdef USE_OPENGL
- m_glWidget->setVisible(!show);
+ m_glWidget->setVisible(!show);
#endif
- }
- m_effectWidget->setVisible(show);
- m_effectWidget->getVisibilityAction()->setChecked(show);
- emit requestFrameForAnalysis(show);
- if (show) {
+ }
+ m_effectWidget->setVisible(show);
m_effectWidget->getScene()->slotZoomFit();
- }
+ emit requestFrameForAnalysis(show);
+ }
+ else {
+ m_effectWidget->setVisible(show);
+ emit requestFrameForAnalysis(show);
+ if (videoSurface) {
+ videoSurface->setVisible(!show);
+ // Preview is handeled internally through the Render::showFrame method
+ render->disablePreview(show);
+ } else {
+#ifdef USE_OPENGL
+ m_glWidget->setVisible(!show);
+#endif
+ }
+ }
+ m_effectWidget->showVisibilityButton(show);
+ setUpdatesEnabled(true);
videoBox->setEnabled(show);
- render->doRefresh();
+ //render->doRefresh();
}
}
void adjustRulerSize(int length);
void setTimePos(const QString &pos);
QStringList getZoneInfo() const;
- void slotEffectScene(bool show = true);
+ /** @brief Display the on monitor effect scene (to adjust geometry over monitor). */
+ void slotShowEffectScene(bool show = true);
bool effectSceneDisplayed();
/** @brief Sets m_selectedClip to @param item. Used for looping it. */
m_visibilityAction = new QAction(KIcon("video-display"), i18n("Show/Hide edit mode"), this);
m_visibilityAction->setCheckable(true);
+ m_visibilityAction->setChecked(KdenliveSettings::showOnMonitorScene());
m_visibilityAction->setVisible(false);
m_ui.buttonDirectUpdate->setIcon(KIcon("transform-scale"));
MonitorEditWidget::~MonitorEditWidget()
{
+ KdenliveSettings::setShowOnMonitorScene(m_visibilityAction->isChecked());
delete m_view;
delete m_scene;
delete m_visibilityAction;
}
}
+void Render::disablePreview(bool disable)
+{
+ if (m_mltConsumer) {
+ m_mltConsumer->stop();
+ m_mltConsumer->set("preview_off", (int) disable);
+ m_mltConsumer->set("refresh", 0);
+ m_mltConsumer->start();
+ }
+}
+
void Render::showAudio(Mlt::Frame& frame)
{
if (!frame.is_valid() || frame.get_int("test_audio") != 0) {
refresh();
return true;
-
}
bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList params)
return true;
}
+bool Render::mltEnableEffects(int track, GenTime position, QList <int> effectIndexes, bool disable)
+{
+ if (position < GenTime()) {
+ return mltEnableTrackEffects(track, effectIndexes, disable);
+ }
+ // find filter
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+
+ int clipIndex = trackPlaylist.get_clip_index_at((int) position.frames(m_fps));
+ Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex);
+ if (!clip) {
+ kDebug() << "WARINIG, CANNOT FIND CLIP ON track: " << track << ", AT POS: " << position.frames(m_fps);
+ return false;
+ }
+
+ int duration = clip->get_playtime();
+ bool doRefresh = true;
+ // Check if clip is visible in monitor
+ int diff = trackPlaylist.clip_start(clipIndex) + duration - m_mltProducer->position();
+ if (diff < 0 || diff > duration)
+ doRefresh = false;
+ int ct = 0;
+
+ Mlt::Filter *filter = clip->filter(ct);
+ while (filter) {
+ if (effectIndexes.contains(filter->get_int("kdenlive_ix"))) {
+ filter->set("disable", (int) disable);
+ }
+ ct++;
+ filter = clip->filter(ct);
+ }
+
+ delete clip;
+ service.unlock();
+
+ if (doRefresh) refresh();
+ return true;
+}
+
+bool Render::mltEnableTrackEffects(int track, QList <int> effectIndexes, bool disable)
+{
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ Mlt::Service clipService(trackPlaylist.get_service());
+ int ct = 0;
+
+ Mlt::Filter *filter = clipService.filter(ct);
+ while (filter) {
+ if (effectIndexes.contains(filter->get_int("kdenlive_ix"))) {
+ filter->set("disable", (int) disable);
+ }
+ ct++;
+ filter = clipService.filter(ct);
+ }
+ service.unlock();
+
+ refresh();
+ return true;
+}
+
void Render::mltUpdateEffectPosition(int track, GenTime position, int oldPos, int newPos)
{
Mlt::Service service(m_mltProducer->parent().get_service());
bool addFilterToService(Mlt::Service service, EffectsParameterList params, int duration);
bool mltAddEffect(Mlt::Service service, EffectsParameterList params, int duration, bool doRefresh);
bool mltAddTrackEffect(int track, EffectsParameterList params);
+
+ /** @brief Enable / disable clip effects.
+ * @param track The track where the clip is
+ * @param position The start position of the clip
+ * @param effectIndexes The list of effect indexes to enable / disable
+ * @param disable True if effects should be disabled, false otherwise */
+ bool mltEnableEffects(int track, GenTime position, QList <int> effectIndexes, bool disable);
+ /** @brief Enable / disable track effects.
+ * @param track The track where the effect is
+ * @param effectIndexes The list of effect indexes to enable / disable
+ * @param disable True if effects should be disabled, false otherwise */
+ bool mltEnableTrackEffects(int track, QList <int> effectIndexes, bool disable);
/** @brief Edits an effect parameters in MLT's playlist. */
bool mltEditEffect(int track, GenTime position, EffectsParameterList params);
/** @brief Fill a combobox with the found blackmagic devices */
static bool getBlackMagicDeviceList(KComboBox *devicelist);
static bool getBlackMagicOutputDeviceList(KComboBox *devicelist);
+ /** @brief Frame rendering is handeled by Kdenlive, don't show video through SDL display */
+ void disablePreview(bool disable);
private:
}
QTextStream outStream(&file);
outStream << "#! /bin/sh" << "\n" << "\n";
- outStream << "SOURCE=" << "\"" + playlistPath + "\"" << "\n";
+ outStream << "SOURCE=" << "\"" + KUrl(playlistPath).url() + "\"" << "\n";
outStream << "TARGET=" << "\"" + KUrl(dest).url() + "\"" << "\n";
outStream << "RENDERER=" << "\"" + m_renderer + "\"" << "\n";
outStream << "MELT=" << "\"" + KdenliveSettings::rendererpath() + "\"" << "\n";
} else if (item->type() == ScriptRenderType){
// Script item
kDebug()<<"// SCRIPT process: "<<item->data(1, ParametersRole).toString();
- if (QProcess::startDetached(item->data(1, ParametersRole).toString()) == false) {
+ if (QProcess::startDetached('"' + item->data(1, ParametersRole).toString() + '"') == false) {
item->setStatus(FAILEDJOB);
}
}
l->addWidget(m_keyframeWidget);
MonitorEditWidget *edit = monitor->getEffectEdit();
- edit->showVisibilityButton(true);
m_scene = edit->getScene();
m_scene->cleanup();
m_item = new SplineItem(QList <BPoint>(), NULL, m_scene);
connect(m_item, SIGNAL(changed(bool)), this, SLOT(slotUpdateData(bool)));
- connect(edit, SIGNAL(showEdit(bool)), this, SLOT(slotShowScene(bool)));
- connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
connect(m_keyframeWidget, SIGNAL(positionChanged(int)), this, SLOT(slotPositionChanged(int)));
connect(m_keyframeWidget, SIGNAL(keyframeAdded(int)), this, SLOT(slotAddKeyframe(int)));
connect(m_keyframeWidget, SIGNAL(keyframeRemoved(int)), this, SLOT(slotRemoveKeyframe(int)));
if (m_monitor) {
MonitorEditWidget *edit = m_monitor->getEffectEdit();
- edit->showVisibilityButton(false);
edit->removeCustomControls();
- m_monitor->slotEffectScene(false);
+ m_monitor->slotShowEffectScene(false);
}
}
-void RotoWidget::slotCheckMonitorPosition(int renderPos)
-{
- if (m_showScene)
- emit checkMonitorPosition(renderPos);
-}
-
void RotoWidget::slotSyncPosition(int relTimelinePos)
{
relTimelinePos = qBound(0, relTimelinePos, m_out);
slotPositionChanged(relTimelinePos, false);
}
-void RotoWidget::slotShowScene(bool show)
-{
- m_showScene = show;
- if (!m_showScene)
- m_monitor->slotEffectScene(false);
- else
- slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
-}
-
void RotoWidget::slotUpdateData(int pos, bool editing)
{
Q_UNUSED(editing)
void updateTimecodeFormat();
public slots:
- /** @brief Switches from normal monitor to monitor scene according to @param show. */
- void slotShowScene(bool show = true);
/** @brief Updates the on-monitor item. */
void slotSyncPosition(int relTimelinePos);
signals:
void valueChanged();
- void checkMonitorPosition(int);
void seekToPos(int pos);
void keyframeTimelineFullUpdate();
private slots:
- /** @brief Makes sure the monitor effect scene is only visible if the clip this geometry belongs to is visible.
- * @param renderPos Postion of the Monitor / Timeline cursor */
- void slotCheckMonitorPosition(int renderPos);
/** @brief Updates/Creates the spline at @param pos based on the on-monitor items. */
void slotUpdateData(int pos = -1, bool editing = false);
connect(transitionList, SIGNAL(activated(int)), this, SLOT(slotTransitionChanged()));
connect(transitionTrack, SIGNAL(activated(int)), this, SLOT(slotTransitionTrackChanged()));
connect(m_effectEdit, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement)));
- connect(m_effectEdit, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
- connect(monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
}
void TransitionSettings::updateProjectFormat(MltVideoProfile profile, Timecode t, const QList <TrackInfo> info)
if (m_usedTransition->hasGeometry())
m_effectEdit->transferParamDesc(m_usedTransition->toXML(), m_usedTransition->info(), false);
}
+ slotCheckMonitorPosition(m_effectEdit->monitor()->render->seekFramePosition());
}
void TransitionSettings::slotTransitionTrackChanged()
setEnabled(t != NULL);
m_effectEdit->setFrameSize(p);
m_autoTrackTransition = nextTrack;
+ disconnect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
if (t == m_usedTransition) {
if (t == NULL) return;
if (update) {
slotTransitionChanged(false, false);
transitionList->blockSignals(false);
}
+ if (m_effectEdit->needsMonitorEffectScene()) {
+ connect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
+ }
} else {
// null transition selected
m_usedTransition = NULL;
ItemInfo info;
m_effectEdit->transferParamDesc(QDomElement(), info, false);
}
-
}
void TransitionSettings::slotUpdateEffectParams(const QDomElement oldparam, const QDomElement param)
void TransitionSettings::slotRenderPos(int pos)
{
- if (m_usedTransition)
+ if (m_usedTransition) {
m_effectEdit->slotSyncEffectsPos(pos - m_usedTransition->startPos().frames(KdenliveSettings::project_fps()));
+ if (isEnabled()) slotCheckMonitorPosition(pos);
+ }
}
void TransitionSettings::slotSeekTimeline(int pos)
void TransitionSettings::slotCheckMonitorPosition(int renderPos)
{
- if (renderPos >= m_usedTransition->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_usedTransition->endPos().frames(KdenliveSettings::project_fps())) {
- if (!m_effectEdit->monitor()->getEffectEdit()->getScene()->views().at(0)->isVisible())
- m_effectEdit->monitor()->slotEffectScene(true);
- } else {
- m_effectEdit->monitor()->slotEffectScene(false);
+ if (!isEnabled()) return;
+ if (m_effectEdit->needsMonitorEffectScene()) {
+ if (renderPos >= m_usedTransition->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_usedTransition->endPos().frames(KdenliveSettings::project_fps())) {
+ if (!m_effectEdit->monitor()->effectSceneDisplayed()) {
+ m_effectEdit->monitor()->slotShowEffectScene(true);
+ }
+ } else {
+ m_effectEdit->monitor()->slotShowEffectScene(false);
+ }
+ }
+ else {
+ m_effectEdit->monitor()->slotShowEffectScene(false);
}
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CollapsibleGroup_UI</class>
- <widget class="QWidget" name="CollapsibleGroup_UI">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>245</width>
- <height>48</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="margin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QFrame" name="decoframegroup">
- <property name="autoFillBackground">
- <bool>true</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="verticalSpacing">
- <number>0</number>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QFrame" name="framegroup">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>2</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>2</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <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>
- <widget class="QToolButton" name="enabledButton">
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>80</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QToolButton" name="menuButton">
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- <property name="popupMode">
- <enum>QToolButton::InstantPopup</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="buttonUp">
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="buttonDown">
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="buttonDel">
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QFrame" name="widgetFrame">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
</property>
</widget>
</item>
- <item>
- <widget class="QLabel" name="title">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<x>0</x>
<y>0</y>
<width>129</width>
- <height>86</height>
+ <height>85</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
- <property name="horizontalSpacing">
+ <property name="margin">
<number>0</number>
</property>
- <property name="margin">
+ <property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<property name="margin">
<number>0</number>
</property>
- <item row="0" column="0" colspan="5">
- <layout class="QHBoxLayout" name="horizontalLayout"/>
+ <item row="0" column="0" colspan="2">
+ <layout class="QGridLayout" name="horizontalLayout"/>
</item>
- <item row="2" column="0" colspan="5">
+ <item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout3"/>
</item>
- <item row="1" column="0" colspan="5">
+ <item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout2">
<property name="leftMargin">
<number>0</number>