Fix dropping clip in timeline can lead to crash if drop ended outside timeline

parent 8aa49abd
Pipeline #16298 failed with stage
in 47 seconds
......@@ -629,6 +629,7 @@ bool MyTreeView::performDrag()
drag->setPixmap(QPixmap::fromImage(image));
}
drag->exec();
emit processDragEnd();
return true;
}
......@@ -1958,6 +1959,7 @@ void Bin::slotInitView(QAction *action)
view->setSortingEnabled(true);
view->setWordWrap(true);
connect(view, &MyTreeView::updateDragMode, m_itemModel.get(), &ProjectItemModel::setDragType, Qt::DirectConnection);
connect(view, &MyTreeView::processDragEnd, this, &Bin::processDragEnd);
connect(view, &MyTreeView::displayBinFrame, this, &Bin::showBinFrame);
if (!m_headerInfo.isEmpty()) {
view->header()->restoreState(m_headerInfo);
......@@ -1994,6 +1996,7 @@ void Bin::slotInitView(QAction *action)
view->setGridSize(QSize(zoom.width() * 1.2, zoom.width()));
connect(view, &MyListView::focusView, this, &Bin::slotGotFocus);
connect(view, &MyListView::displayBinFrame, this, &Bin::showBinFrame);
connect(view, &MyListView::processDragEnd, this, &Bin::processDragEnd);
}
m_itemView->setEditTriggers(QAbstractItemView::NoEditTriggers); // DoubleClicked);
m_itemView->setSelectionMode(QAbstractItemView::ExtendedSelection);
......
......@@ -82,6 +82,7 @@ signals:
void focusView();
void updateDragMode(PlaylistState::ClipState type);
void displayBinFrame(QModelIndex ix, int frame);
void processDragEnd();
private:
QPoint m_startPos;
PlaylistState::ClipState m_dragType;
......@@ -115,6 +116,7 @@ signals:
void focusView();
void updateDragMode(PlaylistState::ClipState type);
void displayBinFrame(QModelIndex ix, int frame);
void processDragEnd();
};
class SmallJobLabel : public QPushButton
......@@ -496,6 +498,8 @@ signals:
void refreshPanel(const QString &id);
/** @brief Upon selection, activate timeline target tracks. */
void setupTargets(bool hasVideo, QList <int> audioStreams);
/** @brief A drag event ended, inform timeline. */
void processDragEnd();
};
#endif
......@@ -2203,6 +2203,7 @@ void MainWindow::connectDocument()
connect(m_projectMonitor, &Monitor::durationChanged, this, &MainWindow::slotUpdateProjectDuration);
connect(m_effectList2, &EffectListWidget::reloadFavorites, getMainTimeline(), &TimelineWidget::updateEffectFavorites);
connect(m_transitionList2, &TransitionListWidget::reloadFavorites, getMainTimeline(), &TimelineWidget::updateTransitionFavorites);
connect(pCore->bin(), &Bin::processDragEnd, getMainTimeline(), &TimelineWidget::endDrag);
// TODO REFAC: fix
// trackView->updateProfile(1.0);
......
......@@ -33,6 +33,10 @@ Rectangle {
processingDrag(!root.dragInProgress)
}
function endBinDrag() {
clipDropArea.processDrop()
}
function fitZoom() {
return scrollView.width / (timeline.duration * 1.1)
}
......@@ -377,8 +381,8 @@ Rectangle {
}
}
onExited:{
if (clipBeingDroppedId != -1 && drag.y < drag.x) {
// If we exit on top, remove clip
if (clipBeingDroppedId != -1) {
// If we exit, remove composition
controller.requestItemDeletion(clipBeingDroppedId, false)
clearDropData()
}
......@@ -394,7 +398,9 @@ Rectangle {
clearDropData()
}
}
DropArea { //Drop area for bin/clips
DropArea {
//Drop area for bin/clips
id: clipDropArea
/** @brief local helper function to handle the insertion of multiple dragged items */
function insertAndMaybeGroup(track, frame, droppedData) {
var binIds = droppedData.split(";")
......@@ -424,6 +430,42 @@ Rectangle {
y: ruler.height
x: headerWidth
keys: 'kdenlive/producerslist'
function processDrop()
{
// Process the drop event, useful if drop event happens outside of drop area
if (clipBeingDroppedId != -1) {
var frame = controller.getClipPosition(clipBeingDroppedId)
var track = controller.getClipTrackId(clipBeingDroppedId)
if (!controller.normalEdit()) {
frame = fakeFrame
track = fakeTrack
}
/* We simulate insertion at the final position so that stored undo has correct value
* NOTE: even if dropping multiple clips, requesting the deletion of the first one is
* enough as internally it will request the group deletion
*/
controller.requestItemDeletion(clipBeingDroppedId, false)
var binIds = clipBeingDroppedData.split(";")
if (binIds.length == 1) {
if (controller.normalEdit()) {
timeline.insertClip(track, frame, clipBeingDroppedData, true, true, false)
} else {
timeline.insertClipZone(clipBeingDroppedData, track, frame)
}
} else {
if (controller.normalEdit()) {
timeline.insertClips(track, frame, binIds, true, true)
} else {
// TODO
console.log('multiple clips insert/overwrite not supported yet')
}
}
fakeTrack = -1
fakeFrame = -1
}
clearDropData()
}
onEntered: {
if (clipBeingMovedId == -1 && clipBeingDroppedId == -1) {
//var track = Logic.getTrackIdFromPos(drag.y)
......@@ -489,38 +531,7 @@ Rectangle {
}
}
onDropped: {
if (clipBeingDroppedId != -1) {
var frame = controller.getClipPosition(clipBeingDroppedId)
var track = controller.getClipTrackId(clipBeingDroppedId)
if (!controller.normalEdit()) {
frame = fakeFrame
track = fakeTrack
}
/* We simulate insertion at the final position so that stored undo has correct value
* NOTE: even if dropping multiple clips, requesting the deletion of the first one is
* enough as internally it will request the group deletion
*/
controller.requestItemDeletion(clipBeingDroppedId, false)
var binIds = clipBeingDroppedData.split(";")
if (binIds.length == 1) {
if (controller.normalEdit()) {
timeline.insertClip(track, frame, clipBeingDroppedData, true, true, false)
} else {
timeline.insertClipZone(clipBeingDroppedData, track, frame)
}
} else {
if (controller.normalEdit()) {
timeline.insertClips(track, frame, binIds, true, true)
} else {
// TODO
console.log('multiple clips insert/overwrite not supported yet')
}
}
fakeTrack = -1
fakeFrame = -1
}
clearDropData()
processDrop()
}
}
DropArea { //Drop area for urls (direct drop from file manager)
......
......@@ -369,3 +369,9 @@ void TimelineWidget::focusTimeline()
}
}
void TimelineWidget::endDrag()
{
if (rootObject()) {
QMetaObject::invokeMethod(rootObject(), "endBinDrag");
}
}
......@@ -67,6 +67,8 @@ public slots:
void updateEffectFavorites();
/* @brief Favorite transitions have changed, reload model for context menu */
void updateTransitionFavorites();
/* @brief Bin clip drag ended, make sure we correctly processed the drop */
void endDrag();
private slots:
void slotUngrabHack();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment