]> git.sesse.net Git - kdenlive/blobdiff - src/customtrackview.cpp
* New configuration page to set SDL audio/video driver and audio device
[kdenlive] / src / customtrackview.cpp
index 778d80757f7057b78db63974d3dda7c3db9a833b..aa087fad9f6d9de220de7dbe41b4ae282b5cb487 100644 (file)
@@ -46,6 +46,7 @@
 #include "addtransitioncommand.h"
 #include "edittransitioncommand.h"
 #include "editkeyframecommand.h"
+#include "changespeedcommand.h"
 #include "addmarkercommand.h"
 #include "razorclipcommand.h"
 #include "kdenlivesettings.h"
@@ -719,7 +720,7 @@ 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 (!m_document->renderer()->mltRemoveEffect(track, pos, index)) {
+    if (effect.attribute("disabled") != "1" && !m_document->renderer()->mltRemoveEffect(track, pos, index)) {
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
         return;
     }
@@ -816,7 +817,7 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) {
         newPos.cropStart = item->cropStart() + (cutTime - info.startPos);
         newPos.track = info.track;
         item->resizeEnd(cutPos, m_scale);
-        ClipItem *dup = new ClipItem(item->baseClip(), newPos, m_scale, m_document->fps());
+        ClipItem *dup = item->clone(m_scale, newPos);
         scene()->addItem(dup);
         m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime);
         item->baseClip()->addReference();
@@ -899,7 +900,7 @@ void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) {
     info.startPos = GenTime((int)(mapToScene(pos).x() / m_scale), m_document->fps());
     info.endPos = info.startPos + clip->duration();
     info.track = (int)(pos.y() / m_tracksHeight);
-    //kDebug()<<"------------  ADDING CLIP ITEM----: "<<info.startPos.frames(25)<<", "<<info.endPos.frames(25)<<", "<<info.track;
+    kDebug() << "------------  ADDING CLIP ITEM----: " << info.startPos.frames(25) << ", " << info.endPos.frames(25) << ", " << info.track;
     m_dropItem = new ClipItem(clip, info, m_scale, m_document->fps());
     scene()->addItem(m_dropItem);
 }
@@ -928,12 +929,17 @@ void CustomTrackView::dragLeaveEvent(QDragLeaveEvent * event) {
 
 void CustomTrackView::dropEvent(QDropEvent * event) {
     if (m_dropItem) {
-        AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), m_dropItem->info(), false, false);
+        AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), m_dropItem->info(), m_dropItem->effectList(), false, false);
         m_commandStack->push(command);
         m_dropItem->baseClip()->addReference();
         m_document->updateClip(m_dropItem->baseClip()->getId());
-        // kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_tracksList.count()<<", DROP: "<<m_dropItem->track();
-        m_document->renderer()->mltInsertClip(m_tracksList.count() - m_dropItem->track(), m_dropItem->startPos(), m_dropItem->cropStart(), m_dropItem->xml());
+        ItemInfo info;
+        info = m_dropItem->info();
+        info.track = m_tracksList.count() - m_dropItem->track();
+        //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<<m_tracksList.count()<<", DROP: "<<m_dropItem->track();
+        m_document->renderer()->mltInsertClip(info, m_dropItem->xml(), m_dropItem->baseClip()->producer());
+        //if (m_dropItem->baseClip()->isTransparent()) m_document->renderer()->mltAddClipTransparency(info, getPreviousVideoTrack(m_dropItem->track()), m_dropItem->baseClip()->getId());
+        m_dropItem = NULL;
         m_document->setModified(true);
     } else QGraphicsView::dropEvent(event);
     m_dropItem = NULL;
@@ -997,7 +1003,7 @@ void CustomTrackView::deleteClip(int clipId) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = (ClipItem *)itemList.at(i);
             if (item->clipProducer() == clipId) {
-                AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), true, true);
+                AddTimelineClipCommand *command = new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), true, true);
                 m_commandStack->push(command);
                 //delete item;
             }
@@ -1110,7 +1116,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     info.track = info.track - trackOffset;
                     if (item->type() == AVWIDGET) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
-                        new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, false, true, moveClips);
+                        new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, clip->effectList(), false, true, moveClips);
                         m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos);
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
@@ -1124,8 +1130,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     AbstractClipItem *item = m_selectedClipList.at(i);
                     if (item->type() == AVWIDGET) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
