]> git.sesse.net Git - kdenlive/blobdiff - src/customtrackview.cpp
Vectorscope: Fix CPU burst when widget size not known yet
[kdenlive] / src / customtrackview.cpp
index 7ac1542f1621a2b71c87604f45b955372786e7aa..8e4759354f2aafbc824170343cf54e8c3648c82e 100644 (file)
@@ -58,6 +58,7 @@
 #include "trackdialog.h"
 #include "tracksconfigdialog.h"
 #include "configtrackscommand.h"
+#include "rebuildgroupcommand.h"
 
 #include <KDebug>
 #include <KLocale>
@@ -393,7 +394,13 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
                 m_dragItem->resizeStart((int)(snappedPos));
             } else if (m_operationMode == RESIZEEND && move) {
                 m_document->renderer()->pause();
-                m_dragItem->resizeEnd((int)(snappedPos));
+                if (m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+                    AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+                    if (parent)
+                        parent->resizeEnd((int)(snappedPos) - m_dragItemInfo.endPos.frames(m_document->fps()));
+                } else {
+                    m_dragItem->resizeEnd((int)(snappedPos));
+                }
             } else if (m_operationMode == FADEIN && move) {
                 ((ClipItem*) m_dragItem)->setFadeIn((int)(mappedXPos - m_dragItem->startPos().frames(m_document->fps())));
             } else if (m_operationMode == FADEOUT && move) {
@@ -425,9 +432,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
             for (int i = 0; i < children.count(); i++) {
                 if (children.at(i)->type() == GROUPWIDGET) {
                     QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
-                    for (int j = 0; j < subchildren.count(); j++) {
+                    for (int j = 0; j < subchildren.count(); j++)
                         collidingItems.removeAll(subchildren.at(j));
-                    }
                 }
                 collidingItems.removeAll(children.at(i));
             }
@@ -452,9 +458,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
             for (int i = 0; i < children.count(); i++) {
                 if (children.at(i)->type() == GROUPWIDGET) {
                     QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
-                    for (int j = 0; j < subchildren.count(); j++) {
+                    for (int j = 0; j < subchildren.count(); j++)
                         collidingItems.removeAll(subchildren.at(j));
-                    }
                 }
                 collidingItems.removeAll(children.at(i));
             }
@@ -476,9 +481,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
                 for (int i = 0; i < children.count(); i++) {
                     if (children.at(i)->type() == GROUPWIDGET) {
                         QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
-                        for (int j = 0; j < subchildren.count(); j++) {
+                        for (int j = 0; j < subchildren.count(); j++)
                             collidingItems.removeAll(subchildren.at(j));
-                        }
                     }
                     collidingItems.removeAll(children.at(i));
                 }
@@ -503,9 +507,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
                 for (int i = 0; i < children.count(); i++) {
                     if (children.at(i)->type() == GROUPWIDGET) {
                         QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
-                        for (int j = 0; j < subchildren.count(); j++) {
+                        for (int j = 0; j < subchildren.count(); j++)
                             collidingItems.removeAll(subchildren.at(j));
-                        }
                     }
                     collidingItems.removeAll(children.at(i));
                 }
@@ -566,13 +569,18 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
         }
         m_moveOpMode = opMode;
         setTipAnimation(clip, opMode, size);
-        if (opMode == MOVE)
+        if (opMode == MOVE) {
             setCursor(Qt::OpenHandCursor);
-        else if (opMode == RESIZESTART)
+            ClipItem *ci = static_cast <ClipItem *>(item);
+            QString message = ci->clipName() + i18n(":");
+            message.append(i18n(" Position:") + m_document->timecode().getDisplayTimecode(ci->info().startPos, KdenliveSettings::frametimecode()));
+            message.append(i18n(" Duration:") + m_document->timecode().getDisplayTimecode(ci->cropDuration(),  KdenliveSettings::frametimecode()));
+            emit displayMessage(message, InformationMessage);
+        } else if (opMode == RESIZESTART) {
             setCursor(KCursor("left_side", Qt::SizeHorCursor));
-        else if (opMode == RESIZEEND)
+        } else if (opMode == RESIZEEND) {
             setCursor(KCursor("right_side", Qt::SizeHorCursor));
-        else if (opMode == FADEIN || opMode == FADEOUT) {
+        else if (opMode == FADEIN || opMode == FADEOUT) {
             setCursor(Qt::PointingHandCursor);
             emit displayMessage(i18n("Drag to add or resize a fade effect."), InformationMessage);
         } else if (opMode == TRANSITIONSTART || opMode == TRANSITIONEND) {
@@ -704,7 +712,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
     }
 #if QT_VERSION >= 0x040600
     // Add shadow to dragged item, currently disabled because of painting artifacts
-    //TODO: re-enable when fixed
+    //TODO: re-enable when fixed
     /*QGraphicsDropShadowEffect *eff = new QGraphicsDropShadowEffect();
     eff->setBlurRadius(5);
     eff->setOffset(3, 3);
@@ -1007,8 +1015,18 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
     QGraphicsView::mousePressEvent(event);
 }
 
-void CustomTrackView::rebuildGroup(AbstractGroupItem* group)
+void CustomTrackView::rebuildGroup(int childTrack, GenTime childPos)
 {
+    const QPointF p((int)childPos.frames(m_document->fps()), childTrack * m_tracksHeight + m_tracksHeight / 2);
+    QList<QGraphicsItem *> list = scene()->items(p);
+    AbstractGroupItem *group = NULL;
+    for (int i = 0; i < list.size(); i++) {
+        if (!list.at(i)->isEnabled()) continue;
+        if (list.at(i)->type() == GROUPWIDGET) {
+            group = static_cast <AbstractGroupItem *>(list.at(i));
+            break;
+        }
+    }
     if (group) {
         QList <QGraphicsItem *> children = group->childItems();
         m_document->clipManager()->removeGroup(group);
@@ -1127,7 +1145,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
     if (m_dragItem && m_dragItem->hasKeyFrames()) {
         /*if (m_moveOpMode == KEYFRAME) {
             // user double clicked on a keyframe, open edit dialog
-            //TODO: update for effects with several values per keyframe
+            //TODO: update for effects with several values per keyframe
             QDialog d(parentWidget());
             Ui::KeyFrameDialog_UI view;
             view.setupUi(&d);
@@ -1209,7 +1227,7 @@ void CustomTrackView::editItemDuration()
             getTransitionAvailableSpace(item, minimum, maximum);
         else
             getClipAvailableSpace(item, minimum, maximum);
-        //kDebug()<<"// GOT MOVE POS: "<<minimum.frames(25)<<" - "<<maximum.frames(25);
+
         ClipDurationDialog d(item, m_document->timecode(), minimum, maximum, this);
         if (d.exec() == QDialog::Accepted) {
             ItemInfo clipInfo = item->info();
@@ -2136,7 +2154,9 @@ 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()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT) == -1) {
+
+            int worked = m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT);
+            if (worked == -1) {
                 emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage);
                 brokenClips.append(item);
                 continue;
@@ -2163,7 +2183,7 @@ void CustomTrackView::dropEvent(QDropEvent * event)
         setDocumentModified();
 
         /*
-        // debug info
+        // debug info
         QRectF rect(0, 1 * m_tracksHeight + m_tracksHeight / 2, sceneRect().width(), 2);
         QList<QGraphicsItem *> selection = m_scene->items(rect);
         QStringList timelineList;
@@ -3176,7 +3196,28 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         prepareResizeClipStart(m_dragItem, m_dragItemInfo, m_dragItem->startPos().frames(m_document->fps()));
     } else if (m_operationMode == RESIZEEND && m_dragItem->endPos() != m_dragItemInfo.endPos) {
         // resize end
-        prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps()));
+        if (m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+            AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+            if (parent) {
+                QUndoCommand *resizeCommand = new QUndoCommand();
+                resizeCommand->setText(i18n("Resize group"));
+                QList <QGraphicsItem *> items = parent->childItems();
+                QList <ItemInfo> infos = parent->resizeInfos();
+                parent->clearResizeInfos();
+                int itemcount = 0;
+                for (int i = 0; i < items.count(); ++i) {
+                    AbstractClipItem *item = static_cast<AbstractClipItem *>(items.at(i));
+                    if (item && item->type() == AVWIDGET) {
+                        ItemInfo info = infos.at(itemcount);
+                        prepareResizeClipEnd(item, info, item->endPos().frames(m_document->fps()), false, resizeCommand);
+                        ++itemcount;
+                    }
+                }
+                m_commandStack->push(resizeCommand);
+            }
+        } else {
+            prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps()));
+        }
     } else if (m_operationMode == FADEIN) {
         // resize fade in effect
         ClipItem * item = static_cast <ClipItem *>(m_dragItem);
@@ -3282,7 +3323,9 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         if ((val < -50 || val > 150) && item->editedKeyFramePos() != start && item->editedKeyFramePos() != end) {
             //delete keyframe
             item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), -1, 0);
-        } else item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue());
+        } else {
+            item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue());
+        }
 
         QDomElement newEffect = item->selectedEffect().cloneNode().toElement();
         //item->updateKeyframeEffect();
@@ -3985,7 +4028,7 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool
     setDocumentModified();
 }
 
-void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check)
+void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check, QUndoCommand *command)
 {
     if (pos == oldInfo.startPos.frames(m_document->fps()))
         return;
@@ -4007,8 +4050,13 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
         resizeinfo.track = m_document->tracksCount() - resizeinfo.track;
         bool success = m_document->renderer()->mltResizeClipStart(resizeinfo, item->startPos() - oldInfo.startPos);
         if (success) {
-            QUndoCommand *resizeCommand = new QUndoCommand();
-            resizeCommand->setText(i18n("Resize clip"));
+            bool hasParentCommand = false;
+            if (command) {
+                hasParentCommand = true;
+            } else {
+                command = new QUndoCommand();
+                command->setText(i18n("Resize clip start"));
+            }
 
             // Check if there is an automatic transition on that clip (lower track)
             Transition *transition = getTransitionItemAtStart(oldInfo.startPos, oldInfo.track);
@@ -4017,7 +4065,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
                 ItemInfo newTrInfo = trInfo;
                 newTrInfo.startPos = item->startPos();
                 if (newTrInfo.startPos < newTrInfo.endPos)
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
             }
             // Check if there is an automatic transition on that clip (upper track)
             transition = getTransitionItemAtStart(oldInfo.startPos, oldInfo.track - 1);
@@ -4027,7 +4075,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
                 newTrInfo.startPos = item->startPos();
                 ClipItem * upperClip = getClipItemAt(oldInfo.startPos, oldInfo.track - 1);
                 if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.startPos < newTrInfo.endPos)
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
             }
 
             ClipItem *clip = static_cast < ClipItem * >(item);
@@ -4054,18 +4102,19 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
                 // put a resize command before & after checking keyframes so that
                 // we are sure the resize is performed before whenever we do or undo the action
 
-                new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, true, command);
                 for (int i = 0; i < indexes.count(); i++) {
-                    new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, resizeCommand);
+                    new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, command);
                     updateEffect(m_document->tracksCount() - clip->track(), clip->startPos(), clip->effectAt(indexes.at(i)), indexes.at(i));
                 }
-                new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, true, command);
                 emit clipItemSelected(clip);
             } else {
-                new ResizeClipCommand(this, oldInfo, info, false, false, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, false, command);
             }
 
-            m_commandStack->push(resizeCommand);
+            if (!hasParentCommand)
+                m_commandStack->push(command);
         } else {
             KdenliveSettings::setSnaptopoints(false);
             item->resizeStart((int) oldInfo.startPos.frames(m_document->fps()));
@@ -4081,16 +4130,17 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
             KdenliveSettings::setSnaptopoints(snap);
             emit displayMessage(i18n("Cannot resize transition"), ErrorMessage);
         } else {
-            MoveTransitionCommand *command = new MoveTransitionCommand(this, oldInfo, info, false);
-            m_commandStack->push(command);
+            MoveTransitionCommand *moveCommand = new MoveTransitionCommand(this, oldInfo, info, false, command);
+            if (command == NULL)
+                m_commandStack->push(moveCommand);
         }
 
     }
     if (item->parentItem() && item->parentItem() != m_selectionGroup)
-        rebuildGroup(static_cast <AbstractGroupItem *>(item->parentItem()));
+        new RebuildGroupCommand(this, item->info().track, item->info().startPos, command);
 }
 
-void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check)
+void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check, QUndoCommand *command)
 {
     if (pos == oldInfo.endPos.frames(m_document->fps()))
         return;
@@ -4112,8 +4162,13 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
         resizeinfo.track = m_document->tracksCount() - resizeinfo.track;
         bool success = m_document->renderer()->mltResizeClipEnd(resizeinfo, resizeinfo.endPos - resizeinfo.startPos);
         if (success) {
-            QUndoCommand *resizeCommand = new QUndoCommand();
-            resizeCommand->setText(i18n("Resize clip"));
+            bool hasParentCommand = false;
+            if (command) {
+                hasParentCommand = true;
+            } else {
+                command = new QUndoCommand();
+                command->setText(i18n("Resize clip end"));
+            }
 
             // Check if there is an automatic transition on that clip (lower track)
             Transition *tr = getTransitionItemAtEnd(oldInfo.endPos, oldInfo.track);
@@ -4122,7 +4177,7 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
                 ItemInfo newTrInfo = trInfo;
                 newTrInfo.endPos = item->endPos();
                 if (newTrInfo.endPos > newTrInfo.startPos)
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
             }
 
             // Check if there is an automatic transition on that clip (upper track)
@@ -4133,7 +4188,7 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
                 newTrInfo.endPos = item->endPos();
                 ClipItem * upperClip = getClipItemAtEnd(oldInfo.endPos, oldInfo.track - 1);
                 if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.endPos > newTrInfo.startPos)
-                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+                    new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
 
             }
 
@@ -4159,18 +4214,19 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
                 // put a resize command before & after checking keyframes so that
                 // we are sure the resize is performed before whenever we do or undo the action
 
-                new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, true, command);
                 for (int i = 0; i < indexes.count(); i++) {
-                    new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, resizeCommand);
+                    new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, command);
                     updateEffect(m_document->tracksCount() - clip->track(), clip->startPos(), clip->effectAt(indexes.at(i)), indexes.at(i));
                 }
-                new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, true, command);
                 emit clipItemSelected(clip);
             } else {
-                new ResizeClipCommand(this, oldInfo, info, false, false, resizeCommand);
+                new ResizeClipCommand(this, oldInfo, info, false, false, command);
             }
 
-            m_commandStack->push(resizeCommand);
+            if (!hasParentCommand)
+                m_commandStack->push(command);
             updatePositionEffects(clip, oldInfo);
         } else {
             KdenliveSettings::setSnaptopoints(false);
@@ -4187,12 +4243,13 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
             KdenliveSettings::setSnaptopoints(true);
             emit displayMessage(i18n("Cannot resize transition"), ErrorMessage);
         } else {
-            MoveTransitionCommand *command = new MoveTransitionCommand(this, oldInfo, info, false);
-            m_commandStack->push(command);
+            MoveTransitionCommand *moveCommand = new MoveTransitionCommand(this, oldInfo, info, false, command);
+            if (command == NULL)
+                m_commandStack->push(moveCommand);
         }
     }
     if (item->parentItem() && item->parentItem() != m_selectionGroup)
-        rebuildGroup(static_cast <AbstractGroupItem *>(item->parentItem()));
+        new RebuildGroupCommand(this, item->info().track, item->info().startPos, command);
 }
 
 void CustomTrackView::updatePositionEffects(ClipItem * item, ItemInfo info)
@@ -4639,8 +4696,10 @@ void CustomTrackView::setScale(double scaleFactor, double verticalScale)
 
     int diff = sceneRect().width() - m_projectDuration;
     if (diff * newmatrix.m11() < 50) {
-        if (newmatrix.m11() < 0.4) setSceneRect(0, 0, (m_projectDuration + 100 / newmatrix.m11()), sceneRect().height());
-        else setSceneRect(0, 0, (m_projectDuration + 300), sceneRect().height());
+        if (newmatrix.m11() < 0.4)
+            setSceneRect(0, 0, (m_projectDuration + 100 / newmatrix.m11()), sceneRect().height());
+        else
+            setSceneRect(0, 0, (m_projectDuration + 300), sceneRect().height());
     }
     centerOn(QPointF(cursorPos(), verticalPos));
 }
@@ -4648,9 +4707,8 @@ void CustomTrackView::setScale(double scaleFactor, double verticalScale)
 void CustomTrackView::slotRefreshGuides()
 {
     if (KdenliveSettings::showmarkers()) {
-        for (int i = 0; i < m_guides.count(); i++) {
+        for (int i = 0; i < m_guides.count(); i++)
             m_guides.at(i)->update();
-        }
     }
 }
 
@@ -4750,9 +4808,8 @@ void CustomTrackView::initSearchStrings()
     }
 
     // add guides
-    for (int i = 0; i < m_guides.count(); i++) {
+    for (int i = 0; i < m_guides.count(); i++)
         m_searchPoints.append(m_guides.at(i)->info());
-    }
 
     qSort(m_searchPoints);
 }
@@ -4770,9 +4827,8 @@ QList<ItemInfo> CustomTrackView::findId(const QString &clipId)
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             ClipItem *item = (ClipItem *)itemList.at(i);
-            if (item->clipProducer() == clipId) {
+            if (item->clipProducer() == clipId)
                 matchingInfo << item->info();
-            }
         }
     }
     return matchingInfo;