]> git.sesse.net Git - kdenlive/blobdiff - src/customtrackview.cpp
Fix spacer and group move sometimes moving clips to wrong place:
[kdenlive] / src / customtrackview.cpp
index af1568969f157f6c2c4aa5878e2f661d43c0b0a7..69d903dd5901a30502301d3953654437251a54b4 100644 (file)
@@ -510,6 +510,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) {
 
 // virtual
 void CustomTrackView::mousePressEvent(QMouseEvent * event) {
+    kDebug() << "mousePressEvent STARTED";
     m_menuPosition = QPoint();
     m_blockRefresh = true;
     bool collision = false;
@@ -610,25 +611,27 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) {
             if (event->modifiers() == Qt::ControlModifier) {
                 // Ctrl + click, select all items on track after click position
                 int track = (int)(mapToScene(m_clickEvent).y() / m_tracksHeight);
-                selection = items(m_clickEvent.x(), track * m_tracksHeight + 1, sceneRect().width() - m_clickEvent.x(), m_tracksHeight - 2);
+                selection = items(m_clickEvent.x(), track * m_tracksHeight + m_tracksHeight / 2, mapFromScene(sceneRect().width(), 0).x() - m_clickEvent.x(), m_tracksHeight / 2 - 2);
+
+                kDebug() << "SPACER TOOL + CTRL, SELECTING ALL CLIPS ON TRACK " << track << " WITH SELECTION RECT " << m_clickEvent.x() << "/" <<  track * m_tracksHeight + 1 << "; " << mapFromScene(sceneRect().width(), 0).x() - m_clickEvent.x() << "/" << m_tracksHeight - 2;
             } else {
                 // Select all items on all tracks after click position
-                selection = items(event->pos().x(), 1, sceneRect().width() - event->pos().x(), sceneRect().height());
+                selection = items(event->pos().x(), 1, mapFromScene(sceneRect().width(), 0).x() - event->pos().x(), sceneRect().height());
+                kDebug() << "SELELCTING ELEMENTS WITHIN =" << event->pos().x() << "/" <<  1 << ", " << mapFromScene(sceneRect().width(), 0).x() - event->pos().x() << "/" << sceneRect().height();
             }
-            m_selectionGroup = new AbstractGroupItem(m_document->fps());
-            scene()->addItem(m_selectionGroup);
+
+            resetSelectionGroup(false);
+            m_scene->clearSelection();
 
             for (int i = 0; i < selection.count(); i++) {
                 if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) {
-                    m_selectionGroup->addToGroup(selection.at(i));
-                    selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable);
+                    selection.at(i)->setSelected(true);
                 }
             }
-            QPointF top = m_selectionGroup->boundingRect().topLeft();
-            m_selectionGroup->setPos(top);
-            m_selectionGroup->translate(-top.x(), -top.y() + 1);
+            groupSelectedItems(true);
             m_operationMode = SPACER;
         } else setCursorPos((int)(mapToScene(event->x(), 0).x()));
+        kDebug() << "END mousePress EVENT ";
         return;
     }
 
@@ -712,7 +715,21 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) {
             info.endPos = transitionClip->endPos();
         } else info.endPos = info.startPos + GenTime(65, m_document->fps());
         if (info.endPos == info.startPos) info.endPos = info.startPos + GenTime(65, m_document->fps());
