[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive/refactoring_timeline] src: Reintroduce clip duration dialog
From:       Jean-Baptiste Mardelle <null () kde ! org>
Date:       2018-07-03 17:51:24
Message-ID: E1faPSW-0000DF-0c () code ! kde ! org
[Download RAW message or body]

Git commit 49c042139139c7e4675724e836a47bbe648c760b by Jean-Baptiste Mardelle.
Committed on 03/07/2018 at 17:51.
Pushed by mardelle into branch 'refactoring_timeline'.

Reintroduce clip duration dialog

M  +12   -0    src/mltcontroller/clipcontroller.cpp
M  +1    -0    src/mltcontroller/clipcontroller.h
M  +1    -0    src/timeline2/CMakeLists.txt
M  +1    -1    src/timeline2/model/timelinemodel.hpp
M  +19   -27   src/timeline2/view/dialogs/clipdurationdialog.cpp
M  +3    -4    src/timeline2/view/dialogs/clipdurationdialog.h
M  +10   -6    src/timeline2/view/qml/Clip.qml
M  +81   -0    src/timeline2/view/timelinecontroller.cpp
M  +7    -4    src/timeline2/view/timelinecontroller.h

https://commits.kde.org/kdenlive/49c042139139c7e4675724e836a47bbe648c760b

diff --git a/src/mltcontroller/clipcontroller.cpp \
b/src/mltcontroller/clipcontroller.cpp index 00d714287..4f66ff80a 100644
--- a/src/mltcontroller/clipcontroller.cpp
+++ b/src/mltcontroller/clipcontroller.cpp
@@ -337,6 +337,18 @@ const QString ClipController::getStringDuration()
     return i18n("Unknown");
 }
 
