void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect)
{
+ if (pos < GenTime()) {
+ // Add track effect
+ m_document->addTrackEffect(m_document->tracksCount() - track, effect);
+ m_document->renderer()->mltAddTrackEffect(track, getEffectArgs(effect));
+ emit showTrackEffects(track, m_document->getTrackEffects(m_document->tracksCount() - track));
+ return;
+ }
ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
if (clip) {
// Special case: speed effect
void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect)
{
QString index = effect.attribute("kdenlive_ix");
+ if (pos < GenTime()) {
+ // Delete track effect
+ m_document->removeTrackEffect(m_document->tracksCount() - track, effect);
+ m_document->renderer()->mltRemoveTrackEffect(track, index, true);
+ emit showTrackEffects(track, m_document->getTrackEffects(m_document->tracksCount() - track));
+ return;
+ }
// Special case: speed effect
if (effect.attribute("id") == "speed") {
ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
} else delete effectCommand;
}
-void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect, bool affectGroup)
+void CustomTrackView::slotDeleteEffect(ClipItem *clip, int track, QDomElement effect, bool affectGroup)
{
+ if (clip == NULL) {
+ // delete track effect
+ AddEffectCommand *command = new AddEffectCommand(this, track, GenTime(-1), effect, false);
+ m_commandStack->push(command);
+ setDocumentModified();
+ return;
+ }
if (affectGroup && clip->parentItem() && clip->parentItem() == m_selectionGroup) {
//clip is in a group, also remove the effect in other clips of the group
QList<QGraphicsItem *> items = m_selectionGroup->childItems();
emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
return;
}
- ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
QDomElement effect = insertedEffect.cloneNode().toElement();
+ if (pos < GenTime()) {
+ // editing a track effect
+ EffectsParameterList effectParams = getEffectArgs(effect);
+ if (effect.attribute("tag") == "ladspa") {
+ // Update the ladspa affect file
+ initEffects::ladspaEffectFile(effect.attribute("src"), effect.attribute("ladspaid").toInt(), getLadspaParams(effect));
+ }
+ // check if we are trying to reset a keyframe effect
+ if (effectParams.hasParam("keyframes") && effectParams.paramValue("keyframes").isEmpty()) {
+ //clip->initEffect(effect);
+ effectParams = getEffectArgs(effect);
+ }
+ if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - track, pos, effectParams))
+ emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+ m_document->setTrackEffect(track, ix, effect);
+ return;
+
+ }
+ ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
if (clip) {
// Special case: speed effect
if (effect.attribute("id") == "speed") {
void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos)
{
+ if (pos < GenTime()) {
+ // Moving track effect
+ kDebug() << "MOVING EFFECT IN TK: " << track;
+ QDomElement act = m_document->getTrackEffect(track, newPos - 1);
+ QDomElement before = m_document->getTrackEffect(track, oldPos - 1);
+
+ if (!act.isNull() && !before.isNull()) {
+ m_document->setTrackEffect(track, oldPos - 1, act);
+ m_document->setTrackEffect(track, newPos - 1, before);
+ m_document->renderer()->mltMoveEffect(m_document->tracksCount() - track, pos, oldPos, newPos);
+ emit showTrackEffects(m_document->tracksCount() - track, m_document->getTrackEffects(track));
+ } else emit displayMessage(i18n("Cannot move effect"), ErrorMessage);
+ return;
+ }
ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track);
if (clip && !clip->effectAt(newPos - 1).isNull() && !clip->effectAt(oldPos - 1).isNull()) {
QDomElement act = clip->effectAt(newPos - 1);
} else emit displayMessage(i18n("Cannot move effect"), ErrorMessage);
}
-void CustomTrackView::slotChangeEffectState(ClipItem *clip, int effectPos, bool disable)
+void CustomTrackView::slotChangeEffectState(ClipItem *clip, int track, int effectPos, bool disable)
{
- QDomElement effect = clip->effectAt(effectPos);
+ EditEffectCommand *command;
+ QDomElement effect;
+ if (clip == NULL) effect = m_document->getTrackEffect(m_document->tracksCount() - track, effectPos);
+ else effect = clip->effectAt(effectPos);
QDomElement oldEffect = effect.cloneNode().toElement();
-
effect.setAttribute("disable", (int) disable);
- EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
+
+
+ if (clip == NULL) {
+ // editing track effect
+ command = new EditEffectCommand(this, m_document->tracksCount() - track, GenTime(-1), oldEffect, effect, effectPos, true);
+ } else {
+ command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
+ }
m_commandStack->push(command);
setDocumentModified();;
}
-void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos)
+void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int track, int currentPos, int newPos)
{
- MoveEffectCommand *command = new MoveEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), currentPos, newPos);
+ MoveEffectCommand *command;
+ if (clip == NULL) {
+ // editing track effect
+ command = new MoveEffectCommand(this, m_document->tracksCount() - track, GenTime(-1), currentPos, newPos);
+ } else command = new MoveEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), currentPos, newPos);
m_commandStack->push(command);
setDocumentModified();
}
-void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect, int ix)
+void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, int track, QDomElement oldeffect, QDomElement effect, int ix)
{
- EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldeffect, effect, ix, true);
+ EditEffectCommand *command;
+ if (clip) command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldeffect, effect, ix, true);
+ else command = new EditEffectCommand(this, m_document->tracksCount() - track, GenTime(-1), oldeffect, effect, ix, true);
m_commandStack->push(command);
}
int start = item->cropStart().frames(m_document->fps());
int end = item->fadeIn();
if (end == 0) {
- slotDeleteEffect(item, oldeffect, false);
+ slotDeleteEffect(item, -1, oldeffect, false);
} else {
end += start;
QDomElement effect = oldeffect.cloneNode().toElement();
EffectsList::setParameter(oldeffect, "in", QString::number(start));
EffectsList::setParameter(oldeffect, "out", QString::number(end));
- slotUpdateClipEffect(item, effect, oldeffect, ix);
+ slotUpdateClipEffect(item, -1, effect, oldeffect, ix);
emit clipItemSelected(item, ix);
}
} else if (item->fadeIn() != 0 && ix2 == -1) {
int start = item->cropStart().frames(m_document->fps());
int end = item->fadeIn();
if (end == 0) {
- slotDeleteEffect(item, oldeffect, false);
+ slotDeleteEffect(item, -1, oldeffect, false);
} else {
end += start;
QDomElement effect = oldeffect.cloneNode().toElement();
EffectsList::setParameter(oldeffect, "in", QString::number(start));
EffectsList::setParameter(oldeffect, "out", QString::number(end));
- slotUpdateClipEffect(item, effect, oldeffect, ix2);
+ slotUpdateClipEffect(item, -1, effect, oldeffect, ix2);
emit clipItemSelected(item, ix2);
}
}
int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps());
int start = item->fadeOut();
if (start == 0) {
- slotDeleteEffect(item, oldeffect, false);
+ slotDeleteEffect(item, -1, oldeffect, false);
} else {
start = end - start;
QDomElement effect = oldeffect.cloneNode().toElement();
EffectsList::setParameter(oldeffect, "in", QString::number(start));
EffectsList::setParameter(oldeffect, "out", QString::number(end));
// kDebug()<<"EDIT FADE OUT : "<<start<<"x"<<end;
- slotUpdateClipEffect(item, effect, oldeffect, ix);
+ slotUpdateClipEffect(item, -1, effect, oldeffect, ix);
emit clipItemSelected(item, ix);
}
} else if (item->fadeOut() != 0 && ix2 == -1) {
int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps());
int start = item->fadeOut();
if (start == 0) {
- slotDeleteEffect(item, oldeffect, false);
+ slotDeleteEffect(item, -1, oldeffect, false);
} else {
start = end - start;
QDomElement effect = oldeffect.cloneNode().toElement();
EffectsList::setParameter(oldeffect, "in", QString::number(start));
EffectsList::setParameter(oldeffect, "out", QString::number(end));
// kDebug()<<"EDIT FADE OUT : "<<start<<"x"<<end;
- slotUpdateClipEffect(item, effect, oldeffect, ix2);
+ slotUpdateClipEffect(item, -1, effect, oldeffect, ix2);
emit clipItemSelected(item, ix2);
}
}
void CustomTrackView::slotAddTrackEffect(const QDomElement effect, int ix)
{
- m_document->renderer()->mltAddTrackEffect(m_document->tracksCount() - ix, getEffectArgs(effect));
+ AddEffectCommand *command = new AddEffectCommand(this, m_document->tracksCount() - ix, GenTime(-1), effect, true);
+ m_commandStack->push(command);
}
void setCursorPos(int pos, bool seek = true);
void moveCursorPos(int delta);
void updateCursorPos();
- void slotDeleteEffect(ClipItem *clip, QDomElement effect, bool affectGroup = true);
- void slotChangeEffectState(ClipItem *clip, int effectPos, bool disable);
- void slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos);
- void slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect, int ix);
+ void slotDeleteEffect(ClipItem *clip, int track, QDomElement effect, bool affectGroup = true);
+ void slotChangeEffectState(ClipItem *clip, int track, int effectPos, bool disable);
+ void slotChangeEffectPosition(ClipItem *clip, int track, int currentPos, int newPos);
+ void slotUpdateClipEffect(ClipItem *clip, int track, QDomElement oldeffect, QDomElement effect, int ix);
void slotUpdateClipRegion(ClipItem *clip, int ix, QString region);
void slotRefreshEffects(ClipItem *clip);
void setDuration(int duration);
/** @brief Monitor document changes (for example the presence of audio data in timeline for export widget.*/
void documentModified();
void forceClipProcessing(const QString &);
+ void showTrackEffects(int, EffectsList);
};
#endif
#define DEFINITIONS_H
#include "gentime.h"
+#include "effectslist.h"
#include <QTreeWidgetItem>
#include <KLocale>
bool isMute;
bool isBlind;
bool isLocked;
+ EffectsList effectsList;
};
struct ItemInfo {
EffectStackView::EffectStackView(Monitor *monitor, QWidget *parent) :
QWidget(parent),
- m_monitor(monitor)
+ m_monitor(monitor),
+ m_clipref(NULL),
+ m_trackMode(false),
+ m_trackindex(-1)
{
m_ui.setupUi(this);
QVBoxLayout *vbox1 = new QVBoxLayout(m_ui.frame);
m_ui.region_url->fileDialog()->setFilter(ProjectList::getExtensions());
//m_ui.effectlist->horizontalHeader()->setVisible(false);
//m_ui.effectlist->verticalHeader()->setVisible(false);
- m_clipref = NULL;
m_ui.buttonNew->setIcon(KIcon("document-new"));
m_ui.buttonNew->setToolTip(i18n("Add new effect"));
int i = m_ui.effectlist->currentRow();
QDomDocument doc;
- QDomElement effect = m_clipref->effectAt(i).cloneNode().toElement();
+ QDomElement effect = m_currentEffectList.at(i).cloneNode().toElement();
doc.appendChild(doc.importNode(effect, true));
effect = doc.firstChild().toElement();
effect.removeAttribute("kdenlive_ix");
void EffectStackView::slotUpdateEffectParams(const QDomElement old, const QDomElement e)
{
- if (m_clipref)
- emit updateClipEffect(m_clipref, old, e, m_ui.effectlist->currentRow());
+ if (m_trackMode)
+ emit updateEffect(NULL, m_trackindex, old, e, m_ui.effectlist->currentRow());
+ else if (m_clipref)
+ emit updateEffect(m_clipref, -1, old, e, m_ui.effectlist->currentRow());
}
void EffectStackView::slotClipItemSelected(ClipItem* c, int ix)
return;
}
setEnabled(true);
+ m_trackMode = false;
+ m_currentEffectList = m_clipref->effectList();
setupListView(ix);
}
+void EffectStackView::slotTrackItemSelected(int ix, EffectsList list)
+{
+ setEnabled(!list.isEmpty());
+ m_clipref = NULL;
+ m_trackMode = true;
+ m_currentEffectList = list;
+ m_trackindex = ix;
+ setupListView(0);
+}
+
void EffectStackView::slotItemChanged(QListWidgetItem *item)
{
bool disable = true;
int activeRow = m_ui.effectlist->currentRow();
if (activeRow >= 0) {
m_effectedit->updateParameter("disable", QString::number((int) disable));
- emit changeEffectState(m_clipref, activeRow, disable);
+ if (m_trackMode) emit changeEffectState(NULL, m_trackindex, activeRow, disable);
+ else emit changeEffectState(m_clipref, -1, activeRow, disable);
}
slotUpdateCheckAllButton();
}
KIcon customIcon("kdenlive-custom-effect");
QListWidgetItem* item;
- for (int i = 0; i < m_clipref->effectsCount(); i++) {
- const QDomElement d = m_clipref->effectAt(i);
+ for (int i = 0; i < m_currentEffectList.count(); i++) {
+ const QDomElement d = m_currentEffectList.at(i).cloneNode().toElement();
if (d.isNull()) {
kDebug() << " . . . . WARNING, NULL EFFECT IN STACK!!!!!!!!!";
continue;
bool isChecked = false;
if (hasItem && m_ui.effectlist->currentItem()->checkState() == Qt::Checked) isChecked = true;
if (hasItem && m_ui.effectlist->currentItem()->isSelected()) {
- QDomElement eff = m_clipref->effectAt(activeRow);
- m_effectedit->transferParamDesc(eff,
- 0,
- m_clipref->cropStart().frames(KdenliveSettings::project_fps()),
- (m_clipref->cropStart() + m_clipref->cropDuration()).frames(KdenliveSettings::project_fps())); //minx max frame
+ QDomElement eff = m_currentEffectList.at(activeRow);
+ if (m_trackMode) {
+ // showing track effects
+ m_effectedit->transferParamDesc(eff, 0, 0, -1);
+ } else m_effectedit->transferParamDesc(eff,
+ 0,
+ m_clipref->cropStart().frames(KdenliveSettings::project_fps()),
+ (m_clipref->cropStart() + m_clipref->cropDuration()).frames(KdenliveSettings::project_fps())); //minx max frame
m_ui.region_url->setUrl(KUrl(eff.attribute("region")));
}
- if (m_clipref && update) m_clipref->setSelectedEffect(activeRow);
+ if (!m_trackMode && m_clipref && update) m_clipref->setSelectedEffect(activeRow);
m_ui.buttonDel->setEnabled(hasItem);
m_ui.buttonSave->setEnabled(hasItem);
m_ui.buttonReset->setEnabled(hasItem && isChecked);
{
int activeRow = m_ui.effectlist->currentRow();
if (activeRow <= 0) return;
- emit changeEffectPosition(m_clipref, activeRow + 1, activeRow);
+ if (m_trackMode) emit changeEffectPosition(NULL, m_trackindex, activeRow + 1, activeRow);
+ else emit changeEffectPosition(m_clipref, -1, activeRow + 1, activeRow);
}
void EffectStackView::slotItemDown()
{
int activeRow = m_ui.effectlist->currentRow();
if (activeRow >= m_ui.effectlist->count() - 1) return;
- emit changeEffectPosition(m_clipref, activeRow + 1, activeRow + 2);
+ if (m_trackMode) emit changeEffectPosition(NULL, m_trackindex, activeRow + 1, activeRow + 2);
+ else emit changeEffectPosition(m_clipref, -1, activeRow + 1, activeRow + 2);
}
void EffectStackView::slotItemDel()
{
int activeRow = m_ui.effectlist->currentRow();
if (activeRow >= 0) {
- emit removeEffect(m_clipref, m_clipref->effectAt(activeRow));
+ if (m_trackMode) emit removeEffect(NULL, m_trackindex, m_currentEffectList.at(activeRow).cloneNode().toElement());
+ else emit removeEffect(m_clipref, -1, m_clipref->effectAt(activeRow));
slotUpdateCheckAllButton();
}
}
{
int activeRow = m_ui.effectlist->currentRow();
if (activeRow < 0) return;
- QDomElement old = m_clipref->effectAt(activeRow).cloneNode().toElement();
+ QDomElement old = m_currentEffectList.at(activeRow).cloneNode().toElement();
QDomElement dom;
QString effectName = m_ui.effectlist->currentItem()->text();
foreach(const QString &type, m_effectLists.keys()) {
}
if (!dom.isNull()) {
dom.setAttribute("kdenlive_ix", old.attribute("kdenlive_ix"));
- m_clipref->initEffect(dom);
- m_effectedit->transferParamDesc(dom, 0, m_clipref->cropStart().frames(KdenliveSettings::project_fps()), (m_clipref->cropStart() + m_clipref->cropDuration()).frames(KdenliveSettings::project_fps()));//minx max frame
- m_ui.region_url->setUrl(KUrl(dom.attribute("region")));
- emit updateClipEffect(m_clipref, old, dom, activeRow);
+ if (m_trackMode) {
+ EffectsList::setParameter(dom, "in", QString::number(0));
+ EffectsList::setParameter(dom, "out", QString::number(0));
+ m_effectedit->transferParamDesc(dom, 0, 0, 0);//minx max frame
+ emit updateEffect(NULL, m_trackindex, old, dom, activeRow);
+ } else {
+ m_clipref->initEffect(dom);
+ m_effectedit->transferParamDesc(dom, 0, m_clipref->cropStart().frames(KdenliveSettings::project_fps()), (m_clipref->cropStart() + m_clipref->cropDuration()).frames(KdenliveSettings::project_fps()));//minx max frame
+ m_ui.region_url->setUrl(KUrl(dom.attribute("region")));
+ emit updateEffect(m_clipref, -1, old, dom, activeRow);
+ }
}
}
void EffectStackView::raiseWindow(QWidget* dock)
{
- if (m_clipref && dock)
+ if ((m_clipref || m_trackMode) && dock)
dock->raise();
}
void EffectStackView::slotSeekTimeline(int pos)
{
- if (m_clipref)
+ if (!m_trackMode && m_clipref)
emit seekTimeline(m_clipref->startPos().frames(KdenliveSettings::project_fps()) + pos);
}
void EffectStackView::slotRegionChanged()
{
- emit updateClipRegion(m_clipref, m_ui.effectlist->currentRow(), m_ui.region_url->text());
+ if (!m_trackMode) emit updateClipRegion(m_clipref, m_ui.effectlist->currentRow(), m_ui.region_url->text());
}
void EffectStackView::slotCheckMonitorPosition(int renderPos)
{
+ if (m_trackMode) return;
if (renderPos >= m_clipref->startPos().frames(KdenliveSettings::project_fps()) && renderPos <= m_clipref->endPos().frames(KdenliveSettings::project_fps())) {
if (!m_monitor->getEffectScene()->views().at(0)->isVisible())
m_monitor->slotEffectScene(true);
private:
Ui::EffectStack_UI m_ui;
+ Monitor *m_monitor;
ClipItem* m_clipref;
QMap<QString, EffectsList*> m_effectLists;
+ EffectsList m_currentEffectList;
EffectStackEdit* m_effectedit;
- Monitor *m_monitor;
+
+ /** @brief Effectstackview can show the effects of a clip or the effects of a track.
+ * true if showing track effects. */
+ bool m_trackMode;
+
+ /** @brief The track index of currently edited track. */
+ int m_trackindex;
/** @brief Sets the list of effects according to the clip's effect list.
* @param ix Number of the effect to preselect */
* @param ix Effect to preselect */
void slotClipItemSelected(ClipItem* c, int ix);
+ void slotTrackItemSelected(int ix, EffectsList list);
+
/** @brief Emits updateClipEffect.
* @param old Old effect information
* @param e New effect information
void slotRenderPos(int pos);
signals:
- void removeEffect(ClipItem*, QDomElement);
+ void removeEffect(ClipItem*, int, QDomElement);
/** Parameters for an effect changed, update the filter in playlist */
- void updateClipEffect(ClipItem*, QDomElement, QDomElement, int);
+ void updateEffect(ClipItem*, int, QDomElement, QDomElement, int);
/** An effect in stack was moved, we need to regenerate
all effects for this clip in the playlist */
void refreshEffectStack(ClipItem *);
/** Enable or disable an effect */
- void changeEffectState(ClipItem*, int, bool);
+ void changeEffectState(ClipItem*, int, int, bool);
/** An effect in stack was moved */
- void changeEffectPosition(ClipItem*, int, int);
+ void changeEffectPosition(ClipItem*, int, int, int);
/** an effect was saved, reload list */
void reloadEffects();
/** An effect with position parameter was changed, seek */
return;
}
if (!m_isSelected) emit selectTrack(m_index);
+ emit showTrackEffects(m_index);
QWidget::mousePressEvent(event);
}
void selectTrack(int);
void configTrack(int);
void addTrackInfo(const QDomElement, int);
+ void showTrackEffects(int);
};
#endif
TrackInfo KdenliveDoc::trackInfoAt(int ix) const
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Track INFO outisde of range";
+ return TrackInfo();
+ }
return m_tracksList.at(ix);
}
void KdenliveDoc::switchTrackAudio(int ix, bool hide)
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "SWITCH Track outisde of range";
+ return;
+ }
m_tracksList[ix].isMute = hide; // !m_tracksList.at(ix).isMute;
}
void KdenliveDoc::switchTrackLock(int ix, bool lock)
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Track Lock outisde of range";
+ return;
+ }
m_tracksList[ix].isLocked = lock;
}
bool KdenliveDoc::isTrackLocked(int ix) const
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Track Lock outisde of range";
+ return true;
+ }
return m_tracksList.at(ix).isLocked;
}
void KdenliveDoc::switchTrackVideo(int ix, bool hide)
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "SWITCH Track outisde of range";
+ return;
+ }
m_tracksList[ix].isBlind = hide; // !m_tracksList.at(ix).isBlind;
}
void KdenliveDoc::deleteTrack(int ix)
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Delete Track outisde of range";
+ return;
+ }
m_tracksList.removeAt(ix);
}
void KdenliveDoc::setTrackType(int ix, TrackInfo type)
{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "SET Track Type outisde of range";
+ return;
+ }
m_tracksList[ix].type = type.type;
m_tracksList[ix].isMute = type.isMute;
m_tracksList[ix].isBlind = type.isBlind;
return renderProperties;
}
+void KdenliveDoc::addTrackEffect(int ix, QDomElement effect)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Add Track effect outisde of range";
+ return;
+ }
+ effect.setAttribute("kdenlive_ix", m_tracksList.at(ix).effectsList.count() + 1);
+ m_tracksList[ix].effectsList.append(effect);
+}
+
+void KdenliveDoc::removeTrackEffect(int ix, QDomElement effect)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Remove Track effect outisde of range";
+ return;
+ }
+ QString index;
+ QString toRemove = effect.attribute("kdenlive_ix");
+ for (int i = 0; i < m_tracksList.at(ix).effectsList.count(); ++i) {
+ index = m_tracksList.at(ix).effectsList.at(i).attribute("kdenlive_ix");
+ if (toRemove == index) {
+ m_tracksList[ix].effectsList.removeAt(i);
+ i--;
+ } else if (index.toInt() > toRemove.toInt()) {
+ m_tracksList[ix].effectsList.item(i).setAttribute("kdenlive_ix", index.toInt() - 1);
+ }
+ }
+}
+
+void KdenliveDoc::setTrackEffect(int trackIndex, int effectIndex, QDomElement effect)
+{
+ if (trackIndex < 0 || trackIndex >= m_tracksList.count()) {
+ kWarning() << "Set Track effect outisde of range";
+ return;
+ }
+ if (effectIndex < 0 || effectIndex > (m_tracksList.at(trackIndex).effectsList.count() - 1) || effect.isNull()) {
+ kDebug() << "Invalid effect index: " << effectIndex;
+ return;
+ }
+ kDebug() << "CHange TRK EFFECT AT: " << trackIndex;
+ effect.setAttribute("kdenlive_ix", effectIndex + 1);
+ m_tracksList[trackIndex].effectsList.replace(effectIndex, effect);
+}
+
+const EffectsList KdenliveDoc::getTrackEffects(int ix)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Get Track effects outisde of range";
+ return EffectsList();
+ }
+ return m_tracksList.at(ix).effectsList;
+}
+
+QDomElement KdenliveDoc::getTrackEffect(int trackIndex, int effectIndex) const
+{
+ if (trackIndex < 0 || trackIndex >= m_tracksList.count()) {
+ kWarning() << "Get Track effect outisde of range";
+ return QDomElement();
+ }
+ EffectsList list = m_tracksList.at(trackIndex).effectsList;
+ if (effectIndex > list.count() - 1 || effectIndex < 0 || list.at(effectIndex).isNull()) return QDomElement();
+ return list.at(effectIndex).cloneNode().toElement();
+}
+
#include "kdenlivedoc.moc"
const QString getDocumentProperty(const QString &name) const;
/** @brief get the list of renderer properties that were saved in the document */
QMap <QString, QString> getRenderProperties() const;
+ void addTrackEffect(int ix, QDomElement effect);
+ void removeTrackEffect(int ix, QDomElement effect);
+ void setTrackEffect(int trackIndex, int effectIndex, QDomElement effect);
+ const EffectsList getTrackEffects(int ix);
+ QDomElement getTrackEffect(int trackIndex, int effectIndex) const;
private:
KUrl m_url;
disconnect(m_activeTimeline, SIGNAL(deleteTrack(int)), this, SLOT(slotDeleteTrack(int)));
disconnect(m_activeTimeline, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int)));
disconnect(m_activeDocument, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
- disconnect(m_effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
- disconnect(m_effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
- disconnect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
- disconnect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
+ disconnect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int)));
+ disconnect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
+ disconnect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
+ disconnect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int, int)));
disconnect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
disconnect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
disconnect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int)));
connect(trackView->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), this, SLOT(slotUpdateClipMarkers(DocClipBase*)));
+ connect(trackView, SIGNAL(showTrackEffects(int, EffectsList)), m_effectStack, SLOT(slotTrackItemSelected(int, EffectsList)));
+ connect(trackView, SIGNAL(showTrackEffects(int, EffectsList)), this, SLOT(slotActivateEffectStackView()));
connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), this, SLOT(slotActivateEffectStackView()));
connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_transitionConfig, SLOT(slotTransitionItemSelected(Transition*, int, QPoint, bool)));
connect(trackView->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay()));
- connect(m_effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
+ connect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int)));
connect(m_effectStack, SIGNAL(updateClipRegion(ClipItem*, int, QString)), trackView->projectView(), SLOT(slotUpdateClipRegion(ClipItem*, int, QString)));
- connect(m_effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
- connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
- connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
+ connect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
+ connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
+ connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int, int)));
connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
// setup length here as otherwise default length (currently 15000 frames in MLT) will be taken although outpoint is larger
if (xml.attribute("type").toInt() == COLOR || xml.attribute("type").toInt() == TEXT
- || xml.attribute("type").toInt() == IMAGE || xml.attribute("type").toInt() == SLIDESHOW)
+ || xml.attribute("type").toInt() == IMAGE || xml.attribute("type").toInt() == SLIDESHOW)
producer->set("length", xml.attribute("out").toInt() - xml.attribute("in").toInt() + 1);
if (xml.hasAttribute("out")) producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt());
return newLength;
}
+bool Render::mltRemoveTrackEffect(int track, QString index, bool updateIndex)
+{
+ kDebug() << "REMOVE TK EFF: " << track << ", IX: " << index;
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ bool success = false;
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ Mlt::Service clipService(trackPlaylist.get_service());
+
+ m_isBlocked = true;
+ int ct = 0;
+ Mlt::Filter *filter = clipService.filter(ct);
+ while (filter) {
+ if ((index == "-1" && strcmp(filter->get("kdenlive_id"), "")) || filter->get("kdenlive_ix") == index) {
+ if (clipService.detach(*filter) == 0) success = true;
+ } else if (updateIndex) {
+ // Adjust the other effects index
+ if (QString(filter->get("kdenlive_ix")).toInt() > index.toInt()) filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ ct++;
+ } else ct++;
+ filter = clipService.filter(ct);
+ }
+ m_isBlocked = false;
+ refresh();
+ return success;
+}
+
bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool updateIndex, bool doRefresh)
{
+ if (position < GenTime()) {
+ // Remove track effect
+ return mltRemoveTrackEffect(track, index, updateIndex);
+ }
Mlt::Service service(m_mltProducer->parent().get_service());
bool success = false;
Mlt::Tractor tractor(service);
Mlt::Tractor tractor(service);
Mlt::Producer trackProducer(tractor.track(track));
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
- Mlt::Service trackService(trackPlaylist.get_service());
+ Mlt::Service trackService(trackProducer.get_service()); //trackPlaylist
return mltAddEffect(trackService, params, 15000, true);
}
delete clip;
return mltAddEffect(clipService, params, duration, doRefresh);
}
-
+
bool Render::mltAddEffect(Mlt::Service service, EffectsParameterList params, int duration, bool doRefresh)
{
bool updateIndex = false;
return true;
}
+bool Render::mltEditTrackEffect(int track, EffectsParameterList params)
+{
+ kDebug() << "EDIT TK, FILTER: " << track;
+ 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());
+ m_isBlocked = true;
+ int ct = 0;
+ QString index = params.paramValue("kdenlive_ix");
+ QString tag = params.paramValue("tag");
+
+ Mlt::Filter *filter = clipService.filter(ct);
+ while (filter) {
+ if (filter->get("kdenlive_ix") == index) {
+ break;
+ }
+ ct++;
+ filter = clipService.filter(ct);
+ }
+
+ if (!filter) {
+ kDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT! " << index << ", " << tag;
+ // filter was not found, it was probably a disabled filter, so add it to the correct place...
+
+ bool success = false;//mltAddTrackEffect(track, params);
+ m_isBlocked = false;
+ return success;
+ }
+ QString prefix;
+ QString ser = filter->get("mlt_service");
+ if (ser == "region") prefix = "filter0.";
+ mlt_service_lock(service.get_service());
+ for (int j = 0; j < params.count(); j++) {
+ char *name = decodedString(prefix + params.at(j).name());
+ char *value = decodedString(params.at(j).value());
+ filter->set(name, value);
+ delete[] name;
+ delete[] value;
+ }
+ mlt_service_unlock(service.get_service());
+
+ m_isBlocked = false;
+ refresh();
+ return true;
+
+}
+
bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList params)
{
QString index = params.paramValue("kdenlive_ix");
bool success = mltAddEffect(track, position, params);
return success;
}
-
+ if (position < GenTime()) {
+ return mltEditTrackEffect(track, params);
+ }
// find filter
Mlt::Service service(m_mltProducer->parent().get_service());
Mlt::Tractor tractor(service);
void Render::mltUpdateEffectPosition(int track, GenTime position, int oldPos, int newPos)
{
-
- kDebug() << "MOVING EFFECT FROM " << oldPos << ", TO: " << newPos;
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());
void Render::mltMoveEffect(int track, GenTime position, int oldPos, int newPos)
{
-
- kDebug() << "MOVING EFFECT FROM " << oldPos << ", TO: " << newPos;
+ if (position < GenTime()) {
+ mltMoveTrackEffect(track, oldPos, newPos);
+ return;
+ }
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());
if (doRefresh) refresh();
}
+void Render::mltMoveTrackEffect(int track, int oldPos, int newPos)
+{
+ 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());
+
+ m_isBlocked = true;
+ int ct = 0;
+ QList <Mlt::Filter *> filtersList;
+ Mlt::Filter *filter = clipService.filter(ct);
+ bool found = false;
+ if (newPos > oldPos) {
+ while (filter) {
+ if (!found && QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ filter->set("kdenlive_ix", newPos);
+ filtersList.append(filter);
+ clipService.detach(*filter);
+ filter = clipService.filter(ct);
+ while (filter && QString(filter->get("kdenlive_ix")).toInt() <= newPos) {
+ filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ ct++;
+ filter = clipService.filter(ct);
+ }
+ found = true;
+ }
+ if (filter && QString(filter->get("kdenlive_ix")).toInt() > newPos) {
+ filtersList.append(filter);
+ clipService.detach(*filter);
+ } else ct++;
+ filter = clipService.filter(ct);
+ }
+ } else {
+ while (filter) {
+ if (QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ filter->set("kdenlive_ix", newPos);
+ filtersList.append(filter);
+ clipService.detach(*filter);
+ } else ct++;
+ filter = clipService.filter(ct);
+ }
+
+ ct = 0;
+ filter = clipService.filter(ct);
+ while (filter) {
+ int pos = QString(filter->get("kdenlive_ix")).toInt();
+ if (pos >= newPos) {
+ if (pos < oldPos) filter->set("kdenlive_ix", pos + 1);
+ filtersList.append(filter);
+ clipService.detach(*filter);
+ } else ct++;
+ filter = clipService.filter(ct);
+ }
+ }
+
+ for (int i = 0; i < filtersList.count(); i++) {
+ clipService.attach(*(filtersList.at(i)));
+ }
+ m_isBlocked = false;
+ refresh();
+}
+
bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration)
{
m_isBlocked = true;
/** @brief Deletes an effect from a clip in MLT's playlist. */
bool mltRemoveEffect(int track, GenTime position, QString index, bool updateIndex, bool doRefresh = true);
+ bool mltRemoveTrackEffect(int track, QString index, bool updateIndex);
/** @brief Adds an effect to a clip in MLT's playlist. */
bool mltAddEffect(int track, GenTime position, EffectsParameterList params, bool doRefresh = true);
/** @brief Edits an effect parameters in MLT's playlist. */
bool mltEditEffect(int track, GenTime position, EffectsParameterList params);
+ bool mltEditTrackEffect(int track, EffectsParameterList params);
/** @brief Updates the "kdenlive_ix" (index) value of an effect. */
void mltUpdateEffectPosition(int track, GenTime position, int oldPos, int newPos);
* It switches effects from oldPos and newPos, updating the "kdenlive_ix"
* (index) value. */
void mltMoveEffect(int track, GenTime position, int oldPos, int newPos);
+ void mltMoveTrackEffect(int track, int oldPos, int newPos);
/** @brief Enables/disables audio/video in a track. */
void mltChangeTrackState(int track, bool mute, bool blind);
connect(m_trackview, SIGNAL(trackHeightChanged()), this, SLOT(slotRebuildTrackHeaders()));
connect(m_trackview, SIGNAL(tracksChanged()), this, SLOT(slotReloadTracks()));
connect(m_trackview, SIGNAL(updateTrackHeaders()), this, SLOT(slotRepaintTracks()));
+ connect(m_trackview, SIGNAL(showTrackEffects(int, EffectsList)), this, SIGNAL(showTrackEffects(int, EffectsList)));
parseDocument(m_doc->toXml());
if (m_doc->setSceneList() == -1) *ok = false;
connect(header, SIGNAL(insertTrack(int)), this, SIGNAL(insertTrack(int)));
connect(header, SIGNAL(renameTrack(int, QString)), this, SLOT(slotRenameTrack(int, QString)));
connect(header, SIGNAL(configTrack(int)), this, SIGNAL(configTrack(int)));
- connect(header, SIGNAL(addTrackInfo(const QDomElement, int)), m_trackview, SLOT(slotAddTrackEffect(const QDomElement, int)));
+ connect(header, SIGNAL(addTrackInfo(const QDomElement, int)), m_trackview, SLOT(slotAddTrackEffect(const QDomElement, int)));
+ connect(header, SIGNAL(showTrackEffects(int)), this, SLOT(slotShowTrackEffects(int)));
headers_container->layout()->addWidget(header);
}
frame = new QFrame(this);
m_ruler->update();
}
+void TrackView::slotShowTrackEffects(int ix)
+{
+ emit showTrackEffects(m_doc->tracksCount() - ix, m_doc->getTrackEffects(ix));
+}
+
#include "trackview.moc"
#include <KRuler>
#include "customtrackscene.h"
+#include "effectslist.h"
#include "ui_timeline_ui.h"
class ClipItem;
* the horizontal scrollbar is visible and the position
* of the vertical scrollbar is maximal */
void slotUpdateVerticalScroll(int min, int max);
+ void slotShowTrackEffects(int);
signals:
void mousePosition(int);
void configTrack(int);
void updateTracksInfo();
void setZoom(int);
+ void showTrackEffects(int, EffectsList);
};
#endif