|
From: Jean-Baptiste M. <nu...@kd...> - 2017-05-20 22:02:57
|
Git commit b046c17ab60e0653318b2e6ab8b7cbd0c5208c64 by Jean-Baptiste Mardelle. Committed on 20/05/2017 at 22:02. Pushed by mardelle into branch 'refactoring_timeline'. * implement clip cut shortcut * Fix monitor display & edit of guides/markers * Fix frame displayed twice on seek M +5 -0 src/doc/kdenlivedoc.cpp M +2 -0 src/doc/kdenlivedoc.h M +1 -1 src/gentime.cpp M +3 -9 src/mainwindow.cpp M +3 -4 src/monitor/glwidget.cpp M +7 -0 src/monitor/glwidget.h M +32 -12 src/monitor/monitor.cpp M +1 -0 src/monitor/monitor.h M +2 -2 src/monitor/view/MonitorRuler.qml M +1 -0 src/monitor/view/kdenliveclipmonitor.qml M +1 -0 src/monitor/view/kdenlivemonitor.qml M +8 -1 src/timeline2/model/timelinemodel.cpp M +1 -0 src/timeline2/model/timelinemodel.hpp M +16 -0 src/timeline2/model/trackmodel.cpp M +3 -0 src/timeline2/model/trackmodel.hpp M +4 -0 src/timeline2/view/qml/timeline.qml M +41 -0 src/timeline2/view/timelinecontroller.cpp M +6 -0 src/timeline2/view/timelinecontroller.h https://commits.kde.org/kdenlive/b046c17ab60e0653318b2e6ab8b7cbd0c5208c64 diff --git a/src/doc/kdenlivedoc.cpp b/src/doc/kdenlivedoc.cpp index 1015c4c9d..95dc85205 100644 --- a/src/doc/kdenlivedoc.cpp +++ b/src/doc/kdenlivedoc.cpp @@ -1727,3 +1727,8 @@ void KdenliveDoc::addGuides(QList<CommentedTime> &markers) } } } + +CommentedTime KdenliveDoc::getGuide(const GenTime &pos, bool *ok) const +{ + return m_guideModel->getMarker(pos, ok); +} diff --git a/src/doc/kdenlivedoc.h b/src/doc/kdenlivedoc.h index f174cbd59..a61ebb255 100644 --- a/src/doc/kdenlivedoc.h +++ b/src/doc/kdenlivedoc.h @@ -172,6 +172,8 @@ public: void addGuides(QList<CommentedTime> &markers); /** @brief Load bin thumbnails after document opening */ void loadThumbs(); + /** @brief Get timeline guide at pos. ok set to false if no guide */ + CommentedTime getGuide(const GenTime &pos, bool *ok) const; // TODO REFAC: delete */ Render *renderer(); diff --git a/src/gentime.cpp b/src/gentime.cpp index 48feaa671..381b6b508 100644 --- a/src/gentime.cpp +++ b/src/gentime.cpp @@ -124,5 +124,5 @@ bool GenTime::operator!=(GenTime op) const // static void GenTime::setFps(double fps) { - s_delta = 1.0 / fps; + s_delta = 0.9 / fps; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 87d8d2e1a..bbaf7d3a0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2531,9 +2531,7 @@ void MainWindow::slotDeleteAllGuides() void MainWindow::slotCutTimelineClip() { - if (pCore->projectManager()->currentTimeline()) { - pCore->projectManager()->currentTimeline()->projectView()->cutSelectedClips(); - } + m_timelineTabs->getCurrentTimeline()->controller()->cutClipUnderCursor(); } void MainWindow::slotInsertClipOverwrite() @@ -2822,18 +2820,14 @@ void MainWindow::slotSnapForward() void MainWindow::slotClipStart() { if (m_projectMonitor->isActive()) { - if (pCore->projectManager()->currentTimeline()) { - pCore->projectManager()->currentTimeline()->projectView()->clipStart(); - } + m_timelineTabs->getCurrentTimeline()->controller()->seekCurrentClip(false); } } void MainWindow::slotClipEnd() { if (m_projectMonitor->isActive()) { - if (pCore->projectManager()->currentTimeline()) { - pCore->projectManager()->currentTimeline()->projectView()->clipEnd(); - } + m_timelineTabs->getCurrentTimeline()->controller()->seekCurrentClip(true); } } diff --git a/src/monitor/glwidget.cpp b/src/monitor/glwidget.cpp index 4eb96d347..b55f3a153 100644 --- a/src/monitor/glwidget.cpp +++ b/src/monitor/glwidget.cpp @@ -135,7 +135,7 @@ GLWidget::GLWidget(int id, QObject *parent) connect(this, &QQuickWindow::beforeRendering, this, &GLWidget::paintGL, Qt::DirectConnection); registerTimelineItems(); m_proxy = new MonitorProxy(this); - connect(m_proxy, &MonitorProxy::seekPositionChanged, this, &GLWidget::requestSeek); + connect(m_proxy, &MonitorProxy::seekRequestChanged, this, &GLWidget::requestSeek); rootContext()->setContextProperty("controller", m_proxy); } @@ -634,8 +634,7 @@ bool GLWidget::checkFrameNumber(int pos) rootObject()->setProperty("consumerPosition", pos); if (pos == m_proxy->seekPosition()) { m_proxy->setSeekPosition(SEEK_INACTIVE); - } - if (m_proxy->seekPosition() != SEEK_INACTIVE) { + } else if (m_proxy->seekPosition() != SEEK_INACTIVE) { double speed = m_producer->get_speed(); m_producer->set_speed(0); m_producer->seek(m_proxy->seekPosition()); @@ -1252,7 +1251,7 @@ void GLWidget::onFrameDisplayed(const SharedFrame &frame) m_sharedFrame = frame; m_sendFrame = sendFrameForAnalysis; m_mutex.unlock(); - update(); + //update(); } void GLWidget::mouseReleaseEvent(QMouseEvent *event) diff --git a/src/monitor/glwidget.h b/src/monitor/glwidget.h index 00db1e394..7b31bac15 100644 --- a/src/monitor/glwidget.h +++ b/src/monitor/glwidget.h @@ -292,6 +292,12 @@ public: { } int seekPosition() const { return m_seekPosition; } + Q_INVOKABLE void requestSeekPosition(int pos) + { + m_seekPosition = pos; + emit seekPositionChanged(); + emit seekRequestChanged(); + } void setSeekPosition(int pos) { m_seekPosition = pos; @@ -324,6 +330,7 @@ public: QPoint zone() const { return QPoint(m_zoneIn, m_zoneOut); } signals: void seekPositionChanged(); + void seekRequestChanged(); void zoneChanged(); private: diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp index 0ec01834c..5792f0f45 100644 --- a/src/monitor/monitor.cpp +++ b/src/monitor/monitor.cpp @@ -157,7 +157,7 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren m_glMonitor = new GLWidget((int)id); connect(m_glMonitor, &GLWidget::passKeyEvent, this, &Monitor::doKeyPressEvent); connect(m_glMonitor, &GLWidget::panView, this, &Monitor::panView); - connect(m_glMonitor, &GLWidget::seekPosition, this, &Monitor::seekPosition, Qt::DirectConnection); + connect(m_glMonitor, &GLWidget::seekPosition, this, &Monitor::slotSeekPosition, Qt::DirectConnection); m_videoWidget = QWidget::createWindowContainer(qobject_cast<QWindow *>(m_glMonitor)); m_videoWidget->setAcceptDrops(true); auto *leventEater = new QuickEventEater(this); @@ -1066,25 +1066,28 @@ void Monitor::checkOverlay(int pos) QPoint zone = m_glMonitor->getControllerProxy()->zone(); if (m_id == Kdenlive::ClipMonitor) { if (m_controller) { - overlayText = m_controller->markerComment(GenTime(pos, m_monitorManager->timecode().fps())); - if (overlayText.isEmpty()) { + bool found = false; + CommentedTime marker = m_controller->getMarker(GenTime(pos, m_monitorManager->timecode().fps()), &found); + if (!found) { if (pos == zone.x()) { overlayText = i18n("In Point"); } else if (pos == zone.y()) { overlayText = i18n("Out Point"); } - } + } else overlayText = marker.comment(); } } else if (m_id == Kdenlive::ProjectMonitor) { - // Check for timeline guides - // TODO load timeline guides as monitor markermodel - // overlayText = m_ruler->markerAt(GenTime(pos, m_monitorManager->timecode().fps())); - if (overlayText.isEmpty()) { + bool found = false; + CommentedTime marker = pCore->projectManager()->current()->getGuide(GenTime(pos, m_monitorManager->timecode().fps()), &found); + if (!found) { if (pos == zone.x()) { overlayText = i18n("In Point"); } else if (pos == zone.y()) { overlayText = i18n("Out Point"); } + } else { + overlayText = marker.comment(); + qDebug()<<"/// POSITOIN: "<<pos<<" = "<<overlayText; } } m_glMonitor->rootObject()->setProperty("markerText", overlayText); @@ -2046,16 +2049,26 @@ void Monitor::slotEditInlineMarker() if (m_controller) { // We are editing a clip marker QString newComment = root->property("markerText").toString(); - CommentedTime oldMarker = m_controller->markerAt(render->seekPosition()); - if (newComment == oldMarker.comment()) { + bool found = false; + CommentedTime oldMarker = m_controller->getMarker(m_timePos->gentime(), &found); + if (!found || newComment == oldMarker.comment()) { // No change return; } oldMarker.setComment(newComment); - emit updateClipMarker(m_controller->AbstractProjectItem::clipId(), QList<CommentedTime>() << oldMarker); + m_controller->addMarkers(QList<CommentedTime>() << oldMarker); } else { // We are editing a timeline guide - // TODO + QString newComment = root->property("markerText").toString(); + bool found = false; + CommentedTime oldMarker = pCore->projectManager()->current()->getGuide(m_timePos->gentime(), &found); + if (!found || newComment == oldMarker.comment()) { + // No change + return; + } + oldMarker.setComment(newComment); + pCore->projectManager()->current()->addGuides(QList<CommentedTime>() << oldMarker); + /*QString currentComment = m_ruler->markerAt(render->seekPosition()); QString newComment = root->property("markerText").toString(); if (newComment == currentComment) { @@ -2153,3 +2166,10 @@ int Monitor::duration() const { return m_length; } + +void Monitor::slotSeekPosition(int pos) +{ + emit seekPosition(pos); + m_timePos->setValue(pos); + checkOverlay(); +} diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h index 52e93492a..a2d5769e1 100644 --- a/src/monitor/monitor.h +++ b/src/monitor/monitor.h @@ -278,6 +278,7 @@ private slots: void panView(QPoint diff); /** @brief Project monitor zone changed, inform timeline */ void updateTimelineClipZone(); + void slotSeekPosition(int); public slots: void slotOpenDvdFile(const QString &); diff --git a/src/monitor/view/MonitorRuler.qml b/src/monitor/view/MonitorRuler.qml index 933eea0f5..aa5da1527 100644 --- a/src/monitor/view/MonitorRuler.qml +++ b/src/monitor/view/MonitorRuler.qml @@ -78,12 +78,12 @@ import QtQuick 2.4 onEntered: root.mouseOverRuler = true; onExited: root.mouseOverRuler = false; onPressed: { - controller.seekPosition = mouseX / root.timeScale; + controller.requestSeekPosition(mouseX / root.timeScale); } onPositionChanged: { root.mouseRulerPos = mouseX if (pressed) { - controller.seekPosition = mouseX / root.timeScale; + controller.requestSeekPosition(mouseX / root.timeScale); } } } diff --git a/src/monitor/view/kdenliveclipmonitor.qml b/src/monitor/view/kdenliveclipmonitor.qml index e70adc298..9a32047e5 100644 --- a/src/monitor/view/kdenliveclipmonitor.qml +++ b/src/monitor/view/kdenliveclipmonitor.qml @@ -174,6 +174,7 @@ Item { anchors { left: parent.left bottom: parent.bottom + bottomMargin: root.rulerHeight } visible: root.showMarkers && text != "" text: root.markerText diff --git a/src/monitor/view/kdenlivemonitor.qml b/src/monitor/view/kdenlivemonitor.qml index 77df0a88c..fe6d1d9fa 100644 --- a/src/monitor/view/kdenlivemonitor.qml +++ b/src/monitor/view/kdenlivemonitor.qml @@ -141,6 +141,7 @@ Item { anchors { left: parent.left bottom: parent.bottom + bottomMargin: root.rulerHeight } visible: root.showMarkers && text != "" maximumLength: 20 diff --git a/src/timeline2/model/timelinemodel.cpp b/src/timeline2/model/timelinemodel.cpp index 2f0c607bf..f6ee56ee3 100644 --- a/src/timeline2/model/timelinemodel.cpp +++ b/src/timeline2/model/timelinemodel.cpp @@ -166,6 +166,13 @@ int TimelineModel::getTrackClipsCount(int trackId) const return count; } +int TimelineModel::getClipByPosition(int trackId, int position) const +{ + READ_LOCK(); + Q_ASSERT(isTrack(trackId)); + return getTrackById_const(trackId)->getClipByPosition(position); +} + int TimelineModel::getTrackPosition(int trackId) const { READ_LOCK(); @@ -263,7 +270,7 @@ bool TimelineModel::requestClipCut(int clipId, int position) //QWriteLocker locker(&m_lock); Q_ASSERT(m_allClips.count(clipId) > 0); if (m_allClips[clipId]->getPosition() > position || (m_allClips[clipId]->getPosition() + m_allClips[clipId]->getPlaytime() < position)) { - return true; + return false; } if (m_groups->isInGroup(clipId)) { // TODO diff --git a/src/timeline2/model/timelinemodel.hpp b/src/timeline2/model/timelinemodel.hpp index 0cb803615..0e1c33aef 100644 --- a/src/timeline2/model/timelinemodel.hpp +++ b/src/timeline2/model/timelinemodel.hpp @@ -419,6 +419,7 @@ public: void setTimelineEffectsEnabled(bool enabled); Q_INVOKABLE bool requestClipCut(int clipId, int position); + int getClipByPosition(int trackId, int position) const; protected: /* @brief Register a new track. This is a call-back meant to be called from TrackModel diff --git a/src/timeline2/model/trackmodel.cpp b/src/timeline2/model/trackmodel.cpp index 20786d5f8..a296de61e 100644 --- a/src/timeline2/model/trackmodel.cpp +++ b/src/timeline2/model/trackmodel.cpp @@ -417,6 +417,22 @@ int TrackModel::getId() const return m_id; } +int TrackModel::getClipByPosition(int position) const +{ + auto it = m_allClips.cbegin(); + while (it != m_allClips.cend()) {//row < static_cast<int>(m_allClips.size())) { + std::shared_ptr<ClipModel> clip = (*it).second; + if (clip->getPosition() > position) { + return -1; + } + if (clip->getPosition() + clip->getPlaytime() > position) { + return clip->getId(); + } + std::advance(it, 1); + } + return -1; +} + int TrackModel::getClipByRow(int row) const { if (row >= static_cast<int>(m_allClips.size())) { diff --git a/src/timeline2/model/trackmodel.hpp b/src/timeline2/model/trackmodel.hpp index 0d573f846..4a599a659 100644 --- a/src/timeline2/model/trackmodel.hpp +++ b/src/timeline2/model/trackmodel.hpp @@ -181,6 +181,9 @@ protected: /* Same, but we restrict to a specific track*/ int getBlankEnd(int position, int track); + /* @brief Returns the clip id on this track at position requested, or -1 if no clip */ + int getClipByPosition(int position) const; + public slots: /*Delete the current track and all its associated clips */ void slotDelete(); diff --git a/src/timeline2/view/qml/timeline.qml b/src/timeline2/view/qml/timeline.qml index 579540665..d61c1ee93 100644 --- a/src/timeline2/view/qml/timeline.qml +++ b/src/timeline2/view/qml/timeline.qml @@ -22,6 +22,10 @@ Rectangle { font.family: "Arial" } + function currentTrackId() { + return tracksRepeater.itemAt(root.currentTrack).trackId + } + function zoomByWheel(wheel) { if (wheel.modifiers & Qt.ControlModifier) { //TODO diff --git a/src/timeline2/view/timelinecontroller.cpp b/src/timeline2/view/timelinecontroller.cpp index eae6db8f5..8fd4a5285 100644 --- a/src/timeline2/view/timelinecontroller.cpp +++ b/src/timeline2/view/timelinecontroller.cpp @@ -435,3 +435,44 @@ void TimelineController::setZoneOut(int outPoint) m_zone.setY(outPoint); emit zoneMoved(m_zone); } + +void TimelineController::cutClipUnderCursor() +{ + bool foundClip = false; + for (int cid : m_selection.selectedClips) { + if (m_model->requestClipCut(cid, m_position)) { + foundClip = true; + } + } + if (!foundClip) { + QVariant returnedValue; + QMetaObject::invokeMethod(m_root, "currentTrackId", + Q_RETURN_ARG(QVariant, returnedValue)); + int trackId = returnedValue.toInt(); + if (trackId >= 0) { + int cid = m_model->getClipByPosition(trackId, m_position); + if (cid >= 0) { + m_model->requestClipCut(cid, m_position); + foundClip = true; + } + } + } + if (!foundClip) { + //TODO: display warning, no clip found + } +} + +void TimelineController::seekCurrentClip(bool seekToEnd) +{ + bool foundClip = false; + for (int cid : m_selection.selectedClips) { + int start = m_model->getClipPosition(cid); + if (seekToEnd) { + start += m_model->getClipPlaytime(cid); + } + seek(start); + foundClip = true; + break; + } +} + diff --git a/src/timeline2/view/timelinecontroller.h b/src/timeline2/view/timelinecontroller.h index 0361c9054..291b6b989 100644 --- a/src/timeline2/view/timelinecontroller.h +++ b/src/timeline2/view/timelinecontroller.h @@ -188,6 +188,12 @@ public: */ void addAsset(const QVariantMap data); void checkDuration(); + /* @brief Cuts the clip on current track at timeline position + */ + void cutClipUnderCursor(); + /* @brief Seeks to selected clip start / end + */ + void seekCurrentClip(bool seekToEnd = false); public slots: void selectMultitrack(); |