+int ClipController::getProducerDuration() const
+{
+    if (m_masterProducer) {
+        int playtime = m_masterProducer->get_int("kdenlive:duration");
+        if (playtime <= 0) {
+            return playtime = m_masterProducer->get_length();
+        }
+        return playtime;
+    }
+    return -1;
+}
+
 GenTime ClipController::getPlaytime() const
 {
     if (!m_masterProducer || !m_masterProducer->is_valid()) {
diff --git a/src/mltcontroller/clipcontroller.h b/src/mltcontroller/clipcontroller.h
index e21a94394..4c0e56699 100644
--- a/src/mltcontroller/clipcontroller.h
+++ b/src/mltcontroller/clipcontroller.h
@@ -130,6 +130,7 @@ public:
     const QSize getFrameSize() const;
     /** @brief Returns the clip duration as a string like 00:00:02:01. */
     const QString getStringDuration();
+    int getProducerDuration() const;
 
     /**
      * @brief Returns a pixmap created from a frame of the producer.
diff --git a/src/timeline2/CMakeLists.txt b/src/timeline2/CMakeLists.txt
index df2ffa596..61c0e3dc5 100644
--- a/src/timeline2/CMakeLists.txt
+++ b/src/timeline2/CMakeLists.txt
@@ -11,6 +11,7 @@ set(kdenlive_SRCS
   timeline2/model/builders/meltBuilder.cpp
   timeline2/view/dialogs/spacerdialog.cpp
   timeline2/view/dialogs/trackdialog.cpp
+  timeline2/view/dialogs/clipdurationdialog.cpp
   timeline2/view/previewmanager.cpp
   timeline2/view/timelinetabs.cpp
   timeline2/view/timelinecontroller.cpp
diff --git a/src/timeline2/model/timelinemodel.hpp \
b/src/timeline2/model/timelinemodel.hpp index 10909208b..1e741b58a 100644
--- a/src/timeline2/model/timelinemodel.hpp
+++ b/src/timeline2/model/timelinemodel.hpp
@@ -240,7 +240,7 @@ public:
     */
     int getClipPlaytime(int clipId) const;
 
-    /* @brief Returns the duration of a clip
+    /* @brief Returns the size of the clip's frame (widthxheight)
        @param clipId Id of the clip to test
     */
     QSize getClipFrameSize(int clipId) const;
diff --git a/src/timeline2/view/dialogs/clipdurationdialog.cpp \
b/src/timeline2/view/dialogs/clipdurationdialog.cpp index 646ada3ed..a7a414a70 100644
--- a/src/timeline2/view/dialogs/clipdurationdialog.cpp
+++ b/src/timeline2/view/dialogs/clipdurationdialog.cpp
@@ -18,17 +18,17 @@
  ***************************************************************************/
 
 #include "clipdurationdialog.h"
-#include "clipitem.h"
 
 #include <QFontDatabase>
 
 #include <QWheelEvent>
 
-ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, const Timecode &tc, \
const GenTime &min, const GenTime &max, QWidget *parent): \
+ClipDurationDialog::ClipDurationDialog(int clipId, const Timecode &tc, int pos, int \
minpos, int in, int out, int length, int maxpos, QWidget *parent):  QDialog(parent),
-    m_clip(clip),
-    m_min(min),
-    m_max(max)
+    m_clipId(clipId),
+    m_min(GenTime(minpos, tc.fps())),
+    m_max(GenTime(maxpos, tc.fps())),
+    m_length(GenTime(length, tc.fps()))
 {
     setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
     setupUi(this);
@@ -43,28 +43,21 @@ ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, \
const Timecode &t  clip_duration_box->addWidget(m_dur);
     crop_end_box->addWidget(m_cropEnd);
 
-    bool allowCrop = true;
-    if (clip->type() == AVWidget) {
-        ClipItem *item = static_cast <ClipItem *>(clip);
-        const int t = item->clipType();
-        if (t == Color || t == Image || t == Text) {
-            allowCrop = false;
-        }
-    }
+    bool allowCrop = length != -1;
 
-    if (!allowCrop || clip->type() == TransitionWidget) {
+    if (!allowCrop) {
         m_cropStart->setHidden(true);
         crop_label->hide();
         m_cropEnd->setHidden(true),
-                  end_label->hide();
+        end_label->hide();
     }
 
-    m_crop = m_clip->cropStart();
+    m_crop = GenTime(in, tc.fps());
 
-    m_pos->setValue(m_clip->startPos());
-    m_dur->setValue(m_clip->cropDuration());
-    m_cropStart->setValue(m_clip->cropStart());
-    m_cropEnd->setValue(m_clip->maxDuration() - m_clip->cropDuration() - \
m_clip->cropStart()); +    m_pos->setValue(GenTime(pos, tc.fps()));
+    m_dur->setValue(GenTime(out - in, tc.fps()));
+    m_cropStart->setValue(GenTime(in, tc.fps()));
+    m_cropEnd->setValue(GenTime(length - out, tc.fps()));
 
     connect(m_pos,       &TimecodeDisplay::timeCodeEditingFinished, this, \
                &ClipDurationDialog::slotCheckStart);
     connect(m_dur,       &TimecodeDisplay::timeCodeEditingFinished, this, \
&ClipDurationDialog::slotCheckDuration); @@ -100,10 +93,10 @@ void \
ClipDurationDialog::slotCheckDuration()  GenTime cropStart = m_cropStart->gentime();
     GenTime maxDuration;
 
-    if (m_clip->maxDuration() == GenTime()) {
+    if (m_length <= GenTime()) {
         maxDuration = m_max;
     } else {
-        maxDuration = m_max == GenTime() ? start + m_clip->maxDuration() - cropStart \
: qMin(m_max, start + m_clip->maxDuration() - cropStart); +        maxDuration = \
m_max == GenTime() ? start + m_length - cropStart : qMin(m_max, start + m_length - \
cropStart);  }
 
     if (maxDuration != GenTime() && start + duration > maxDuration) {
@@ -113,7 +106,7 @@ void ClipDurationDialog::slotCheckDuration()
     }
 
     m_cropEnd->blockSignals(true);
-    m_cropEnd->setValue(m_clip->maxDuration() - m_dur->gentime() - cropStart);
+    m_cropEnd->setValue(m_length - m_dur->gentime() - cropStart);
     m_cropEnd->blockSignals(false);
 }
 
@@ -121,7 +114,6 @@ void ClipDurationDialog::slotCheckCrop()
 {
     GenTime duration = m_dur->gentime();
     GenTime cropStart = m_cropStart->gentime();
-    GenTime maxDuration = m_clip->maxDuration();
 
     GenTime diff = cropStart - m_crop;
     if ((diff > GenTime() && diff < duration) || diff < GenTime()) {
@@ -131,7 +123,7 @@ void ClipDurationDialog::slotCheckCrop()
         return;
     }
 
-    if (maxDuration != GenTime() && cropStart + duration > maxDuration) {
+    if (m_length > GenTime() && cropStart + duration > m_length) {
         m_cropStart->setValue(m_crop);
     } else {
         m_crop = cropStart;
@@ -145,14 +137,14 @@ void ClipDurationDialog::slotCheckEnd()
 {
     GenTime cropStart = m_cropStart->gentime();
     GenTime cropEnd = m_cropEnd->gentime();
-    GenTime duration = m_clip->maxDuration() - cropEnd - cropStart;
+    GenTime duration = m_length - cropEnd - cropStart;
 
     if (duration >= GenTime()) {
         m_dur->setValue(duration);
         slotCheckDuration();
     } else {
         m_cropEnd->blockSignals(true);
-        m_cropEnd->setValue(m_clip->maxDuration() - m_dur->gentime() - cropStart);
+        m_cropEnd->setValue(m_length - m_dur->gentime() - cropStart);
         m_cropEnd->blockSignals(false);
     }
 }
diff --git a/src/timeline2/view/dialogs/clipdurationdialog.h \
b/src/timeline2/view/dialogs/clipdurationdialog.h index 5e4656f8f..cf804cd6f 100644
--- a/src/timeline2/view/dialogs/clipdurationdialog.h
+++ b/src/timeline2/view/dialogs/clipdurationdialog.h
@@ -20,8 +20,6 @@
 #ifndef CLIPDURATIONDIALOG_H
 #define CLIPDURATIONDIALOG_H
 
-#include "timeline/abstractclipitem.h"
-
 #include "timecodedisplay.h"
 #include "ui_clipdurationdialog_ui.h"
 
@@ -36,7 +34,7 @@ class ClipDurationDialog : public QDialog, public \
Ui::ClipDurationDialog_UI  Q_OBJECT
 
 public:
-    explicit ClipDurationDialog(AbstractClipItem *clip, const Timecode &tc, const \
GenTime &min, const GenTime &max, QWidget *parent = nullptr); +    explicit \
ClipDurationDialog(int clipId, const Timecode &tc, int pos, int minpos, int in, int \
out, int length, int maxpos, QWidget *parent = nullptr);  ~ClipDurationDialog();
     GenTime startPos() const;
     GenTime cropStart() const;
@@ -49,7 +47,7 @@ private slots:
     void slotCheckEnd();
 
 private:
-    AbstractClipItem *m_clip;
+    int m_clipId;
     TimecodeDisplay *m_pos;
     TimecodeDisplay *m_dur;
     TimecodeDisplay *m_cropStart;
@@ -57,6 +55,7 @@ private:
     GenTime m_min;
     GenTime m_max;
     GenTime m_crop;
+    GenTime m_length;
 };
 
 #endif
diff --git a/src/timeline2/view/qml/Clip.qml b/src/timeline2/view/qml/Clip.qml
index 124122b43..d9a0501b8 100644
--- a/src/timeline2/view/qml/Clip.qml
+++ b/src/timeline2/view/qml/Clip.qml
@@ -285,13 +285,17 @@ Rectangle {
             }
         }
         onDoubleClicked: {
-            if (showKeyframes) {
-                // Add new keyframe
-                var xPos = Math.round(mouse.x  / timeline.scaleFactor)
-                var yPos = (clipRoot.height - mouse.y) / clipRoot.height
-                keyframeModel.addKeyframe(xPos + clipRoot.inPoint, yPos)
+            if (mouse.modifiers & Qt.ShiftModifier) {
+                if (keyframeModel && showKeyframes) {
+                    // Add new keyframe
+                    var xPos = Math.round(mouse.x  / timeline.scaleFactor)
+                    var yPos = (clipRoot.height - mouse.y) / clipRoot.height
+                    keyframeModel.addKeyframe(xPos + clipRoot.inPoint, yPos)
+                } else {
+                    timeline.position = clipRoot.x / timeline.scaleFactor
+                }
             } else {
-                timeline.position = clipRoot.x / timeline.scaleFactor
+                timeline.editItemDuration(clipId)
             }
         }
         onWheel: zoomByWheel(wheel)
diff --git a/src/timeline2/view/timelinecontroller.cpp \
b/src/timeline2/view/timelinecontroller.cpp index 4d8a19cc3..6c75f77e8 100644
--- a/src/timeline2/view/timelinecontroller.cpp
+++ b/src/timeline2/view/timelinecontroller.cpp
@@ -38,6 +38,7 @@
 #include "timeline2/model/timelineitemmodel.hpp"
 #include "timeline2/model/trackmodel.hpp"
 #include "timeline2/view/dialogs/trackdialog.h"
+#include "timeline2/view/dialogs/clipdurationdialog.h"
 #include "timelinewidget.h"
 #include "transitions/transitionsrepository.hpp"
 #include "utils/KoIconUtils.h"
@@ -1560,3 +1561,83 @@ double TimelineController::fps() const
 {
     return pCore->getCurrentFps();
 }
+
+void TimelineController::editItemDuration(int id)
+{
+    int start = m_model->getItemPosition(id);
+    int in = 0;
+    int duration = m_model->getItemPlaytime(id);
+    int maxLength = -1;
+    if (m_model->isClip(id)) {
+        in = m_model->getClipIn(id);
+        std::shared_ptr<ProjectClip> clip = \
pCore->bin()->getBinClip(getClipBinId(id)); +        if (clip && \
clip->hasLimitedDuration()) { +            maxLength = clip->getProducerDuration();
+        }
+    }
+    int trackId = m_model->getItemTrackId(id);
+    int maxFrame = m_model->getTrackById(trackId)->getBlankSizeNearClip(id, true);
+    int minFrame = in - m_model->getTrackById(trackId)->getBlankSizeNearClip(id, \
false); +    int partner = m_model->getClipSplitPartner(id);
+    QPointer<ClipDurationDialog> dialog = new ClipDurationDialog(id, \
pCore->currentDoc()->timecode(), start, minFrame, in, in + duration, maxLength, \
maxFrame, qApp->activeWindow()); +    if (dialog->exec() == QDialog::Accepted) {
+        std::function<bool(void)> undo = []() { return true; };
+        std::function<bool(void)> redo = []() { return true; };
+        int newPos = dialog->startPos().frames(pCore->getCurrentFps());
+        int newIn = dialog->cropStart().frames(pCore->getCurrentFps());
+        int newDuration = dialog->duration().frames(pCore->getCurrentFps());
+        bool result = true;
+        if (newPos < start) {
+            if (m_model->isClip(id)) {
+                result = m_model->requestClipMove(id, trackId, newPos, true, true, \
undo, redo); +                if (result && partner > -1) {
+                    result = m_model->requestClipMove(partner, \
m_model->getItemTrackId(partner), newPos, true, true, undo, redo); +                }
+            } else {
+                result = m_model->requestCompositionMove(id, trackId, newPos, \
m_model->m_allCompositions[id]->getForcedTrack(), true, undo, redo); +            }
+            if (result && newIn != in) {
+                m_model->requestItemResize(id, duration + (in - newIn), false, true, \
undo, redo); +                if (result && partner > -1) {
+                    result = m_model->requestItemResize(partner, duration + (in - \
newIn), false, true, undo, redo); +                }
+            }
+            if (newDuration != duration + (in - newIn)) {
+                result = result && m_model->requestItemResize(id, newDuration, true, \
true, undo, redo); +                if (result && partner > -1) {
+                    result = m_model->requestItemResize(partner, newDuration, false, \
true, undo, redo); +                }
+            }
+        } else {
+            // perform resize first
+            if (newIn != in) {
+                result = m_model->requestItemResize(id, duration + (in - newIn), \
false, true, undo, redo); +                if (result && partner > -1) {
+                    result = m_model->requestItemResize(partner, duration + (in - \
newIn), false, true, undo, redo); +                }
+            }
+            if (newDuration != duration + (in - newIn)) {
+                result = result && m_model->requestItemResize(id, newDuration, \
false, true, undo, redo); +                if (result && partner > -1) {
+                    result = m_model->requestItemResize(partner, newDuration, false, \
true, undo, redo); +                }
+            }
+            if (start != newPos || newIn != in) {
+                if (m_model->isClip(id)) {
+                    result = result && m_model->requestClipMove(id, trackId, newPos, \
true, true, undo, redo); +                    if (result && partner > -1) {
+                        result = m_model->requestClipMove(partner, \
m_model->getItemTrackId(partner), newPos, true, true, undo, redo); +                  \
} +                } else {
+                    result = result && m_model->requestCompositionMove(id, trackId, \
newPos, m_model->m_allCompositions[id]->getForcedTrack(), true, undo, redo); +        \
} +            }
+        }
+        if (result) {
+            pCore->pushUndo(undo, redo, i18n("Edit item"));
+        } else {
+            undo();
+        }
+    }
+}
+
diff --git a/src/timeline2/view/timelinecontroller.h \
b/src/timeline2/view/timelinecontroller.h index 70b82b9b4..554c62dee 100644
--- a/src/timeline2/view/timelinecontroller.h
+++ b/src/timeline2/view/timelinecontroller.h
@@ -66,20 +66,23 @@ class TimelineController : public QObject
 public:
     TimelineController(QObject *parent);
     virtual ~TimelineController();
-    /* @brief Sets the model that this widgets displays */
+    /** @brief Sets the model that this widgets displays */
     void setModel(std::shared_ptr<TimelineItemModel> model);
     std::shared_ptr<TimelineItemModel> getModel() const;
     void setRoot(QQuickItem *root);
 
     Q_INVOKABLE bool isMultitrackSelected() const { return \
                m_selection.isMultitrackSelected; }
     Q_INVOKABLE int selectedTrack() const { return m_selection.selectedTrack; }
-    /* @brief Add a clip id to current selection
+    /** @brief Add a clip id to current selection
      */
     Q_INVOKABLE void addSelection(int newSelection);
-    /* @brief Clear current selection and inform the view
+    /** @brief Edit an item's in/out points with a dialog
+     */
+    Q_INVOKABLE void editItemDuration(int itemId);
+    /** @brief Clear current selection and inform the view
      */
     void clearSelection();
-    /* @brief Select all timeline items
+    /** @brief Select all timeline items
      */
     void selectAll();
     /* @brief Select all items in one track


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic