]> git.sesse.net Git - kdenlive/blobdiff - src/customtrackview.cpp
Fix Coverity #980691
[kdenlive] / src / customtrackview.cpp
index dc0a76a10fb0644723a11cfcde7f53ad3a45f97a..51b230ad8c2cfb4744aa94dcadbd8521f181cde1 100644 (file)
@@ -110,35 +110,44 @@ bool sortGuidesList(const Guide *g1 , const Guide *g2)
 // const int duration = animate ? 1500 : 1;
 
 CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent) :
-    QGraphicsView(projectscene, parent),
-    m_tracksHeight(KdenliveSettings::trackheight()),
-    m_projectDuration(0),
-    m_cursorPos(0),
-    m_document(doc),
-    m_scene(projectscene),
-    m_cursorLine(NULL),
-    m_operationMode(NONE),
-    m_moveOpMode(NONE),
-    m_dragItem(NULL),
-    m_dragGuide(NULL),
-    m_visualTip(NULL),
-    m_animation(NULL),
-    m_clickPoint(),
-    m_autoScroll(KdenliveSettings::autoscroll()),
-    m_pasteEffectsAction(NULL),
-    m_ungroupAction(NULL),
-    m_scrollOffset(0),
-    m_clipDrag(false),
-    m_findIndex(0),
-    m_tool(SELECTTOOL),
-    m_copiedItems(),
-    m_menuPosition(),
-    m_blockRefresh(false),
-    m_selectionGroup(NULL),
-    m_selectedTrack(0),
-    m_audioCorrelator(NULL),
-    m_audioAlignmentReference(NULL),
-    m_controlModifier(false)
+    QGraphicsView(projectscene, parent)
+    , m_tracksHeight(KdenliveSettings::trackheight())
+    , m_projectDuration(0)
+    , m_cursorPos(0)
+    , m_document(doc)
+    , m_scene(projectscene)
+    , m_cursorLine(NULL)
+    , m_operationMode(NONE)
+    , m_moveOpMode(NONE)
+    , m_dragItem(NULL)
+    , m_dragGuide(NULL)
+    , m_visualTip(NULL)
+    , m_animation(NULL)
+    , m_clickPoint()
+    , m_autoScroll(KdenliveSettings::autoscroll())
+    , m_timelineContextMenu(NULL)
+    , m_timelineContextClipMenu(NULL)
+    , m_timelineContextTransitionMenu(NULL)
+    , m_markerMenu(NULL)
+    , m_autoTransition(NULL)
+    , m_pasteEffectsAction(NULL)
+    , m_ungroupAction(NULL)
+    , m_editGuide(NULL)
+    , m_deleteGuide(NULL)
+    , m_clipTypeGroup(NULL)
+    , m_scrollOffset(0)
+    , m_clipDrag(false)
+    , m_findIndex(0)
+    , m_tool(SELECTTOOL)
+    , m_copiedItems()
+    , m_menuPosition()
+    , m_blockRefresh(false)
+    , m_selectionGroup(NULL)
+    , m_selectedTrack(0)
+    , m_spacerOffset(0)
+    , m_audioCorrelator(NULL)
+    , m_audioAlignmentReference(NULL)
+    , m_controlModifier(false)
 {
     if (doc) {
         m_commandStack = doc->commandStack();
@@ -324,12 +333,9 @@ bool CustomTrackView::checkTrackHeight()
         }
     }
     double newHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22();
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), newHeight - 1);
-
+    m_cursorLine->setLine(0, 0, 0, newHeight - 1);
     for (int i = 0; i < m_guides.count(); i++) {
-        QLineF l = m_guides.at(i)->line();
-        l.setP2(QPointF(l.x2(), newHeight));
-        m_guides.at(i)->setLine(l);
+        m_guides.at(i)->setLine(0, 0, 0, newHeight - 1);
     }
 
     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_document->tracksCount());
@@ -847,7 +853,11 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
                m_selectionGroup->setProperty("locked_tracks", lockedTracks);
            }
            if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET && m_dragItem->parentItem() != m_selectionGroup) {
-                dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+               QGraphicsItem *topGroup = m_dragItem->parentItem();
+               while (topGroup->parentItem() && topGroup->parentItem()->type() == GROUPWIDGET && topGroup->parentItem() != m_selectionGroup) {
+                   topGroup = topGroup->parentItem();
+               }
+                dragGroup = static_cast <AbstractGroupItem *>(topGroup);
                dragGroup->setProperty("y_absolute", yOffset);
                dragGroup->setProperty("locked_tracks", lockedTracks);
             }