-        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
+        // Check there is no other transition at that place
+        double startY = info.track * m_tracksHeight + 1 + m_tracksHeight / 2;
+        QRectF r(info.startPos.frames(m_document->fps()), startY, (info.endPos - info.startPos).frames(m_document->fps()), m_tracksHeight / 2);
+        QList<QGraphicsItem *> selection = m_scene->items(r);
+        bool transitionAccepted = true;
+        for (int i = 0; i < selection.count(); i++) {
+            if (selection.at(i)->type() == TRANSITIONWIDGET) {
+                Transition *tr = static_cast <Transition *>(selection.at(i));
+                if (tr->startPos() - info.startPos > GenTime(5, m_document->fps())) {
+                    if (tr->startPos() < info.endPos) info.endPos = tr->startPos();
+                } else transitionAccepted = false;
+            }
+        }
+        if (transitionAccepted) slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack);
+        else emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
     } else if (m_operationMode == TRANSITIONEND) {
         ItemInfo info;
         info.endPos = GenTime(m_dragItem->endPos().frames(m_document->fps()), m_document->fps());
@@ -726,7 +743,23 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) {
         if (info.endPos == info.startPos) info.startPos = info.endPos - GenTime(65, m_document->fps());
         QDomElement transition = MainWindow::transitions.getEffectByName("Luma").cloneNode().toElement();
         EffectsList::setParameter(transition, "reverse", "1");
-        slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack, transition);
+
+        // Check there is no other transition at that place
+        double startY = info.track * m_tracksHeight + 1 + m_tracksHeight / 2;
+        QRectF r(info.startPos.frames(m_document->fps()), startY, (info.endPos - info.startPos).frames(m_document->fps()), m_tracksHeight / 2);
+        QList<QGraphicsItem *> selection = m_scene->items(r);
+        bool transitionAccepted = true;
+        for (int i = 0; i < selection.count(); i++) {
+            if (selection.at(i)->type() == TRANSITIONWIDGET) {
+                Transition *tr = static_cast <Transition *>(selection.at(i));
+                if (info.endPos - tr->endPos() > GenTime(5, m_document->fps())) {
+                    if (tr->endPos() > info.startPos) info.startPos = tr->endPos();
+                } else transitionAccepted = false;
+            }
+        }
+        if (transitionAccepted) slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack, transition);
+        else emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+
     } else if ((m_operationMode == RESIZESTART || m_operationMode == RESIZEEND) && m_selectionGroup) {
         resetSelectionGroup(false);
         m_dragItem->setSelected(true);
@@ -743,24 +776,32 @@ void CustomTrackView::resetSelectionGroup(bool selectItems) {
         bool snap = KdenliveSettings::snaptopoints();
         KdenliveSettings::setSnaptopoints(false);
         QList<QGraphicsItem *> children = m_selectionGroup->childItems();
+        scene()->destroyItemGroup(m_selectionGroup);
         for (int i = 0; i < children.count(); i++) {
             children.at(i)->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
             children.at(i)->setSelected(selectItems);
         }
-        scene()->destroyItemGroup(m_selectionGroup);
         m_selectionGroup = NULL;
         KdenliveSettings::setSnaptopoints(snap);
     }
 }
 
-void CustomTrackView::groupSelectedItems() {
+void CustomTrackView::groupSelectedItems(bool force) {
     if (m_selectionGroup) {
         kDebug() << "///// ERROR, TRYING TO OVERRIDE EXISTING GROUP";
         return;
     }
     QList<QGraphicsItem *> selection = m_scene->selectedItems();
-    if (selection.count() > 1) {
+    QGraphicsItemGroup *group = m_scene->createItemGroup(selection);
+    scene()->addItem(group);
+    QPointF top = group->sceneBoundingRect().topLeft();
+    m_scene->destroyItemGroup(group);
+    if (force || selection.count() > 1) {
+        bool snap = KdenliveSettings::snaptopoints();
+        KdenliveSettings::setSnaptopoints(false);
         m_selectionGroup = new AbstractGroupItem(m_document->fps());
+        m_selectionGroup->translate(-top.x(), -top.y() + 1);
+        m_selectionGroup->setPos(top.x(), top.y() - 1);
         scene()->addItem(m_selectionGroup);
         for (int i = 0; i < selection.count(); i++) {
             if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) {
@@ -768,16 +809,19 @@ void CustomTrackView::groupSelectedItems() {
                 selection.at(i)->setFlags(QGraphicsItem::ItemIsSelectable);
             }
         }
+        KdenliveSettings::setSnaptopoints(snap);
 
         if (m_selectionGroup) {
-            bool snap = KdenliveSettings::snaptopoints();
+            /*bool snap = KdenliveSettings::snaptopoints();
             KdenliveSettings::setSnaptopoints(false);
             QPointF top = m_selectionGroup->sceneBoundingRect().topLeft();
-            m_selectionGroup->translate(-top.x(), -top.y() + 1);
-            m_selectionGroup->setPos(top);
+            // kDebug()<<"SEL GRP TOP: "<<top;
+            // Fix group item position
+            m_selectionGroup->translate(-top.x(), -top.y());
+            m_selectionGroup->setPos(top);*/
             m_selectionGroupInfo.startPos = GenTime(m_selectionGroup->scenePos().x(), m_document->fps());
             m_selectionGroupInfo.track = m_selectionGroup->track();
-            KdenliveSettings::setSnaptopoints(snap);
+            //KdenliveSettings::setSnaptopoints(snap);
         }
     } else resetSelectionGroup();
 }
@@ -896,7 +940,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) {
         info.cropStart = GenTime(list.at(1).toInt(), m_document->fps());
         info.endPos = info.startPos + GenTime(list.at(2).toInt() - list.at(1).toInt(), m_document->fps());
         info.track = (int)(pos.y() / m_tracksHeight);
-        ClipItem *item = new ClipItem(clip, info, m_document->fps());
+        ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0);
         m_selectionGroup->addToGroup(item);
         //TODO: check if we do not overlap another clip when first dropping in timeline
         // if (insertPossible(m_selectionGroup, event->pos()))
@@ -916,7 +960,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) {
             info.startPos = GenTime(pos.x(), m_document->fps());
             info.endPos = info.startPos + clip->duration();
             info.track = (int)(pos.y() / m_tracksHeight);
-            ClipItem *item = new ClipItem(clip, info, m_document->fps());
+            ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0);
             pos.setX(pos.x() + clip->duration().frames(m_document->fps()));
             m_selectionGroup->addToGroup(item);
         }
@@ -961,7 +1005,7 @@ bool CustomTrackView::insertPossible(AbstractGroupItem *group, const QPoint &pos
 void CustomTrackView::slotRefreshEffects(ClipItem *clip) {
     int track = m_document->tracksCount() - clip->track();
     GenTime pos = clip->startPos();
-    if (!m_document->renderer()->mltRemoveEffect(track, pos, "-1", false)) {
+    if (!m_document->renderer()->mltRemoveEffect(track, pos, "-1", false, false)) {
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
         return;
     }
@@ -984,7 +1028,8 @@ void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) {
 
 void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) {
     QString index = effect.attribute("kdenlive_ix");
-    if (effect.attribute("disabled") != "1" && !m_document->renderer()->mltRemoveEffect(track, pos, index)) {
+    if (!m_document->renderer()->mltRemoveEffect(track, pos, index, true) && effect.attribute("disabled") != "1") {
+        kDebug() << "// ERROR REMOV EFFECT: " << index << ", DISABLE: " << effect.attribute("disabled");
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
         return;
     }
@@ -1041,7 +1086,7 @@ void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, i
             effectParams = clip->getEffectArgs(effect);
         }
         if (effectParams.paramValue("disabled") == "1") {
-            if (m_document->renderer()->mltRemoveEffect(track, pos, effectParams.paramValue("kdenlive_ix"))) {
+            if (m_document->renderer()->mltRemoveEffect(track, pos, effectParams.paramValue("kdenlive_ix"), false)) {
                 kDebug() << "//////  DISABLING EFFECT: " << index << ", CURRENTLA: " << clip->selectedEffectIndex();
             } else emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
         } else if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - clip->track(), clip->startPos(), effectParams))
@@ -1190,6 +1235,22 @@ void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition) {
                 if (transitionClip && transitionClip->endPos() < item->endPos()) {
                     info.endPos = transitionClip->endPos();
                 } else 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;
+                QRectF r(info.startPos.frames(m_document->fps()), startY, (info.endPos - info.startPos).frames(m_document->fps()), m_tracksHeight / 2);
+                QList<QGraphicsItem *> selection = m_scene->items(r);
+                bool transitionAccepted = true;
+                for (int i = 0; i < selection.count(); i++) {
+                    if (selection.at(i)->type() == TRANSITIONWIDGET) {
+                        Transition *tr = static_cast <Transition *>(selection.at(i));
+                        if (tr->startPos() - info.startPos > GenTime(5, m_document->fps())) {
+                            if (tr->startPos() < info.endPos) info.endPos = tr->startPos();
+                        } else transitionAccepted = false;
+                    }
+                }
+                if (transitionAccepted) slotAddTransition(item, info, transitiontrack, transition);
+                else emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+
             } else {
                 // add transition to clip  end
                 info.endPos = item->endPos();
@@ -1198,8 +1259,23 @@ void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition) {
                     info.startPos = transitionClip->startPos();
                 } else info.startPos = info.endPos - GenTime(65, m_document->fps());
                 if (transition.attribute("tag") == "luma") EffectsList::setParameter(transition, "reverse", "1");
+
+                // Check there is no other transition at that place
+                double startY = info.track * m_tracksHeight + 1 + m_tracksHeight / 2;
+                QRectF r(info.startPos.frames(m_document->fps()), startY, (info.endPos - info.startPos).frames(m_document->fps()), m_tracksHeight / 2);
+                QList<QGraphicsItem *> selection = m_scene->items(r);
+                bool transitionAccepted = true;
+                for (int i = 0; i < selection.count(); i++) {
+                    if (selection.at(i)->type() == TRANSITIONWIDGET) {
+                        Transition *tr = static_cast <Transition *>(selection.at(i));
+                        if (info.endPos - tr->endPos() > GenTime(5, m_document->fps())) {
+                            if (tr->endPos() > info.startPos) info.startPos = tr->endPos();
+                        } else transitionAccepted = false;
+                    }
+                }
+                if (transitionAccepted) slotAddTransition(item, info, transitiontrack, transition);
+                else emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
             }
