CuteLogger
Fast and simple logging solution for Qt based applications
timelinedock.h
1/*
2 * Copyright (c) 2013-2022 Meltytech, LLC
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TIMELINEDOCK_H
19#define TIMELINEDOCK_H
20
21#include <QDockWidget>
22#include <QQuickWidget>
23#include <QApplication>
24#include <QTimer>
25#include <QDateTime>
26#include "models/markersmodel.h"
27#include "models/multitrackmodel.h"
28#include "sharedframe.h"
29#include "jobs/ffmpegjob.h"
30
31namespace Timeline {
32class UpdateCommand;
33class TrimCommand;
34}
35class UndoHelper;
36class QMenu;
37
38class TimelineDock : public QDockWidget
39{
40 Q_OBJECT
41 Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged)
42 Q_PROPERTY(int currentTrack READ currentTrack WRITE setCurrentTrack NOTIFY currentTrackChanged)
43 Q_PROPERTY(QVariantList selection READ selectionForJS WRITE setSelectionFromJS NOTIFY
44 selectionChanged)
45 Q_PROPERTY(bool isRecording READ isRecording NOTIFY isRecordingChanged)
46
47public:
48 explicit TimelineDock(QWidget *parent = 0);
49 ~TimelineDock();
50
51 enum TrimLocation {
52 TrimInPoint,
53 TrimOutPoint
54 };
55
56 MultitrackModel *model()
57 {
58 return &m_model;
59 }
60 MarkersModel *markersModel()
61 {
62 return & m_markersModel;
63 }
64 int position() const
65 {
66 return m_position;
67 }
68 void setPosition(int position);
69 Mlt::Producer producerForClip(int trackIndex, int clipIndex);
70 int clipIndexAtPlayhead(int trackIndex = -1);
71 int clipIndexAtPosition(int trackIndex, int position);
72 void chooseClipAtPosition(int position, int &trackIndex, int &clipIndex);
73 void setCurrentTrack(int currentTrack);
74 int currentTrack() const;
75 int clipCount(int trackIndex) const;
76 void setSelectionFromJS(const QVariantList &list);
77 void setSelection(QList<QPoint> selection = QList<QPoint>(), int trackIndex = -1,
78 bool isMultitrack = false);
79 QVariantList selectionForJS() const;
80 const QList<QPoint> selection() const;
81 const QVector<QUuid> selectionUuids();
82 void saveAndClearSelection();
83 Q_INVOKABLE void restoreSelection();
84 void selectClipUnderPlayhead();
85 int centerOfClip(int trackIndex, int clipIndex);
86 bool isTrackLocked(int trackIndex) const;
87 void trimClipAtPlayhead(TrimLocation location, bool ripple);
88 Q_INVOKABLE bool isMultitrackSelected() const
89 {
90 return m_selection.isMultitrackSelected;
91 }
92 Q_INVOKABLE int selectedTrack() const
93 {
94 return m_selection.selectedTrack;
95 }
96 Q_INVOKABLE bool isFloating() const
97 {
98 return QDockWidget::isFloating();
99 }
100 Q_INVOKABLE static void openProperties();
101 void emitSelectedChanged(const QVector<int> &roles);
102 void replaceClipsWithHash(const QString &hash, Mlt::Producer &producer);
103 Q_INVOKABLE void recordAudio();
104 Q_INVOKABLE void stopRecording();
105 bool isRecording() const
106 {
107 return m_isRecording;
108 }
109
110signals:
111 void currentTrackChanged();
112 void selectionChanged();
113 void seeked(int position);
114 void positionChanged();
115 void clipOpened(Mlt::Producer *producer);
116 void dragging(const QPointF &pos, int duration);
117 void dropped();
118 void dropAccepted(const QString &xml);
119 void fadeInChanged(int duration);
120 void fadeOutChanged(int duration);
121 void selected(Mlt::Producer *producer);
122 void clipClicked();
123 void showStatusMessage(QString);
124 void clipCopied();
125 void clipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
126 void filteredClicked();
127 void durationChanged();
128 void transitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
129 void zoomIn();
130 void zoomOut();
131 void zoomToFit();
132 void setZoom(double value);
133 void markerRangesChanged();
134 void markerSeeked(int markerIndex);
135 void isRecordingChanged(bool);
136 void multitrackSelected();
137 void warnTrackLocked(int trackIndex);
138 void refreshWaveforms();
139 void updateThumbnails(int trackIndex, int clipIndex);
140
141public slots:
142 void addAudioTrack();
143 void addVideoTrack();
144 void alignSelectedClips();
145 void onShowFrame(const SharedFrame &frame);
146 void onSeeked(int position);
147 void append(int trackIndex);
148 void remove(int trackIndex, int clipIndex);
149 bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
150 void lift(int trackIndex, int clipIndex);
151 void removeSelection(bool withCopy = false);
152 void liftSelection();
153 void incrementCurrentTrack(int by);
154 void selectTrackHead(int trackIndex);
155 void selectMultitrack();
156 void copy(int trackIndex, int clipIndex);
157 void setTrackName(int trackIndex, const QString &value);
158 void toggleTrackMute(int trackIndex);
159 void toggleTrackHidden(int trackIndex);
160 void setTrackComposite(int trackIndex, bool composite);
161 void setTrackLock(int trackIndex, bool lock);
162 bool moveClip(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
163 void onClipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
164 bool trimClipIn(int trackIndex, int clipIndex, int oldClipIndex, int delta, bool ripple);
165 bool trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple);
166 void insert(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
167 void overwrite(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
168 void appendFromPlaylist(Mlt::Playlist *playlist, bool skipProxy);
169 void splitClip(int trackIndex = -1, int clipIndex = -1);
170 void fadeIn(int trackIndex, int clipIndex = -1, int duration = -1);
171 void fadeOut(int trackIndex, int clipIndex = -1, int duration = -1);
172 void seekPreviousEdit();
173 void seekNextEdit();
174 void seekInPoint(int clipIndex);
175 void clearSelectionIfInvalid();
176 void insertTrack();
177 void insertAudioTrack();
178 void insertVideoTrack();
179 void removeTrack();
180 void moveTrack(int fromTrackIndex, int toTrackIndex);
181 void moveTrackUp();
182 void moveTrackDown();
183 void onProducerChanged(Mlt::Producer *);
184 void emitSelectedFromSelection();
185 void remakeAudioLevels(int trackIndex, int clipIndex, bool force = true);
186 void commitTrimCommand();
187 void onRowsInserted(const QModelIndex &parent, int first, int last);
188 void onRowsRemoved(const QModelIndex &parent, int first, int last);
189 void onRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination,
190 int row);
191 void detachAudio(int trackIndex, int clipIndex);
192 void selectAll();
193 void selectAllOnCurrentTrack();
194 bool blockSelection(bool block);
195 void onProducerModified();
196 void replace(int trackIndex, int clipIndex, const QString &xml = QString());
197 void createOrEditMarker();
198 void createOrEditSelectionMarker();
199 void createMarker();
200 void editMarker(int markerIndex);
201 void deleteMarker(int markerIndex = -1);
202 void seekNextMarker();
203 void seekPrevMarker();
204 void onFilterModelChanged();
205 void trimClipIn(bool ripple = false);
206 void trimClipOut(bool ripple = false);
207
208protected:
209 void dragEnterEvent(QDragEnterEvent *event);
210 void dragMoveEvent(QDragMoveEvent *event);
211 void dragLeaveEvent(QDragLeaveEvent *event);
212 void dropEvent(QDropEvent *event);
213 bool event(QEvent *event);
214 void keyPressEvent(QKeyEvent *event);
215 void keyReleaseEvent(QKeyEvent *event);
216
217private:
218 bool isBlank(int trackIndex, int clipIndex);
219 bool clipsAreSelected();
220 bool blankIsSelected();
221 bool isTransition(int trackIndex, int clipIndex);
222 void emitNonSeekableWarning();
223 void addTrackIfNeeded(int mltTrackIndex, Mlt::Producer *srcTrack);
224 void setupActions();
225 bool isMultitrackValid()
226 {
227 return m_model.tractor() && !m_model.trackList().empty();
228 }
229
230 QQuickWidget m_quickView;
231 MultitrackModel m_model;
232 MarkersModel m_markersModel;
233 int m_position;
234 QScopedPointer<Timeline::UpdateCommand> m_updateCommand;
235 bool m_ignoreNextPositionChange;
236 struct Selection {
237 QList<QPoint> selectedClips; // x is the clip index, y is the track index
238 int selectedTrack;
239 bool isMultitrackSelected;
240 };
241 Selection m_selection;
242 int m_savedSelectedTrack;
243 bool m_savedIsMultitrackSelected;
244 QVector<QUuid> m_savedSelectionUuids;
245 QScopedPointer<Timeline::TrimCommand> m_trimCommand;
246 QScopedPointer<UndoHelper> m_undoHelper;
247 int m_trimDelta;
248 int m_transitionDelta;
249 bool m_blockSetSelection;
250 bool m_isRecording {false};
251 QScopedPointer<AbstractJob> m_recordJob;
252 QTimer m_recordingTimer;
253 QDateTime m_recordingTime;
254 int m_recordingTrackIndex;
255 int m_recordingClipIndex;
256 int m_currentTrack {0};
257 QMenu *m_mainMenu;
258 QMenu *m_clipMenu;
259
260private slots:
261 void load(bool force = false);
262 void onTopLevelChanged(bool floating);
263 void onTransitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
264 void selectClip(int trackIndex, int clipIndex);
265 void onMultitrackClosed();
266 void reloadTimelineMarkers();
267 void onRecordStarted();
268 void updateRecording();
269 void onRecordFinished(AbstractJob *, bool);
270 void onWarnTrackLocked();
271 void onTimelineRightClicked();
272 void onClipRightClicked();
273};
274
275class TimelineSelectionBlocker
276{
277public:
278 TimelineSelectionBlocker(TimelineDock &timeline)
279 : m_timelineDock(timeline)
280 {
281 m_timelineDock.blockSelection(true);
282 }
283 ~TimelineSelectionBlocker()
284 {
285 QCoreApplication::processEvents();
286 m_timelineDock.blockSelection(false);
287 }
288
289private:
290 TimelineDock &m_timelineDock;
291};
292
293#endif // TIMELINEDOCK_H
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition: sharedframe.h:49