aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2016-05-01 23:08:07 +0200
committerJean-Baptiste Mardelle <[email protected]>2016-05-01 23:08:07 +0200
commit4d06ce302b8c161badea362b5a1253dfec9dcbf5 (patch)
tree7416a9542917abd131bf82574d32141a5d31ef15
parentcdaef081729680c1f3d52446e45a242286242122 (diff)
Fix Insert adding audio clip when no audio target is set
Fix Non audio clips being split Enable Timeline Insert mode for mouse navigation (only affects current track) Ref: T1961
-rw-r--r--src/bin/projectclip.cpp5
-rw-r--r--src/bin/projectclip.h2
-rw-r--r--src/definitions.h9
-rw-r--r--src/mainwindow.cpp4
-rw-r--r--src/timeline/abstractgroupitem.cpp18
-rw-r--r--src/timeline/abstractgroupitem.h2
-rw-r--r--src/timeline/clipitem.cpp5
-rw-r--r--src/timeline/clipitem.h7
-rw-r--r--src/timeline/customtrackview.cpp249
-rw-r--r--src/timeline/customtrackview.h13
-rw-r--r--src/timeline/timeline.cpp11
-rw-r--r--src/timeline/timeline.h7
-rw-r--r--src/timeline/timelinecommands.cpp28
-rw-r--r--src/timeline/timelinecommands.h10
-rw-r--r--src/timeline/track.cpp20
-rw-r--r--src/timeline/track.h8
16 files changed, 272 insertions, 126 deletions
diff --git a/src/bin/projectclip.cpp b/src/bin/projectclip.cpp
index b888fe2..27e6ffa 100644
--- a/src/bin/projectclip.cpp
+++ b/src/bin/projectclip.cpp
@@ -1278,3 +1278,8 @@ QImage ProjectClip::findCachedThumb(int pos)
const QString path = url().path() + '_' + QString::number(pos);
return bin()->findCachedPixmap(path);
}
+
+bool ProjectClip::hasAudio() const
+{
+ return (m_type == AV || m_type == Audio || m_type == Playlist);
+}
diff --git a/src/bin/projectclip.h b/src/bin/projectclip.h
index 3fb38d4..4c8c537 100644
--- a/src/bin/projectclip.h
+++ b/src/bin/projectclip.h
@@ -214,6 +214,8 @@ public:
/** @brief Returns a cached pixmap for a frame of this clip */
QImage findCachedThumb(int pos);
void slotQueryIntraThumbs(QList <int> frames);
+ /** @brief Returns true if this producer has audio */
+ bool hasAudio() const;
public slots:
void updateAudioThumbnail(QVariantList audioLevels);
diff --git a/src/definitions.h b/src/definitions.h
index e157d9e..fcdbd7d 100644
--- a/src/definitions.h
+++ b/src/definitions.h
@@ -218,6 +218,15 @@ public:
bool isValid() const {
return startPos != endPos;
}
+ bool contains(GenTime pos) const {
+ if (startPos == endPos)
+ return true;
+ return (pos < endPos && pos > startPos);
+ }
+ bool operator==(const ItemInfo &a)
+ {
+ return startPos == a.startPos && endPos == a.endPos && track == a.track && cropStart == a.cropStart;
+ }
};
class TransitionInfo {
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index b39dce8..e8bcf0b 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -847,8 +847,6 @@ void MainWindow::setupActions()
toolbar->addAction(m_insertEditTool);
m_insertEditTool->setCheckable(true);
m_insertEditTool->setChecked(false);
- // not implemented yet
- m_insertEditTool->setEnabled(false);
QActionGroup *editGroup = new QActionGroup(this);
editGroup->addAction(m_normalEditTool);
@@ -856,8 +854,6 @@ void MainWindow::setupActions()
editGroup->addAction(m_insertEditTool);
editGroup->setExclusive(true);
connect(editGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotChangeEdit(QAction*)));
- //connect(m_overwriteEditTool, SIGNAL(toggled(bool)), this, SLOT(slotSetOverwriteMode(bool)));
-
toolbar->addSeparator();
// create tools buttons
diff --git a/src/timeline/abstractgroupitem.cpp b/src/timeline/abstractgroupitem.cpp
index 587274f..11128c8 100644
--- a/src/timeline/abstractgroupitem.cpp
+++ b/src/timeline/abstractgroupitem.cpp
@@ -574,4 +574,22 @@ GenTime AbstractGroupItem::duration()
return end - start;
}
+GenTime AbstractGroupItem::startPos()
+{
+ QList <QGraphicsItem *> children = childItems();
+ GenTime start = GenTime(-1.0);
+ for (int i = 0; i < children.count(); ++i) {
+ if (children.at(i)->type() != GroupWidget) {
+ AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
+ if (item) {
+ if (start < GenTime() || item->startPos() < start)
+ start = item->startPos();
+ }
+ } else {
+ children << children.at(i)->childItems();
+ }
+ }
+ return start;
+}
+
diff --git a/src/timeline/abstractgroupitem.h b/src/timeline/abstractgroupitem.h
index bdf7b4b..35c3bd8 100644
--- a/src/timeline/abstractgroupitem.h
+++ b/src/timeline/abstractgroupitem.h
@@ -60,6 +60,8 @@ public:
/** @brief Gets the duration (length) of the group. */
GenTime duration();
+ /** @brief Gets the start frame of the group. */
+ GenTime startPos();
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
diff --git a/src/timeline/clipitem.cpp b/src/timeline/clipitem.cpp
index 3420cb8..671da75 100644
--- a/src/timeline/clipitem.cpp
+++ b/src/timeline/clipitem.cpp
@@ -1854,6 +1854,11 @@ PlaylistState::ClipState ClipItem::clipState() const
return m_clipState;
}
+bool ClipItem::hasAudio() const
+{
+ return (m_clipState != PlaylistState::VideoOnly && m_binClip->hasAudio());
+}
+
void ClipItem::updateState(const QString &id)
{
if (id.startsWith(QLatin1String("slowmotion"))) {
diff --git a/src/timeline/clipitem.h b/src/timeline/clipitem.h
index 9432682..0dd5c58 100644
--- a/src/timeline/clipitem.h
+++ b/src/timeline/clipitem.h
@@ -179,13 +179,16 @@ public:
void resetFrameWidth(int width);
/** @brief Clip is about to be deleted, block thumbs. */
void stopThumbs();
-
+
/** @brief Get a free index value for effect group. */
int nextFreeEffectGroupIndex() const;
-
+
/** @brief Returns true of this clip needs a duplicate (MLT requires duplicate for clips with audio or we get clicks. */
bool needsDuplicate() const;
+ /** @brief Returns true of this has audio. */
+ bool hasAudio() const;
+
/** @brief Returns some info useful for recreating this clip. */
PlaylistState::ClipState clipState() const;
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 777e283..3b98fca 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -1585,7 +1585,7 @@ void CustomTrackView::editItemDuration()
startInfo = clipInfo;
clipInfo.startPos = d->startPos();
clipInfo.endPos = item->endPos() + (clipInfo.startPos - startInfo.startPos);
- new MoveClipCommand(this, startInfo, clipInfo, true, moveCommand);
+ new MoveClipCommand(this, startInfo, clipInfo, false, true, moveCommand);
}
if (d->duration() > item->cropDuration()) {
@@ -1773,12 +1773,12 @@ void CustomTrackView::insertClipCut(const QString &id, int in, int out)
// Add refresh command for undo
QUndoCommand *addCommand = new QUndoCommand();
addCommand->setText(i18n("Add timeline clip"));
- new RefreshMonitorCommand(this, false, true, addCommand);
+ new RefreshMonitorCommand(this, pasteInfo, false, true, addCommand);
new AddTimelineClipCommand(this, id, pasteInfo, EffectsList(), state, true, false, addCommand);
- new RefreshMonitorCommand(this, true, false, addCommand);
+ new RefreshMonitorCommand(this, pasteInfo, true, false, addCommand);
// Automatic audio split
if (KdenliveSettings::splitaudio() && m_timeline->audioTarget > -1 && m_timeline->videoTarget > -1) {
- if (!m_timeline->getTrackInfo(m_timeline->audioTarget).isLocked)
+ if (!m_timeline->getTrackInfo(m_timeline->audioTarget).isLocked && m_document->getBinClip(id)->hasAudio())
splitAudio(false, pasteInfo, m_timeline->audioTarget, addCommand);
}
else
@@ -1827,7 +1827,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos)
pasteInfo.track = track;
framePos.setX((int)(framePos.x() + 0.5));
framePos.setY(getPositionFromTrack(track));
- if (!canBePastedTo(pasteInfo, AVWidget)) {
+ if (m_scene->editMode() == TimelineMode::NormalEdit && !canBePastedTo(pasteInfo, AVWidget)) {
return true;
}
m_selectionGroup = new AbstractGroupItem(m_document->fps());
@@ -1893,7 +1893,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos)
infoList.append(info);
start += info.cropDuration;
}
- if (!canBePastedTo(infoList, AVWidget)) {
+ if (m_scene->editMode() == TimelineMode::NormalEdit && !canBePastedTo(infoList, AVWidget)) {
return true;
}
if (ids.size() > 1) {
@@ -3044,11 +3044,18 @@ void CustomTrackView::leaveEvent(QEvent * event)
void CustomTrackView::dropEvent(QDropEvent * event)
{
+ GenTime startPos;
+ GenTime duration;
if ((m_selectionGroup || m_dragItem) && m_clipDrag) {
QList<QGraphicsItem *> items;
- if (m_selectionGroup) items = m_selectionGroup->childItems();
- else if (m_dragItem) {
+ if (m_selectionGroup) {
+ items = m_selectionGroup->childItems();
+ startPos = m_selectionGroup->startPos();
+ duration = m_selectionGroup->duration();
+ } else if (m_dragItem) {
m_dragItem->setMainSelectedClip(false);
+ startPos = m_dragItem->startPos();
+ duration = m_dragItem->cropDuration();
items.append(m_dragItem);
}
resetSelectionGroup();
@@ -3060,7 +3067,23 @@ void CustomTrackView::dropEvent(QDropEvent * event)
QList <ClipItem *> brokenClips;
// Add refresh command for undo
- new RefreshMonitorCommand(this, false, true, addCommand);
+ ItemInfo undoRange;
+ undoRange.startPos = startPos;
+ undoRange.endPos = startPos + duration;
+ new RefreshMonitorCommand(this, undoRange, false, true, addCommand);
+ for (int i = 0; i < items.count(); ++i) {
+ m_scene->removeItem(items.at(i));
+ }
+
+ if (m_scene->editMode() == TimelineMode::InsertEdit) {
+ cutTimeline(startPos.frames(m_document->fps()), QList <ItemInfo>(), addCommand);
+ ItemInfo info;
+ info.startPos = startPos;
+ info.cropDuration = duration;
+ new AddSpaceCommand(this, info, QList <ItemInfo>(), true, addCommand);
+ } else if (m_scene->editMode() == TimelineMode::OverwriteEdit) {
+ extractZone(QPoint(startPos.frames(m_document->fps()), (startPos+duration).frames(m_document->fps())), false, QList <ItemInfo>(), addCommand);
+ }
for (int i = 0; i < items.count(); ++i) {
ClipItem *item = static_cast <ClipItem *>(items.at(i));
if (!hasVideoClip && (item->clipType() == AV || item->clipType() == Video)) hasVideoClip = true;
@@ -3069,32 +3092,11 @@ void CustomTrackView::dropEvent(QDropEvent * event)
} else {
updateClipTypeActions(NULL);
}
-
- //TODO: take care of edit mode for undo
- //item->baseClip()->addReference();
- //m_document->updateClip(item->baseClip()->getId());
ItemInfo info = item->info();
-
- bool isLocked = m_timeline->getTrackInfo(info.track).isLocked;
- if (isLocked) item->setItemLocked(true);
QString clipBinId = item->getBinId();
- Mlt::Producer *prod;
- if (item->clipState() == PlaylistState::VideoOnly) {
- prod = m_document->renderer()->getBinVideoProducer(clipBinId);
- }
- else {
- prod = m_document->renderer()->getBinProducer(clipBinId);
- }
- if (!m_timeline->track(info.track)->add(info.startPos.seconds(), prod, info.cropStart.seconds(), (info.cropStart + info.cropDuration).seconds(), item->clipState(), item->needsDuplicate(), m_scene->editMode())) {
- emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage);
- brokenClips.append(item);
- continue;
- }
- item->binClip()->addRef();
- adjustTimelineClips(m_scene->editMode(), item, ItemInfo(), addCommand, false);
- new AddTimelineClipCommand(this, clipBinId, item->info(), item->effectList(), item->clipState(), false, false, addCommand);
+ new AddTimelineClipCommand(this, clipBinId, info, item->effectList(), item->clipState(), true, false, addCommand);
// Automatic audio split
- if (KdenliveSettings::splitaudio())
+ if (KdenliveSettings::splitaudio() && item->hasAudio())
splitAudio(false, info, -1, addCommand);
else
updateTrackDuration(info.track, addCommand);
@@ -3106,16 +3108,10 @@ void CustomTrackView::dropEvent(QDropEvent * event)
new AddTransitionCommand(this, info, getPreviousVideoTrack(info.track), trans, false, true, addCommand);
}
}
- item->setSelected(true);
}
-
+ qDeleteAll(items);
// Add refresh command for redo
- new RefreshMonitorCommand(this, false, false, addCommand);
- for (int i = 0; i < brokenClips.count(); i++) {
- items.removeAll(brokenClips.at(i));
- }
- qDeleteAll(brokenClips);
- brokenClips.clear();
+ new RefreshMonitorCommand(this, undoRange, true, false, addCommand);
if (addCommand->childCount() > 0) m_commandStack->push(addCommand);
else delete addCommand;
@@ -3137,6 +3133,7 @@ void CustomTrackView::dropEvent(QDropEvent * event)
//qDebug() << "// COMPARE:\n" << timelineList << "\n-------------------";
*/
+ /*
m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
if (items.count() > 1) {
groupSelectedItems(items);
@@ -3144,8 +3141,7 @@ void CustomTrackView::dropEvent(QDropEvent * event)
m_dragItem = static_cast <AbstractClipItem *>(items.at(0));
m_dragItem->setMainSelectedClip(true);
emit clipItemSelected(static_cast<ClipItem*>(m_dragItem), false);
- }
- m_document->renderer()->doRefresh();
+ }*/
event->setDropAction(Qt::MoveAction);
event->accept();
@@ -3239,6 +3235,7 @@ void CustomTrackView::adjustTimelineClips(TimelineMode::EditMode mode, ClipItem
ClipItem *clip = static_cast<ClipItem *>(selection.at(i));
if (clip->startPos() < info.startPos && clip->endPos() > info.startPos) {
// Clip goes before and after insert zone, cut
+ qDebug()<<"* * *FOUND 1 clip to CUT: "<<clip->info().startPos.frames(25);
new RazorClipCommand(this, clip->info(), clip->effectList(), info.startPos, true, command);
}
}
@@ -3260,7 +3257,7 @@ void CustomTrackView::adjustTimelineClips(TimelineMode::EditMode mode, ClipItem
emit displayMessage(i18n("Cannot insert space in a track with a group"), ErrorMessage);
return;
}
-
+ if (item) selection.removeAll(item);
QList<ItemInfo> clipsToMove;
QList<ItemInfo> transitionsToMove;
@@ -3288,9 +3285,16 @@ void CustomTrackView::adjustTimelineClips(TimelineMode::EditMode mode, ClipItem
KdenliveSettings::setSnaptopoints(snap);
}
-void CustomTrackView::cutTimeline(int cutPos, QUndoCommand *masterCommand)
+void CustomTrackView::cutTimeline(int cutPos, QList <ItemInfo> excluded, QUndoCommand *masterCommand, int track)
{
- QRectF rect(cutPos, 0, 1, m_timeline->visibleTracksCount() * m_tracksHeight);
+ QRectF rect;
+ if (track == -1) {
+ // Cut all tracks
+ rect = QRectF(cutPos, 0, 1, m_timeline->visibleTracksCount() * m_tracksHeight);
+ } else {
+ // Cut only selected track
+ rect = QRectF(cutPos, getPositionFromTrack(track) + m_tracksHeight / 2, 1, 2);
+ }
QList<QGraphicsItem *> selection = m_scene->items(rect);
// We are going to move clips that are after zone, so break locked groups first.
QList<ItemInfo> clipsToCut;
@@ -3303,6 +3307,9 @@ void CustomTrackView::cutTimeline(int cutPos, QUndoCommand *masterCommand)
if (m_timeline->getTrackInfo(clip->track()).isLocked)
continue;
ItemInfo moveInfo = clip->info();
+ if (excluded.contains(moveInfo)) {
+ continue;
+ }
if (clip->type() == AVWidget) {
clipsToCut.append(moveInfo);
} else if (clip->type() == TransitionWidget) {
@@ -3321,18 +3328,26 @@ void CustomTrackView::cutTimeline(int cutPos, QUndoCommand *masterCommand)
// Skip locked tracks
if (m_timeline->getTrackInfo(clip->track()).isLocked)
continue;
- new RazorClipCommand(this, clip->info(), clip->effectList(), GenTime(cutPos, m_document->fps()), true, masterCommand);
+ ItemInfo info = clip->info();
+ if (excluded.contains(info)) {
+ continue;
+ }
+ new RazorClipCommand(this, info, clip->effectList(), GenTime(cutPos, m_document->fps()), true, masterCommand);
} else if (selection.at(i)->type() == TransitionWidget) {
Transition *trans = static_cast<Transition *>(selection.at(i));
// Skip locked tracks
if (m_timeline->getTrackInfo(trans->track()).isLocked)
continue;
- new RazorTransitionCommand(this, trans->info(), trans->toXML(), GenTime(cutPos, m_document->fps()), true, masterCommand);
+ ItemInfo info = trans->info();
+ if (excluded.contains(info)) {
+ continue;
+ }
+ new RazorTransitionCommand(this, info, trans->toXML(), GenTime(cutPos, m_document->fps()), true, masterCommand);
}
}
}
-void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterCommand)
+void CustomTrackView::extractZone(QPoint z, bool closeGap, QList <ItemInfo> excludedClips, QUndoCommand *masterCommand, int track)
{
// remove track zone and close gap
if (closeGap && m_timeline->getTrackInfo(m_selectedTrack).isLocked) {
@@ -3342,7 +3357,14 @@ void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterC
}
if (z.isNull())
z = m_document->zone();
- QRectF rect(z.x(), 0, z.y() - z.x() - 1, m_timeline->visibleTracksCount() * m_tracksHeight);
+ QRectF rect;
+ if (track == -1) {
+ // All tracks
+ rect = QRectF(z.x(), 0, z.y() - z.x() - 1, m_timeline->visibleTracksCount() * m_tracksHeight);
+ } else {
+ // All tracks
+ rect = QRectF(z.x(), getPositionFromTrack(track) + m_tracksHeight / 2, z.y() - z.x() - 1, 2);
+ }
QList<QGraphicsItem *> selection = m_scene->items(rect);
QList<QGraphicsItem *> gapSelection;
if (selection.isEmpty())
@@ -3388,8 +3410,10 @@ void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterC
// Skip locked tracks
if (m_timeline->getTrackInfo(clip->track()).isLocked)
continue;
+ ItemInfo baseInfo = clip->info();
+ if (excludedClips.contains(baseInfo))
+ continue;
if (clip->startPos() < inPoint) {
- ItemInfo baseInfo = clip->info();
ItemInfo info = baseInfo;
info.startPos = inPoint;
info.cropDuration = info.endPos - info.startPos;
@@ -3403,14 +3427,14 @@ void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterC
new RazorClipCommand(this, baseInfo, clip->effectList(), inPoint, true, masterCommand);
new AddTimelineClipCommand(this, clip->getBinId(), info, clip->effectList(), clip->clipState(), true, true, masterCommand);
} else if (clip->endPos() > outPoint) {
- ItemInfo newclipInfo = clip->info();
- new RazorClipCommand(this, newclipInfo, clip->effectList(), outPoint, true, masterCommand);
- newclipInfo.endPos = outPoint;
- newclipInfo.cropDuration = newclipInfo.endPos - newclipInfo.startPos;
- new AddTimelineClipCommand(this, clip->getBinId(), newclipInfo, clip->effectList(), clip->clipState(), true, true, masterCommand);
+ new RazorClipCommand(this, baseInfo, clip->effectList(), outPoint, true, masterCommand);
+ ItemInfo newInfo = baseInfo;
+ newInfo.endPos = outPoint;
+ newInfo.cropDuration = newInfo.endPos - newInfo.startPos;
+ new AddTimelineClipCommand(this, clip->getBinId(), newInfo, clip->effectList(), clip->clipState(), true, true, masterCommand);
} else {
// Clip is entirely inside zone, delete it
- new AddTimelineClipCommand(this, clip->getBinId(), clip->info(), clip->effectList(), clip->clipState(), true, true, masterCommand);
+ new AddTimelineClipCommand(this, clip->getBinId(), baseInfo, clip->effectList(), clip->clipState(), true, true, masterCommand);
}
} else if (selection.at(i)->type() == TransitionWidget) {
Transition *trans = static_cast<Transition *>(selection.at(i));
@@ -3418,9 +3442,12 @@ void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterC
if (m_timeline->getTrackInfo(trans->track()).isLocked)
continue;
ItemInfo baseInfo = trans->info();
+ if (excludedClips.contains(baseInfo))
+ continue;
QDomElement xml = trans->toXML();
if (trans->startPos() < inPoint) {
ItemInfo info = baseInfo;
+ ItemInfo newInfo = baseInfo;
info.startPos = inPoint;
info.cropDuration = info.endPos - info.startPos;
if (trans->endPos() > outPoint) {
@@ -3428,10 +3455,10 @@ void CustomTrackView::extractZone(QPoint z, bool closeGap, QUndoCommand *masterC
new RazorTransitionCommand(this, baseInfo, xml, outPoint, true, masterCommand);
info.cropDuration = outPoint - inPoint;
info.endPos = outPoint;
- baseInfo.endPos = outPoint;
- baseInfo.cropDuration = outPoint - baseInfo.startPos;
+ newInfo.endPos = outPoint;
+ newInfo.cropDuration = outPoint - newInfo.startPos;
}
- new RazorTransitionCommand(this, baseInfo, xml, inPoint, true, masterCommand);
+ new RazorTransitionCommand(this, newInfo, xml, inPoint, true, masterCommand);
new AddTransitionCommand(this, info, trans->transitionEndTrack(), xml, true, true, masterCommand);
} else if (trans->endPos() > outPoint) {
// Cut and remove first part
@@ -4018,19 +4045,32 @@ void CustomTrackView::slotInsertSpace()
}
}
-void CustomTrackView::insertTimelineSpace(GenTime startPos, GenTime duration)
+void CustomTrackView::insertTimelineSpace(GenTime startPos, GenTime duration, int track, QList <ItemInfo> excludeList)
{
int pos = startPos.frames(m_document->fps());
- QRectF rect(pos, 0, sceneRect().width() - pos, m_timeline->visibleTracksCount() * m_tracksHeight);
+ QRectF rect;
+ if (track == -1) {
+ // all tracks
+ rect = QRectF(pos, 0, sceneRect().width() - pos, m_timeline->visibleTracksCount() * m_tracksHeight);
+ } else {
+ // selected track only
+ rect = QRectF(pos, getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - pos, m_timeline->visibleTracksCount() * 2);
+ }
QList<QGraphicsItem *> items = scene()->items(rect);
QList<ItemInfo> clipsToMove;
QList<ItemInfo> transitionsToMove;
+ QList<QGraphicsItem *> excludedItems;
for (int i = 0; i < items.count(); ++i) {
if (items.at(i)->type() == AVWidget || items.at(i)->type() == TransitionWidget) {
AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
if (m_timeline->getTrackInfo(item->track()).isLocked)
continue;
+ if (excludeList.contains(item->info())) {
+ excludedItems << item;
+ m_scene->removeItem(item);
+ continue;
+ }
if (item->type() == AVWidget)
clipsToMove.append(item->info());
else if (item->type() == TransitionWidget)
@@ -4040,6 +4080,9 @@ void CustomTrackView::insertTimelineSpace(GenTime startPos, GenTime duration)
if (!clipsToMove.isEmpty() || !transitionsToMove.isEmpty()) {
insertSpace(clipsToMove, transitionsToMove, -1, duration, GenTime());
}
+ foreach(QGraphicsItem *item, excludedItems) {
+ m_scene->addItem(item);
+ }
}
void CustomTrackView::insertSpace(QList<ItemInfo> clipsToMove, QList<ItemInfo> transToMove, int track, const GenTime &duration, const GenTime &offset)
@@ -4121,7 +4164,7 @@ void CustomTrackView::deleteClip(const QString &clipId, QUndoCommand *deleteComm
{
resetSelectionGroup();
QList<QGraphicsItem *> itemList = items();
- new RefreshMonitorCommand(this, false, true, deleteCommand);
+ new RefreshMonitorCommand(this, ItemInfo(), false, true, deleteCommand);
int count = 0;
for (int i = 0; i < itemList.count(); ++i) {
if (itemList.at(i)->type() == AVWidget) {
@@ -4144,7 +4187,7 @@ void CustomTrackView::deleteClip(const QString &clipId, QUndoCommand *deleteComm
}
}
if (count > 0) {
- new RefreshMonitorCommand(this, true, false, deleteCommand);
+ new RefreshMonitorCommand(this, ItemInfo(), true, false, deleteCommand);
updateTrackDuration(-1, deleteCommand);
}
}
@@ -4378,14 +4421,31 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
// we are moving one clip, easy
if (m_dragItem->type() == AVWidget && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
ClipItem *item = static_cast <ClipItem *>(m_dragItem);
- bool success = m_timeline->moveClip(m_dragItemInfo.track, m_dragItemInfo.startPos.seconds(), info.track, info.startPos.seconds(), item->clipState(), m_scene->editMode(), item->needsDuplicate());
+ bool success = true;
+ //m_timeline->moveClip(m_dragItemInfo.track, m_dragItemInfo.startPos.seconds(), info.track, info.startPos.seconds(), item->clipState(), m_scene->editMode(), item->needsDuplicate());
if (success) {
QUndoCommand *moveCommand = new QUndoCommand();
moveCommand->setText(i18n("Move clip"));
- adjustTimelineClips(m_scene->editMode(), item, ItemInfo(), moveCommand, false);
+ new RefreshMonitorCommand(this, ItemInfo(), false, true, moveCommand);
+ QList <ItemInfo> excluded;
+ excluded << info;
+ item->setItemLocked(true);
+ ItemInfo initialClip = m_dragItemInfo;
+ if (m_scene->editMode() == TimelineMode::InsertEdit) {
+ cutTimeline(info.startPos.frames(m_document->fps()), excluded, moveCommand, info.track);
+ new AddSpaceCommand(this, info, excluded, true, moveCommand, true);
+ bool isLastClip = m_timeline->isLastClip(info);
+ if (!isLastClip && info.track == m_dragItemInfo.track && info.startPos < m_dragItemInfo.startPos) {
+ //remove offset to allow finding correct clip to move
+ initialClip.startPos += m_dragItemInfo.cropDuration;
+ initialClip.endPos += m_dragItemInfo.cropDuration;
+ }
+ } else if (m_scene->editMode() == TimelineMode::OverwriteEdit) {
+ extractZone(QPoint(info.startPos.frames(m_document->fps()), info.endPos.frames(m_document->fps())), false, excluded, moveCommand, info.track);
+ }
+ //adjustTimelineClips(m_scene->editMode(), item, ItemInfo(), moveCommand, false);
bool isLocked = m_timeline->getTrackInfo(item->track()).isLocked;
- if (isLocked) item->setItemLocked(true);
- new MoveClipCommand(this, m_dragItemInfo, info, false, moveCommand);
+ new MoveClipCommand(this, initialClip, info, true, true, moveCommand);
// Also move automatic transitions (on lower track)
Transition *startTransition = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track);
@@ -4524,7 +4584,9 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
updateTrackDuration(info.track, moveCommand);
if (m_dragItemInfo.track != info.track)
updateTrackDuration(m_dragItemInfo.track, moveCommand);
+ new RefreshMonitorCommand(this, ItemInfo(), false, false, moveCommand);
m_commandStack->push(moveCommand);
+ item->setItemLocked(isLocked);
//checkTrackSequence(m_dragItem->track());
} else {
// undo last move and emit error message
@@ -4932,7 +4994,7 @@ void CustomTrackView::deleteSelectedClips()
}
scene()->clearSelection();
QUndoCommand *deleteSelected = new QUndoCommand();
- new RefreshMonitorCommand(this, false, true, deleteSelected);
+ new RefreshMonitorCommand(this, ItemInfo(), false, true, deleteSelected);
int groupCount = 0;
int clipCount = 0;
@@ -4992,7 +5054,7 @@ void CustomTrackView::deleteSelectedClips()
deleteSelected->setText(i18np("Delete selected transition", "Delete selected transitions", transitionCount));
else deleteSelected->setText(i18n("Delete selected items"));
updateTrackDuration(-1, deleteSelected);
- new RefreshMonitorCommand(this, true, false, deleteSelected);
+ new RefreshMonitorCommand(this, ItemInfo(), true, false, deleteSelected);
m_commandStack->push(deleteSelected);
}
@@ -5340,7 +5402,7 @@ void CustomTrackView::addClip(const QString &clipId, ItemInfo info, EffectsList
prod = m_document->renderer()->getBinProducer(clipId);
}
binClip->addRef();
- m_timeline->track(info.track)->add(info.startPos.seconds(), prod, info.cropStart.seconds(), (info.cropStart+info.cropDuration).seconds(), state, duplicate, m_scene->editMode());
+ m_timeline->track(info.track)->add(info.startPos.seconds(), prod, info.cropStart.seconds(), (info.cropStart+info.cropDuration).seconds(), state, duplicate, TimelineMode::NormalEdit);// m_scene->editMode());
for (int i = 0; i < item->effectsCount(); ++i) {
m_document->renderer()->mltAddEffect(info.track, info.startPos, EffectsController::getEffectArgs(m_document->getProfileInfo(), item->effect(i)), false);
@@ -5493,10 +5555,14 @@ Transition *CustomTrackView::getTransitionItemAtStart(GenTime pos, int track)
return clip;
}
-bool CustomTrackView::moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, ItemInfo *out_actualEnd)
+bool CustomTrackView::moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, bool alreadyMoved, ItemInfo *out_actualEnd)
{
if (m_selectionGroup) resetSelectionGroup(false);
- ClipItem *item = getClipItemAtStart(start.startPos, start.track);
+ ClipItem *item = NULL;
+ if (alreadyMoved)
+ item = getClipItemAtStart(end.startPos, end.track);
+ else
+ item = getClipItemAtStart(start.startPos, start.track);
if (!item) {
emit displayMessage(i18n("Cannot move clip at time: %1 on track %2", m_document->timecode().getTimecodeFromFrames(start.startPos.frames(m_document->fps())), start.track), ErrorMessage);
//qDebug() << "---------------- ERROR, CANNOT find clip to move at.. ";
@@ -5511,7 +5577,10 @@ bool CustomTrackView::moveClip(const ItemInfo &start, const ItemInfo &end, bool
#endif
bool success = m_timeline->moveClip(start.track, start.startPos.seconds(), end.track, end.startPos.seconds(), item->clipState(), m_scene->editMode(), item->needsDuplicate());
- if (success) {
+ if (!success) {
+ // undo last move and emit error message
+ emit displayMessage(i18n("Cannot move clip to position %1", m_document->timecode().getTimecodeFromFrames(end.startPos.frames(m_document->fps()))), ErrorMessage);
+ } else if (!alreadyMoved) {
bool snap = KdenliveSettings::snaptopoints();
KdenliveSettings::setSnaptopoints(false);
item->setPos((int) end.startPos.frames(m_document->fps()), getPositionFromTrack(end.track) + 1);
@@ -5535,9 +5604,6 @@ bool CustomTrackView::moveClip(const ItemInfo &start, const ItemInfo &end, bool
}
}*/
KdenliveSettings::setSnaptopoints(snap);
- } else {
- // undo last move and emit error message
- emit displayMessage(i18n("Cannot move clip to position %1", m_document->timecode().getTimecodeFromFrames(end.startPos.frames(m_document->fps()))), ErrorMessage);
}
if (refresh) m_document->renderer()->doRefresh();
if (out_actualEnd != NULL) {
@@ -6501,12 +6567,12 @@ void CustomTrackView::drawBackground(QPainter * painter, const QRectF &rect)
painter->setClipRect(rect);
QPen pen1 = painter->pen();
QColor lineColor = palette().text().color();
- lineColor.setAlpha(100);
+ lineColor.setAlpha(50);
pen1.setColor(lineColor);
painter->setPen(pen1);
double min = rect.left();
double max = rect.right();
- painter->drawLine(QPointF(min, 0), QPointF(max, 0));
+ //painter->drawLine(QPointF(min, 0), QPointF(max, 0));
int maxTrack = m_timeline->visibleTracksCount();
QColor audioColor = palette().alternateBase().color();
QColor activeLockColor = m_lockedTrackColor;
@@ -6522,6 +6588,7 @@ void CustomTrackView::drawBackground(QPainter * painter, const QRectF &rect)
}
painter->drawLine(QPointF(min, m_tracksHeight * (maxTrack - i) - 1), QPointF(max, m_tracksHeight * (maxTrack - i) - 1));
}
+ painter->drawLine(QPointF(min, m_tracksHeight * (maxTrack) - 1), QPointF(max, m_tracksHeight * (maxTrack) - 1));
}
bool CustomTrackView::findString(const QString &text)
@@ -6732,7 +6799,7 @@ void CustomTrackView::pasteClip()
}
QUndoCommand *pasteClips = new QUndoCommand();
pasteClips->setText(QStringLiteral("Paste clips"));
- new RefreshMonitorCommand(this, false, true, pasteClips);
+ new RefreshMonitorCommand(this, ItemInfo(), false, true, pasteClips);
for (int i = 0; i < m_copiedItems.count(); ++i) {
// parse all clip names
@@ -6762,7 +6829,7 @@ void CustomTrackView::pasteClip()
}
}
updateTrackDuration(-1, pasteClips);
- new RefreshMonitorCommand(this, false, false, pasteClips);
+ new RefreshMonitorCommand(this, ItemInfo(), false, false, pasteClips);
m_commandStack->push(pasteClips);
}
@@ -7175,7 +7242,7 @@ void CustomTrackView::deleteTimelineTrack(int ix, TrackInfo trackinfo)
QList<QGraphicsItem *> selection = m_scene->items(r);
QUndoCommand *deleteTrack = new QUndoCommand();
deleteTrack->setText(QStringLiteral("Delete track"));
- new RefreshMonitorCommand(this, false, true, deleteTrack);
+ new RefreshMonitorCommand(this, ItemInfo(), false, true, deleteTrack);
// Remove clips on that track from groups
QList<QGraphicsItem *> groupsToProceed;
@@ -7237,7 +7304,7 @@ void CustomTrackView::deleteTimelineTrack(int ix, TrackInfo trackinfo)
}
new AddTrackCommand(this, ix, trackinfo, false, deleteTrack);
- new RefreshMonitorCommand(this, true, false, deleteTrack);
+ new RefreshMonitorCommand(this, ItemInfo(), true, false, deleteTrack);
m_commandStack->push(deleteTrack);
}
@@ -7489,7 +7556,7 @@ void CustomTrackView::slotAlignClip(int track, int pos, int shift)
}
emit displayMessage(i18n("Clip aligned."), OperationCompletedMessage);
moveCommand->setText(i18n("Auto-align clip"));
- new MoveClipCommand(this, start, end, true, moveCommand);
+ new MoveClipCommand(this, start, end, false, true, moveCommand);
updateTrackDuration(clip->track(), moveCommand);
m_commandStack->push(moveCommand);
@@ -7627,6 +7694,12 @@ void CustomTrackView::setClipType(PlaylistState::ClipState state)
m_commandStack->push(videoCommand);
}
+void CustomTrackView::monitorRefresh(ItemInfo range)
+{
+ if (range.contains(GenTime(m_cursorPos, m_document->fps())))
+ m_document->renderer()->doRefresh();
+}
+
void CustomTrackView::monitorRefresh()
{
m_document->renderer()->doRefresh();
@@ -8008,11 +8081,11 @@ void CustomTrackView::insertZone(TimelineMode::EditMode sceneMode, const QString
addCommand->setText(i18n("Insert clip"));
if (sceneMode == TimelineMode::OverwriteEdit) {
// We clear the selected zone in all non locked tracks
- extractZone(QPoint(timelineZone.x(), info.endPos.frames(m_document->fps())), false, addCommand);
+ extractZone(QPoint(timelineZone.x(), info.endPos.frames(m_document->fps())), false, QList <ItemInfo>(), addCommand);
} else {
// Cut and move clips forward
- cutTimeline(timelineZone.x(), addCommand);
- new AddSpaceCommand(this, info, true, addCommand);
+ cutTimeline(timelineZone.x(), QList <ItemInfo>(), addCommand);
+ new AddSpaceCommand(this, info, QList <ItemInfo>(), true, addCommand);
}
if (KdenliveSettings::splitaudio()) {
if (extractVideo) {
@@ -8034,8 +8107,8 @@ void CustomTrackView::insertZone(TimelineMode::EditMode sceneMode, const QString
new AddTimelineClipCommand(this, clipId, info, EffectsList(), PlaylistState::Original, true, false, addCommand);
}
// Automatic audio split
- if (KdenliveSettings::splitaudio() && extractVideo) {
- if (!m_timeline->getTrackInfo(m_timeline->audioTarget).isLocked)
+ if (KdenliveSettings::splitaudio() && extractVideo && extractAudio) {
+ if (!m_timeline->getTrackInfo(m_timeline->audioTarget).isLocked && m_document->getBinClip(clipId)->hasAudio())
splitAudio(false, info, m_timeline->audioTarget, addCommand);
}
updateTrackDuration(info.track, addCommand);
diff --git a/src/timeline/customtrackview.h b/src/timeline/customtrackview.h
index 0d4ff1b..2489b54 100644
--- a/src/timeline/customtrackview.h
+++ b/src/timeline/customtrackview.h
@@ -68,7 +68,7 @@ public:
If \c out_actualEnd is not NULL, it will be set to the position the clip really ended up at.
For example, attempting to move a clip to t = -1 s will actually move it to t = 0 s.
*/
- bool moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, ItemInfo *out_actualEnd = NULL);
+ bool moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, bool alreadyMoved, ItemInfo *out_actualEnd = NULL);
void moveGroup(QList<ItemInfo> startClip, QList<ItemInfo> startTransition, const GenTime &offset, const int trackOffset, bool reverseMove = false);
/** move transition, startPos = (old start, old end), endPos = (new start, new end) */
void moveTransition(const ItemInfo &start, const ItemInfo &end, bool refresh);
@@ -211,7 +211,9 @@ public:
/** @brief Trigger a monitor refresh. */
void monitorRefresh();
-
+ /** @brief Trigger a monitor refresh if timeline cursor is inside range. */
+ void monitorRefresh(ItemInfo range);
+
/** @brief Returns frame number of current mouse position. */
int getMousePos() const;
@@ -255,7 +257,8 @@ public:
/** @brief Switch current track lock state */
void switchTrackLock();
void switchAllTrackLock();
- void insertTimelineSpace(GenTime startPos, GenTime duration);
+ /** @brief Insert space in timeline. track = -1 means all tracks */
+ void insertTimelineSpace(GenTime startPos, GenTime duration, int track = -1, QList <ItemInfo> excludeList = QList <ItemInfo>());
public slots:
/** @brief Send seek request to MLT. */
@@ -341,7 +344,7 @@ public slots:
/** @brief Export part of the playlist in an xml file */
void exportTimelineSelection(QString path = QString());
/** Remove zone from current track */
- void extractZone(QPoint z, bool closeGap, QUndoCommand *masterCommand = NULL);
+ void extractZone(QPoint z, bool closeGap, QList <ItemInfo> excludedClips = QList <ItemInfo>(), QUndoCommand *masterCommand = NULL, int track = -1);
/** @brief Select an item in timeline. */
void slotSelectItem(AbstractClipItem *item);
@@ -534,7 +537,7 @@ private:
/** @brief Break groups containing an item in a locked track. */
void breakLockedGroups(QList<ItemInfo> clipsToMove, QList<ItemInfo> transitionsToMove, QUndoCommand *masterCommand, bool doIt = true);
/** @brief Cut clips in all non locked tracks. */
- void cutTimeline(int cutPos, QUndoCommand *masterCommand);
+ void cutTimeline(int cutPos, QList <ItemInfo> excluded, QUndoCommand *masterCommand, int track = -1);
private slots:
void slotRefreshGuides();
diff --git a/src/timeline/timeline.cpp b/src/timeline/timeline.cpp
index 1e8162e..d853077 100644
--- a/src/timeline/timeline.cpp
+++ b/src/timeline/timeline.cpp
@@ -598,6 +598,15 @@ TrackInfo Timeline::getTrackInfo(int ix)
return tk->info();
}
+bool Timeline::isLastClip(ItemInfo info)
+{
+ Track *tk = track(info.track);
+ if (tk == NULL) {
+ return true;
+ }
+ return tk->isLastClip(info.endPos.ms());
+}
+
void Timeline::setTrackInfo(int ix, TrackInfo info)
{
if (ix < 0 || ix > m_tracks.count()) {
@@ -1267,7 +1276,7 @@ void Timeline::checkTrackHeight(bool force)
}
}
-bool Timeline::moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, int mode, bool duplicate)
+bool Timeline::moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, TimelineMode::EditMode mode, bool duplicate)
{
if (startTrack == endTrack) {
return track(startTrack)->move(startPos, endPos, mode);
diff --git a/src/timeline/timeline.h b/src/timeline/timeline.h
index b034553..f039bc8 100644
--- a/src/timeline/timeline.h
+++ b/src/timeline/timeline.h
@@ -92,7 +92,7 @@ public:
*
* Parses all tracks to check if there is audio data. */
bool checkProjectAudio();
-
+
/** @brief Load guides from data */
void loadGuides(QMap <double, QString> guidesData);
@@ -102,7 +102,7 @@ public:
/** @brief Returns a kdenlive effect xml description from an effect tag / id */
static QDomElement getEffectByTag(const QString &effecttag, const QString &effectid);
/** @brief Move a clip between tracks */
- bool moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, int mode, bool duplicate);
+ bool moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, TimelineMode::EditMode mode, bool duplicate);
void renameTrack(int ix, const QString &name);
void updateTrackState(int ix, int state);
/** @brief Returns info about a track.
@@ -155,7 +155,8 @@ public:
void switchTrackTarget();
/** @brief Refresh Header Leds */
void updateHeaders();
-
+ /** @brief Returns true if position is on the last clip */
+ bool isLastClip(ItemInfo info);
protected:
void keyPressEvent(QKeyEvent * event);
diff --git a/src/timeline/timelinecommands.cpp b/src/timeline/timelinecommands.cpp
index bf7794a..be8be5c 100644
--- a/src/timeline/timelinecommands.cpp
+++ b/src/timeline/timelinecommands.cpp
@@ -426,26 +426,29 @@ void GroupClipsCommand::redo()
m_doIt = true;
}
-AddSpaceCommand::AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, bool doIt, QUndoCommand * parent) :
+AddSpaceCommand::AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, QList <ItemInfo> excludeList, bool doIt, QUndoCommand * parent, bool trackonly) :
QUndoCommand(parent),
m_view(view),
m_spaceInfo(spaceInfo),
- m_doIt(doIt)
+ m_excludeList(excludeList),
+ m_doIt(doIt),
+ m_trackOnly(trackonly)
{
}
// virtual
void AddSpaceCommand::undo()
{
- m_view->insertTimelineSpace(m_spaceInfo.startPos, -m_spaceInfo.cropDuration);
+ m_view->insertTimelineSpace(m_spaceInfo.startPos, -m_spaceInfo.cropDuration, m_trackOnly ? m_spaceInfo.track : -1);
}
// virtual
void AddSpaceCommand::redo()
{
if (m_doIt) {
- m_view->insertTimelineSpace(m_spaceInfo.startPos, m_spaceInfo.cropDuration);
+ m_view->insertTimelineSpace(m_spaceInfo.startPos, m_spaceInfo.cropDuration, m_trackOnly ? m_spaceInfo.track : -1, m_excludeList);
}
m_doIt = true;
+ m_excludeList.clear();
}
@@ -499,13 +502,14 @@ void LockTrackCommand::redo()
m_view->lockTrack(m_ix, m_lock);
}
-MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool doIt, QUndoCommand * parent)
+MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool alreadyMoved, bool doIt, QUndoCommand * parent)
: QUndoCommand(parent),
m_view(view),
m_startPos(start),
m_endPos(end),
m_doIt(doIt),
- m_success(true)
+ m_success(true),
+ m_alreadyMoved(alreadyMoved)
{
setText(i18n("Move clip"));
if (parent) {
@@ -523,17 +527,18 @@ void MoveClipCommand::undo()
// We can only undo what was done;
// if moveClip() failed in redo() the document does (or should) not change.
if (m_success) {
- m_view->moveClip(m_endPos, m_startPos, m_refresh);
+ m_view->moveClip(m_endPos, m_startPos, m_refresh, false);
}
}
void MoveClipCommand::redo()
{
if (m_doIt) {
// qDebug() << "Executing move clip command. End now:" << m_endPos;
- m_success = m_view->moveClip(m_startPos, m_endPos, m_refresh, &m_endPos);
+ m_success = m_view->moveClip(m_startPos, m_endPos, m_refresh, m_alreadyMoved, &m_endPos);
// qDebug() << "Move clip command executed. End now: " << m_endPos;
}
m_doIt = true;
+ m_alreadyMoved = false;
}
MoveEffectCommand::MoveEffectCommand(CustomTrackView *view, const int track, const GenTime &pos, const QList<int> &oldPos, int newPos, QUndoCommand * parent) :
@@ -714,9 +719,10 @@ void RebuildGroupCommand::redo()
m_view->rebuildGroup(m_childTrack, m_childPos);
}
-RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute, bool refreshOnUndo, QUndoCommand * parent) :
+RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, ItemInfo info, bool execute, bool refreshOnUndo, QUndoCommand * parent) :
QUndoCommand(parent),
m_view(view),
+ m_info(info),
m_exec(execute),
m_execOnUndo(refreshOnUndo)
{
@@ -725,13 +731,13 @@ RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute
void RefreshMonitorCommand::undo()
{
if (m_execOnUndo)
- m_view->monitorRefresh();
+ m_view->monitorRefresh(m_info);
}
// virtual
void RefreshMonitorCommand::redo()
{
if (m_exec && !m_execOnUndo)
- m_view->monitorRefresh();
+ m_view->monitorRefresh(m_info);
m_exec = true;
}
diff --git a/src/timeline/timelinecommands.h b/src/timeline/timelinecommands.h
index 9b10ffb..426c5e4 100644
--- a/src/timeline/timelinecommands.h
+++ b/src/timeline/timelinecommands.h
@@ -238,13 +238,15 @@ private:
class AddSpaceCommand : public QUndoCommand
{
public:
- AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, bool doIt, QUndoCommand * parent = 0);
+ AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, QList <ItemInfo> excludeList, bool doIt, QUndoCommand * parent = 0, bool trackonly = false);
void undo();
void redo();
private:
CustomTrackView *m_view;
ItemInfo m_spaceInfo;
+ QList <ItemInfo> m_excludeList;
bool m_doIt;
+ bool m_trackOnly;
};
class LockTrackCommand : public QUndoCommand
@@ -262,7 +264,7 @@ private:
class MoveClipCommand : public QUndoCommand
{
public:
- MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool doIt, QUndoCommand * parent = 0);
+ MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool alreadyMoved, bool doIt, QUndoCommand * parent = 0);
void undo();
void redo();
private:
@@ -272,6 +274,7 @@ private:
bool m_doIt;
bool m_refresh;
bool m_success;
+ bool m_alreadyMoved;
};
class MoveEffectCommand : public QUndoCommand
@@ -382,11 +385,12 @@ private:
class RefreshMonitorCommand : public QUndoCommand
{
public:
- RefreshMonitorCommand(CustomTrackView *view, bool execute, bool refreshOnUndo, QUndoCommand * parent = 0);
+ RefreshMonitorCommand(CustomTrackView *view, ItemInfo info, bool execute, bool refreshOnUndo, QUndoCommand * parent = 0);
void undo();
void redo();
private:
CustomTrackView *m_view;
+ ItemInfo m_info;
bool m_exec;
bool m_execOnUndo;
};
diff --git a/src/timeline/track.cpp b/src/timeline/track.cpp
index eb575ef..5aae058 100644
--- a/src/timeline/track.cpp
+++ b/src/timeline/track.cpp
@@ -68,8 +68,7 @@ qreal Track::length() {
}
// basic clip operations
-
-bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, int mode)
+bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, TimelineMode::EditMode mode)
{
Mlt::Producer *cut = NULL;
if (parent == NULL || !parent->is_valid()) {
@@ -92,14 +91,14 @@ bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, Playlis
return result;
}
-bool Track::doAdd(qreal t, Mlt::Producer *cut, int mode)
+bool Track::doAdd(qreal t, Mlt::Producer *cut, TimelineMode::EditMode mode)
{
int pos = frame(t);
int len = cut->get_out() - cut->get_in() + 1;
if (pos < m_playlist.get_playtime() && mode > 0) {
- if (mode == 1) {
+ if (mode == TimelineMode::OverwriteEdit) {
m_playlist.remove_region(pos, len);
- } else if (mode == 2) {
+ } else if (mode == TimelineMode::InsertEdit) {
m_playlist.split_at(pos);
}
//m_playlist.insert_blank(m_playlist.get_clip_index_at(pos), len);
@@ -111,7 +110,7 @@ bool Track::doAdd(qreal t, Mlt::Producer *cut, int mode)
return true;
}
-bool Track::move(qreal start, qreal end, int mode)
+bool Track::move(qreal start, qreal end, TimelineMode::EditMode mode)
{
int pos = frame(start);
m_playlist.lock();
@@ -139,6 +138,15 @@ bool Track::move(qreal start, qreal end, int mode)
return result;
}
+bool Track::isLastClip(qreal t)
+{
+ int clipIndex = m_playlist.get_clip_index_at(frame(t));
+ if (clipIndex >= m_playlist.count() - 1) {
+ return true;
+ }
+ return false;
+}
+
bool Track::del(qreal t)
{
m_playlist.lock();
diff --git a/src/timeline/track.h b/src/timeline/track.h
index c7f7e88..8914876 100644
--- a/src/timeline/track.h
+++ b/src/timeline/track.h
@@ -103,14 +103,14 @@ public:
* @param mode allow insert in non-blanks by replacing (mode=1) or pushing (mode=2) content
* The playlist must be locked / unlocked before and after calling doAdd
* @return true if success */
- bool doAdd(qreal t, Mlt::Producer *cut, int mode);
- bool add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, int mode);
+ bool doAdd(qreal t, Mlt::Producer *cut, TimelineMode::EditMode mode);
+ bool add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, TimelineMode::EditMode mode);
/** @brief Move a clip in the track
* @param start where clip is present (in seconds);
* @param end wher the clip should be moved
* @param mode allow insert in non-blanks by replacing (mode=1) or pushing (mode=2) content
* @return true if success */
- bool move(qreal start, qreal end, int mode = 0);
+ bool move(qreal start, qreal end, TimelineMode::EditMode mode = TimelineMode::NormalEdit);
/** @brief delete a clip
* @param time where clip is present (in seconds);
* @return true if success */
@@ -193,6 +193,8 @@ public:
int spaceLength(int pos, bool fromBlankStart);
/** @brief Dis/enable all effects on this track. */
void disableEffects(bool disable);
+ /** @brief Returns true if position is on last clip or beyond track length. */
+ bool isLastClip(qreal t);
signals:
/** @brief notify track length change to update background