@@ -1040,10 +1050,12 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
         } else {
            resetSelectionGroup();
        }
-        dragGroup = NULL;
-        if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET) {
-            dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
-        }
+        /*if () {
+           dragGroup = NULL;
+           if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET) {
+               dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+           }
+       }*/
 
         bool selected = !m_dragItem->isSelected();
        QGraphicsView::mousePressEvent(event);
@@ -1085,8 +1097,9 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
             m_selectionGroup->setSelected(itemSelected);
            
        }
-       if (dragGroup)
+       if (dragGroup) {
             dragGroup->setSelected(itemSelected);
+       }
        m_dragItem->setSelected(itemSelected);
     }
 
@@ -1247,11 +1260,11 @@ void CustomTrackView::rebuildGroup(AbstractGroupItem *group)
     if (group) {
         QList <QGraphicsItem *> children = group->childItems();
         m_document->clipManager()->removeGroup(group);
-       /*for (int i = 0; i < children.count(); i++) {
+       for (int i = 0; i < children.count(); i++) {
            group->removeFromGroup(children.at(i));
-       }*/
+       }
        scene()->destroyItemGroup(group);
-        groupSelectedItems(children, true, true);
+        groupSelectedItems(children, group != m_selectionGroup, true);
     }
 }
 
@@ -1266,14 +1279,16 @@ void CustomTrackView::resetSelectionGroup(bool selectItems)
         scene()->destroyItemGroup(m_selectionGroup);
        m_selectionGroup = NULL;
         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 <AbstractClipItem *>(children.at(i))->isItemLocked()) {
-                    children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true);
-                    children.at(i)->setSelected(selectItems);
-                }
-            } else if (children.at(i)->type() == GROUPWIDGET) {
-                children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true);
-                children.at(i)->setSelected(selectItems);
+            if (children.at(i)->parentItem() == 0) {
+               if ((children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET)) {
+                   if (!static_cast <AbstractClipItem *>(children.at(i))->isItemLocked()) {
+                       children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true);
+                       children.at(i)->setSelected(selectItems);
+                   }
+               } else if (children.at(i)->type() == GROUPWIDGET) {
+                   children.at(i)->setFlag(QGraphicsItem::ItemIsMovable, true);
+                   children.at(i)->setSelected(selectItems);
+               }
             }
         }
         KdenliveSettings::setSnaptopoints(snap);