-            slotAddTransition(item, info, transitiontrack, transition);
         }
     } else for (int i = 0; i < itemList.count(); i++) {
             if (itemList.at(i)->type() == AVWIDGET) {
@@ -1208,13 +1284,32 @@ void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition) {
                 info.startPos = item->startPos();
                 info.endPos = info.startPos + GenTime(65, m_document->fps());
                 info.track = item->track();
+
+                // Check there is no other transition at that place
+                double startY = info.track * m_tracksHeight + 1 + m_tracksHeight / 2;
+                QRectF r(info.startPos.frames(m_document->fps()), startY, (info.endPos - info.startPos).frames(m_document->fps()), m_tracksHeight / 2);
+                QList<QGraphicsItem *> selection = m_scene->items(r);
+                bool transitionAccepted = true;
+                for (int i = 0; i < selection.count(); i++) {
+                    if (selection.at(i)->type() == TRANSITIONWIDGET) {
+                        Transition *tr = static_cast <Transition *>(selection.at(i));
+                        if (tr->startPos() - info.startPos > GenTime(5, m_document->fps())) {
+                            if (tr->startPos() < info.endPos) info.endPos = tr->startPos();
+                        } else transitionAccepted = false;
+                    }
+                }
                 int transitiontrack = getPreviousVideoTrack(info.track);
-                slotAddTransition(item, info, transitiontrack, transition);
+                if (transitionAccepted) slotAddTransition(item, info, transitiontrack, transition);
+                else emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
             }
         }
 }
 
 void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo, int endTrack, QDomElement transition) {
+    if (transitionInfo.startPos >= transitionInfo.endPos) {
+        emit displayMessage(i18n("Invalid transition"), ErrorMessage);
+        return;
+    }
     AddTransitionCommand* command = new AddTransitionCommand(this, transitionInfo, endTrack, transition, false, true);
     m_commandStack->push(command);
     m_document->setModified(true);
@@ -1222,15 +1317,18 @@ void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo,
 
 void CustomTrackView::addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
     Transition *tr = new Transition(transitionInfo, endTrack, m_document->fps(), params, true);
-    scene()->addItem(tr);
-
     //kDebug() << "---- ADDING transition " << params.attribute("value");
-    m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
-    m_document->setModified(true);
+    if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML())) {
+        scene()->addItem(tr);
+        m_document->setModified(true);
+    } else {
+        emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+        delete tr;
+    }
 }
 
 void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) {
-    Transition *item = getTransitionItemAt((int)transitionInfo.startPos.frames(m_document->fps()), transitionInfo.track);
+    Transition *item = getTransitionItemAt(transitionInfo.startPos, transitionInfo.track);
     if (!item) {
         emit displayMessage(i18n("Select clip to delete"), ErrorMessage);
         return;
@@ -1262,7 +1360,7 @@ void CustomTrackView::slotTransitionTrackUpdated(Transition *tr, int track) {
 }
 
 void CustomTrackView::updateTransition(int track, GenTime pos, QDomElement oldTransition, QDomElement transition, bool updateTransitionWidget) {
-    Transition *item = getTransitionItemAt((int)pos.frames(m_document->fps()), track);
+    Transition *item = getTransitionItemAt(pos, track);
     if (!item) {
         kWarning() << "Unable to find transition at pos :" << pos.frames(m_document->fps()) << ", ON track: " << track;
         return;
@@ -1314,9 +1412,13 @@ void CustomTrackView::dropEvent(QDropEvent * event) {
             if (item->baseClip()->isTransparent()) {
                 // add transparency transition
                 int endTrack = getPreviousVideoTrack(info.track);
-                Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "alphatransparency"), true);
-                scene()->addItem(tr);
-                m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
+                Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "composite"), true);
+                if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML())) {
+                    scene()->addItem(tr);
+                } else {
+                    emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+                    delete tr;
+                }
             }
             info.track = m_document->tracksCount() - item->track();
             m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer(item->track()));
