X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcustomtrackview.cpp;h=54b6f66a290cba2a8775f3093ff0cd6e176ef464;hb=880efc8572a7df65453dfb5736de6455fe129a86;hp=b90c587ecffa8169746f71999baeed87bd325a28;hpb=3d6860cb1c05c50a462a82ca7fbfa163ec295b66;p=kdenlive diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index b90c587e..54b6f66a 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -19,7 +19,6 @@ #include "customtrackview.h" -#include "customtrackscene.h" #include "docclipbase.h" #include "clipitem.h" #include "definitions.h" @@ -73,7 +72,7 @@ #include #include #include - +#include bool sortGuidesList(const Guide *g1 , const Guide *g2) { @@ -114,7 +113,8 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen m_copiedItems(), m_menuPosition(), m_blockRefresh(false), - m_selectionGroup(NULL) + m_selectionGroup(NULL), + m_selectedTrack(0) { if (doc) m_commandStack = doc->commandStack(); else m_commandStack = NULL; @@ -143,7 +143,7 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen QPen pen1 = QPen(); pen1.setWidth(1); - pen1.setColor(Qt::black); + pen1.setColor(palette().text().color()); m_cursorLine->setPen(pen1); m_cursorLine->setFlag(QGraphicsItem::ItemIgnoresTransformations, true); @@ -170,6 +170,18 @@ CustomTrackView::~CustomTrackView() m_waitingThumbs.clear(); } +//virtual +void CustomTrackView::keyPressEvent(QKeyEvent * event) +{ + if (event->key() == Qt::Key_Up) { + slotTrackUp(); + event->accept(); + } else if (event->key() == Qt::Key_Down) { + slotTrackDown(); + event->accept(); + } else QWidget::keyPressEvent(event); +} + void CustomTrackView::setDocumentModified() { m_document->setModified(true); @@ -323,7 +335,7 @@ void CustomTrackView::slotCheckPositionScrolling() void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { int pos = event->x(); - int mappedXPos = (int)(mapToScene(event->pos()).x() + 0.5); + int mappedXPos = qMax((int)(mapToScene(event->pos()).x() + 0.5), 0); double snappedPos = getSnapPointForPos(mappedXPos); emit mousePosition(mappedXPos); @@ -367,25 +379,28 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) pos = (br.bottom() - pos) * maxh; m_dragItem->updateKeyFramePos(keyFramePos, pos); } - if (m_visualTip) scene()->removeItem(m_visualTip); - m_animationTimer->stop(); - delete m_animation; - m_animation = NULL; - delete m_visualTip; - m_visualTip = NULL; + if (m_visualTip) { + scene()->removeItem(m_visualTip); + m_animationTimer->stop(); + delete m_animation; + m_animation = NULL; + delete m_visualTip; + m_visualTip = NULL; + } return; } else if (m_operationMode == MOVEGUIDE) { - if (m_visualTip) scene()->removeItem(m_visualTip); - m_animationTimer->stop(); - delete m_animation; - m_animation = NULL; - delete m_visualTip; - m_visualTip = NULL; + if (m_visualTip) { + scene()->removeItem(m_visualTip); + m_animationTimer->stop(); + delete m_animation; + m_animation = NULL; + delete m_visualTip; + m_visualTip = NULL; + } QGraphicsView::mouseMoveEvent(event); return; } else if (m_operationMode == SPACER && move && m_selectionGroup) { // spacer tool - int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5); if (snappedPos < 0) snappedPos = 0; // Make sure there is no collision QList children = m_selectionGroup->childItems(); @@ -793,7 +808,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) QRectF rect(mapToScene(m_clickEvent).x(), track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width() - mapToScene(m_clickEvent).x(), m_tracksHeight / 2 - 2); bool isOk; - selection = checkForGroups(rect, isOk); + selection = checkForGroups(rect, &isOk); if (!isOk) { // groups found on track, do not allow the move emit displayMessage(i18n("Cannot use spacer in a track with a group"), ErrorMessage); @@ -817,7 +832,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) offsetList.append(item->startPos()); offsetList.append(item->endPos()); m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } else if (selection.at(i)->parentItem() == 0 && selection.at(i)->type() == GROUPWIDGET) { QList children = selection.at(i)->childItems(); for (int j = 0; j < children.count(); j++) { @@ -826,10 +841,10 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) offsetList.append(item->endPos()); } m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } else if (selection.at(i)->parentItem()) { m_selectionGroup->addToGroup(selection.at(i)->parentItem()); - selection.at(i)->parentItem()->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } } @@ -950,6 +965,8 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) return; } else if (m_operationMode == MOVE) { setCursor(Qt::ClosedHandCursor); + if (m_dragItem) m_dragItem->setZValue(10); + if (m_selectionGroup) m_selectionGroup->setZValue(10); } else if (m_operationMode == TRANSITIONSTART && event->modifiers() != Qt::ControlModifier) { ItemInfo info; info.startPos = m_dragItem->startPos(); @@ -959,7 +976,11 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_document->tracksCount() - transitiontrack); if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) { info.endPos = transitionClip->endPos(); - } else info.endPos = info.startPos + GenTime(65, m_document->fps()); + } else { + GenTime transitionDuration(65, m_document->fps()); + if (m_dragItem->cropDuration() < transitionDuration) info.endPos = m_dragItem->endPos(); + else info.endPos = info.startPos + transitionDuration; + } if (info.endPos == info.startPos) info.endPos = info.startPos + GenTime(65, m_document->fps()); // Check there is no other transition at that place double startY = info.track * m_tracksHeight + 1 + m_tracksHeight / 2; @@ -985,7 +1006,11 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_document->tracksCount() - transitiontrack); if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) { info.startPos = transitionClip->startPos(); - } else info.startPos = info.endPos - GenTime(65, m_document->fps()); + } else { + GenTime transitionDuration(65, m_document->fps()); + if (m_dragItem->cropDuration() < transitionDuration) info.startPos = m_dragItem->startPos(); + else info.startPos = info.endPos - transitionDuration; + } if (info.endPos == info.startPos) info.startPos = info.endPos - GenTime(65, m_document->fps()); QDomElement transition = MainWindow::transitions.getEffectByTag("luma", "dissolve").cloneNode().toElement(); EffectsList::setParameter(transition, "reverse", "1"); @@ -1028,11 +1053,11 @@ void CustomTrackView::resetSelectionGroup(bool selectItems) for (int i = 0; i < children.count(); i++) { if (children.at(i)->parentItem() == 0 && (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET)) { if (!static_cast (children.at(i))->isItemLocked()) { - children.at(i)->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true); children.at(i)->setSelected(selectItems); } } else if (children.at(i)->type() == GROUPWIDGET) { - children.at(i)->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true); children.at(i)->setSelected(selectItems); } } @@ -1091,7 +1116,7 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup) for (int i = 0; i < selection.count(); i++) { if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) { newGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } } KdenliveSettings::setSnaptopoints(snap); @@ -1106,7 +1131,7 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup) for (int i = 0; i < selection.count(); i++) { if (selection.at(i)->parentItem() == 0 && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } } KdenliveSettings::setSnaptopoints(snap); @@ -1270,7 +1295,6 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint pos) info.cropStart = GenTime(list.at(1).toInt(), m_document->fps()); info.endPos = GenTime(list.at(2).toInt() - list.at(1).toInt(), m_document->fps()); info.cropDuration = info.endPos - info.startPos; - info.originalcropStart = info.cropStart; info.track = 0; // Check if clip can be inserted at that position @@ -1284,13 +1308,14 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint pos) m_selectionGroup = new AbstractGroupItem(m_document->fps()); ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1); m_selectionGroup->addToGroup(item); - item->setFlags(QGraphicsItem::ItemIsSelectable); + item->setFlag(QGraphicsItem::ItemIsMovable, false); QList offsetList; offsetList.append(info.endPos); updateSnapPoints(NULL, offsetList); m_selectionGroup->setPos(framePos); scene()->addItem(m_selectionGroup); + m_selectionGroup->setZValue(10); return true; } else if (data->hasFormat("kdenlive/producerslist")) { m_clipDrag = true; @@ -1334,7 +1359,8 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint pos) start += info.cropDuration; offsetList.append(start); ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, false); - item->setFlags(QGraphicsItem::ItemIsSelectable); + item->setZValue(10); + item->setFlag(QGraphicsItem::ItemIsMovable, false); m_selectionGroup->addToGroup(item); m_waitingThumbs.append(item); } @@ -1342,6 +1368,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint pos) updateSnapPoints(NULL, offsetList); m_selectionGroup->setPos(framePos); scene()->addItem(m_selectionGroup); + m_selectionGroup->setZValue(10); m_thumbsTimer.start(); return true; @@ -1406,11 +1433,10 @@ void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage); return; } - ItemInfo info = clip->info(); double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0; int strobe = EffectsList::parameter(effect, "strobe").toInt(); if (strobe == 0) strobe = 1; - doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId()); + doChangeClipSpeed(clip->info(), clip->speedIndependantInfo(), speed, 1.0, strobe, clip->baseClip()->getId()); EffectsParameterList params = clip->addEffect(effect); m_document->renderer()->mltAddEffect(track, pos, params); if (clip->isSelected()) emit clipItemSelected(clip); @@ -1435,8 +1461,7 @@ void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) if (effect.attribute("id") == "speed") { ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), m_document->tracksCount() - track); if (clip) { - ItemInfo info = clip->info(); - doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId()); + doChangeClipSpeed(clip->info(), clip->speedIndependantInfo(), 1.0, clip->speed(), 1, clip->baseClip()->getId()); clip->deleteEffect(index); emit clipItemSelected(clip); m_document->renderer()->mltRemoveEffect(track, pos, index, true); @@ -1476,7 +1501,7 @@ void CustomTrackView::slotAddGroupEffect(QDomElement effect, AbstractGroupItem * if (item->isAudioOnly() || item->clipType() == AUDIO) continue; } - if (item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1 && effect.attribute("unique", "0") != "0") { + if (effect.attribute("unique", "0") != "0" && item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1) { emit displayMessage(i18n("Effect already present in clip"), ErrorMessage); continue; } @@ -1539,7 +1564,9 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) if (item->isItemLocked()) { continue; } - item->initEffect(effect); + if (effect.attribute("id") == "freeze" && m_cursorPos > item->startPos().frames(m_document->fps()) && m_cursorPos < item->endPos().frames(m_document->fps())) { + item->initEffect(effect, m_cursorPos - item->startPos().frames(m_document->fps())); + } else item->initEffect(effect); if (effect.attribute("tag") == "ladspa") { QString ladpsaFile = m_document->getLadspaFile(); initEffects::ladspaEffectFile(ladpsaFile, effect.attribute("ladspaid").toInt(), getLadspaParams(effect)); @@ -1564,18 +1591,21 @@ void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect) void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement insertedEffect, int ix, bool triggeredByUser) { + if (insertedEffect.isNull()) { + 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 (clip) { // Special case: speed effect if (effect.attribute("id") == "speed") { - ItemInfo info = clip->info(); - if (effect.attribute("disabled") == "1") doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId()); + if (effect.attribute("disabled") == "1") doChangeClipSpeed(clip->info(), clip->speedIndependantInfo(), 1.0, clip->speed(), 1, clip->baseClip()->getId()); else { double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0; int strobe = EffectsList::parameter(effect, "strobe").toInt(); if (strobe == 0) strobe = 1; - doChangeClipSpeed(info, speed, clip->speed(), strobe, clip->baseClip()->getId()); + doChangeClipSpeed(clip->info(), clip->speedIndependantInfo(), speed, clip->speed(), strobe, clip->baseClip()->getId()); } clip->setEffectAt(ix, effect); if (ix == clip->selectedEffectIndex()) { @@ -1665,7 +1695,7 @@ void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect m_commandStack->push(command); } -void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) +ClipItem *CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut, bool execute) { if (cut) { // cut clip @@ -1674,7 +1704,7 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) emit displayMessage(i18n("Cannot find clip to cut"), ErrorMessage); kDebug() << "///////// ERROR CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); m_blockRefresh = false; - return; + return NULL; } if (item->parentItem()) { // Item is part of a group, reset group @@ -1682,16 +1712,14 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) } kDebug() << "///////// CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); - m_document->renderer()->mltCutClip(m_document->tracksCount() - info.track, cutTime); + if (execute) m_document->renderer()->mltCutClip(m_document->tracksCount() - info.track, cutTime); int cutPos = (int) cutTime.frames(m_document->fps()); - ItemInfo newPos = info; - double speed = item->speed(); + ItemInfo newPos; newPos.startPos = cutTime; newPos.endPos = info.endPos; newPos.cropStart = item->info().cropStart + (cutTime - info.startPos); newPos.track = info.track; - newPos.cropDuration = GenTime((int)((newPos.endPos - newPos.startPos).frames(m_document->fps()) * speed), m_document->fps()); - newPos.originalcropStart = GenTime((int)(newPos.cropStart .frames(m_document->fps()) * speed), m_document->fps()); + newPos.cropDuration = newPos.endPos - newPos.startPos; ClipItem *dup = item->clone(newPos); @@ -1706,13 +1734,14 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) QDomElement oldeffect = item->effectAt(ix); dup->deleteEffect(oldeffect.attribute("kdenlive_ix")); } - item->resizeEnd(cutPos, false); + item->resizeEnd(cutPos); scene()->addItem(dup); if (item->checkKeyFrames()) slotRefreshEffects(item); if (dup->checkKeyFrames()) slotRefreshEffects(dup); item->baseClip()->addReference(); m_document->updateClip(item->baseClip()->getId()); setDocumentModified(); + return dup; //kDebug() << "///////// CUTTING CLIP RESULT: (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), DUP: (" << dup->startPos().frames(25) << "-" << dup->endPos().frames(25) << ")" << ", CUT: " << cutTime.frames(25); } else { // uncut clip @@ -1722,11 +1751,11 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) if (!item || !dup || item == dup) { emit displayMessage(i18n("Cannot find clip to uncut"), ErrorMessage); m_blockRefresh = false; - return; + return NULL; } if (m_document->renderer()->mltRemoveClip(m_document->tracksCount() - info.track, cutTime) == false) { emit displayMessage(i18n("Error removing clip at %1 on track %2", m_document->timecode().getTimecodeFromFrames(cutTime.frames(m_document->fps())), info.track), ErrorMessage); - return; + return NULL; } /*kDebug() << "// UNCUTTING CLIPS: ITEM 1 (" << item->startPos().frames(25) << "x" << item->endPos().frames(25) << ")"; @@ -1749,9 +1778,10 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) setDocumentModified(); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); + return item; } - QTimer::singleShot(3000, this, SLOT(slotEnableRefresh())); + //QTimer::singleShot(3000, this, SLOT(slotEnableRefresh())); } void CustomTrackView::slotEnableRefresh() @@ -1881,7 +1911,13 @@ void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QD } m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_document->tracksCount() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML(), refresh); if (m_dragItem == item) m_dragItem = NULL; + +#if QT_VERSION >= 0x040600 + // animate item deletion + item->closeAnimation(); +#else delete item; +#endif emit transitionItemSelected(NULL); setDocumentModified(); } @@ -1968,8 +2004,9 @@ void CustomTrackView::dropEvent(QDropEvent * event) updateClipTypeActions(NULL); } - new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, addCommand); + //TODO: take care of edit mode for undo item->baseClip()->addReference(); + item->setZValue(item->defaultZValue()); m_document->updateClip(item->baseClip()->getId()); ItemInfo info = item->info(); @@ -1978,9 +2015,12 @@ void CustomTrackView::dropEvent(QDropEvent * event) if (isLocked) item->setItemLocked(true); ItemInfo clipInfo = info; clipInfo.track = m_document->tracksCount() - item->track(); - if (m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track())) == -1) { + if (m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT) == -1) { emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage); } + adjustTimelineClips(m_scene->editMode(), item, addCommand); + + new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, addCommand); if (item->baseClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) { // add transparency transition @@ -1999,6 +2039,98 @@ void CustomTrackView::dropEvent(QDropEvent * event) setFocus(); } +void CustomTrackView::adjustTimelineClips(EDITMODE mode, ClipItem *item, QUndoCommand *command) +{ + if (mode == OVERWRITEEDIT) { + // if we are in overwrite or push mode, move clips accordingly + bool snap = KdenliveSettings::snaptopoints(); + KdenliveSettings::setSnaptopoints(false); + ItemInfo info = item->info(); + QRectF rect(info.startPos.frames(m_document->fps()), info.track * m_tracksHeight + m_tracksHeight / 2, (info.endPos - info.startPos).frames(m_document->fps()) - 1, 5); + QList selection = m_scene->items(rect); + selection.removeAll(item); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET) { + ClipItem *clip = static_cast(selection.at(i)); + if (clip->startPos() < info.startPos) { + if (clip->endPos() > info.endPos) { + ItemInfo clipInfo = clip->info(); + ItemInfo dupInfo = clipInfo; + GenTime diff = info.startPos - clip->startPos(); + dupInfo.startPos = info.startPos; + dupInfo.cropStart += diff; + dupInfo.cropDuration = clipInfo.endPos - info.startPos; + ItemInfo newdupInfo = dupInfo; + GenTime diff2 = info.endPos - info.startPos; + newdupInfo.startPos = info.endPos; + newdupInfo.cropStart += diff2; + newdupInfo.cropDuration = clipInfo.endPos - info.endPos; + new RazorClipCommand(this, clipInfo, info.startPos, false, command); + new ResizeClipCommand(this, dupInfo, newdupInfo, false, false, command); + ClipItem *dup = cutClip(clipInfo, info.startPos, true, false); + if (dup) dup->resizeStart(info.endPos.frames(m_document->fps())); + + } else { + ItemInfo newclipInfo = clip->info(); + newclipInfo.endPos = info.startPos; + new ResizeClipCommand(this, clip->info(), newclipInfo, false, false, command); + clip->resizeEnd(info.startPos.frames(m_document->fps())); + } + } else if (clip->endPos() < info.endPos) { + new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), clip->info(), clip->effectList(), false, true, command); + scene()->removeItem(clip); + delete clip; + clip = NULL; + } else { + ItemInfo newclipInfo = clip->info(); + newclipInfo.startPos = info.endPos; + new ResizeClipCommand(this, clip->info(), newclipInfo, false, false, command); + clip->resizeStart(info.endPos.frames(m_document->fps())); + } + } + } + KdenliveSettings::setSnaptopoints(snap); + } +} + + +void CustomTrackView::adjustTimelineTransitions(EDITMODE mode, Transition *item, QUndoCommand *command) +{ + if (mode == OVERWRITEEDIT) { + // if we are in overwrite or push mode, move clips accordingly + bool snap = KdenliveSettings::snaptopoints(); + KdenliveSettings::setSnaptopoints(false); + ItemInfo info = item->info(); + QRectF rect(info.startPos.frames(m_document->fps()), info.track * m_tracksHeight + m_tracksHeight, (info.endPos - info.startPos).frames(m_document->fps()) - 1, 5); + QList selection = m_scene->items(rect); + selection.removeAll(item); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == TRANSITIONWIDGET) { + Transition *tr = static_cast(selection.at(i)); + if (tr->startPos() < info.startPos) { + ItemInfo firstPos = tr->info(); + ItemInfo newPos = firstPos; + firstPos.endPos = item->startPos(); + newPos.startPos = item->endPos(); + new MoveTransitionCommand(this, tr->info(), firstPos, true, command); + if (tr->endPos() > info.endPos) { + // clone transition + new AddTransitionCommand(this, newPos, tr->transitionEndTrack(), tr->toXML(), false, true, command); + } + } else if (tr->endPos() > info.endPos) { + // just resize + ItemInfo firstPos = tr->info(); + firstPos.startPos = item->endPos(); + new MoveTransitionCommand(this, tr->info(), firstPos, true, command); + } else { + // remove transition + new AddTransitionCommand(this, tr->info(), tr->transitionEndTrack(), tr->toXML(), true, true, command); + } + } + } + KdenliveSettings::setSnaptopoints(snap); + } +} QStringList CustomTrackView::mimeTypes() const { @@ -2051,7 +2183,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) for (int i = 0; i < selection.count(); i++) { if ((!selection.at(i)->parentItem()) && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } } // Move graphic items @@ -2101,7 +2233,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight); setSceneRect(0, 0, sceneRect().width(), maxHeight); viewport()->update(); - emit trackHeightChanged(); + emit tracksChanged(); //QTimer::singleShot(500, this, SIGNAL(trackHeightChanged())); //setFixedHeight(50 * m_tracksCount); } @@ -2123,7 +2255,7 @@ void CustomTrackView::removeTrack(int ix) for (int i = 0; i < selection.count(); i++) { if ((!selection.at(i)->parentItem()) && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) { m_selectionGroup->addToGroup(selection.at(i)); - selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable); + selection.at(i)->setFlag(QGraphicsItem::ItemIsMovable, false); } } // Move graphic items @@ -2173,8 +2305,10 @@ void CustomTrackView::removeTrack(int ix) } m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight); setSceneRect(0, 0, sceneRect().width(), maxHeight); + + m_selectedTrack = qMin(m_selectedTrack, m_document->tracksCount() - 1); viewport()->update(); - emit trackHeightChanged(); + emit tracksChanged(); //QTimer::singleShot(500, this, SIGNAL(trackHeightChanged())); } @@ -2235,18 +2369,19 @@ void CustomTrackView::slotSwitchTrackVideo(int ix) setDocumentModified(); } -QList CustomTrackView::checkForGroups(const QRectF &rect, bool &ok) +QList CustomTrackView::checkForGroups(const QRectF &rect, bool *ok) { // Check there is no group going over several tracks there, or that would result in timeline corruption QList selection = scene()->items(rect); + *ok = true; int maxHeight = m_tracksHeight * 1.5; for (int i = 0; i < selection.count(); i++) { // Check that we don't try to move a group with clips on other tracks if (selection.at(i)->type() == GROUPWIDGET && (selection.at(i)->boundingRect().height() >= maxHeight)) { - ok = false; + *ok = false; break; } else if (selection.at(i)->parentItem() && (selection.at(i)->parentItem()->boundingRect().height() >= maxHeight)) { - ok = false; + *ok = false; break; } } @@ -2283,7 +2418,7 @@ void CustomTrackView::slotRemoveSpace() QRectF rect(pos.frames(m_document->fps()), track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 2 - 2); bool isOk; - QList items = checkForGroups(rect, isOk); + QList items = checkForGroups(rect, &isOk); if (!isOk) { // groups found on track, do not allow the move emit displayMessage(i18n("Cannot remove space in a track with a group"), ErrorMessage); @@ -2330,7 +2465,7 @@ void CustomTrackView::slotInsertSpace() // Make sure there is no group in the way QRectF rect(pos.frames(m_document->fps()), track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 2 - 2); bool isOk; - QList items = checkForGroups(rect, isOk); + QList items = checkForGroups(rect, &isOk); if (!isOk) { // groups found on track, do not allow the move emit displayMessage(i18n("Cannot insert space in a track with a group"), ErrorMessage); @@ -2379,10 +2514,10 @@ void CustomTrackView::insertSpace(QList clipsToMove, QList t if (clip) { if (clip->parentItem()) { m_selectionGroup->addToGroup(clip->parentItem()); - clip->parentItem()->setFlags(QGraphicsItem::ItemIsSelectable); + clip->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } else { m_selectionGroup->addToGroup(clip); - clip->setFlags(QGraphicsItem::ItemIsSelectable); + clip->setFlag(QGraphicsItem::ItemIsMovable, false); } if (trackClipStartList.value(m_document->tracksCount() - clipsToMove.at(i).track) == -1 || clipsToMove.at(i).startPos.frames(m_document->fps()) < trackClipStartList.value(m_document->tracksCount() - clipsToMove.at(i).track)) trackClipStartList[m_document->tracksCount() - clipsToMove.at(i).track] = clipsToMove.at(i).startPos.frames(m_document->fps()); @@ -2395,10 +2530,10 @@ void CustomTrackView::insertSpace(QList clipsToMove, QList t if (transition) { if (transition->parentItem()) { m_selectionGroup->addToGroup(transition->parentItem()); - transition->parentItem()->setFlags(QGraphicsItem::ItemIsSelectable); + transition->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } else { m_selectionGroup->addToGroup(transition); - transition->setFlags(QGraphicsItem::ItemIsSelectable); + transition->setFlag(QGraphicsItem::ItemIsMovable, false); } if (trackTransitionStartList.value(m_document->tracksCount() - transToMove.at(i).track) == -1 || transToMove.at(i).startPos.frames(m_document->fps()) < trackTransitionStartList.value(m_document->tracksCount() - transToMove.at(i).track)) trackTransitionStartList[m_document->tracksCount() - transToMove.at(i).track] = transToMove.at(i).startPos.frames(m_document->fps()); @@ -2586,7 +2721,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (m_operationMode == MOVE) { setCursor(Qt::OpenHandCursor); - + if (m_dragItem) m_dragItem->setZValue(m_dragItem->defaultZValue()); + if (m_selectionGroup) m_selectionGroup->setZValue(1); if (m_dragItem->parentItem() == 0) { // we are moving one clip, easy if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) { @@ -2595,33 +2731,39 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (item->isAudioOnly()) prod = item->baseClip()->audioProducer(m_dragItemInfo.track); else if (item->isVideoOnly()) prod = item->baseClip()->videoProducer(); else prod = item->baseClip()->producer(m_dragItemInfo.track); - bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), prod); + bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), prod, m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT); if (success) { + QUndoCommand *moveCommand = new QUndoCommand(); + moveCommand->setText(i18n("Move clip")); + adjustTimelineClips(m_scene->editMode(), item, moveCommand); + int tracknumber = m_document->tracksCount() - item->track() - 1; bool isLocked = m_document->trackInfoAt(tracknumber).isLocked; if (isLocked) item->setItemLocked(true); - QUndoCommand *moveCommand = new QUndoCommand(); - moveCommand->setText(i18n("Move clip")); new MoveClipCommand(this, m_dragItemInfo, info, false, moveCommand); // Also move automatic transitions (on lower track) - Transition *tr = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track); - if (tr && tr->isAutomatic()) { - ItemInfo trInfo = tr->info(); - ItemInfo newTrInfo = trInfo; - newTrInfo.track = info.track; - newTrInfo.startPos = m_dragItem->startPos(); - if (m_dragItemInfo.track == info.track && !item->baseClip()->isTransparent() && getClipItemAtEnd(newTrInfo.endPos, m_document->tracksCount() - tr->transitionEndTrack())) { + Transition *startTransition = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track); + ItemInfo startTrInfo; + ItemInfo newStartTrInfo; + bool moveStartTrans = false; + bool moveEndTrans = false; + if (startTransition && startTransition->isAutomatic()) { + startTrInfo = startTransition->info(); + newStartTrInfo = startTrInfo; + newStartTrInfo.track = info.track; + newStartTrInfo.startPos = info.startPos; + if (m_dragItemInfo.track == info.track && !item->baseClip()->isTransparent() && getClipItemAtEnd(newStartTrInfo.endPos, m_document->tracksCount() - startTransition->transitionEndTrack())) { // transition end should stay the same } else { // transition end should be adjusted to clip - newTrInfo.endPos = newTrInfo.endPos + (newTrInfo.startPos - trInfo.startPos); + newStartTrInfo.endPos = newStartTrInfo.endPos + (newStartTrInfo.startPos - startTrInfo.startPos); } - if (newTrInfo.startPos < newTrInfo.endPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (newStartTrInfo.startPos < newStartTrInfo.endPos) moveStartTrans = true; } - if (tr == NULL || tr->endPos() < m_dragItemInfo.endPos) { + if (startTransition == NULL || startTransition->endPos() < m_dragItemInfo.endPos) { // Check if there is a transition at clip end - tr = getTransitionItemAtEnd(m_dragItemInfo.endPos, m_dragItemInfo.track); + Transition *tr = getTransitionItemAtEnd(m_dragItemInfo.endPos, m_dragItemInfo.track); if (tr && tr->isAutomatic()) { ItemInfo trInfo = tr->info(); ItemInfo newTrInfo = trInfo; @@ -2633,12 +2775,34 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // transition start should be moved newTrInfo.startPos = newTrInfo.startPos + (newTrInfo.endPos - trInfo.endPos); } - if (newTrInfo.startPos < newTrInfo.endPos) + if (newTrInfo.startPos < newTrInfo.endPos) { + moveEndTrans = true; + if (moveStartTrans) { + // we have to move both transitions, remove the start one so that there is no collision + new AddTransitionCommand(this, startTrInfo, startTransition->transitionEndTrack(), startTransition->toXML(), true, true, moveCommand); + } + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (moveStartTrans) { + // re-add transition in correct place + int transTrack = startTransition->transitionEndTrack(); + if (m_dragItemInfo.track != info.track && !startTransition->forcedTrack()) { + transTrack = getPreviousVideoTrack(info.track); + } + adjustTimelineTransitions(m_scene->editMode(), startTransition, moveCommand); + new AddTransitionCommand(this, newStartTrInfo, transTrack, startTransition->toXML(), false, true, moveCommand); + } + } } } + + if (moveStartTrans && !moveEndTrans) { + adjustTimelineTransitions(m_scene->editMode(), startTransition, moveCommand); + new MoveTransitionCommand(this, startTrInfo, newStartTrInfo, true, moveCommand); + } + // Also move automatic transitions (on upper track) - tr = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track - 1); + Transition *tr = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track - 1); if (m_dragItemInfo.track == info.track && tr && tr->isAutomatic() && (m_document->tracksCount() - tr->transitionEndTrack()) == m_dragItemInfo.track) { ItemInfo trInfo = tr->info(); ItemInfo newTrInfo = trInfo; @@ -2649,7 +2813,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // transition end should be adjusted to clip on upper track newTrInfo.endPos = newTrInfo.endPos + (newTrInfo.startPos - trInfo.startPos); } - if (newTrInfo.startPos < newTrInfo.endPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (newTrInfo.startPos < newTrInfo.endPos) { + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); + new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + } } } if (m_dragItemInfo.track == info.track && (tr == NULL || tr->endPos() < m_dragItemInfo.endPos)) { @@ -2667,11 +2834,15 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // transition start should be moved newTrInfo.startPos = newTrInfo.startPos + (newTrInfo.endPos - trInfo.endPos); } - if (newTrInfo.startPos < newTrInfo.endPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (newTrInfo.startPos < newTrInfo.endPos) { + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); + new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + } } } } m_commandStack->push(moveCommand); + //checkTrackSequence(m_dragItem->track()); } else { // undo last move and emit error message bool snap = KdenliveSettings::snaptopoints(); @@ -2684,14 +2855,17 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } if (m_dragItem->type() == TRANSITIONWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) { Transition *transition = static_cast (m_dragItem); + transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track())); if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) { // Moving transition failed, revert to previous position emit displayMessage(i18n("Cannot move transition"), ErrorMessage); transition->setPos((int) m_dragItemInfo.startPos.frames(m_document->fps()), (m_dragItemInfo.track) * m_tracksHeight + 1); } else { - MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); - m_commandStack->push(command); - transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track())); + QUndoCommand *moveCommand = new QUndoCommand(); + moveCommand->setText(i18n("Move transition")); + adjustTimelineTransitions(m_scene->editMode(), transition, moveCommand); + new MoveTransitionCommand(this, m_dragItemInfo, info, false, moveCommand); + m_commandStack->push(moveCommand); } } } else { @@ -2706,6 +2880,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) GenTime timeOffset = GenTime(m_dragItem->scenePos().x(), m_document->fps()) - m_dragItemInfo.startPos; const int trackOffset = (int)(m_dragItem->scenePos().y() / m_tracksHeight) - m_dragItemInfo.track; //kDebug() << "// MOVED SEVERAL CLIPS" << timeOffset.frames(25); + QUndoCommand *moveGroup = new QUndoCommand(); + moveGroup->setText(i18n("Move group")); if (timeOffset != GenTime() || trackOffset != 0) { // remove items in MLT playlist @@ -2752,10 +2928,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) ClipItem *clip = static_cast (item); info.track = m_document->tracksCount() - info.track; Mlt::Producer *prod; + adjustTimelineClips(m_scene->editMode(), clip, moveGroup); if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track); else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer(); else prod = clip->baseClip()->producer(info.track); - m_document->renderer()->mltInsertClip(info, clip->xml(), prod); + m_document->renderer()->mltInsertClip(info, clip->xml(), prod, m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT); for (int i = 0; i < clip->effectsCount(); i++) { m_document->renderer()->mltAddEffect(info.track, info.startPos, clip->getEffectArgs(clip->effectAt(i)), false); } @@ -2766,12 +2943,13 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) newTrack = getPreviousVideoTrack(info.track); } tr->updateTransitionEndTrack(newTrack); + adjustTimelineTransitions(m_scene->editMode(), tr, moveGroup); m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML()); } } - MoveGroupCommand *move = new MoveGroupCommand(this, clipsToMove, transitionsToMove, timeOffset, trackOffset, false); - m_commandStack->push(move); + new MoveGroupCommand(this, clipsToMove, transitionsToMove, timeOffset, trackOffset, false, moveGroup); + m_commandStack->push(moveGroup); //QPointF top = group->sceneBoundingRect().topLeft(); //QPointF oldpos = m_selectionGroup->scenePos(); @@ -2818,7 +2996,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } ClipItem *clip = static_cast < ClipItem * >(m_dragItem); - updateClipFade(clip); + updatePositionEffects(clip, m_dragItemInfo); // check keyframes QDomDocument doc; @@ -2852,14 +3030,20 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) m_commandStack->push(resizeCommand); } else { + bool snap = KdenliveSettings::snaptopoints(); + KdenliveSettings::setSnaptopoints(false); m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps())); + KdenliveSettings::setSnaptopoints(snap); emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } } else if (m_dragItem->type() == TRANSITIONWIDGET) { Transition *transition = static_cast (m_dragItem); if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) { // Cannot resize transition + bool snap = KdenliveSettings::snaptopoints(); + KdenliveSettings::setSnaptopoints(false); transition->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps())); + KdenliveSettings::setSnaptopoints(snap); emit displayMessage(i18n("Cannot resize transition"), ErrorMessage); } else { MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); @@ -2942,14 +3126,14 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } else new ResizeClipCommand(this, m_dragItemInfo, info, false, false, resizeCommand); m_commandStack->push(resizeCommand); - updateClipFade(clip); + updatePositionEffects(clip, m_dragItemInfo); } else { m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps())); emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } } else if (m_dragItem->type() == TRANSITIONWIDGET) { Transition *transition = static_cast (m_dragItem); - if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) { + if (!m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItemInfo.track), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos)) { // Cannot resize transition transition->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps())); emit displayMessage(i18n("Cannot resize transition"), ErrorMessage); @@ -2974,6 +3158,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // resize fade in effect ClipItem * item = static_cast (m_dragItem); int ix = item->hasEffect("volume", "fadein"); + int ix2 = item->hasEffect("", "fade_from_black"); if (ix != -1) { QDomElement oldeffect = item->effectAt(ix); int start = item->cropStart().frames(m_document->fps()); @@ -2988,14 +3173,17 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) slotUpdateClipEffect(item, effect, oldeffect, ix); emit clipItemSelected(item, ix); } - } else if (item->fadeIn() != 0 && item->hasEffect("", "fade_from_black") == -1) { - QDomElement effect = MainWindow::audioEffects.getEffectByTag("volume", "fadein").cloneNode().toElement(); + } else if (item->fadeIn() != 0 && ix2 == -1) { + QDomElement effect; + if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) { + // add video fade + effect = MainWindow::videoEffects.getEffectByTag("", "fade_from_black").cloneNode().toElement(); + } else effect = MainWindow::audioEffects.getEffectByTag("volume", "fadein").cloneNode().toElement(); EffectsList::setParameter(effect, "out", QString::number(item->fadeIn())); slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track()); } - ix = item->hasEffect("volume", "fade_from_black"); - if (ix != -1) { - QDomElement oldeffect = item->effectAt(ix); + if (ix2 != -1) { + QDomElement oldeffect = item->effectAt(ix2); int start = item->cropStart().frames(m_document->fps()); int end = item->fadeIn(); if (end == 0) { @@ -3005,14 +3193,15 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) QDomElement effect = oldeffect.cloneNode().toElement(); EffectsList::setParameter(oldeffect, "in", QString::number(start)); EffectsList::setParameter(oldeffect, "out", QString::number(end)); - slotUpdateClipEffect(item, effect, oldeffect, ix); - emit clipItemSelected(item, ix); + slotUpdateClipEffect(item, effect, oldeffect, ix2); + emit clipItemSelected(item, ix2); } } } else if (m_operationMode == FADEOUT) { // resize fade in effect ClipItem * item = static_cast (m_dragItem); int ix = item->hasEffect("volume", "fadeout"); + int ix2 = item->hasEffect("", "fade_to_black"); if (ix != -1) { QDomElement oldeffect = item->effectAt(ix); int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps()); @@ -3028,15 +3217,18 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) slotUpdateClipEffect(item, effect, oldeffect, ix); emit clipItemSelected(item, ix); } - } else if (item->fadeOut() != 0 && item->hasEffect("", "fade_to_black") == -1) { - QDomElement effect = MainWindow::audioEffects.getEffectByTag("volume", "fadeout").cloneNode().toElement(); + } else if (item->fadeOut() != 0 && ix2 == -1) { + QDomElement effect; + if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) { + // add video fade + effect = MainWindow::videoEffects.getEffectByTag("", "fade_to_black").cloneNode().toElement(); + } else effect = MainWindow::audioEffects.getEffectByTag("volume", "fadeout").cloneNode().toElement(); EffectsList::setParameter(effect, "in", QString::number(item->fadeOut())); EffectsList::setParameter(effect, "out", QString::number(0)); slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track()); } - ix = item->hasEffect("brightness", "fade_to_black"); - if (ix != -1) { - QDomElement oldeffect = item->effectAt(ix); + if (ix2 != -1) { + QDomElement oldeffect = item->effectAt(ix2); int end = (item->cropDuration() + item->cropStart()).frames(m_document->fps()); int start = item->fadeOut(); if (start == 0) { @@ -3047,8 +3239,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) EffectsList::setParameter(oldeffect, "in", QString::number(start)); EffectsList::setParameter(oldeffect, "out", QString::number(end)); // kDebug()<<"EDIT FADE OUT : "<removeItem(item); +#if QT_VERSION >= 0x040600 + // animate item deletion + item->closeAnimation(); +#else delete item; item = NULL; +#endif + setDocumentModified(); if (refresh) m_document->renderer()->doRefresh(); } @@ -3203,7 +3400,7 @@ void CustomTrackView::changeClipSpeed() else delete changeSelected; } -void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, int strobe, const QString &id) +void CustomTrackView::doChangeClipSpeed(ItemInfo info, ItemInfo speedIndependantInfo, const double speed, const double oldspeed, int strobe, const QString &id) { DocClipBase *baseclip = m_document->clipManager()->getClipById(id); ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track); @@ -3213,13 +3410,14 @@ void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const return; } info.track = m_document->tracksCount() - item->track(); - int endPos = m_document->renderer()->mltChangeClipSpeed(info, speed, oldspeed, strobe, baseclip->producer()); + int endPos = m_document->renderer()->mltChangeClipSpeed(info, speedIndependantInfo, speed, oldspeed, strobe, baseclip->producer()); if (endPos >= 0) { item->setSpeed(speed, strobe); item->updateRectGeometry(); - if (item->cropDuration().frames(m_document->fps()) > endPos) - item->AbstractClipItem::resizeEnd(info.startPos.frames(m_document->fps()) + endPos, speed); - updateClipFade(item); + if (item->cropDuration().frames(m_document->fps()) != endPos) { + item->resizeEnd((int) info.startPos.frames(m_document->fps()) + endPos - 1); + } + updatePositionEffects(item, info); setDocumentModified(); } else emit displayMessage(i18n("Invalid clip"), ErrorMessage); } @@ -3284,7 +3482,7 @@ void CustomTrackView::doGroupClips(QList clipInfos, QList m_document->clipManager()->removeGroup(grp); scene()->destroyItemGroup(grp); } - clip->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + clip->setFlag(QGraphicsItem::ItemIsMovable, true); } for (int i = 0; i < transitionInfos.count(); i++) { Transition *tr = getTransitionItemAt(transitionInfos.at(i).startPos, transitionInfos.at(i).track); @@ -3294,7 +3492,7 @@ void CustomTrackView::doGroupClips(QList clipInfos, QList m_document->clipManager()->removeGroup(grp); scene()->destroyItemGroup(grp); } - tr->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + tr->setFlag(QGraphicsItem::ItemIsMovable, true); } setDocumentModified(); return; @@ -3540,10 +3738,10 @@ void CustomTrackView::moveGroup(QList startClip, QList sta clip->setItemLocked(false); if (clip->parentItem()) { m_selectionGroup->addToGroup(clip->parentItem()); - clip->parentItem()->setFlags(QGraphicsItem::ItemIsSelectable); + clip->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } else { m_selectionGroup->addToGroup(clip); - clip->setFlags(QGraphicsItem::ItemIsSelectable); + clip->setFlag(QGraphicsItem::ItemIsMovable, false); } m_document->renderer()->mltRemoveClip(m_document->tracksCount() - startClip.at(i).track, startClip.at(i).startPos); } else kDebug() << "//MISSING CLIP AT: " << startClip.at(i).startPos.frames(25); @@ -3558,10 +3756,10 @@ void CustomTrackView::moveGroup(QList startClip, QList sta tr->setItemLocked(false); if (tr->parentItem()) { m_selectionGroup->addToGroup(tr->parentItem()); - tr->parentItem()->setFlags(QGraphicsItem::ItemIsSelectable); + tr->parentItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } else { m_selectionGroup->addToGroup(tr); - tr->setFlags(QGraphicsItem::ItemIsSelectable); + tr->setFlag(QGraphicsItem::ItemIsMovable, false); } m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_document->tracksCount() - startTransition.at(i).track, startTransition.at(i).startPos, startTransition.at(i).endPos, tr->toXML()); } else kDebug() << "//MISSING TRANSITION AT: " << startTransition.at(i).startPos.frames(25); @@ -3581,7 +3779,7 @@ void CustomTrackView::moveGroup(QList startClip, QList sta for (int i = 0; i < max; i++) { if (children.at(i)->type() == GROUPWIDGET) { children += children.at(i)->childItems(); - AbstractGroupItem *grp = static_cast(children.at(i)); + //AbstractGroupItem *grp = static_cast(children.at(i)); //grp->moveBy(offset.frames(m_document->fps()), trackOffset *(qreal) m_tracksHeight); /*m_document->clipManager()->removeGroup(grp); m_scene->destroyItemGroup(grp);*/ @@ -3609,17 +3807,15 @@ void CustomTrackView::moveGroup(QList startClip, QList sta else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer(); else prod = clip->baseClip()->producer(info.track); m_document->renderer()->mltInsertClip(info, clip->xml(), prod); - kDebug() << "// inserting new clp: " << info.startPos.frames(25); } else if (item->type() == TRANSITIONWIDGET) { Transition *tr = static_cast (item); - int newTrack = tr->transitionEndTrack(); - kDebug() << "/// TRANSITION CURR TRK: " << newTrack; - if (!tr->forcedTrack()) { - newTrack += trackOffset; + int newTrack; + if (!tr->forcedTrack()) newTrack = getPreviousVideoTrack(info.track); + else { + newTrack = tr->transitionEndTrack() + trackOffset; if (newTrack < 0 || newTrack > m_document->tracksCount()) newTrack = getPreviousVideoTrack(info.track); } tr->updateTransitionEndTrack(newTrack); - kDebug() << "/// TRANSITION UPDATED TRK: " << newTrack; m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML()); } } @@ -3673,6 +3869,7 @@ void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end, b emit transitionItemSelected(item, getPreviousVideoTrack(item->track()), p); } if (m_refresh) m_document->renderer()->doRefresh(); + setDocumentModified(); } void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool dontWorry) @@ -3699,7 +3896,7 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool if (success) { kDebug() << "RESIZE CLP STRAT TO:" << end.startPos.frames(m_document->fps()) << ", OLD ST: " << start.startPos.frames(25); item->resizeStart((int) end.startPos.frames(m_document->fps())); - updateClipFade(item); + updatePositionEffects(item, clipinfo); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } else { ItemInfo clipinfo = item->info(); @@ -3707,7 +3904,7 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, end.endPos - clipinfo.startPos); if (success) { item->resizeEnd((int) end.endPos.frames(m_document->fps())); - updateClipFade(item); + updatePositionEffects(item, clipinfo); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } if (!resizeClipStart && end.cropStart != start.cropStart) { @@ -3722,9 +3919,10 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool } m_document->renderer()->doRefresh(); KdenliveSettings::setSnaptopoints(snap); + setDocumentModified(); } -void CustomTrackView::updateClipFade(ClipItem * item) +void CustomTrackView::updatePositionEffects(ClipItem * item, ItemInfo info) { int end = item->fadeIn(); if (end != 0) { @@ -3806,6 +4004,20 @@ void CustomTrackView::updateClipFade(ClipItem * item) if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos); } } + + int effectPos = item->hasEffect("freeze", "freeze"); + if (effectPos != -1) { + // Freeze effect needs to be adjusted with clip resize + int diff = (info.startPos - item->startPos()).frames(m_document->fps()); + QDomElement eff = item->getEffectAt(effectPos); + if (!eff.isNull() && diff != 0) { + int freeze_pos = EffectsList::parameter(eff, "frame").toInt() + diff; + EffectsList::setParameter(eff, "frame", QString::number(freeze_pos)); + if (item->isSelected() && item->selectedEffect().attribute("id") == "freeze") { + emit clipItemSelected(item, item->selectedEffectIndex()); + } + } + } } double CustomTrackView::getSnapPointForPos(double pos) @@ -4107,12 +4319,14 @@ void CustomTrackView::setScale(double scaleFactor, double verticalScale) QMatrix matrix; matrix = matrix.scale(scaleFactor, verticalScale); m_scene->setScale(scaleFactor, verticalScale); - if (m_visualTip) scene()->removeItem(m_visualTip); - m_animationTimer->stop(); - delete m_visualTip; - m_visualTip = NULL; - delete m_animation; - m_animation = NULL; + if (m_visualTip) { + scene()->removeItem(m_visualTip); + m_animationTimer->stop(); + delete m_animation; + m_animation = NULL; + delete m_visualTip; + m_visualTip = NULL; + } double verticalPos = mapToScene(QPoint(0, viewport()->height() / 2)).y(); setMatrix(matrix); m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_document->tracksCount() * verticalScale); @@ -4144,15 +4358,16 @@ void CustomTrackView::drawBackground(QPainter * painter, const QRectF &rect) double min = rect.left(); double max = rect.right(); painter->drawLine(QPointF(min, 0), QPointF(max, 0)); - uint maxTrack = m_document->tracksCount(); + int maxTrack = m_document->tracksCount(); QColor lockedColor = scheme.background(KColorScheme::NegativeBackground).color(); QColor audioColor = palette().alternateBase().color(); QColor base = scheme.background(KColorScheme::NormalBackground).color(); - for (uint i = 0; i < maxTrack; i++) { + for (int i = 0; i < maxTrack; i++) { TrackInfo info = m_document->trackInfoAt(maxTrack - i - 1); - if (info.isLocked || info.type == AUDIOTRACK) { + if (info.isLocked || info.type == AUDIOTRACK || i == m_selectedTrack) { const QRectF track(min, m_tracksHeight * i + 1, max - min, m_tracksHeight - 1); - painter->fillRect(track, info.isLocked ? lockedColor : audioColor); + if (i == m_selectedTrack) painter->fillRect(track, scheme.background(KColorScheme::ActiveBackground).color()); + else painter->fillRect(track, info.isLocked ? lockedColor : audioColor); } painter->drawLine(QPointF(min, m_tracksHeight *(i + 1)), QPointF(max, m_tracksHeight *(i + 1))); } @@ -4252,6 +4467,10 @@ void CustomTrackView::copyClip() bool CustomTrackView::canBePastedTo(ItemInfo info, int type) const { + if (m_scene->editMode() != NORMALEDIT) { + // If we are in overwrite mode, always allow the move + return true; + } QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double)(m_tracksHeight - 1)); QList collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect); for (int i = 0; i < collisions.count(); i++) { @@ -4358,10 +4577,13 @@ void CustomTrackView::pasteClip() info.startPos = tr->startPos() + offset; info.endPos = tr->endPos() + offset; info.track = tr->track() + trackOffset; + int transitionEndTrack; + if (!tr->forcedTrack()) transitionEndTrack = getPreviousVideoTrack(info.track); + else transitionEndTrack = tr->transitionEndTrack(); if (canBePastedTo(info, TRANSITIONWIDGET)) { if (info.startPos >= info.endPos) { emit displayMessage(i18n("Invalid transition"), ErrorMessage); - } else new AddTransitionCommand(this, info, tr->transitionEndTrack() + trackOffset, tr->toXML(), false, true, pasteClips); + } else new AddTransitionCommand(this, info, transitionEndTrack, tr->toXML(), false, true, pasteClips); } else emit displayMessage(i18n("Cannot paste transition to selected place"), ErrorMessage); } } @@ -4384,11 +4606,20 @@ void CustomTrackView::pasteClipEffects() if (clips.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast < ClipItem *>(clips.at(i)); for (int j = 0; j < clip->effectsCount(); j++) { - new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), clip->effectAt(j), true, paste); + QDomElement eff = clip->effectAt(j); + if (eff.attribute("unique", "0") == "0" || item->hasEffect(eff.attribute("tag"), eff.attribute("id")) == -1) { + new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), eff, true, paste); + } } } } m_commandStack->push(paste); + + // adjust effects (fades, ...) + for (int i = 0; i < clips.count(); ++i) { + ClipItem *item = static_cast < ClipItem *>(clips.at(i)); + updatePositionEffects(item, item->info()); + } } @@ -4460,7 +4691,7 @@ void CustomTrackView::setInPoint() ItemInfo startInfo = clip->info(); ItemInfo endInfo = startInfo; endInfo.startPos = GenTime(m_cursorPos, m_document->fps()); - if (endInfo.startPos >= startInfo.endPos) { + if (endInfo.startPos >= startInfo.endPos || endInfo.startPos < startInfo.startPos - startInfo.cropStart) { // Check for invalid resize emit displayMessage(i18n("Invalid action"), ErrorMessage); return; @@ -4491,13 +4722,15 @@ void CustomTrackView::setOutPoint() ItemInfo startInfo = clip->info(); ItemInfo endInfo = clip->info(); endInfo.endPos = GenTime(m_cursorPos, m_document->fps()); - if (endInfo.endPos <= startInfo.startPos) { + CLIPTYPE type = (CLIPTYPE) static_cast (clip)->clipType(); + if (endInfo.endPos <= startInfo.startPos || (type != IMAGE && type != COLOR && type != TEXT && endInfo.endPos > startInfo.startPos + clip->maxDuration() - startInfo.cropStart)) { // Check for invalid resize emit displayMessage(i18n("Invalid action"), ErrorMessage); return; } else if (endInfo.endPos > startInfo.endPos) { - int length = m_document->renderer()->mltGetSpaceLength(endInfo.endPos, m_document->tracksCount() - startInfo.track, false); - if ((clip->type() == TRANSITIONWIDGET && itemCollision(clip, endInfo) == true) || (clip->type() == AVWIDGET && length < (endInfo.endPos - startInfo.endPos).frames(m_document->fps()))) { + int length = m_document->renderer()->mltGetSpaceLength(startInfo.endPos, m_document->tracksCount() - startInfo.track, false); + if ((clip->type() == TRANSITIONWIDGET && itemCollision(clip, endInfo) == true) || (clip->type() == AVWIDGET && length != -1 && length < (endInfo.endPos - startInfo.endPos).frames(m_document->fps()))) { + kDebug() << " RESIZE ERROR, BLNK: " << length << ", RESIZE: " << (endInfo.endPos - startInfo.endPos).frames(m_document->fps()); emit displayMessage(i18n("Invalid action"), ErrorMessage); return; } @@ -4529,8 +4762,8 @@ void CustomTrackView::slotUpdateAllThumbs() } else { QString startThumb = thumbBase + item->baseClip()->getClipHash() + '_'; QString endThumb = startThumb; - startThumb.append(QString::number(item->cropStart().frames(m_document->fps())) + ".png"); - endThumb.append(QString::number((item->cropStart() + item->cropDuration()).frames(m_document->fps()) - 1) + ".png"); + startThumb.append(QString::number(item->speedIndependantCropStart().frames(m_document->fps())) + ".png"); + endThumb.append(QString::number((item->speedIndependantCropStart() + item->speedIndependantCropDuration()).frames(m_document->fps()) - 1) + ".png"); if (QFile::exists(startThumb)) { QPixmap pix(startThumb); item->slotSetStartThumb(pix); @@ -4567,8 +4800,8 @@ void CustomTrackView::saveThumbnails() } else { QString startThumb = thumbBase + item->baseClip()->getClipHash() + '_'; QString endThumb = startThumb; - startThumb.append(QString::number(item->cropStart().frames(m_document->fps())) + ".png"); - endThumb.append(QString::number((item->cropStart() + item->cropDuration()).frames(m_document->fps()) - 1) + ".png"); + startThumb.append(QString::number(item->speedIndependantCropStart().frames(m_document->fps())) + ".png"); + endThumb.append(QString::number((item->speedIndependantCropStart() + item->speedIndependantCropDuration()).frames(m_document->fps()) - 1) + ".png"); if (!QFile::exists(startThumb)) { QPixmap pix(item->startThumb()); pix.save(startThumb); @@ -4718,6 +4951,7 @@ void CustomTrackView::autoTransition() tr->setAutomatic(!tr->isAutomatic()); QDomElement transition = tr->toXML(); m_document->renderer()->mltUpdateTransition(transition.attribute("tag"), transition.attribute("tag"), transition.attribute("transition_btrack").toInt(), m_document->tracksCount() - transition.attribute("transition_atrack").toInt(), tr->startPos(), tr->endPos(), transition); + setDocumentModified(); } @@ -4901,7 +5135,7 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, bool split) break; } } - clip->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + clip->setFlag(QGraphicsItem::ItemIsMovable, true); m_document->clipManager()->removeGroup(grp); scene()->destroyItemGroup(grp); } @@ -5111,7 +5345,7 @@ void CustomTrackView::updateProjectFps() for (int j = 0; j < children.count(); j++) { if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) { AbstractClipItem *clip = static_cast (children.at(j)); - clip->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + clip->setFlag(QGraphicsItem::ItemIsMovable, true); clip->updateFps(m_document->fps()); } } @@ -5133,3 +5367,114 @@ void CustomTrackView::updateProjectFps() } viewport()->update(); } + +void CustomTrackView::slotTrackDown() +{ + if (m_selectedTrack > m_document->tracksCount() - 2) m_selectedTrack = 0; + else m_selectedTrack++; + emit updateTrackHeaders(); + QRectF rect(mapToScene(QPoint()).x(), m_selectedTrack * m_tracksHeight, 10, m_tracksHeight); + ensureVisible(rect); + viewport()->update(); +} + +void CustomTrackView::slotTrackUp() +{ + if (m_selectedTrack > 0) m_selectedTrack--; + else m_selectedTrack = m_document->tracksCount() - 1; + emit updateTrackHeaders(); + QRectF rect(mapToScene(QPoint()).x(), m_selectedTrack * m_tracksHeight, 10, m_tracksHeight); + ensureVisible(rect); + viewport()->update(); +} + +int CustomTrackView::selectedTrack() const +{ + return m_selectedTrack; +} + +void CustomTrackView::slotSelectTrack(int ix) +{ + m_selectedTrack = qMax(0, ix); + m_selectedTrack = qMin(ix, m_document->tracksCount() - 1); + emit updateTrackHeaders(); + QRectF rect(mapToScene(QPoint()).x(), m_selectedTrack * m_tracksHeight, 10, m_tracksHeight); + ensureVisible(rect); + viewport()->update(); +} + +void CustomTrackView::selectClip(bool add, bool group) +{ + QRectF rect(m_cursorPos, m_selectedTrack * m_tracksHeight + m_tracksHeight / 2, 1, 1); + QList selection = m_scene->items(rect); + resetSelectionGroup(group); + if (!group) m_scene->clearSelection(); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET) { + selection.at(i)->setSelected(add); + break; + } + } + if (group) groupSelectedItems(); +} + +void CustomTrackView::selectTransition(bool add, bool group) +{ + QRectF rect(m_cursorPos, m_selectedTrack * m_tracksHeight + m_tracksHeight, 1, 1); + QList selection = m_scene->items(rect); + resetSelectionGroup(group); + if (!group) m_scene->clearSelection(); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == TRANSITIONWIDGET) { + selection.at(i)->setSelected(add); + break; + } + } + if (group) groupSelectedItems(); +} + +QStringList CustomTrackView::extractTransitionsLumas() +{ + QStringList urls; + QList itemList = items(); + Transition *transitionitem; + QDomElement transitionXml; + for (int i = 0; i < itemList.count(); i++) { + if (itemList.at(i)->type() == TRANSITIONWIDGET) { + transitionitem = static_cast (itemList.at(i)); + transitionXml = transitionitem->toXML(); + QString luma = EffectsList::parameter(transitionXml, "luma"); + if (!luma.isEmpty()) urls << luma; + } + } + return urls; +} + +void CustomTrackView::setEditMode(EDITMODE mode) +{ + m_scene->setEditMode(mode); +} + +void CustomTrackView::checkTrackSequence(int track) +{ + QList times = m_document->renderer()->checkTrackSequence(m_document->tracksCount() - track); + //track = m_document->tracksCount() -track; + QRectF rect(0, track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width(), 2); + QList selection = m_scene->items(rect); + QList timelineList; + timelineList.append(0); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET) { + ClipItem *clip = static_cast (selection.at(i)); + int start = clip->startPos().frames(m_document->fps()); + int end = clip->endPos().frames(m_document->fps()); + if (!timelineList.contains(start)) timelineList.append(start); + if (!timelineList.contains(end)) timelineList.append(end); + } + } + qSort(timelineList); + kDebug() << "// COMPARE:\n" << times << "\n" << timelineList << "\n-------------------"; + if (times != timelineList) KMessageBox::sorry(this, i18n("error"), i18n("TRACTOR")); +} + +