@@ -1295,6 +1310,9 @@ void CustomTrackView::groupSelectedItems(QList <QGraphicsItem *> selection, bool
        if (selectNewGroup) selection.at(i)->setSelected(true);
        if (selection.at(i)->type() == GROUPWIDGET) {
            AbstractGroupItem *it = static_cast <AbstractGroupItem *> (selection.at(i));
+           while (it->parentItem() && it->parentItem()->type() == GROUPWIDGET) {
+               it = static_cast <AbstractGroupItem *>(it->parentItem());
+           }
            if (!it || it->isItemLocked()) continue;
            groupsList.insert(it);
        }
@@ -1303,6 +1321,9 @@ void CustomTrackView::groupSelectedItems(QList <QGraphicsItem *> selection, bool
        if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) {
            if (selection.at(i)->parentItem() && selection.at(i)->parentItem()->type() == GROUPWIDGET) {
                AbstractGroupItem *it = static_cast <AbstractGroupItem *> (selection.at(i)->parentItem());
+               while (it->parentItem() && it->parentItem()->type() == GROUPWIDGET) {
+                   it = static_cast <AbstractGroupItem *>(it->parentItem());
+               }
                if (!it || it->isItemLocked()) continue;
                groupsList.insert(it);
            }
@@ -1339,8 +1360,11 @@ void CustomTrackView::groupSelectedItems(QList <QGraphicsItem *> selection, bool
         newGroup->translate(-diff.x(), -diff.y());
         //newGroup->translate((int) -rectUnion.left(), (int) -rectUnion.top() + 1);
 
-        scene()->addItem(newGroup);
         // Check if we are trying to include a group in a group
+       foreach (QGraphicsItemGroup *value, groupsList) {
+           newGroup->addItem(value);
+        }
+       
        foreach (QGraphicsItemGroup *value, groupsList) {
            QList<QGraphicsItem *> children = value->childItems();
            for (int i = 0; i < children.count(); i++) {
@@ -1355,6 +1379,7 @@ void CustomTrackView::groupSelectedItems(QList <QGraphicsItem *> selection, bool
        foreach (QGraphicsItem *value, itemsList) {
            newGroup->addItem(value);
         }
+        scene()->addItem(newGroup);
         KdenliveSettings::setSnaptopoints(snap);
        if (selectNewGroup) newGroup->setSelected(true);
     } else {
@@ -3057,12 +3082,10 @@ void CustomTrackView::addTrack(TrackInfo type, int ix)
 
     int maxHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22();
     for (int i = 0; i < m_guides.count(); i++) {
-        QLineF l = m_guides.at(i)->line();
-        l.setP2(QPointF(l.x2(), maxHeight));
-        m_guides.at(i)->setLine(l);
+        m_guides.at(i)->setLine(0, 0, 0, maxHeight - 1);
     }
 
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight - 1);
+    m_cursorLine->setLine(0, 0, 0, maxHeight - 1);
     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_document->tracksCount());
     viewport()->update();
     //QTimer::singleShot(500, this, SIGNAL(trackHeightChanged()));
@@ -3073,6 +3096,10 @@ void CustomTrackView::addTrack(TrackInfo type, int ix)
 
 void CustomTrackView::removeTrack(int ix)
 {
+    // Clear effect stack
+    clearSelection();
+    emit transitionItemSelected(NULL);
+
     // Delete track in MLT playlist
     m_document->renderer()->mltDeleteTrack(m_document->tracksCount() - ix);
     m_document->deleteTrack(m_document->tracksCount() - ix - 1);
@@ -3081,12 +3108,10 @@ void CustomTrackView::removeTrack(int ix)
     QRectF r(0, startY, sceneRect().width(), sceneRect().height() - startY);
     QList<QGraphicsItem *> selection = m_scene->items(r);
 
-    resetSelectionGroup();
-
     m_selectionGroup = new AbstractGroupItem(m_document->fps());
     scene()->addItem(m_selectionGroup);
     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)) {
+        if ((selection.at(i) && !selection.at(i)->parentItem() && selection.at(i)->isEnabled()) && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) {
             m_selectionGroup->addItem(selection.at(i));
         }
     }
@@ -3130,11 +3155,9 @@ void CustomTrackView::removeTrack(int ix)
 
     int maxHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22();
     for (int i = 0; i < m_guides.count(); i++) {
-        QLineF l = m_guides.at(i)->line();
-        l.setP2(QPointF(l.x2(), maxHeight));
-        m_guides.at(i)->setLine(l);
+        m_guides.at(i)->setLine(0, 0, 0, maxHeight - 1);
     }
-    m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight - 1);
+    m_cursorLine->setLine(0, 0, 0, maxHeight - 1);
     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_document->tracksCount());
 
     m_selectedTrack = qMin(m_selectedTrack, m_document->tracksCount() - 1);
@@ -3637,6 +3660,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         }
         m_dragGuide = NULL;
         m_dragItem = NULL;
+       QGraphicsView::mouseReleaseEvent(event);
         return;
     } else if (m_operationMode == SPACER && m_selectionGroup) {
         int track;
@@ -4254,7 +4278,7 @@ void CustomTrackView::deleteSelectedClips()
     int groupCount = 0;
     int clipCount = 0;
     int transitionCount = 0;
-    // expand & destroy groups
+    // expand & destroy groups    
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == GROUPWIDGET) {
             groupCount++;
@@ -4281,20 +4305,19 @@ void CustomTrackView::deleteSelectedClips()
         } else if (itemList.at(i)->parentItem() && itemList.at(i)->parentItem()->type() == GROUPWIDGET)
             itemList.insert(i + 1, itemList.at(i)->parentItem());
     }
-
+    emit clipItemSelected(NULL);
+    emit transitionItemSelected(NULL);
     for (int i = 0; i < itemList.count(); i++) {
         if (itemList.at(i)->type() == AVWIDGET) {
             clipCount++;
             ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
             //kDebug()<<"// DELETE CLP AT: "<<item->info().startPos.frames(25);
             new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, true, true, deleteSelected);
-            emit clipItemSelected(NULL);
         } else if (itemList.at(i)->type() == TRANSITIONWIDGET) {
             transitionCount++;
             Transition *item = static_cast <Transition *>(itemList.at(i));
             //kDebug()<<"// DELETE TRANS AT: "<<item->info().startPos.frames(25);
             new AddTransitionCommand(this, item->info(), item->transitionEndTrack(), item->toXML(), true, true, deleteSelected);
-            emit transitionItemSelected(NULL);
         }
     }
     if (groupCount > 0 && clipCount == 0 && transitionCount == 0)
