diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp index fd611c4a128ffb202b5edc82cc09498de1bd77a9..af999657526d711b05a0113a83a941d96099a768 100644 --- a/src/bin/bin.cpp +++ b/src/bin/bin.cpp @@ -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); diff --git a/src/bin/bin.h b/src/bin/bin.h index 680734fce1a5199c45e972445c4d5988a7711bb0..04308411d78f965346fa6169f5d7807b8c259d8d 100644 --- a/src/bin/bin.h +++ b/src/bin/bin.h @@ -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 audioStreams); + /** @brief A drag event ended, inform timeline. */ + void processDragEnd(); }; #endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 701f538cecd7dbac56295cd929ecd04db17b285e..2129d406fb8cbdb8285c0d4b65c2d8cdbd66ca73 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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); diff --git a/src/timeline2/view/qml/timeline.qml b/src/timeline2/view/qml/timeline.qml index cc05a3907239f8b852faae13b9aa5c76437433e5..34761b920b8d86abbc330e0bbc616052148957b7 100644 --- a/src/timeline2/view/qml/timeline.qml +++ b/src/timeline2/view/qml/timeline.qml @@ -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) diff --git a/src/timeline2/view/timelinewidget.cpp b/src/timeline2/view/timelinewidget.cpp index d6072d5677c18a5f6fe591f86c00827e715f0025..10ec942be429177cf74988ff572e0d0bc30e82b2 100644 --- a/src/timeline2/view/timelinewidget.cpp +++ b/src/timeline2/view/timelinewidget.cpp @@ -369,3 +369,9 @@ void TimelineWidget::focusTimeline() } } +void TimelineWidget::endDrag() +{ + if (rootObject()) { + QMetaObject::invokeMethod(rootObject(), "endBinDrag"); + } +} diff --git a/src/timeline2/view/timelinewidget.h b/src/timeline2/view/timelinewidget.h index 057b9ed8a7d10891de2a111c99d1e06efa5b9d90..13444b7438f335cba85071d096c9da352d8f5912 100644 --- a/src/timeline2/view/timelinewidget.h +++ b/src/timeline2/view/timelinewidget.h @@ -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();