@@ -1512,7 +1614,7 @@ void CustomTrackView::slotRemoveSpace() {
     }
     ClipItem *item = getClipItemAt(pos, track);
     if (item) {
-        emit displayMessage(i18n("You must be in an empty space to remove space (time=%1, track:%2)", m_document->timecode().getTimecodeFromFrames(mapToScene(m_menuPosition).x()), track), ErrorMessage);
+        emit displayMessage(i18n("You must be in an empty space to remove space (time: %1, track: %2)", m_document->timecode().getTimecodeFromFrames(mapToScene(m_menuPosition).x()), track), ErrorMessage);
         return;
     }
     int length = m_document->renderer()->mltGetSpaceLength(pos, m_document->tracksCount() - track, true);
@@ -1714,11 +1816,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
             // We are moving all tracks
             track = -1;
         }
-
-        int startPos = (int) m_selectionGroup->boundingRect().topLeft().x();
-        int diff = ((int) m_selectionGroup->pos().x()) - startPos;
-        //kDebug()<<"//////// SPACER DIFF: "<<diff<<<<m_selectionGroup->boundingRect().topLeft();
-        if (diff != 0) {
+        GenTime timeOffset = GenTime(m_selectionGroup->scenePos().x(), m_document->fps()) - m_selectionGroupInfo.startPos;
+        if (timeOffset != GenTime()) {
             QList<QGraphicsItem *> items = m_selectionGroup->childItems();
 
             QList<ItemInfo> clipsToMove = QList<ItemInfo> ();
@@ -1747,10 +1846,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 }
             }
 
-            InsertSpaceCommand *command = new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, GenTime(diff, m_document->fps()), false);
+            InsertSpaceCommand *command = new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, timeOffset, false);
             m_commandStack->push(command);
             if (track != -1) track = m_document->tracksCount() - track;
-            m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, GenTime(diff, m_document->fps()), GenTime());
+            m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime());
         }
         resetSelectionGroup(false);
         m_operationMode = NONE;
@@ -1854,11 +1953,16 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 }
             }
             if (m_dragItem->type() == TRANSITIONWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
-                MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
-                m_commandStack->push(command);
-                Transition *transition = (Transition *) m_dragItem;
-                transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track()));
-                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);
+                Transition *transition = static_cast <Transition *>(m_dragItem);
+                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()));
+                }
             }
         } else {
             // Moving several clips. We need to delete them and readd them to new position,
@@ -1901,12 +2005,14 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
                         info.track = m_document->tracksCount() - info.track;
                         m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer(info.track));
+                        for (int i = 0; i < clip->effectsCount(); i++) {
+                            m_document->renderer()->mltAddEffect(info.track, info.startPos, clip->getEffectArgs(clip->effectAt(i)), false);
+                        }
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
                         int newTrack = tr->transitionEndTrack();
                         if (!tr->forcedTrack()) {
-                            newTrack += trackOffset;
-                            if (newTrack < 0 || newTrack > m_document->tracksCount()) newTrack = getPreviousVideoTrack(info.track);
+                            newTrack = getPreviousVideoTrack(info.track);
                         }
                         tr->updateTransitionEndTrack(newTrack);
                         m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
@@ -1941,7 +2047,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     ItemInfo trInfo = transition->info();
                     ItemInfo newTrInfo = trInfo;
                     newTrInfo.startPos = m_dragItem->startPos();
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    if (newTrInfo.startPos < newTrInfo.endPos)
+                        new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
                 }
                 // Check if there is an automatic transition on that clip (upper track)
                 transition = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track - 1);