-                        new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), item->info(), false, false, moveClips);
-                        m_document->renderer()->mltInsertClip(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), clip->xml());
+                        new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), item->info(), clip->effectList(), false, false, moveClips);
+                        ItemInfo info = item->info();
+                        info.track = m_tracksList.count() - item->track();
+                        m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer());
                     } else {
                         Transition *tr = static_cast <Transition*>(item);
                         ItemInfo transitionInfo = tr->info();
@@ -1140,10 +1148,16 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
     } else if (m_operationMode == RESIZESTART && m_dragItem->startPos() != m_dragItemInfo.startPos) {
         // resize start
         if (m_dragItem->type() == AVWIDGET) {
-            m_document->renderer()->mltResizeClipStart(m_tracksList.count() - m_dragItem->track(), m_dragItem->endPos(), m_dragItem->startPos(), m_dragItemInfo.startPos, m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos());
-            updateClipFade((ClipItem *) m_dragItem);
-            ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
-            m_commandStack->push(command);
+            bool success = m_document->renderer()->mltResizeClipStart(m_tracksList.count() - m_dragItem->track(), m_dragItem->endPos(), m_dragItem->startPos(), m_dragItemInfo.startPos, m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos());
+           if (success) {
+               updateClipFade((ClipItem *) m_dragItem);
+               ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false);
+               m_commandStack->push(command);
+           }
+           else {
+               m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps()), m_scale);
+               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);
@@ -1257,10 +1271,10 @@ void CustomTrackView::deleteSelectedClips() {
     deleteSelected->setText("Delete selected items");
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
-            ClipItem *item = static_cast <ClipItem *> (itemList.at(i));
-            new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), true, true, deleteSelected);
+            ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
+            new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), true, true, deleteSelected);
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
-            Transition *item = static_cast <Transition *> (itemList.at(i));
+            Transition *item = static_cast <Transition *>(itemList.at(i));
             ItemInfo info;
             info.startPos = item->startPos();
             info.endPos = item->endPos();
@@ -1271,6 +1285,43 @@ void CustomTrackView::deleteSelectedClips() {
     m_commandStack->push(deleteSelected);
 }
 
+void CustomTrackView::changeClipSpeed() {
+    QList<QGraphicsItem *> itemList = scene()->selectedItems();
+    if (itemList.count() == 0) {
+        emit displayMessage(i18n("Select clip to change speed"), ErrorMessage);
+        return;
+    }
+    QUndoCommand *changeSelected = new QUndoCommand();
+    changeSelected->setText("Edit clip speed");
+    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)"), 100, 1, 300);
+            double speed = (double) percent / 100.0;
+           if (item->speed() != speed)
+               new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), true, changeSelected);
+        }
+    }
+    m_commandStack->push(changeSelected);
+}
+
+void CustomTrackView::doChangeClipSpeed(ItemInfo info, double speed, int id) {
+    DocClipBase *baseclip = m_document->clipManager()->getClipById(id);
+    ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track);
+    info.track = m_tracksList.count() - item->track();
+    m_document->renderer()->mltChangeClipSpeed(info, speed, baseclip->producer());
+    item->setSpeed(speed);
+    GenTime maxDuration = item->maxDuration();
+    if (maxDuration < item->duration()) {
+        info = item->info();
+        ItemInfo endInfo = info;
+        endInfo.endPos = info.startPos + maxDuration;
+        ResizeClipCommand *command = new ResizeClipCommand(this, info, endInfo, true);
+        m_commandStack->push(command);
+    }
+}
+
 void CustomTrackView::cutSelectedClips() {
     QList<QGraphicsItem *> itemList = scene()->selectedItems();
     GenTime currentPos = GenTime(m_cursorPos, m_document->fps());
@@ -1289,13 +1340,18 @@ void CustomTrackView::cutSelectedClips() {
     }
 }
 
-void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info) {
+void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info, EffectsList effects) {
     DocClipBase *baseclip = m_document->clipManager()->getClipById(clipId);
     ClipItem *item = new ClipItem(baseclip, info, m_scale, m_document->fps());
+    item->setEffectList(effects);
     scene()->addItem(item);
     baseclip->addReference();
     m_document->updateClip(baseclip->getId());
-    m_document->renderer()->mltInsertClip(m_tracksList.count() - info.track, info.startPos, info.cropStart, xml);
+    info.track = m_tracksList.count() - info.track;
+    m_document->renderer()->mltInsertClip(info, xml, baseclip->producer());
+    for (int i = 0; i < item->effectsCount(); i++) {
+        m_document->renderer()->mltAddEffect(info.track, info.startPos, item->getEffectArgs(item->effectAt(i)), false);
+    }
     m_document->renderer()->doRefresh();
 }
 
@@ -1307,7 +1363,9 @@ void CustomTrackView::slotUpdateClip(int clipId) {
             clip = static_cast <ClipItem *>(list.at(i));
             if (clip->clipProducer() == clipId) {
                 clip->refreshClip();
-                m_document->renderer()->mltUpdateClip(m_tracksList.count() - clip->track(), clip->startPos(), clip->cropStart(), clip->xml());
+                ItemInfo info = clip->info();
+                info.track = m_tracksList.count() - clip->track();
+                m_document->renderer()->mltUpdateClip(info, clip->xml(), clip->baseClip()->producer());
             }
         }
     }
