CuteLogger
Fast and simple logging solution for Qt based applications
timelinedock.h
1/*
2 * Copyright (c) 2013-2023 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 int addTrackIfNeeded(TrackType trackType);
110
111signals:
112 void currentTrackChanged();
113 void selectionChanged();
114 void seeked(int position);
115 void positionChanged();
116 void clipOpened(Mlt::Producer *producer);
117 void dragging(const QPointF &pos, int duration);
118 void dropped();
119 void dropAccepted(const QString &xml);
120 void fadeInChanged(int duration);
121 void fadeOutChanged(int duration);
122 void selected(Mlt::Producer *producer);
123 void clipClicked();
124 void showStatusMessage(QString);
125 void clipCopied();
126 void clipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
127 void filteredClicked();
128 void durationChanged();
129 void transitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
130 void zoomIn();
131 void zoomOut();
132 void zoomToFit();
133 void setZoom(double value);
134 void markerRangesChanged();
135 void markerSeeked(int markerIndex);
136 void isRecordingChanged(bool);
137 void multitrackSelected();
138 void warnTrackLocked(int trackIndex);
139 void refreshWaveforms();
140 void updateThumbnails(int trackIndex, int clipIndex);
141
142public slots:
143 int addAudioTrack();
144 int addVideoTrack();
145 void alignSelectedClips();
146 void onShowFrame(const SharedFrame &frame);
147 void onSeeked(int position);
148 void append(int trackIndex);
149 void remove(int trackIndex, int clipIndex);
150 bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
151 void lift(int trackIndex, int clipIndex);
152 void removeSelection(bool withCopy = false);
153 void liftSelection();
154 void incrementCurrentTrack(int by);
155 void selectTrackHead(int trackIndex);
156 void selectMultitrack();
157 void copy(int trackIndex, int clipIndex);
158 void setTrackName(int trackIndex, const QString &value);
159 void toggleTrackMute(int trackIndex);
160 void toggleTrackHidden(int trackIndex);
161 void setTrackComposite(int trackIndex, bool composite);
162 void setTrackLock(int trackIndex, bool lock);
163 bool moveClip(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
164 void onClipMoved(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
165 bool trimClipIn(int trackIndex, int clipIndex, int oldClipIndex, int delta, bool ripple);
166 bool trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple);
167 void insert(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
168 void overwrite(int trackIndex, int position = -1, const QString &xml = QString(), bool seek = true);
169 void appendFromPlaylist(Mlt::Playlist *playlist, bool skipProxy);
170 void splitClip(int trackIndex = -1, int clipIndex = -1);
171 void fadeIn(int trackIndex, int clipIndex = -1, int duration = -1);
172 void fadeOut(int trackIndex, int clipIndex = -1, int duration = -1);
173 void seekPreviousEdit();
174 void seekNextEdit();
175 void seekInPoint(int clipIndex);
176 void clearSelectionIfInvalid();
177 void insertTrack();
178 void insertAudioTrack();
179 void insertVideoTrack();
180 void removeTrack();
181 void moveTrack(int fromTrackIndex, int toTrackIndex);
182 void moveTrackUp();
183 void moveTrackDown();
184 void onProducerChanged(Mlt::Producer *);
185 void emitSelectedFromSelection();
186 void remakeAudioLevels(int trackIndex, int clipIndex, bool force = true);
187 void commitTrimCommand();
188 void onRowsInserted(const QModelIndex &parent, int first, int last);
189 void onRowsRemoved(const QModelIndex &parent, int first, int last);
190 void onRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination,
191 int row);
192 void detachAudio(int trackIndex, int clipIndex);
193 void selectAll();
194 void selectAllOnCurrentTrack();
195 bool blockSelection(bool block);
196 void onProducerModified();
197 void replace(int trackIndex, int clipIndex, const QString &xml = QString());
198 void createOrEditMarker();
199 void createOrEditSelectionMarker();
200 void createMarker();
201 void editMarker(int markerIndex);
202 void deleteMarker(int markerIndex = -1);
203 void seekNextMarker();
204 void seekPrevMarker();
205 void onFilterModelChanged();
206 void trimClipIn(bool ripple = false);
207 void trimClipOut(bool ripple = false);
208 void initLoad();
209 void handleDrop(int trackIndex, int position, QString xml);
210
211protected:
212 void dragEnterEvent(QDragEnterEvent *event);
213 void dragMoveEvent(QDragMoveEvent *event);
214 void dragLeaveEvent(QDragLeaveEvent *event);
215 void dropEvent(QDropEvent *event);
216 bool event(QEvent *event);
217 void keyPressEvent(QKeyEvent *event);
218 void keyReleaseEvent(QKeyEvent *event);
219
220private:
221 bool isBlank(int trackIndex, int clipIndex);
222 bool clipsAreSelected();
223 bool blankIsSelected();
224 bool isTransition(int trackIndex, int clipIndex);
225 void emitNonSeekableWarning();
226 void addTrackIfNeeded(int mltTrackIndex, Mlt::Producer *srcTrack);
227 void setupActions();
228 bool isMultitrackValid()
229 {
230 return m_model.tractor() && !m_model.trackList().empty();
231 }
232
233 QQuickWidget m_quickView;
234 MultitrackModel m_model;
235 MarkersModel m_markersModel;
236 int m_position;
237 std::unique_ptr<Timeline::UpdateCommand> m_updateCommand;
238 bool m_ignoreNextPositionChange;
239 struct Selection {
240 QList<QPoint> selectedClips; // x is the clip index, y is the track index
241 int selectedTrack;
242 bool isMultitrackSelected;
243 };
244 Selection m_selection;
245 int m_savedSelectedTrack;
246 bool m_savedIsMultitrackSelected;
247 QVector<QUuid> m_savedSelectionUuids;
248 std::unique_ptr<Timeline::TrimCommand> m_trimCommand;
249 std::unique_ptr<UndoHelper> m_undoHelper;
250 int m_trimDelta;
251 int m_transitionDelta;
252 bool m_blockSetSelection;
253 bool m_isRecording {false};
254 std::unique_ptr<AbstractJob> m_recordJob;
255 QTimer m_recordingTimer;
256 QDateTime m_recordingTime;
257 int m_recordingTrackIndex;
258 int m_recordingClipIndex;
259 int m_currentTrack {0};
260 QMenu *m_mainMenu;
261 QMenu *m_clipMenu;
262
263private slots:
264 void load(bool force);
265 void onTopLevelChanged(bool floating);
266 void onTransitionAdded(int trackIndex, int clipIndex, int position, bool ripple);
267 void selectClip(int trackIndex, int clipIndex);
268 void onMultitrackClosed();
269 void reloadTimelineMarkers();
270 void onRecordStarted();
271 void updateRecording();
272 void onRecordFinished(AbstractJob *, bool);
273 void onWarnTrackLocked();
274 void onTimelineRightClicked();
275 void onClipRightClicked();
276};
277
278class TimelineSelectionBlocker
279{
280public:
281 TimelineSelectionBlocker(TimelineDock &timeline)
282 : m_timelineDock(timeline)
283 {
284 m_timelineDock.blockSelection(true);
285 }
286 ~TimelineSelectionBlocker()
287 {
288 QCoreApplication::processEvents();
289 m_timelineDock.blockSelection(false);
290 }
291
292private:
293 TimelineDock &m_timelineDock;
294};
295
296#endif // TIMELINEDOCK_H
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition: sharedframe.h:49