summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <jb@kdenlive.org>2016-09-23 13:57:57 (GMT)
committerJean-Baptiste Mardelle <jb@kdenlive.org>2016-09-23 13:57:57 (GMT)
commit8b78b8b9518ac98016e3844269daa3a00e785eb5 (patch)
tree23ab01a4a0ce666f94aadb8135f529732b6207eb
parentd9d5d95a4565fbfbb890be20696fb424140943de (diff)
Rolling edit can now be triggered by selecting a timeline clip
and pressing Ctrl + Arrow key. This will start a rolling edit on the clip end that is the closest to timeline cursor. Press again Ctrl + Left/Right Arrow to move edit point. You currently have to press "Escape" or click "Close" in monitor to finish operation, or kdenlive will be unstable if you try doing another operation while in rolling mode. Ref T1953
-rw-r--r--data/kdenlivemonitorripple.qml24
-rw-r--r--src/bin/projectclip.cpp4
-rw-r--r--src/effectslist/effectslistview.cpp1
-rw-r--r--src/monitor/glwidget.cpp5
-rw-r--r--src/monitor/monitor.cpp52
-rw-r--r--src/timeline/abstractclipitem.cpp6
-rw-r--r--src/timeline/customtrackview.cpp68
-rw-r--r--src/timeline/customtrackview.h5
-rw-r--r--src/timeline/managers/trimmanager.cpp56
-rw-r--r--src/timeline/managers/trimmanager.h5
-rw-r--r--src/timeline/timeline.cpp25
-rw-r--r--src/timeline/timeline.h3
12 files changed, 162 insertions, 92 deletions
diff --git a/data/kdenlivemonitorripple.qml b/data/kdenlivemonitorripple.qml
index d2b75a5..f750008 100644
--- a/data/kdenlivemonitorripple.qml
+++ b/data/kdenlivemonitorripple.qml
@@ -32,36 +32,20 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
- root.doAcceptRipple(mouseX > width / 2)
- }
- }
-
- Rectangle {
- id: cancel
- anchors {
- left: root.left
- top: info.bottom
- }
- width: root.width / 2
- height: root.height / 2 - info.height
- color: "darkRed"
- Text {
- text: 'Cancel'
- color: "white"
- anchors.centerIn: parent
+ root.doAcceptRipple(true)
}
}
Rectangle {
id: accept
anchors {
- right: root.right
+ left: root.left
top: info.bottom
}
- width: root.width / 2
+ width: root.width
height: root.height / 2 - info.height
color: "darkGreen"
Text {
- text: 'Accept'
+ text: 'close'
color: "white"
anchors.centerIn: parent
}
diff --git a/src/bin/projectclip.cpp b/src/bin/projectclip.cpp
index cc3933f..12fc4fa 100644
--- a/src/bin/projectclip.cpp
+++ b/src/bin/projectclip.cpp
@@ -861,6 +861,8 @@ void ProjectClip::doExtractIntra()
}
prod->seek(pos);
Mlt::Frame *frame = prod->get_frame();
+ frame->set("deinterlace_method", "onefield");
+ frame->set("top_field_first", -1 );
if (frame && frame->is_valid()) {
img = KThumb::getFrame(frame, fullWidth, 150);
bin()->cachePixmap(path, img);
@@ -910,6 +912,8 @@ void ProjectClip::doExtractImage()
}
prod->seek(pos);
Mlt::Frame *frame = prod->get_frame();
+ frame->set("deinterlace_method", "onefield");
+ frame->set("top_field_first", -1 );
if (frame && frame->is_valid()) {
img = KThumb::getFrame(frame, frameWidth, 150);
bin()->cachePixmap(path, img);
diff --git a/src/effectslist/effectslistview.cpp b/src/effectslist/effectslistview.cpp
index 6150b0b..13cb121 100644
--- a/src/effectslist/effectslistview.cpp
+++ b/src/effectslist/effectslistview.cpp
@@ -42,7 +42,6 @@ bool TreeEventEater::eventFilter(QObject *obj, QEvent *event)
if (((QKeyEvent*)event)->key() == Qt::Key_Escape) {
emit clearSearchLine();
}
- return QObject::eventFilter(obj, event);
}
return QObject::eventFilter(obj, event);
}
diff --git a/src/monitor/glwidget.cpp b/src/monitor/glwidget.cpp
index 038a601..d8f5ff1 100644
--- a/src/monitor/glwidget.cpp
+++ b/src/monitor/glwidget.cpp
@@ -612,8 +612,9 @@ void GLWidget::mouseMoveEvent(QMouseEvent* event)
void GLWidget::keyPressEvent(QKeyEvent* event)
{
QQuickView::keyPressEvent(event);
- if (event->isAccepted()) return;
- emit passKeyEvent(event);
+ if (!event->isAccepted()) {
+ emit passKeyEvent(event);
+ }
}
void GLWidget::createThread(RenderThread **thread, thread_function_t function, void *data)
diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp
index 518f614..29a4d31 100644
--- a/src/monitor/monitor.cpp
+++ b/src/monitor/monitor.cpp
@@ -73,30 +73,40 @@ QuickEventEater::QuickEventEater(QObject *parent) : QObject(parent)
bool QuickEventEater::eventFilter(QObject *obj, QEvent *event)
{
- if (event->type() == QEvent::DragEnter) {
- QDragEnterEvent *ev = reinterpret_cast< QDragEnterEvent* >(event);
- if (ev->mimeData()->hasFormat(QStringLiteral("kdenlive/effectslist"))) {
- ev->acceptProposedAction();
- return true;
+ switch (event->type()) {
+ case QEvent::DragEnter:
+ {
+ QDragEnterEvent *ev = reinterpret_cast< QDragEnterEvent* >(event);
+ if (ev->mimeData()->hasFormat(QStringLiteral("kdenlive/effectslist"))) {
+ ev->acceptProposedAction();
+ return true;
+ }
+ break;
}
- }
- else if (event->type() == QEvent::DragMove) {
- QDragEnterEvent *ev = reinterpret_cast< QDragEnterEvent* >(event);
- if (ev->mimeData()->hasFormat(QStringLiteral("kdenlive/effectslist"))) {
- ev->acceptProposedAction();
- return true;
+ case QEvent::DragMove:
+ {
+ QDragEnterEvent *ev = reinterpret_cast< QDragEnterEvent* >(event);
+ if (ev->mimeData()->hasFormat(QStringLiteral("kdenlive/effectslist"))) {
+ ev->acceptProposedAction();
+ return true;
+ }
+ break;
}
- }
- else if (event->type() == QEvent::Drop) {
- QDropEvent *ev = static_cast< QDropEvent* >(event);
- if (ev) {
- const QString effects = QString::fromUtf8(ev->mimeData()->data(QStringLiteral("kdenlive/effectslist")));
- QDomDocument doc;
- doc.setContent(effects, true);
- emit addEffect(doc.documentElement());
- ev->accept();
- return true;
+ case QEvent::Drop:
+ {
+ QDropEvent *ev = static_cast< QDropEvent* >(event);
+ if (ev) {
+ const QString effects = QString::fromUtf8(ev->mimeData()->data(QStringLiteral("kdenlive/effectslist")));
+ QDomDocument doc;
+ doc.setContent(effects, true);
+ emit addEffect(doc.documentElement());
+ ev->accept();
+ return true;
+ }
+ break;
}
+ default:
+ break;
}
return QObject::eventFilter(obj, event);
}
diff --git a/src/timeline/abstractclipitem.cpp b/src/timeline/abstractclipitem.cpp
index c09fbfe..0f0f325 100644
--- a/src/timeline/abstractclipitem.cpp
+++ b/src/timeline/abstractclipitem.cpp
@@ -189,7 +189,9 @@ void AbstractClipItem::updateRectGeometry()
void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChange*/)
{
GenTime durationDiff = GenTime(posx, m_fps) - m_info.startPos;
- if (durationDiff == GenTime()) return;
+ if (durationDiff == GenTime()) {
+ return;
+ }
if (type() == AVWidget && hasSizeLimit && (cropStart() + durationDiff < GenTime())) {
durationDiff = GenTime() - cropStart();
@@ -206,7 +208,6 @@ void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChang
if (m_info.cropStart < GenTime())
negCropStart = true;
}
-
m_info.cropDuration -= durationDiff;
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
moveBy(durationDiff.frames(m_fps), 0);
@@ -220,7 +221,6 @@ void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChang
m_info.cropDuration -= diff;
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
}
-
// set crop from start to 0 (isn't relevant as this only happens for color clips, images)
if (negCropStart)
m_info.cropStart = GenTime();
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index bb42870..3462496 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -209,13 +209,55 @@ void CustomTrackView::initTools()
//virtual
void CustomTrackView::keyPressEvent(QKeyEvent * event)
{
- if (event->key() == Qt::Key_Up) {
- slotTrackUp();
- event->accept();
- } else if (event->key() == Qt::Key_Down) {
- slotTrackDown();
- event->accept();
- } else QWidget::keyPressEvent(event);
+ switch(event->key()) {
+ case Qt::Key_Up:
+ slotTrackUp();
+ event->accept();
+ break;
+ case Qt::Key_Down:
+ slotTrackDown();
+ event->accept();
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (event->modifiers() == Qt::ControlModifier) {
+ if (m_dragItem == NULL || m_dragItem->type() != AVWidget) {
+ QGraphicsView::keyPressEvent(event);
+ return;
+ }
+ // Enter rolling
+ int diffStart = qAbs(m_cursorPos - m_dragItem->startPos().frames(m_document->fps()));
+ int diffEnd = qAbs(m_cursorPos - m_dragItem->endPos().frames(m_document->fps()));
+ TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
+ if (m_moveOpMode == RollingEnd || m_moveOpMode == RollingStart) {
+ // Already in trim mode, move
+ mgr->moveRoll(event->key() == Qt::Key_Right);
+ } else {
+ // init trim
+ mgr->enterTrimMode(m_dragItem->info(), diffStart < diffEnd);
+ }
+ setFocus();
+ event->accept();
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ QGraphicsView::keyPressEvent(event);
+}
+
+bool CustomTrackView::event( QEvent * e )
+{
+ if ((m_moveOpMode == RollingEnd || m_moveOpMode == RollingStart) && e->type() == QEvent::ShortcutOverride) {
+ if (((QKeyEvent*)e)->key() == Qt::Key_Escape) {
+ TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
+ mgr->endRoll();
+ e->accept();
+ return true;
+ }
+ }
+ return QGraphicsView::event(e);
}
void CustomTrackView::setDocumentModified()
@@ -2206,10 +2248,11 @@ void CustomTrackView::rippleMode(bool enable)
emit displayMessage(i18n("Select a clip to enter ripple mode"), InformationMessage);
return;
}
- if (m_operationMode == ResizeEnd)
+ if (m_operationMode == ResizeEnd) {
m_moveOpMode = RollingEnd;
- else if (m_operationMode == ResizeStart)
+ } else if (m_operationMode == ResizeStart) {
m_moveOpMode = RollingStart;
+ }
int ripplePos = m_moveOpMode == RollingStart ? m_dragItem->startPos().frames(m_document->fps()) : m_dragItem->endPos().frames(m_document->fps());
if (m_timeline->createRippleWindow(m_dragItem->track(), ripplePos)) {
emit loadMonitorScene(MonitorSceneRipple, true);
@@ -8471,8 +8514,11 @@ void CustomTrackView::switchAllTrackLock()
void CustomTrackView::slotAcceptRipple(bool accept)
{
- m_timeline->removeSplitOverlay();
- QMetaObject::invokeMethod(this, "doRipple", Qt::QueuedConnection, Q_ARG(bool, accept));
+ if (m_moveOpMode == RollingEnd || m_moveOpMode == RollingStart) {
+ TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
+ if (mgr)
+ QMetaObject::invokeMethod(mgr, "endRoll", Qt::QueuedConnection);
+ }
}
void CustomTrackView::doRipple(bool accept)
diff --git a/src/timeline/customtrackview.h b/src/timeline/customtrackview.h
index 12471f3..467cdb2 100644
--- a/src/timeline/customtrackview.h
+++ b/src/timeline/customtrackview.h
@@ -369,8 +369,6 @@ public slots:
/** @brief Shows the configure tracks dialog. */
void slotConfigTracks(int ix);
void clipNameChanged(const QString &id);
- void slotTrackUp();
- void slotTrackDown();
void slotSelectTrack(int ix, bool switchTarget = false);
int insertZone(TimelineMode::EditMode sceneMode, const QString clipId, QPoint binZone);
@@ -418,6 +416,7 @@ protected:
virtual void dragEnterEvent(QDragEnterEvent * event);
virtual void dragMoveEvent(QDragMoveEvent * event);
virtual void dragLeaveEvent(QDragLeaveEvent * event);
+ virtual bool event( QEvent * e );
/** @brief Something has been dropped onto the timeline */
virtual void dropEvent(QDropEvent * event);
virtual void enterEvent(QEvent * event);
@@ -558,6 +557,8 @@ private:
void updateTimelineSelection();
/** @brief Break groups containing an item in a locked track. */
void breakLockedGroups(QList<ItemInfo> clipsToMove, QList<ItemInfo> transitionsToMove, QUndoCommand *masterCommand, bool doIt = true);
+ void slotTrackUp();
+ void slotTrackDown();
private slots:
void slotRefreshGuides();
diff --git a/src/timeline/managers/trimmanager.cpp b/src/timeline/managers/trimmanager.cpp
index 3d93ea5..5e1c7c4 100644
--- a/src/timeline/managers/trimmanager.cpp
+++ b/src/timeline/managers/trimmanager.cpp
@@ -37,8 +37,31 @@ TrimManager::TrimManager(CustomTrackView *view, DocUndoStack *commandStack) : Ab
bool TrimManager::mousePress(ItemInfo info, Qt::KeyboardModifiers, QList<QGraphicsItem *>)
{
- qDebug()<<"OP MODE: "<<m_view->prepareMode();
- if (m_view->prepareMode() == ResizeStart) {
+ return enterTrimMode(info, m_view->prepareMode() == ResizeStart);
+}
+
+void TrimManager::mouseMove(int pos)
+{
+ if (!m_firstInfo.isValid() || !m_secondInfo.isValid())
+ return;
+ if (pos < m_firstClip->endPos().frames(m_view->fps())) {
+ m_firstClip->resizeEnd(pos, false);
+ m_secondClip->resizeStart(pos, true, false);
+ } else {
+ m_secondClip->resizeStart(pos, true, false);
+ m_firstClip->resizeEnd(pos, false);
+ }
+ m_view->seekCursorPos(pos);
+}
+
+void TrimManager::mouseRelease(GenTime)
+{
+ endRoll();
+}
+
+bool TrimManager::enterTrimMode(ItemInfo info, bool trimStart)
+{
+ if (trimStart) {
m_firstClip = m_view->getClipItemAtEnd(info.startPos, info.track);
m_secondClip = m_view->getClipItemAtStart(info.startPos, info.track);
} else {
@@ -46,40 +69,47 @@ bool TrimManager::mousePress(ItemInfo info, Qt::KeyboardModifiers, QList<QGraphi
m_secondClip = m_view->getClipItemAtStart(info.endPos, info.track);
}
if (!m_firstClip || !m_secondClip) {
- qDebug()<<"/ / / / WARNING, ERROR WITH TRIM CLIPS";
m_view->setOperationMode(None);
m_firstInfo = ItemInfo();
m_secondInfo = ItemInfo();
return false;
}
- m_firstInfo = m_firstClip->info();
- m_secondInfo = m_secondClip->info();
AbstractClipItem *dragItem = m_view->dragItem();
- m_view->rippleMode(true);
- m_view->loadMonitorScene(MonitorSceneRipple, true);
AbstractGroupItem *selectionGroup = m_view->selectionGroup();
if (selectionGroup) {
m_view->resetSelectionGroup(false);
dragItem->setSelected(true);
}
+ m_view->setOperationMode(trimStart ? RollingStart : RollingEnd);
+ m_firstInfo = m_firstClip->info();
+ m_secondInfo = m_secondClip->info();
+ m_view->rippleMode(true);
+ m_view->loadMonitorScene(MonitorSceneRipple, true);
+ m_view->seekCursorPos(trimStart ? info.startPos.frames(m_view->fps()) : info.endPos.frames(m_view->fps()));
return true;
}
-void TrimManager::mouseMove(int pos)
+void TrimManager::moveRoll(bool forward)
{
if (!m_firstInfo.isValid() || !m_secondInfo.isValid())
return;
- if (pos < m_firstClip->endPos().frames(m_view->fps())) {
- m_firstClip->resizeEnd(pos, false);
+ int pos = m_firstClip->endPos().frames(m_view->fps());
+ bool snap = KdenliveSettings::snaptopoints();
+ KdenliveSettings::setSnaptopoints(false);
+ if (forward) {
+ pos++;
m_secondClip->resizeStart(pos, true, false);
+ m_firstClip->resizeEnd(pos, false);
} else {
- m_secondClip->resizeStart(pos, true, false);
+ pos--;
m_firstClip->resizeEnd(pos, false);
+ m_secondClip->resizeStart(pos, true, false);
}
m_view->seekCursorPos(pos);
+ KdenliveSettings::setSnaptopoints(snap);
}
-void TrimManager::mouseRelease(GenTime)
+void TrimManager::endRoll()
{
if (!m_firstInfo.isValid() || !m_secondInfo.isValid())
return;
@@ -97,5 +127,3 @@ void TrimManager::mouseRelease(GenTime)
m_firstInfo = ItemInfo();
m_secondInfo = ItemInfo();
}
-
-
diff --git a/src/timeline/managers/trimmanager.h b/src/timeline/managers/trimmanager.h
index 6670fc1..c68d617 100644
--- a/src/timeline/managers/trimmanager.h
+++ b/src/timeline/managers/trimmanager.h
@@ -38,6 +38,11 @@ public:
bool mousePress(ItemInfo info = ItemInfo(), Qt::KeyboardModifiers modifiers = Qt::NoModifier, QList<QGraphicsItem *> list = QList<QGraphicsItem *>());
void mouseMove(int pos);
void mouseRelease(GenTime pos = GenTime());
+ bool enterTrimMode(ItemInfo info, bool trimStart);
+ void moveRoll(bool forward);
+
+public slots:
+ void endRoll();
private:
ClipItem *m_firstClip;
diff --git a/src/timeline/timeline.cpp b/src/timeline/timeline.cpp
index d0fd31e..7b58564 100644
--- a/src/timeline/timeline.cpp
+++ b/src/timeline/timeline.cpp
@@ -85,6 +85,7 @@ Timeline::Timeline(KdenliveDoc *doc, const QList<QAction *> &actions, const QLis
connect(splitter, &QSplitter::splitterMoved, this, &Timeline::storeHeaderSize);
m_scene = new CustomTrackScene(this);
m_trackview = new CustomTrackView(doc, this, m_scene, parent);
+ setFocusProxy(m_trackview);
if (m_doc->setSceneList() == -1) *ok = false;
else *ok = true;
Mlt::Service s(m_doc->renderer()->getProducer()->parent().get_service());
@@ -232,18 +233,6 @@ int Timeline::visibleTracksCount() const
return m_tractor->count() - 1 - m_hasOverlayTrack - m_usePreview;
}
-//virtual
-void Timeline::keyPressEvent(QKeyEvent * event)
-{
- if (event->key() == Qt::Key_Up) {
- m_trackview->slotTrackUp();
- event->accept();
- } else if (event->key() == Qt::Key_Down) {
- m_trackview->slotTrackDown();
- event->accept();
- } else QWidget::keyPressEvent(event);
-}
-
int Timeline::duration() const
{
return m_trackview->duration();
@@ -1735,17 +1724,23 @@ bool Timeline::createRippleWindow(int tk, int startPos)
}
Mlt::Producer *firstClip = playlist.get_clip(clipIndex - 1);
Mlt::Producer *secondClip = playlist.get_clip(clipIndex);
-
+ qDebug()<<"** TRIM ON TK: "<<tk<<", POS: "<<startPos;
+ if (!firstClip || !firstClip->is_valid()) {
+ m_tractor->unlock();
+ return false;
+ }
+ if (!secondClip || !secondClip->is_valid()) {
+ m_tractor->unlock();
+ return false;
+ }
// Create duplicate of second clip
Clip clp2(secondClip->parent());
Mlt::Producer *cln2 = clp2.clone();
Clip(*cln2).addEffects(*secondClip);
-
// Create copy of first clip
Mlt::Producer *cln = new Mlt::Producer(firstClip->parent());
cln->set_in_and_out(firstClip->get_in(), -1);
Clip(*cln).addEffects(*firstClip);
-
int secondStart = playlist.clip_start(clipIndex) - secondClip->get_in();
int rippleStart = playlist.clip_start(clipIndex - 1);
diff --git a/src/timeline/timeline.h b/src/timeline/timeline.h
index acdad80..2a69285 100644
--- a/src/timeline/timeline.h
+++ b/src/timeline/timeline.h
@@ -189,9 +189,6 @@ public:
/** @brief Toggle current project's compositing mode. */
void switchComposite(int mode);
-protected:
- void keyPressEvent(QKeyEvent * event);
-
public slots:
void slotDeleteClip(const QString &clipId, QUndoCommand *deleteCommand);
void slotChangeZoom(int horizontal, int vertical = -1);