@@ -1403,9 +1461,12 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) {
         return;
     }
     if (resizeClipStart) {
-        m_document->renderer()->mltResizeClipStart(m_tracksList.count() - item->track(), item->endPos(), end.startPos, item->startPos(), item->cropStart() + end.startPos - start.startPos, item->cropStart() + end.startPos - start.startPos + item->endPos() - end.startPos);
-        item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
-        updateClipFade(item);
+        bool success = m_document->renderer()->mltResizeClipStart(m_tracksList.count() - item->track(), item->endPos(), end.startPos, item->startPos(), item->cropStart() + end.startPos - start.startPos, item->cropStart() + end.startPos - start.startPos + item->endPos() - end.startPos);
+        if (success) {
+           item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale);
+           updateClipFade(item);
+       }
+       else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
     } else {
         m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + end.endPos - item->startPos());
         item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale);
@@ -1725,6 +1786,7 @@ void CustomTrackView::editGuide(const GenTime oldPos, const GenTime pos, const Q
         }
         if (!found) emit displayMessage(i18n("No guide at cursor time"), ErrorMessage);
     }
+    m_document->syncGuides(m_guides);
 }
 
 bool CustomTrackView::addGuide(const GenTime pos, const QString &comment) {
@@ -1737,6 +1799,7 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment) {
     Guide *g = new Guide(this, pos, comment, m_scale, m_document->fps(), m_tracksHeight * m_tracksList.count());
     scene()->addItem(g);
     m_guides.append(g);
+    m_document->syncGuides(m_guides);
     return true;
 }
 
@@ -1859,19 +1922,6 @@ void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) {
         painter->fillRect(QRectF(rectInView.left(), lowerLimit, rectInView.width(), height() - lowerLimit), QBrush(base));
 }
 
-QDomElement CustomTrackView::xmlInfo() {
-    QDomDocument doc;
-    QDomElement e;
-    QDomElement guides = doc.createElement("guides");
-    for (int i = 0; i < m_guides.count(); i++) {
-        e = doc.createElement("guide");
-        e.setAttribute("time", m_guides.at(i)->position().ms() / 1000);
-        e.setAttribute("comment", m_guides.at(i)->label());
-        guides.appendChild(e);
-    }
-    return guides;
-}
-
 bool CustomTrackView::findString(const QString &text) {
     QString marker;
     for (int i = 0; i < m_searchPoints.size(); ++i) {
@@ -1946,7 +1996,7 @@ void CustomTrackView::copyClip() {
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *dup = static_cast <ClipItem *>(itemList.at(i));
-            m_copiedItems.append(dup->clone(m_scale));
+            m_copiedItems.append(dup->clone(m_scale, dup->info()));
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
             Transition *dup = static_cast <Transition *>(itemList.at(i));
             m_copiedItems.append(dup->clone(m_scale));
@@ -2032,7 +2082,7 @@ void CustomTrackView::pasteClip() {
             info.cropStart = clip->cropStart();
             info.track = clip->track() + trackOffset;
             if (canBePastedTo(info, AVWIDGET)) {
-                new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, true, false, pasteClips);
+                new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, clip->effectList(), true, false, pasteClips);
             } else emit displayMessage(i18n("Cannot paste clip to selected place"), ErrorMessage);
         } else if (m_copiedItems.at(i) && m_copiedItems.at(i)->type() == TRANSITIONWIDGET) {
             Transition *tr = static_cast <Transition *>(m_copiedItems.at(i));
@@ -2048,6 +2098,30 @@ void CustomTrackView::pasteClip() {
     m_commandStack->push(pasteClips);
 }
 
+void CustomTrackView::pasteClipEffects() {
+    if (m_copiedItems.count() != 1 || m_copiedItems.at(0)->type() != AVWIDGET) {
+        emit displayMessage(i18n("You must copy exactly one clip before pasting effects"), ErrorMessage);
+        return;
+    }
+    ClipItem *clip = static_cast < ClipItem *>(m_copiedItems.at(0));
+    EffectsList effects = clip->effectList();
+
+    QUndoCommand *paste = new QUndoCommand();
+    paste->setText("Paste effects");
+
+    QList<QGraphicsItem *> clips = scene()->selectedItems();
+    for (int i = 0; i < clips.count(); ++i) {
+        if (clips.at(i)->type() == AVWIDGET) {
+            ClipItem *item = static_cast < ClipItem *>(clips.at(i));
+            for (int i = 0; i < clip->effectsCount(); i++) {
+                new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), clip->effectAt(i), true, paste);
+            }
+        }
+    }
+    m_commandStack->push(paste);
+}
+
+
 /*
 void CustomTrackView::drawForeground ( QPainter * painter, const QRectF & rect )
 {