summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <jb@kdenlive.org>2016-09-21 21:32:37 (GMT)
committerJean-Baptiste Mardelle <jb@kdenlive.org>2016-09-21 21:36:11 (GMT)
commitd9d5d95a4565fbfbb890be20696fb424140943de (patch)
tree6fb2ac7a61245635342a547d649aa92fc1e1ef5b
parenta0ee357c06ee529cecb9c1b1e03ba6d53a6fe5c6 (diff)
Add new timeline action: Remove space from all tracks that works if there are grouped clips
CCBUG: 369123
-rw-r--r--src/kdenliveui.rc3
-rw-r--r--src/mainwindow.cpp8
-rw-r--r--src/mainwindow.h1
-rw-r--r--src/timeline/customtrackview.cpp173
-rw-r--r--src/timeline/customtrackview.h11
-rw-r--r--src/timeline/spacerdialog.cpp15
-rw-r--r--src/ui/spacerdialog_ui.ui50
7 files changed, 100 insertions, 161 deletions
diff --git a/src/kdenliveui.rc b/src/kdenliveui.rc
index 5ffa0c9..bebe39e 100644
--- a/src/kdenliveui.rc
+++ b/src/kdenliveui.rc
@@ -1,5 +1,5 @@
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="kdenlive" version="147" translationDomain="kdenlive">
+<kpartgui name="kdenlive" version="148" translationDomain="kdenlive">
<MenuBar>
<Menu name="file" >
<Action name="dvd_wizard" />
@@ -129,6 +129,7 @@
<Menu name="space_menu" ><text>Space</text>
<Action name="insert_space" />
<Action name="delete_space" />
+ <Action name="delete_space_all_tracks" />
</Menu>
<Action name="group_clip" />
<Action name="ungroup_clip" />
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 0bb1000..8022226 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -525,6 +525,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("insert_space")));
m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("delete_space")));
+ m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("delete_space_all_tracks")));
m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
m_timelineContextClipMenu->addAction(actionCollection()->action(QStringLiteral("clip_in_project_tree")));
@@ -1380,6 +1381,7 @@ void MainWindow::setupActions()
addAction(QStringLiteral("insert_space"), i18n("Insert Space"), this, SLOT(slotInsertSpace()));
addAction(QStringLiteral("delete_space"), i18n("Remove Space"), this, SLOT(slotRemoveSpace()));
+ addAction(QStringLiteral("delete_space_all_tracks"), i18n("Remove Space In All Tracks"), this, SLOT(slotRemoveAllSpace()));
KActionCategory *timelineActions = new KActionCategory(i18n("Tracks"), actionCollection());
QAction *insertTrack = new QAction(QIcon(), i18n("Insert Track"), this);
@@ -2314,6 +2316,12 @@ void MainWindow::slotRemoveSpace()
pCore->projectManager()->currentTimeline()->projectView()->slotRemoveSpace();
}
+void MainWindow::slotRemoveAllSpace()
+{
+ if (pCore->projectManager()->currentTimeline())
+ pCore->projectManager()->currentTimeline()->projectView()->slotRemoveSpace(true);
+}
+
void MainWindow::slotInsertTrack()
{
pCore->monitorManager()->activateMonitor(Kdenlive::ProjectMonitor);
diff --git a/src/mainwindow.h b/src/mainwindow.h
index cb9d1a4..7656703 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -359,6 +359,7 @@ private slots:
void slotInsertSpace();
void slotRemoveSpace();
+ void slotRemoveAllSpace();
void slotAddGuide();
void slotEditGuide(int pos = -1, QString text = QString());
void slotDeleteGuide();
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 7668f93..bb42870 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -727,14 +727,19 @@ QList<QGraphicsItem *> CustomTrackView::selectAllItemsToTheRight(int x)
return m_scene->items(r);
}
-int CustomTrackView::spaceToolSelectTrackOnly(int track, QList<QGraphicsItem *> &selection)
+int CustomTrackView::spaceToolSelectTrackOnly(int track, QList<QGraphicsItem *> &selection, GenTime pos)
{
if (m_timeline->getTrackInfo(track).isLocked) {
// Cannot use spacer on locked track
emit displayMessage(i18n("Cannot use spacer in a locked track"), ErrorMessage);
return -1;
}
- QRectF rect(mapToScene(m_clickEvent).x(), getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - mapToScene(m_clickEvent).x(), m_tracksHeight / 2 - 2);
+ QRectF rect;
+ if (pos > GenTime()) {
+ rect = QRectF(pos.frames(m_document->fps()), getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 2 - 2);
+ } else {
+ rect = QRectF(mapToScene(m_clickEvent).x(), getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - mapToScene(m_clickEvent).x(), m_tracksHeight / 2 - 2);
+ }
bool isOk;
selection = checkForGroups(rect, &isOk);
if (!isOk) {
@@ -3788,7 +3793,7 @@ QList<QGraphicsItem *> CustomTrackView::checkForGroups(const QRectF &rect, bool
return selection;
}
-void CustomTrackView::slotRemoveSpace()
+void CustomTrackView::slotRemoveSpace(bool multiTrack)
{
GenTime pos;
int track = 0;
@@ -3832,69 +3837,29 @@ void CustomTrackView::slotRemoveSpace()
return;
}
- // Make sure there is no group in the way
- QRectF rect(pos.frames(m_document->fps()), getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 2 - 2);
-
- bool isOk;
- QList<QGraphicsItem *> items = checkForGroups(rect, &isOk);
- if (!isOk) {
- // groups found on track, do not allow the move
- emit displayMessage(i18n("Cannot remove space in a track with a group"), ErrorMessage);
- return;
- }
-
- QList<ItemInfo> clipsToMove;
- QList<ItemInfo> transitionsToMove;
-
- 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));
- ItemInfo info = item->info();
- if (item->type() == AVWidget) {
- clipsToMove.append(info);
- } else if (item->type() == TransitionWidget) {
- transitionsToMove.append(info);
- }
+ QList<QGraphicsItem *> selection;
+ if (multiTrack) {
+ selection = selectAllItemsToTheRight(pos.frames(m_document->fps()));
+ } else {
+ if (spaceToolSelectTrackOnly(track, selection, pos) == -1) {
+ return;
}
}
-
- if (!transitionsToMove.isEmpty()) {
- // Make sure that by moving the items, we don't get a transition collision
- // Find first transition
- ItemInfo info = transitionsToMove.at(0);
- for (int i = 1; i < transitionsToMove.count(); ++i)
- if (transitionsToMove.at(i).startPos < info.startPos) info = transitionsToMove.at(i);
-
- // make sure there are no transitions on the way
- QRectF rect(info.startPos.frames(m_document->fps()) - length, getPositionFromTrack(track) + m_tracksHeight / 2, length - 1, m_tracksHeight / 2 - 2);
- items = scene()->items(rect);
- int transitionCorrection = -1;
- for (int i = 0; i < items.count(); ++i) {
- if (items.at(i)->type() == TransitionWidget) {
- // There is a transition on the way
- AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
- int transitionEnd = item->endPos().frames(m_document->fps());
- if (transitionEnd > transitionCorrection) transitionCorrection = transitionEnd;
- }
- }
-
- if (transitionCorrection > 0) {
- // We need to fix the move length
- length = info.startPos.frames(m_document->fps()) - transitionCorrection;
- }
-
- // Make sure we don't send transition before 0
- if (info.startPos.frames(m_document->fps()) < length) {
- // reduce length to maximum possible
- length = info.startPos.frames(m_document->fps());
- }
+ createGroupForSelectedItems(selection);
+ QList <AbstractClipItem *> items;
+ foreach(QGraphicsItem *item, selection) {
+ if (item->type() == AVWidget || item->type() == TransitionWidget)
+ items << (AbstractClipItem *) item;
+ }
+ GenTime timeOffset(-length, m_document->fps());
+ if (canBePasted(items, timeOffset, 0)) {
+ completeSpaceOperation(multiTrack ? -1 : track, timeOffset, true);
+ } else {
+ // Conflict, cannot move clips
+ emit displayMessage(i18n("Clip collision, cannot perform operation"), ErrorMessage);
+ clearSelection();
+ m_operationMode = None;
}
- QUndoCommand *command = new QUndoCommand;
- command->setText(length > 0 ? i18n("Remove space") : i18n("Insert space"));
- breakLockedGroups(clipsToMove, transitionsToMove, command);
- new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, GenTime(-length, m_document->fps()), true, command);
- updateTrackDuration(track, command);
- m_commandStack->push(command);
}
void CustomTrackView::slotInsertSpace()
@@ -3927,41 +3892,14 @@ void CustomTrackView::slotInsertSpace()
ClipItem *item = getClipItemAtMiddlePoint(pos, track);
if (item) pos = item->startPos().frames(m_document->fps());
- // Make sure there is no group in the way
- QRectF rect(pos, getPositionFromTrack(track) + m_tracksHeight / 2, sceneRect().width() - pos, m_tracksHeight / 2 - 2);
- bool isOk;
- items = checkForGroups(rect, &isOk);
- if (!isOk) {
- // groups found on track, do not allow the move
- emit displayMessage(i18n("Cannot insert space in a track with a group"), ErrorMessage);
+ if (spaceToolSelectTrackOnly(track, items, GenTime(pos, m_document->fps())) == -1) {
return;
}
} else {
- QRectF rect(pos, 0, sceneRect().width() - pos, m_timeline->visibleTracksCount() * m_tracksHeight);
- items = scene()->items(rect);
- }
-
- QList<ItemInfo> clipsToMove;
- QList<ItemInfo> transitionsToMove;
-
- 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));
- ItemInfo info = item->info();
- if (item->type() == AVWidget)
- clipsToMove.append(info);
- else if (item->type() == TransitionWidget)
- transitionsToMove.append(info);
- }
- }
- if (!clipsToMove.isEmpty() || !transitionsToMove.isEmpty()) {
- QUndoCommand *command = new QUndoCommand;
- command->setText(spaceDuration < GenTime() ? i18n("Remove space") : i18n("Insert space"));
- breakLockedGroups(clipsToMove, transitionsToMove, command);
- new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, spaceDuration, true, command);
- updateTrackDuration(track, command);
- m_commandStack->push(command);
+ items = selectAllItemsToTheRight(pos);
}
+ createGroupForSelectedItems(items);
+ completeSpaceOperation(track, spaceDuration, true);
}
void CustomTrackView::insertTimelineSpace(GenTime startPos, GenTime duration, int track, QList <ItemInfo> excludeList)
@@ -4189,7 +4127,7 @@ void CustomTrackView::scrollToStart()
horizontalScrollBar()->setValue(0);
}
-void CustomTrackView::completeSpaceOperation(int track, GenTime &timeOffset)
+void CustomTrackView::completeSpaceOperation(int track, GenTime &timeOffset, bool fromStart)
{
QList <AbstractGroupItem*> groups;
@@ -4223,25 +4161,25 @@ void CustomTrackView::completeSpaceOperation(int track, GenTime &timeOffset)
{
if (items.at(i)->type() == AVWidget)
{
- AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
- ItemInfo info = item->info();
- clipsToMove.append(info);
+ AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
+ ItemInfo info = item->info();
+ clipsToMove.append(info);
int realTrack = getTrackFromPos(item->scenePos().y());
- item->updateItem(realTrack);
- if (trackClipStartList.value(info.track) == -1 ||
- info.startPos.frames(m_document->fps()) < trackClipStartList.value(info.track))
- trackClipStartList[info.track] = info.startPos.frames(m_document->fps());
- }
+ item->updateItem(realTrack);
+ if (trackClipStartList.value(info.track) == -1 ||
+ info.startPos.frames(m_document->fps()) < trackClipStartList.value(info.track))
+ trackClipStartList[info.track] = info.startPos.frames(m_document->fps());
+ }
else if (items.at(i)->type() == TransitionWidget)
{
- AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
- ItemInfo info = item->info();
- transitionsToMove.append(info);
+ AbstractClipItem *item = static_cast <AbstractClipItem *>(items.at(i));
+ ItemInfo info = item->info();
+ transitionsToMove.append(info);
int realTrack = getTrackFromPos(item->scenePos().y());
- item->updateItem(realTrack);
- if (trackTransitionStartList.value(info.track) == -1 ||
- info.startPos.frames(m_document->fps()) < trackTransitionStartList.value(info.track))
- trackTransitionStartList[info.track] = info.startPos.frames(m_document->fps());
+ item->updateItem(realTrack);
+ if (trackTransitionStartList.value(info.track) == -1 ||
+ info.startPos.frames(m_document->fps()) < trackTransitionStartList.value(info.track))
+ trackTransitionStartList[info.track] = info.startPos.frames(m_document->fps());
}
}
if (!clipsToMove.isEmpty() || !transitionsToMove.isEmpty())
@@ -4249,15 +4187,16 @@ void CustomTrackView::completeSpaceOperation(int track, GenTime &timeOffset)
QUndoCommand *command = new QUndoCommand;
command->setText(timeOffset < GenTime() ? i18n("Remove space") : i18n("Insert space"));
//TODO: break groups upstream
- breakLockedGroups(clipsToMove, transitionsToMove, command, false);
- new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, timeOffset, false, command);
+ breakLockedGroups(clipsToMove, transitionsToMove, command, fromStart);
+ new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, timeOffset, fromStart, command);
updateTrackDuration(track, command);
m_commandStack->push(command);
- m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime());
+ if (!fromStart)
+ m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime());
}
}
resetSelectionGroup();
- for (int i = 0; i < groups.count(); ++i)
+ if (!fromStart) for (int i = 0; i < groups.count(); ++i)
{
rebuildGroup(groups.at(i));
}
@@ -6324,7 +6263,7 @@ void CustomTrackView::copyClip()
pasteAction->setEnabled(!m_copiedItems.isEmpty());
}
-bool CustomTrackView::canBePastedTo(ItemInfo info, int type) const
+bool CustomTrackView::canBePastedTo(ItemInfo info, int type, QList<AbstractClipItem *>excluded) const
{
if (m_scene->editMode() != TimelineMode::NormalEdit) {
// If we are in overwrite mode, always allow the move
@@ -6343,7 +6282,7 @@ bool CustomTrackView::canBePastedTo(ItemInfo info, int type) const
QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(getPositionFromTrack(info.track) + 1 + offset), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double) height);
QList<QGraphicsItem *> collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect);
for (int i = 0; i < collisions.count(); ++i) {
- if (collisions.at(i)->type() == type) {
+ if (collisions.at(i)->type() == type && !excluded.contains((AbstractClipItem *)collisions.at(i))) {
return false;
}
}
@@ -6371,7 +6310,7 @@ bool CustomTrackView::canBePasted(QList<AbstractClipItem *> items, GenTime offse
info.startPos += offset;
info.endPos += offset;
info.track += trackOffset;
- if (!canBePastedTo(info, items.at(i)->type())) return false;
+ if (!canBePastedTo(info, items.at(i)->type(), items)) return false;
}
return true;
}
diff --git a/src/timeline/customtrackview.h b/src/timeline/customtrackview.h
index dd324b6..12471f3 100644
--- a/src/timeline/customtrackview.h
+++ b/src/timeline/customtrackview.h
@@ -133,7 +133,7 @@ public:
* Shows a dialog to configure length and track. */
void slotInsertSpace();
/** @brief Prepares removing space. */
- void slotRemoveSpace();
+ void slotRemoveSpace(bool multiTrack = false);
void insertSpace(QList<ItemInfo> clipsToMove, QList<ItemInfo> transToMove, int track, const GenTime &duration, const GenTime &offset);
ClipItem *getActiveClipUnderCursor(bool allowOutsideCursor = false) const;
void deleteTimelineTrack(int ix, TrackInfo trackinfo);
@@ -181,7 +181,7 @@ public:
int selectedTrack() const;
QStringList selectedClips() const;
/** @brief Checks whether an item can be inserted (make sure it does not overlap another item) */
- bool canBePastedTo(ItemInfo info, int type) const;
+ bool canBePastedTo(ItemInfo info, int type, QList<AbstractClipItem *>excluded = QList<AbstractClipItem *>()) const;
/** @brief Selects a clip.
* @param add Whether to select or deselect
@@ -223,11 +223,11 @@ public:
/** @brief Returns frame number of current mouse position. */
int getMousePos() const;
-
- void completeSpaceOperation(int track, GenTime &timeOffset);
+ /** @brief Insert space in timeline after clips were moved. if fromstart is true, we assume clips have not yet been moved manually. */
+ void completeSpaceOperation(int track, GenTime &timeOffset, bool fromStart = false);
void spaceToolMoveToSnapPos(double snappedPos);
void createRectangleSelection(Qt::KeyboardModifiers modifiers);
- int spaceToolSelectTrackOnly(int track, QList<QGraphicsItem *> &selection);
+ int spaceToolSelectTrackOnly(int track, QList<QGraphicsItem *> &selection, GenTime pos = GenTime(-1));
QList<QGraphicsItem *> selectAllItemsToTheRight(int x);
GenTime createGroupForSelectedItems(QList<QGraphicsItem *> &selection);
void resetSelectionGroup(bool selectItems = true);
@@ -527,7 +527,6 @@ private:
bool insertDropClips(const QMimeData *data, const QPoint &pos);
bool canBePastedTo(QList <ItemInfo> infoList, int type) const;
bool canBePasted(QList<AbstractClipItem *> items, GenTime offset, int trackOffset) const;
- bool canBeMoved(QList<AbstractClipItem *> items, GenTime offset, int trackOffset) const;
ClipItem *getClipUnderCursor() const;
AbstractClipItem *getMainActiveClip() const;
/** Get available space for clip move (min and max free positions) */
diff --git a/src/timeline/spacerdialog.cpp b/src/timeline/spacerdialog.cpp
index 6307199..ae4a7a2 100644
--- a/src/timeline/spacerdialog.cpp
+++ b/src/timeline/spacerdialog.cpp
@@ -38,22 +38,13 @@ SpacerDialog::SpacerDialog(const GenTime &duration, const Timecode &tc, int trac
inputLayout->addWidget(&m_in);
m_in.setValue(duration);
- /*QStringList trackItems;
- trackItems << i18n("All tracks");
- for (int i = tracks.count() - 1; i > 0; --i) {
- if (!tracks.at(i).trackName.isEmpty())
- trackItems << tracks.at(i).trackName;
- else
- trackItems << QString::number(i);
- }
- track_number->addItems(trackItems);*/
QIcon videoIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-video"));
QIcon audioIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-audio"));
- track_number->addItem(i18n("All tracks"));
+ track_number->addItem(i18n("All tracks"), -1);
for (int i = tracks.count() - 1; i > 0 ; i--) {
TrackInfo info = tracks.at(i);
track_number->addItem(info.type == VideoTrack ? videoIcon : audioIcon,
- info.trackName.isEmpty() ? QString::number(i) : info.trackName);
+ info.trackName.isEmpty() ? QString::number(i) : info.trackName, i);
}
track_number->setCurrentIndex(track == 0 ? 0 : tracks.count() - track);
@@ -67,7 +58,7 @@ GenTime SpacerDialog::selectedDuration() const
int SpacerDialog::selectedTrack() const
{
- return track_number->count() - track_number->currentIndex();
+ return track_number->currentData().toInt();
}
diff --git a/src/ui/spacerdialog_ui.ui b/src/ui/spacerdialog_ui.ui
index 0b3f8e5..5e63ceb 100644
--- a/src/ui/spacerdialog_ui.ui
+++ b/src/ui/spacerdialog_ui.ui
@@ -6,14 +6,37 @@
<rect>
<x>0</x>
<y>0</y>
- <width>184</width>
- <height>94</height>
+ <width>226</width>
+ <height>174</height>
</rect>
</property>
<property name="windowTitle">
<string>Add space</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0" colspan="2">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="clip_filesize_3">
+ <property name="text">
+ <string>Track:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="KComboBox" name="track_number"/>
+ </item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
@@ -31,32 +54,9 @@
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="clip_filesize_3">
- <property name="text">
- <string>Track:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="KComboBox" name="track_number"/>
- </item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="inputLayout"/>
</item>
- <item row="2" column="0" colspan="2">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</widget>
<customwidgets>