@@ -4475,7 +4498,8 @@ void CustomTrackView::doGroupClips(QList <ItemInfo> clipInfos, QList <ItemInfo>
     resetSelectionGroup();
     m_scene->clearSelection();
     if (!group) {
-        for (int i = 0; i < clipInfos.count(); i++) {
+       // ungroup, find main group to destroy it...
+       for (int i = 0; i < clipInfos.count(); i++) {
             ClipItem *clip = getClipItemAt(clipInfos.at(i).startPos, clipInfos.at(i).track);
             if (clip == NULL) continue;
             if (clip->parentItem() && clip->parentItem()->type() == GROUPWIDGET) {
@@ -5169,10 +5193,21 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI
         } else {
             // Check transition keyframes
             QDomElement old = transition->toXML();
-            if (transition->updateKeyframes()) {
+            if (transition->updateKeyframes(oldInfo.cropDuration.frames(m_document->fps()) - 1)) {
                 QDomElement xml = transition->toXML();
                 m_document->renderer()->mltUpdateTransition(xml.attribute("tag"), xml.attribute("tag"), xml.attribute("transition_btrack").toInt(), m_document->tracksCount() - xml.attribute("transition_atrack").toInt(), transition->startPos(), transition->endPos(), xml);
                 new EditTransitionCommand(this, transition->track(), transition->startPos(), old, xml, false, command);
+               ItemInfo info = transition->info();
+               QPoint p;
+               ClipItem *transitionClip = getClipItemAt(info.startPos, info.track);
+               if (transitionClip && transitionClip->baseClip()) {
+                   QString size = transitionClip->baseClip()->getProperty("frame_size");
+                   double factor = transitionClip->baseClip()->getProperty("aspect_ratio").toDouble();
+                   if (factor == 0) factor = 1.0;
+                   p.setX((int)(size.section('x', 0, 0).toInt() * factor + 0.5));
+                   p.setY(size.section('x', 1, 1).toInt());
+               }
+               emit transitionItemSelected(transition, getPreviousVideoTrack(info.track), p, true);
             }
             new MoveTransitionCommand(this, oldInfo, info, false, command);
         }
@@ -5813,11 +5848,9 @@ void CustomTrackView::setScale(double scaleFactor, double verticalScale)
     setMatrix(newmatrix);
     if (adjust) {
         double newHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22();
-        m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), newHeight - 1);
+       m_cursorLine->setLine(0, 0, 0, newHeight - 1);
         for (int i = 0; i < m_guides.count(); i++) {
-            QLineF l = m_guides.at(i)->line();
-            l.setP2(QPointF(l.x2(), newHeight));
-            m_guides.at(i)->setLine(l);
+            m_guides.at(i)->setLine(0, 0, 0, newHeight - 1);
         }
         setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_document->tracksCount());
     }
@@ -6486,7 +6519,11 @@ void CustomTrackView::slotConfigTracks(int ix)
 void CustomTrackView::deleteTimelineTrack(int ix, TrackInfo trackinfo)
 {
     if (m_document->tracksCount() < 2) return;
-    double startY = ix * m_tracksHeight + 1 + m_tracksHeight / 2;
+    // Clear effect stack
+    clearSelection();
+    emit transitionItemSelected(NULL);
+    
+    double startY = ix * m_tracksHeight + 1 + m_tracksHeight / 2;    
     QRectF r(0, startY, sceneRect().width(), m_tracksHeight / 2 - 1);
     QList<QGraphicsItem *> selection = m_scene->items(r);
     QUndoCommand *deleteTrack = new QUndoCommand();
@@ -7328,6 +7365,7 @@ void CustomTrackView::insertZoneOverwrite(QStringList data, int in)
 
 void CustomTrackView::clearSelection(bool emitInfo)
 {
+    if (m_dragItem) m_dragItem->setSelected(false);
     resetSelectionGroup();
     scene()->clearSelection();
     m_dragItem = NULL;