@@ -1950,7 +2057,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     ItemInfo newTrInfo = trInfo;
                     newTrInfo.startPos = m_dragItem->startPos();
                     ClipItem * upperClip = getClipItemAt(m_dragItemInfo.startPos, m_dragItemInfo.track - 1);
-                    if (!upperClip || !upperClip->baseClip()->isTransparent()) {
+                    if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.startPos < newTrInfo.endPos) {
                         new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
                     }
                 }
@@ -1962,10 +2069,16 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
             }
         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
-            MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
-            m_commandStack->push(command);
             Transition *transition = static_cast <Transition *>(m_dragItem);
-            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);
+            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->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps()));
+                emit displayMessage(i18n("Cannot resize transition"), ErrorMessage);
+            } else {
+                MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
+                m_commandStack->push(command);
+            }
+
         }
 
         //m_document->renderer()->doRefresh();
@@ -1985,7 +2098,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     ItemInfo trInfo = tr->info();
                     ItemInfo newTrInfo = trInfo;
                     newTrInfo.endPos = m_dragItem->endPos();
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    if (newTrInfo.endPos > newTrInfo.startPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
                 }
 
                 // Check if there is an automatic transition on that clip (upper track)
@@ -1995,7 +2108,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     ItemInfo newTrInfo = trInfo;
                     newTrInfo.endPos = m_dragItem->endPos();
                     ClipItem * upperClip = getClipItemAtEnd(m_dragItemInfo.endPos, m_dragItemInfo.track - 1);
-                    if (!upperClip || !upperClip->baseClip()->isTransparent()) {
+                    if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.endPos > newTrInfo.startPos) {
                         new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
                     }
                 }
@@ -2008,10 +2121,15 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
             }
         } else if (m_dragItem->type() == TRANSITIONWIDGET) {
-            MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
-            m_commandStack->push(command);
             Transition *transition = static_cast <Transition *>(m_dragItem);
-            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), 0, 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);
+            } else {
+                MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false);
+                m_commandStack->push(command);
+            }
         }
         //m_document->renderer()->doRefresh();
     } else if (m_operationMode == FADEIN) {
@@ -2052,12 +2170,14 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                 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);
                 emit clipItemSelected(item, ix);
             }
         } else if (item->fadeOut() != 0) {
             QDomElement effect = MainWindow::audioEffects.getEffectByTag("volume", "fadeout").cloneNode().toElement();
-            EffectsList::setParameter(effect, "out", QString::number(item->fadeOut()));
+            EffectsList::setParameter(effect, "in", QString::number(item->fadeOut()));
+            EffectsList::setParameter(effect, "out", QString::number(0));
             slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track());
         }
     } else if (m_operationMode == KEYFRAME) {
@@ -2089,7 +2209,7 @@ void CustomTrackView::deleteClip(ItemInfo info) {
 
     if (item->baseClip()->isTransparent()) {
         // also remove automatic transition
-        Transition *tr = getTransitionItemAt((int) info.startPos.frames(m_document->fps()), info.track);
+        Transition *tr = getTransitionItemAt(info.startPos, info.track);
         if (tr && tr->isAutomatic()) {
             m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
             scene()->removeItem(tr);
@@ -2134,17 +2254,22 @@ void CustomTrackView::changeClipSpeed() {
     }
     QUndoCommand *changeSelected = new QUndoCommand();
     changeSelected->setText("Edit clip speed");
+    int count = 0;
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
             ItemInfo info = item->info();
-            int percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, 1, 300);
+            bool ok;
+            int percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, 1, 300, 1, &ok);
             double speed = (double) percent / 100.0;
-            if (item->speed() != speed)
+            if (ok && item->speed() != speed) {
+                count++;
                 new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), true, changeSelected);
+            }
         }
     }
-    m_commandStack->push(changeSelected);
+    if (count > 0) m_commandStack->push(changeSelected);
+    else delete changeSelected;
 }
 
 void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id) {
@@ -2180,15 +2305,19 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
         emit displayMessage(i18n("No clip copied"), ErrorMessage);
         return;
     }
