Commits

Anonymous committed a01e37d

Fix crash when doing clip resize and clicking item quickly

Comments (0)

Files changed (2)

src/customtrackview.cpp

     bool found = false;
     QStringList lockedTracks;
     double yOffset = 0;
+    m_selectionMutex.lock();
     while (!m_dragGuide && ct < collisionList.count()) {
         if (collisionList.at(ct)->type() == AVWIDGET || collisionList.at(ct)->type() == TRANSITIONWIDGET) {
             collisionClip = static_cast <AbstractClipItem *>(collisionList.at(ct));
         displayContextMenu(event->globalPos(), m_dragItem, dragGroup);
         m_menuPosition = m_clickEvent;
     }
-
+    m_selectionMutex.unlock();
     // No item under click
     if (m_dragItem == NULL || m_tool == SPACERTOOL) {
         resetSelectionGroup(false);
 
             QList <GenTime> offsetList;
             // create group to hold selected items
+	    m_selectionMutex.lock();
             m_selectionGroup = new AbstractGroupItem(m_document->fps());
             scene()->addItem(m_selectionGroup);
 
                 }
             }
             m_spacerOffset = m_selectionGroup->sceneBoundingRect().left() - (int)(mapToScene(m_clickEvent).x());
+	    m_selectionMutex.unlock();
             if (!offsetList.isEmpty()) {
                 qSort(offsetList);
                 QList <GenTime> cleandOffsetList;
 	    m_dragItem = NULL;
 	}
         groupSelectedItems(QList <QGraphicsItem*>(), false, true);
+	m_selectionMutex.lock();
 	if (m_selectionGroup) {
 	    m_selectionGroup->setProperty("y_absolute", yOffset);
 	    m_selectionGroup->setProperty("locked_tracks", lockedTracks);
 	}
-	
+	m_selectionMutex.unlock();
 	if (m_dragItem) { 
 	    ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
 	    updateClipTypeActions(dragGroup == NULL ? clip : NULL);
     }
     else {
 	QGraphicsView::mousePressEvent(event);
+	m_selectionMutex.lock();
 	if (m_selectionGroup) {
 	    QList<QGraphicsItem *> children = m_selectionGroup->childItems();
 	    for (int i = 0; i < children.count(); i++) {
             dragGroup->setSelected(itemSelected);
 	}
 	m_dragItem->setSelected(itemSelected);
+	m_selectionMutex.unlock();
     }
 
     if (collisionClip != NULL || m_dragItem == NULL) {
         else
             updateSnapPoints(m_dragItem);
     } else {
+	m_selectionMutex.lock();
         QList <GenTime> offsetList;
         QList<QGraphicsItem *> children = m_selectionGroup->childItems();
         for (int i = 0; i < children.count(); i++) {
             }
             updateSnapPoints(NULL, cleandOffsetList, true);
         }
+        m_selectionMutex.unlock();
     }
 
     if (m_operationMode == KEYFRAME) {
 void CustomTrackView::rebuildGroup(AbstractGroupItem *group)
 {
     if (group) {
+	m_selectionMutex.lock();
+	if (group == m_selectionGroup) m_selectionGroup = NULL;
         QList <QGraphicsItem *> children = group->childItems();
         m_document->clipManager()->removeGroup(group);
 	for (int i = 0; i < children.count(); i++) {
 	    group->removeFromGroup(children.at(i));
 	}
 	scene()->destroyItemGroup(group);
+	m_selectionMutex.unlock();
         groupSelectedItems(children, group != m_selectionGroup, true);
     }
 }
 
 void CustomTrackView::resetSelectionGroup(bool selectItems)
 {
+    QMutexLocker lock(&m_selectionMutex);
     if (m_selectionGroup) {
         // delete selection group
         bool snap = KdenliveSettings::snaptopoints();
 
 void CustomTrackView::groupSelectedItems(QList <QGraphicsItem *> selection, bool createNewGroup, bool selectNewGroup)
 {
+    QMutexLocker lock(&m_selectionMutex);
     if (m_selectionGroup) {
         kDebug() << "///// ERROR, TRYING TO OVERRIDE EXISTING GROUP";
         return;
 	    }
 	    AbstractGroupItem *grp = static_cast<AbstractGroupItem *>(value);
 	    m_document->clipManager()->removeGroup(grp);
+	    if (grp == m_selectionGroup) m_selectionGroup = NULL;
 	    scene()->destroyItemGroup(grp);
 	}
 
     m_scene->clearSelection();
     m_dragItem = NULL;
     resetSelectionGroup(false);
+    QMutexLocker lock(&m_selectionMutex);
     if (track < 0 || track > m_document->tracksCount() - 1 || m_document->trackInfoAt(m_document->tracksCount() - track - 1).isLocked) return true;
     if (data->hasFormat("kdenlive/clip")) {    
         QStringList list = QString(data->data("kdenlive/clip")).split(';');
         m_thumbsTimer.stop();
         m_waitingThumbs.clear();
         QList<QGraphicsItem *> items;
+	QMutexLocker lock(&m_selectionMutex);
 	if (m_selectionGroup) items = m_selectionGroup->childItems();
 	else if (m_dragItem) items.append(m_dragItem);
         qDeleteAll(items);
         QRectF r(0, startY, sceneRect().width(), sceneRect().height() - startY);
         QList<QGraphicsItem *> selection = m_scene->items(r);
         resetSelectionGroup();
-
+	m_selectionMutex.lock();
         m_selectionGroup = new AbstractGroupItem(m_document->fps());
         scene()->addItem(m_selectionGroup);
         for (int i = 0; i < selection.count(); i++) {
 	    if (tr) tr->setForcedTrack(info.forceTrack, info.a_track);
 	    else kDebug()<<"// Cannot update TRANSITION AT: "<<info.b_track<<" / "<<info.startPos.frames(m_document->fps()); 
 	}
-	
+	m_selectionMutex.unlock();
         resetSelectionGroup(false);
         m_document->renderer()->unlockService(tractor);
     }
     double startY = ix * (m_tracksHeight + 1) + m_tracksHeight / 2;
     QRectF r(0, startY, sceneRect().width(), sceneRect().height() - startY);
     QList<QGraphicsItem *> selection = m_scene->items(r);
-
+    m_selectionMutex.lock();
     m_selectionGroup = new AbstractGroupItem(m_document->fps());
     scene()->addItem(m_selectionGroup);
     for (int i = 0; i < selection.count(); i++) {
             }
         }
     }
+    m_selectionMutex.unlock();
     resetSelectionGroup(false);
     m_document->renderer()->unlockService(tractor);
 
 {
     int diff = duration.frames(m_document->fps());
     resetSelectionGroup();
+    m_selectionMutex.lock();
     m_selectionGroup = new AbstractGroupItem(m_document->fps());
     scene()->addItem(m_selectionGroup);
     ClipItem *clip;
             }
         }
     }
+    m_selectionMutex.unlock();
     resetSelectionGroup(false);
     if (track != -1)
         track = m_document->tracksCount() - track;
             if (clip->parentItem() && clip->parentItem()->type() == GROUPWIDGET) {
                 AbstractGroupItem *grp = static_cast <AbstractGroupItem *>(clip->parentItem());
                 m_document->clipManager()->removeGroup(grp);
+		if (grp == m_selectionGroup) m_selectionGroup = NULL;
                 scene()->destroyItemGroup(grp);
             }
             clip->setFlag(QGraphicsItem::ItemIsMovable, true);
             if (tr->parentItem() && tr->parentItem()->type() == GROUPWIDGET) {
                 AbstractGroupItem *grp = static_cast <AbstractGroupItem *>(tr->parentItem());
                 m_document->clipManager()->removeGroup(grp);
+		if (grp == m_selectionGroup) m_selectionGroup = NULL;
                 scene()->destroyItemGroup(grp);
+		grp = NULL;
             }
             tr->setFlag(QGraphicsItem::ItemIsMovable, true);
         }
     // Group Items
     resetSelectionGroup();
     m_scene->clearSelection();
-
+    m_selectionMutex.lock();
     m_selectionGroup = new AbstractGroupItem(m_document->fps());
     scene()->addItem(m_selectionGroup);
 
                 m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
             }
         }
-
+	m_selectionMutex.unlock();
         resetSelectionGroup(false);
 	for (int i = 0; i < groupList.count(); i++) {
 	    rebuildGroup(groupList.at(i));
         }
         clip->setFlag(QGraphicsItem::ItemIsMovable, true);
         m_document->clipManager()->removeGroup(grp);
+	if (grp == m_selectionGroup) m_selectionGroup = NULL;
         scene()->destroyItemGroup(grp);
     }
 }
             }
             m_document->clipManager()->removeGroup(grp);
             m_scene->addItem(grp);
+	    if (grp == m_selectionGroup) m_selectionGroup = NULL;
             scene()->destroyItemGroup(grp);
             scene()->clearSelection();
             /*for (int j = 0; j < children.count(); j++) {

src/customtrackview.h

     int m_selectedTrack;
     int m_spacerOffset;
 
+    QMutex m_selectionMutex;
     QMutex m_mutex;
     QWaitCondition m_producerNotReady;
     KStatefulBrush m_activeTrackBrush;