CuteLogger
Fast and simple logging solution for Qt based applications
timelinedock.h
1/*
2 * Copyright (c) 2013-2024 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 Q_PROPERTY(int loopStart READ loopStart NOTIFY loopChanged)
47 Q_PROPERTY(int loopEnd READ loopEnd NOTIFY loopChanged)
48
49public:
50 explicit TimelineDock(QWidget *parent = 0);
51 ~TimelineDock();
52
53 enum TrimLocation {
54 TrimInPoint,
55 TrimOutPoint
56 };
57
58 MultitrackModel *model()
59 {
60 return &m_model;
61 }
62 MarkersModel *markersModel()
63 {
64 return & m_markersModel;
65 }
66 int position() const
67 {
68 return m_position;
69 }
70 void setPosition(int position);
71 Mlt::Producer producerForClip(int trackIndex, int clipIndex);
72 int clipIndexAtPlayhead(int trackIndex = -1);
73 int clipIndexAtPosition(int trackIndex, int position);
74 void chooseClipAtPosition(int position, int &trackIndex, int &clipIndex);
75 void setCurrentTrack(int currentTrack);
76 int currentTrack() const;
77 int clipCount(int trackIndex) const;
78 void setSelectionFromJS(const QVariantList &list);
79 void setSelection(QList<QPoint> selection = QList<QPoint>(), int trackIndex = -1,
80 bool isMultitrack = false);
81 QVariantList selectionForJS() const;
82 const QList<QPoint> selection() const;
83 const QVector<QUuid> selectionUuids();
84 const QList<QPoint> uuidsToSelection(QVector<QUuid> uuids) const;
85 void saveAndClearSelection();
86 Q_INVOKABLE void restoreSelection();
87 Q_INVOKABLE QVariantList getGroupForClip(int trackIndex, int clipIndex);
88 void selectClipUnderPlayhead();
89 int centerOfClip(int trackIndex, int clipIndex);
90 bool isTrackLocked(int trackIndex) const;
91 void trimClipAtPlayhead(TrimLocation location, bool ripple);
92 Q_INVOKABLE bool isMultitrackSelected() const
93 {
94 return m_selection.isMultitrackSelected;
95 }
96 Q_INVOKABLE int selectedTrack() const
97 {
98 return m_selection.selectedTrack;
99 }
100 Q_INVOKABLE bool isFloating() const
101 {
102 return QDockWidget::isFloating();
103 }
104 Q_INVOKABLE static void openProperties();
105 void emitSelectedChanged(const QVector<int> &roles);
106 void replaceClipsWithHash(const QString &hash, Mlt::Producer &producer);
107 Q_INVOKABLE void recordAudio();
108 Q_INVOKABLE void stopRecording();
109 bool isRecording() const
110 {
111 return m_isRecording;
112 }
113 int addTrackIfNeeded(TrackType trackType);
114 void getSelectionRange(int *start, int *end);
115 int loopStart() const
116 {
117 return m_loopStart;
118 }
119 int loopEnd() const
120 {
121 return m_loopEnd;
122 }
123
124signals:
125 void currentTrackChanged();
126 void selectionChanged();
127 void seeked(int position);
128 void positionChanged();
129 void loopChanged();
130 void clipOpened(Mlt::Producer *producer);
131 void dragging(const QPointF &pos, int duration);
132 void dropped();
133 void dropAccepted(const QString &xml);
134 void fadeInChanged(int duration);
135 void fadeOutChanged(int duration);
136 void selected(Mlt::Producer *producer);
137 void clipClicked();
138 void showStatusMessage(QString);
139 void clipCopied();
140 void clipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
141 void filteredClicked();
142 void durationChanged();
143 void transitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
144 void zoomIn();
145 void zoomOut();
146 void zoomToFit();
147 void setZoom(double value);
148 void markerRangesChanged();
149 void markerSeeked(int markerIndex);
150 void isRecordingChanged(bool);
151 void multitrackSelected();
152 void warnTrackLocked(int trackIndex);
153 void refreshWaveforms();
154 void updateThumbnails(int trackIndex, int clipIndex);
155
156public slots:
157 int addAudioTrack();
158 int addVideoTrack();
159 void alignSelectedClips();
160 void onShowFrame(const SharedFrame &frame);
161 void onSeeked(int position);
162 void append(int trackIndex);
163 void remove(int trackIndex, int clipIndex);
164 bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
165 void lift(int trackIndex, int clipIndex);
166 void removeSelection(bool withCopy = false);
167 void liftSelection();
168 void incrementCurrentTrack(int by);
169 void selectTrackHead(int trackIndex);
170 void selectMultitrack();
171 void copy(int trackIndex, int clipIndex);
172 void setTrackName(int trackIndex, const QString &value);
173 void toggleTrackMute(int trackIndex);
174 void toggleTrackHidden(int trackIndex);
175 void setTrackComposite(int trackIndex, bool composite);
176 void setTrackLock(int trackIndex, bool lock);
177 bool moveClip(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
178 void onClipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
179 bool trimClipIn(int trackIndex, int clipIndex, int oldClipIndex, int delta, bool ripple);
180 bool trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple);
181 void insert(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
182 void overwrite(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
183 void appendFromPlaylist(Mlt::Playlist *playlist, bool skipProxy);
184 void fadeIn(int trackIndex, int clipIndex = -1, int duration = -1);
185 void fadeOut(int trackIndex, int clipIndex = -1, int duration = -1);
186 void seekPreviousEdit();
187 void seekNextEdit();
188 void seekInPoint(int clipIndex);
189 void clearSelectionIfInvalid();
190 void insertTrack();
191 void insertAudioTrack();
192 void insertVideoTrack();
193 void removeTrack();
194 void moveTrack(int fromTrackIndex, int toTrackIndex);
195 void moveTrackUp();
196 void moveTrackDown();
197 void onProducerChanged(Mlt::Producer *);
198 void emitSelectedFromSelection();
199 void remakeAudioLevels(int trackIndex, int clipIndex, bool force = true);
200 void commitTrimCommand();
201 void onRowsInserted(const QModelIndex &parent, int first, int last);
202 void onRowsRemoved(const QModelIndex &parent, int first, int last);
203 void onRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination,
204 int row);
205 void detachAudio(int trackIndex, int clipIndex);
206 void selectAll();
207 void selectAllOnCurrentTrack();
208 void onProducerModified();
209 void replace(int trackIndex, int clipIndex, const QString &xml = QString());
210 void createOrEditMarker();
211 void createOrEditSelectionMarker();
212 void createMarker();
213 void editMarker(int markerIndex);
214 void deleteMarker(int markerIndex = -1);
215 void seekNextMarker();
216 void seekPrevMarker();
217 void onFilterModelChanged();
218 void trimClipIn(bool ripple = false);
219 void trimClipOut(bool ripple = false);
220 void initLoad();
221 void handleDrop(int trackIndex, int position, QString xml);
222 void onLoopChanged(int start, int end);
223
224protected:
225 void dragEnterEvent(QDragEnterEvent *event);
226 void dragMoveEvent(QDragMoveEvent *event);
227 void dragLeaveEvent(QDragLeaveEvent *event);
228 void dropEvent(QDropEvent *event);
229 bool event(QEvent *event);
230 void keyPressEvent(QKeyEvent *event);
231 void keyReleaseEvent(QKeyEvent *event);
232
233private:
234 bool isBlank(int trackIndex, int clipIndex);
235 bool clipsAreSelected();
236 bool blankIsSelected();
237 bool nothingIsSelected();
238 bool isTransition(int trackIndex, int clipIndex);
239 void emitNonSeekableWarning();
240 void addTrackIfNeeded(int mltTrackIndex, Mlt::Producer *srcTrack);
241 void setupActions();
242 bool isMultitrackValid()
243 {
244 return m_model.tractor() && !m_model.trackList().empty();
245 }
246 void reportSelectionChange();
247 void applyCopiedFiltersToSelectdClips();
248
249 QQuickWidget m_quickView;
250 MultitrackModel m_model;
251 MarkersModel m_markersModel;
252 int m_position;
253 std::unique_ptr<Timeline::UpdateCommand> m_updateCommand;
254 bool m_ignoreNextPositionChange;
255 struct Selection {
256 QList<QPoint> selectedClips; // x is the clip index, y is the track index
257 int selectedTrack;
258 bool isMultitrackSelected;
259 };
260 Selection m_selection;
261 int m_savedSelectedTrack;
262 bool m_savedIsMultitrackSelected;
263 QVector<QUuid> m_savedSelectionUuids;
264 QTimer m_selectionSignalTimer;
265 std::unique_ptr<Timeline::TrimCommand> m_trimCommand;
266 std::unique_ptr<UndoHelper> m_undoHelper;
267 int m_trimDelta;
268 int m_transitionDelta;
269 bool m_isRecording {false};
270 std::unique_ptr<AbstractJob> m_recordJob;
271 QTimer m_recordingTimer;
272 QDateTime m_recordingTime;
273 int m_recordingTrackIndex;
274 int m_recordingClipIndex;
275 int m_currentTrack {0};
276 QMenu *m_mainMenu;
277 QMenu *m_clipMenu;
278 int m_loopStart;
279 int m_loopEnd;
280
281private slots:
282 void load(bool force);
283 void onTopLevelChanged(bool floating);
284 void onTransitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
285 void selectClip(int trackIndex, int clipIndex);
286 void onMultitrackClosed();
287 void reloadTimelineMarkers();
288 void onRecordStarted();
289 void updateRecording();
290 void onRecordFinished(AbstractJob *, bool);
291 void onWarnTrackLocked();
292 void onTimelineRightClicked();
293 void onClipRightClicked();
294 void onNoMoreEmptyTracks(bool isAudio);
295};
296
297#endif // TIMELINEDOCK_H
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition sharedframe.h:49