-    ClipItem *item = new ClipItem(baseclip, info, m_document->fps());
+    ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble());
     item->setEffectList(effects);
     scene()->addItem(item);
     if (item->baseClip()->isTransparent()) {
         // add transparency transition
         int endTrack = getPreviousVideoTrack(info.track);
-        Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "alphatransparency"), true);
-        scene()->addItem(tr);
-        m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
+        Transition *tr = new Transition(info, endTrack, m_document->fps(), MainWindow::transitions.getEffectByTag("composite", "composite"), true);
+        if (m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML())) scene()->addItem(tr);
+        else {
+            emit displayMessage(i18n("Cannot add transition"), ErrorMessage);
+            delete tr;
+        }
+
     }
 
     baseclip->addReference();
@@ -2261,8 +2390,8 @@ ClipItem *CustomTrackView::getClipItemAt(GenTime pos, int track) {
     return getClipItemAt(framepos, track);
 }
 
-Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
-    QList<QGraphicsItem *> list = scene()->items(QPointF(pos, (track + 1) * m_tracksHeight));
+Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
+    QList<QGraphicsItem *> list = scene()->items(QPointF(pos.frames(m_document->fps()), (track + 1) * m_tracksHeight));
     Transition *clip = NULL;
     for (int i = 0; i < list.size(); i++) {
         if (list.at(i)->type() == TRANSITIONWIDGET) {
@@ -2273,11 +2402,6 @@ Transition *CustomTrackView::getTransitionItemAt(int pos, int track) {
     return clip;
 }
 
-Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) {
-    int framepos = (int)(pos.frames(m_document->fps()));
-    return getTransitionItemAt(framepos, track);
-}
-
 Transition *CustomTrackView::getTransitionItemAtEnd(GenTime pos, int track) {
     int framepos = (int)(pos.frames(m_document->fps()));
     QList<QGraphicsItem *> list = scene()->items(QPointF(framepos - 1, (track + 1) * m_tracksHeight));
@@ -2322,7 +2446,7 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
         item->setSelected(true);
         if (item->baseClip()->isTransparent()) {
             // Also move automatic transition
-            Transition *tr = getTransitionItemAt((int) start.startPos.frames(m_document->fps()), start.track);
+            Transition *tr = getTransitionItemAt(start.startPos, start.track);
             if (tr && tr->isAutomatic()) {
                 tr->updateTransitionEndTrack(getPreviousVideoTrack(end.track));
                 m_document->renderer()->mltMoveTransition(tr->transitionTag(), m_document->tracksCount() - start.track, m_document->tracksCount() - end.track, tr->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos);
@@ -2408,7 +2532,7 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
 }
 
 void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end) {
-    Transition *item = getTransitionItemAt((int)start.startPos.frames(m_document->fps()), start.track);
+    Transition *item = getTransitionItemAt(start.startPos, start.track);
     if (!item) {
         emit displayMessage(i18n("Cannot move transition at time: %1 on track %2", m_document->timecode().getTimecodeFromFrames(start.startPos.frames(m_document->fps())), start.track), ErrorMessage);
         kDebug() << "----------------  ERROR, CANNOT find transition to move... ";// << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2;
@@ -2988,7 +3112,9 @@ void CustomTrackView::pasteClip() {
             info.endPos = tr->endPos() + offset;
             info.track = tr->track() + trackOffset;
             if (canBePastedTo(info, TRANSITIONWIDGET)) {
-                new AddTransitionCommand(this, info, tr->transitionEndTrack() + trackOffset, tr->toXML(), false, true, pasteClips);
+                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 emit displayMessage(i18n("Cannot paste transition to selected place"), ErrorMessage);
         }
     }
@@ -3325,4 +3451,18 @@ QStringList CustomTrackView::getLadspaParams(QDomElement effect) const {
     return result;
 }
 
+void CustomTrackView::clipNameChanged(const QString id, const QString name) {
+    QList<QGraphicsItem *> list = scene()->items();
+    ClipItem *clip = NULL;
+    for (int i = 0; i < list.size(); ++i) {
+        if (list.at(i)->type() == AVWIDGET) {
+            clip = static_cast <ClipItem *>(list.at(i));
+            if (clip->clipProducer() == id) {
+                clip->setClipName(name);
+            }
+        }
+    }
+    viewport()->update();
+}
+
 #include "customtrackview.moc"