Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Start invalidating timeline preview on clip move/insert/delete

parent 27066bf8
......@@ -2739,12 +2739,6 @@ void MainWindow::slotFitZoom()
void MainWindow::slotSetZoom(int value, bool zoomOnMouse)
{
value = qBound(m_zoomSlider->minimum(), value, m_zoomSlider->maximum());
//TODO refac
/*
if (pCore->projectManager()->currentTimeline()) {
pCore->projectManager()->currentTimeline()->slotChangeZoom(value, -1, zoomOnMouse);
}
m_timelineTabs->changeZoom(value, zoomOnMouse);
m_zoomOut->setEnabled(value < m_zoomSlider->maximum());
m_zoomIn->setEnabled(value > m_zoomSlider->minimum());
......@@ -2753,7 +2747,6 @@ void MainWindow::slotSetZoom(int value, bool zoomOnMouse)
m_zoomSlider->blockSignals(true);
m_zoomSlider->setValue(value);
m_zoomSlider->blockSignals(false);
*/
}
void MainWindow::slotShowZoomSliderToolTip(int zoomlevel)
......
......@@ -177,7 +177,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
bool ok = false;
if (pCore->bin()->getBinClip(binId)) {
int cid = ClipModel::construct(timeline, binId, clip);
ok = timeline->requestClipMove(cid, tid, position, true, undo, redo);
ok = timeline->requestClipMove(cid, tid, position, true, false, undo, redo);
} else {
qDebug() << "// Cannot find bin clip: " << binId<<" - "<< clip->get("id");
}
......
......@@ -60,7 +60,7 @@ bool TimelineFunctions::requestClipCut(std::shared_ptr<TimelineItemModel> timeli
res = res && timeline->requestItemResize(clipId, position - start, true, true, undo, redo);
int newDuration = timeline->getClipPlaytime(clipId);
res = res && timeline->requestItemResize(newId, duration - newDuration, false, true, undo, redo);
res = res && timeline->requestClipMove(newId, timeline->getClipTrackId(clipId), position, true, undo, redo);
res = res && timeline->requestClipMove(newId, timeline->getClipTrackId(clipId), position, true, false, undo, redo);
return res;
}
bool TimelineFunctions::requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position)
......@@ -130,10 +130,10 @@ bool TimelineFunctions::requestSpacerEndOperation(std::shared_ptr<TimelineItemMo
bool final = false;
if (res > -1) {
if (clips.size() > 1) {
final = timeline->requestGroupMove(clipId, res, 0, endPosition - startPosition, true, undo, redo);
final = timeline->requestGroupMove(clipId, res, 0, endPosition - startPosition, true, true, undo, redo);
} else {
// only 1 clip to be moved
final = timeline->requestClipMove(clipId, track, endPosition, true, undo, redo);
final = timeline->requestClipMove(clipId, track, endPosition, true, true, undo, redo);
}
}
if (final && clips.size() > 1) {
......
......@@ -251,8 +251,9 @@ int TimelineModel::getPreviousVideoTrackPos(int trackId) const
return it == m_allTracks.begin() ? 0 : getTrackMltIndex((*it)->getId());
}
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, Fun &undo, Fun &redo)
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, Fun &undo, Fun &redo)
{
qDebug()<<"// FINAL MOVE: "<<invalidateTimeline<< ", UPDATE VIEW: "<<updateView;
if (trackId == -1) {
return false;
}
......@@ -262,14 +263,14 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
bool ok = true;
int old_trackId = getClipTrackId(clipId);
if (old_trackId != -1) {
ok = getTrackById(old_trackId)->requestClipDeletion(clipId, updateView, local_undo, local_redo);
ok = getTrackById(old_trackId)->requestClipDeletion(clipId, updateView, invalidateTimeline, local_undo, local_redo);
if (!ok) {
bool undone = local_undo();
Q_ASSERT(undone);
return false;
}
}
ok = getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, local_undo, local_redo);
ok = getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, invalidateTimeline, local_undo, local_redo);
if (!ok) {
bool undone = local_undo();
Q_ASSERT(undone);
......@@ -279,7 +280,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
return true;
}
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool logUndo)
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool logUndo, bool invalidateTimeline)
{
#ifdef LOGGING
m_logFile << "timeline->requestClipMove(" << clipId << "," << trackId << " ," << position << ", " << (updateView ? "true" : "false") << ", "
......@@ -302,7 +303,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
}
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool res = requestClipMove(clipId, trackId, position, updateView, undo, redo);
bool res = requestClipMove(clipId, trackId, position, updateView, invalidateTimeline, undo, redo);
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Move clip"));
}
......@@ -347,7 +348,7 @@ int TimelineModel::suggestClipMove(int clipId, int trackId, int position, int sn
// we check if move is possible
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool possible = requestClipMove(clipId, trackId, position, false, undo, redo);
bool possible = requestClipMove(clipId, trackId, position, false, false, undo, redo);
qDebug() << "Original move success" << possible;
if (possible) {
undo();
......@@ -436,7 +437,7 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
QWriteLocker locker(&m_lock);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestClipInsertion(binClipId, trackId, position, id, undo, redo);
bool result = requestClipInsertion(binClipId, trackId, position, id, logUndo, undo, redo);
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Insert Clip"));
}
......@@ -478,12 +479,12 @@ bool TimelineModel::requestClipCreation(const QString &binClipId, int &id, Fun &
return true;
}
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, Fun &undo, Fun &redo)
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, Fun &undo, Fun &redo)
{
std::function<bool(void)> local_undo = []() { return true; };
std::function<bool(void)> local_redo = []() { return true; };
bool res = requestClipCreation(binClipId, id, local_undo, local_redo);
res = res && requestClipMove(id, trackId, position, true, local_undo, local_redo);
res = res && requestClipMove(id, trackId, position, logUndo, logUndo, local_undo, local_redo);
if (!res) {
bool undone = local_undo();
Q_ASSERT(undone);
......@@ -525,7 +526,7 @@ bool TimelineModel::requestClipDeletion(int clipId, Fun &undo, Fun &redo)
{
int trackId = getClipTrackId(clipId);
if (trackId != -1) {
bool res = getTrackById(trackId)->requestClipDeletion(clipId, true, undo, redo);
bool res = getTrackById(trackId)->requestClipDeletion(clipId, true, true, undo, redo);
if (!res) {
undo();
return false;
......@@ -598,14 +599,14 @@ bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, i
{
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool res = requestGroupMove(clipId, groupId, delta_track, delta_pos, updateView, undo, redo);
bool res = requestGroupMove(clipId, groupId, delta_track, delta_pos, updateView, logUndo, undo, redo);
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Move group"));
}
return res;
}
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, Fun &undo, Fun &redo)
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool finalMove, Fun &undo, Fun &redo)
{
#ifdef LOGGING
m_logFile << "timeline->requestGroupMove(" << clipId << "," << groupId << " ," << delta_track << ", " << delta_pos << ", "
......@@ -640,7 +641,7 @@ bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, i
std::advance(it, target_track_position);
int target_track = (*it)->getId();
int target_position = m_allClips[clip]->getPosition() + delta_pos;
ok = requestClipMove(clip, target_track, target_position, updateView || (clip != clipId), undo, redo);
ok = requestClipMove(clip, target_track, target_position, updateView || (clip != clipId), finalMove, undo, redo);
} else {
ok = false;
}
......@@ -1743,8 +1744,8 @@ void TimelineModel::requestClipReload(int clipId)
int old_trackId = getClipTrackId(clipId);
int oldPos = getClipPosition(clipId);
if (old_trackId != -1) {
getTrackById(old_trackId)->requestClipDeletion(clipId, false, local_undo, local_redo);
getTrackById(old_trackId)->requestClipInsertion(clipId, oldPos, false, local_undo, local_redo);
getTrackById(old_trackId)->requestClipDeletion(clipId, false, false, local_undo, local_redo);
getTrackById(old_trackId)->requestClipInsertion(clipId, oldPos, true, true, local_undo, local_redo);
}
}
......
......@@ -253,7 +253,7 @@ public:
@param updateView if set to false, no signal is sent to qml
@param logUndo if set to false, no undo object is stored
*/
Q_INVOKABLE bool requestClipMove(int clipId, int trackId, int position, bool updateView = true, bool logUndo = true);
Q_INVOKABLE bool requestClipMove(int clipId, int trackId, int position, bool updateView = true, bool logUndo = true, bool invalidateTimeline = false);
/* @brief Move a composition to a specific position This action is undoable
Returns true on success. If it fails, nothing is modified. If the clip is
......@@ -265,7 +265,7 @@ public:
/* Same function, but accumulates undo and redo, and doesn't check
for group*/
bool requestClipMove(int clipId, int trackId, int position, bool updateView, Fun &undo, Fun &redo);
bool requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, Fun &undo, Fun &redo);
bool requestCompositionMove(int transid, int trackId, int compositionTrack, int position, bool updateView, Fun &undo, Fun &redo);
Q_INVOKABLE int getCompositionPosition(int compoId) const;
......@@ -295,7 +295,7 @@ public:
stored */
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo = true);
/* Same function, but accumulates undo and redo*/
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, Fun &undo, Fun &redo);
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, Fun &undo, Fun &redo);
/* @brief Creates a new clip instance without inserting it.
This action is undoable, returns true on success
......@@ -326,7 +326,7 @@ public:
@param logUndo if set to true, an undo object is created
*/
bool requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView = true, bool logUndo = true);
bool requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, Fun &undo, Fun &redo);
bool requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool finalMove, Fun &undo, Fun &redo);
/* @brief Deletes all clips inside the group that contains the given clip.
This action is undoable
......@@ -553,6 +553,8 @@ signals:
/* @brief signal triggered by clearAssetView */
void requestClearAssetView(int);
void requestMonitorRefresh();
/* @brief signal triggered by track operations */
void invalidateClip(int);
protected:
std::unique_ptr<Mlt::Tractor> m_tractor;
......
......@@ -98,16 +98,17 @@ int TrackModel::getClipsCount()
return count;
}
Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updateView)
Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove)
{
QWriteLocker locker(&m_lock);
// By default, insertion occurs in topmost track
// Find out the clip id at position
int target_clip = m_playlists[0].get_clip_index_at(position);
int count = m_playlists[0].count();
bool audioOnly = false;
// we create the function that has to be executed after the melt order. This is essentially book-keeping
auto end_function = [clipId, this, position, updateView]() {
auto end_function = [clipId, this, position, updateView, finalMove]() {
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> clip = ptr->getClipPtr(clipId);
m_allClips[clip->getId()] = clip; // store clip
......@@ -123,10 +124,15 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
ptr->_beginInsertRows(ptr->makeTrackIndexFromID(getId()), clip_index, clip_index);
ptr->_endInsertRows();
int state = m_track->get_int("hide");
if ((state == 0 || state == 2) && m_track->get_int("kdenlive:audio_track") != 1) {
bool audioOnly = clip->isAudioOnly();
if (!audioOnly && (state == 0 || state == 2) && m_track->get_int("kdenlive:audio_track") != 1) {
// only refresh monitor if not an audio track and not hidden
ptr->checkRefresh(new_in, new_out);
}
if (!audioOnly && finalMove) {
qDebug()<<"/// INVALIDATE CLIP ON INSERTT!!!!!!";
ptr->invalidateClip(clip->getId());
}
}
return true;
}
......@@ -158,7 +164,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
length = clip->getPlaytime();
}
if (blank_end >= position + length) {
return [this, position, clipId, end_function]() {
return [this, position, clipId, end_function, updateView]() {
if (auto ptr = m_parent.lock()) {
// Lock MLT playlist so that we don't end up with an invalid frame being displayed
m_playlists[0].lock();
......@@ -177,26 +183,27 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
return []() { return false; };
}
bool TrackModel::requestClipInsertion(int clipId, int position, bool updateView, Fun &undo, Fun &redo)
bool TrackModel::requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
auto operation = requestClipInsertion_lambda(clipId, position, updateView);
auto operation = requestClipInsertion_lambda(clipId, position, updateView, finalMove);
if (operation()) {
auto reverse = requestClipDeletion_lambda(clipId, updateView);
auto reverse = requestClipDeletion_lambda(clipId, updateView, finalMove);
UPDATE_UNDO_REDO(operation, reverse, undo, redo);
return true;
}
return false;
}
Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView)
Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove)
{
QWriteLocker locker(&m_lock);
// Find index of clip
int clip_position = m_allClips[clipId]->getPosition();
bool audioOnly = m_allClips[clipId]->isAudioOnly();
int old_in = clip_position;
int old_out = old_in + m_allClips[clipId]->getPlaytime();
return [clip_position, clipId, old_in, old_out, updateView, this]() {
return [clip_position, clipId, old_in, old_out, updateView, finalMove, audioOnly, this]() {
auto clip_loc = getClipIndexAt(clip_position);
int old_clip_index = getRowfromClip(clipId);
if (updateView) {
......@@ -212,6 +219,12 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView)
Q_ASSERT(!m_playlists[target_track].is_blank(target_clip));
auto prod = m_playlists[target_track].replace_with_blank(target_clip);
if (prod != nullptr) {
if (finalMove && !audioOnly) {
if (auto ptr = m_parent.lock()) {
qDebug()<<"/// INVALIDATE CLIP ON DELETE!!!!!!";
ptr->invalidateClip(clipId);
}
}
m_playlists[target_track].consolidate_blanks();
m_allClips[clipId]->setCurrentTrackId(-1);
m_allClips.erase(clipId);
......@@ -221,7 +234,7 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView)
ptr->m_snaps->removePoint(old_in);
ptr->m_snaps->removePoint(old_out);
int state = m_track->get_int("hide");
if ((state == 0 || state == 2) && m_track->get_int("kdenlive:audio_track") != 1) {
if (!audioOnly && (state == 0 || state == 2) && m_track->get_int("kdenlive:audio_track") != 1) {
// only refresh monitor if not an audio track and not hidden
ptr->checkRefresh(old_in, old_out);
}
......@@ -233,15 +246,15 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView)
};
}
bool TrackModel::requestClipDeletion(int clipId, bool updateView, Fun &undo, Fun &redo)
bool TrackModel::requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
Q_ASSERT(m_allClips.count(clipId) > 0);
auto old_clip = m_allClips[clipId];
int old_position = old_clip->getPosition();
auto operation = requestClipDeletion_lambda(clipId, updateView);
auto operation = requestClipDeletion_lambda(clipId, updateView, finalMove);
if (operation()) {
auto reverse = requestClipInsertion_lambda(clipId, old_position, updateView);
auto reverse = requestClipInsertion_lambda(clipId, old_position, updateView, finalMove);
UPDATE_UNDO_REDO(operation, reverse, undo, redo);
return true;
}
......
......@@ -104,9 +104,9 @@ protected:
@param undo Lambda function containing the current undo stack. Will be updated with current operation
@param redo Lambda function containing the current redo queue. Will be updated with current operation
*/
bool requestClipInsertion(int clipId, int position, bool updateView, Fun &undo, Fun &redo);
bool requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo);
/* @brief This function returns a lambda that performs the requested operation */
Fun requestClipInsertion_lambda(int clipId, int position, bool updateView);
Fun requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove);
/* @brief Performs an deletion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
......@@ -116,9 +116,9 @@ protected:
@param undo Lambda function containing the current undo stack. Will be updated with current operation
@param redo Lambda function containing the current redo queue. Will be updated with current operation
*/
bool requestClipDeletion(int clipId, bool updateView, Fun &undo, Fun &redo);
bool requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo);
/* @brief This function returns a lambda that performs the requested operation */
Fun requestClipDeletion_lambda(int clipId, bool updateView);
Fun requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove);
/* @brief Performs an insertion of the given composition.
Returns true if the operation succeeded, and otherwise, the track is not modified.
......
......@@ -109,7 +109,7 @@ bool PreviewManager::initialize()
bool PreviewManager::buildPreviewTrack()
{
if (m_previewTrack) {
if (m_previewTrack != nullptr) {
return false;
}
// Create overlay track
......@@ -551,10 +551,8 @@ void PreviewManager::invalidatePreview(int startFrame, int endFrame)
end *= chunkSize;
qSort(m_renderedChunks);
for (const auto &ix : m_renderedChunks) {
if (ix.toInt() >= start && ix.toInt() <= end) {
return;
}
if (m_renderedChunks.isEmpty() || m_renderedChunks.constFirst().toInt() > end || m_renderedChunks.constLast().toInt() < start) {
return;
}
m_previewGatherTimer.stop();
abortPreview();
......@@ -568,10 +566,14 @@ void PreviewManager::invalidatePreview(int startFrame, int endFrame)
}
Mlt::Producer *prod = m_previewTrack->replace_with_blank(ix);
delete prod;
m_renderedChunks.removeAll(i);
m_dirtyChunks << i;
}
}
if (hasPreview) {
m_previewTrack->consolidate_blanks();
m_controller->renderedChunksChanged();
m_controller->dirtyChunksChanged();
}
m_tractor->unlock();
m_previewGatherTimer.start();
......@@ -600,7 +602,6 @@ void PreviewManager::reloadChunks(const QVariantList chunks)
void PreviewManager::gotPreviewRender(int frame, const QString &file, int progress)
{
qDebug()<<"// GOT PREV RENDER: "<<frame;
if (m_previewTrack == nullptr) {
return;
}
......@@ -618,18 +619,15 @@ void PreviewManager::gotPreviewRender(int frame, const QString &file, int progre
if (m_previewTrack->is_blank_at(frame)) {
Mlt::Producer prod(*m_tractor->profile(), file.toUtf8().constData());
if (prod.is_valid()) {
qDebug()<<"// YOP PROD OK";
m_renderedChunks << frame;
m_controller->renderedChunksChanged();
//m_ruler->updatePreview(frame, true, true);
prod.set("mlt_service", "avformat-novalidate");
m_previewTrack->insert_at(frame, &prod, 1);
} else {
qDebug()<<"// INVALID PROD: "<<file;
qCDebug(KDENLIVE_LOG) << "* * * INVALID PROD: " << file;
}
} else {
qDebug()<<"// NON EMPTY PREV: ";
qCDebug(KDENLIVE_LOG) << "* * * NON EMPTY PROD: " << frame;
}
m_previewTrack->consolidate_blanks();
......
......@@ -223,11 +223,9 @@ Column{
var cIndex = clip.clipId
var frame = Math.round(clip.x / timeScale)
var origFrame = Math.round(clip.originalX / timeScale)
console.log("Asking move ",toTrack, cIndex, frame)
controller.requestClipMove(cIndex, clip.originalTrackId, origFrame, false, false)
var val = controller.requestClipMove(cIndex, toTrack, frame, true, true)
console.log("RESULT", val)
controller.requestClipMove(cIndex, clip.originalTrackId, origFrame, false, false, false)
var val = controller.requestClipMove(cIndex, toTrack, frame, true, true, true)
}
onDragged: { //called when the move is in process
var toTrack = clip.trackId
......@@ -236,8 +234,7 @@ Column{
var frame = Math.round(clip.x / timeScale)
frame = controller.suggestClipMove(cIndex, toTrack, frame, root.snapping);
if (!controller.requestClipMove(cIndex, toTrack, frame, false, false)) {
if (!controller.requestClipMove(cIndex, toTrack, frame, false, false, false)) {
// Abort move
clip.x = clip.draggedX
} else {
......
......@@ -220,15 +220,13 @@ Rectangle {
scrollTimer.running = false
}
onPositionChanged: {
console.log('======================== ON POS CHANGED ========================================')
if (clipBeingMovedId == -1) {
var track = Logic.getTrackIdFromPos(drag.y)
var frame = Math.round((drag.x + scrollView.flickableItem.contentX) / timeline.scaleFactor)
frame = controller.suggestSnapPoint(frame, root.snapping)
if (clipBeingDroppedId >= 0){
controller.requestClipMove(clipBeingDroppedId, track, frame, true, false)
controller.requestClipMove(clipBeingDroppedId, track, frame, true, false, false)
continuousScrolling(drag.x + scrollView.flickableItem.contentX)
} else {
clipBeingDroppedId = timeline.insertClip(track, frame, drag.getDataAsString('kdenlive/producerslist'), false)
continuousScrolling(drag.x + scrollView.flickableItem.contentX)
......@@ -545,7 +543,7 @@ Rectangle {
var track = controller.getClipTrackId(spacerGroup)
var frame = Math.round((mouse.x + scrollView.flickableItem.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame
frame = controller.suggestClipMove(spacerGroup, track, frame, root.snapping);
controller.requestClipMove(spacerGroup, track, frame, true, false)
controller.requestClipMove(spacerGroup, track, frame, true, false, false)
continuousScrolling(mouse.x + scrollView.flickableItem.contentX)
}
scim = true
......@@ -900,14 +898,14 @@ Rectangle {
var frame = Math.max(0, Math.round(clip.x / timeScale))
if (currentTrack >= 0 && currentTrack < tracksRepeater.count) {
var track = tracksRepeater.itemAt(currentTrack)
if (controller.requestClipMove(clip.clipId, track.trackId, frame, false, false)) {
if (controller.requestClipMove(clip.clipId, track.trackId, frame, false, false, false)) {
clip.reparent(track)
clip.trackIndex = track.DelegateModel.itemsIndex
clip.trackId = track.trackId
} else {
if (track.trackId != clip.trackId) {
// check if we can move on existing track
if (!controller.requestClipMove(clip.clipId, clip.trackId, frame, false, false)) {
if (!controller.requestClipMove(clip.clipId, clip.trackId, frame, false, false, false)) {
// Abort move
clip.x = clip.draggedX
} else {
......
......@@ -68,6 +68,9 @@ void TimelineController::setModel(std::shared_ptr<TimelineItemModel> model)
[&](int id){pCore->clearAssetPanel(id);});
connect(m_model.get(), &TimelineItemModel::requestMonitorRefresh,
[&](){pCore->requestMonitorRefresh();});
connect(m_model.get(), &TimelineModel::invalidateClip, this,
&TimelineController::invalidateClip, Qt::DirectConnection);
}
std::shared_ptr<TimelineItemModel> TimelineController::getModel() const
......@@ -954,3 +957,13 @@ void TimelineController::removeSpace(int trackId, int frame, bool affectAllTrack
requestSpacerEndOperation(cid, start, start - spaceDuration);
}
void TimelineController::invalidateClip(int cid)
{
if (!m_timelinePreview) {
return;
}
int start = m_model->getItemPosition(cid);
int end = start + m_model->getItemPlaytime(cid);
qDebug()<<"invalid range: "<<start<<"-"<<end;
m_timelinePreview->invalidatePreview(start, end);
}
......@@ -288,6 +288,9 @@ public slots:
/** @brief Dis / enable timeline preview. */
void disablePreview(bool disable);
private slots:
void invalidateClip(int cid);
private:
QQuickItem *m_root;
KActionCollection *m_actionCollection;
......
......@@ -1356,7 +1356,7 @@ TEST_CASE("Undo and Redo", "[ClipModel]")
{
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
REQUIRE(timeline->requestClipMove(cid6, tid1, 7, true, undo, redo));
REQUIRE(timeline->requestClipMove(cid6, tid1, 7, true, true, undo, redo));
pCore->pushUndo(undo, redo, QString());
}
auto state3 = [&]() {
......
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