CuteLogger
Fast and simple logging solution for Qt based applications
multitrackmodel.h
1/*
2 * Copyright (c) 2013-2026 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 MULTITRACKMODEL_H
19#define MULTITRACKMODEL_H
20
21#include <MltPlaylist.h>
22#include <MltTractor.h>
23#include <QAbstractItemModel>
24#include <QByteArray>
25#include <QList>
26#include <QString>
27
28#include <memory>
29
30class SharedFrame;
31
32typedef enum {
33 PlaylistTrackType = 0,
34 BlackTrackType,
35 SilentTrackType,
36 AudioTrackType,
37 VideoTrackType
38} TrackType;
39
40typedef struct
41{
42 TrackType type;
43 int number;
44 int mlt_index;
45 double audioLevel = -100.0;
46} Track;
47
48typedef QList<Track> TrackList;
49
50class MultitrackModel : public QAbstractItemModel
51{
52 Q_OBJECT
53 Q_PROPERTY(int trackHeight READ trackHeight WRITE setTrackHeight NOTIFY trackHeightChanged)
54 Q_PROPERTY(int trackHeaderWidth READ trackHeaderWidth WRITE setTrackHeaderWidth NOTIFY
55 trackHeaderWidthChanged FINAL)
56 Q_PROPERTY(double scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
57 Q_PROPERTY(bool filtered READ isFiltered NOTIFY filteredChanged)
58 Q_PROPERTY(bool trackLevelIndicatorSupported READ trackLevelIndicatorSupported CONSTANT)
59 Q_PROPERTY(bool hasAudioTracks READ hasAudioTracks NOTIFY hasAudioTracksChanged)
60
61public:
63 enum {
64 NameRole = Qt::UserRole + 1,
65 CommentRole,
66 ResourceRole,
67 ServiceRole,
68 IsBlankRole,
69 StartRole,
70 DurationRole,
71 InPointRole,
72 OutPointRole,
73 FramerateRole,
74 IsMuteRole,
75 IsHiddenRole,
76 IsAudioRole,
77 AudioLevelRole,
78 AudioLevelsRole,
79 IsCompositeRole,
80 IsLockedRole,
81 FadeInRole,
82 FadeOutRole,
83 IsTransitionRole,
84 FileHashRole,
85 SpeedRole,
86 IsFilteredRole,
87 IsTopVideoRole,
88 IsBottomVideoRole,
89 IsTopAudioRole,
90 IsBottomAudioRole,
91 AudioIndexRole,
92 GroupRole,
93 GainRole,
94 GainEnabledRole,
95 };
96
97 explicit MultitrackModel(QObject *parent = 0);
98 ~MultitrackModel();
99
100 Mlt::Tractor *tractor() const { return m_tractor; }
101 const TrackList &trackList() const { return m_trackList; }
102
103 int rowCount(const QModelIndex &parent = QModelIndex()) const;
104 int columnCount(const QModelIndex &parent) const;
105 QVariant data(const QModelIndex &index, int role) const;
106 QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
107 QModelIndex makeIndex(int trackIndex, int clipIndex) const;
108 QModelIndex parent(const QModelIndex &index) const;
109 QHash<int, QByteArray> roleNames() const;
110 Q_INVOKABLE void audioLevelsReady(const QPersistentModelIndex &index);
111 const QByteArray *getAudioLevels(int trackIndex, int clipIndex) const;
112 void updateTrackAudioLevels(const SharedFrame &frame);
113 void updateTrackGains(int position);
114 void clearTrackAudioLevels();
115 bool createIfNeeded();
116 void addBackgroundTrack();
117 int addAudioTrack();
118 int addVideoTrack();
119 void removeTrack(int trackIndex);
120 void load();
121 void close();
122 int clipIndex(int trackIndex, int position);
123 void setClipGroup(int trackIndex, int position, int group);
124 void relinkTransitions(int trackIndex, int clipIndex);
125 bool trimClipInValid(int trackIndex, int clipIndex, int delta, bool ripple);
126 bool trimClipOutValid(int trackIndex, int clipIndex, int delta, bool ripple);
127 bool transitionOverlapValid(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
128 int trackHeight() const;
129 void setTrackHeight(int height);
130 int trackHeaderWidth() const;
131 void setTrackHeaderWidth(int width);
132 double scaleFactor() const;
133 void setScaleFactor(double scale);
134 bool isTransition(Mlt::Playlist &playlist, int clipIndex) const;
135 void insertTrack(int trackIndex, TrackType type = VideoTrackType);
136 void moveTrack(int fromTrackIndex, int toTrackIndex);
137 void insertOrAdjustBlankAt(QList<int> tracks, int position, int length);
138 bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
139 std::unique_ptr<Mlt::ClipInfo> findClipByUuid(const QUuid &uuid,
140 int &trackIndex,
141 int &clipIndex);
142 std::unique_ptr<Mlt::ClipInfo> getClipInfo(int trackIndex, int clipIndex);
143 Q_INVOKABLE int clipStart(int trackIndex, int clipIndex);
144 QString getTrackName(int trackIndex);
145 int bottomVideoTrackIndex() const;
146 int mltIndexForTrack(int trackIndex) const;
147 bool checkForEmptyTracks(int trackIndex);
148 QString trackTransitionService();
149 bool trackLevelIndicatorSupported() const;
150 bool hasAudioTracks() const;
151 void beginBulkUpdate();
152 void endBulkUpdate(bool changed = true);
153 bool isBulkUpdating() const { return m_bulkUpdateDepth > 0; }
154
155signals:
156 void created();
157 void aboutToClose();
158 void closed();
159 void modified();
160 void seeked(int position, bool seekPlayer = true);
161 void trackHeightChanged();
162 void trackHeaderWidthChanged();
163 void scaleFactorChanged();
164 void showStatusMessage(QString);
165 void durationChanged();
166 void filteredChanged();
167 void hasAudioTracksChanged();
168 void reloadRequested();
169 void appended(int trackIndex, int clipIndex);
170 void inserted(int trackIndex, int clipIndex);
171 void overWritten(int trackIndex, int clipIndex);
172 void removing(Mlt::Service *service);
173 void noMoreEmptyTracks(bool isAudio);
174 void bulkUpdateFinished();
175
176public slots:
177 void refreshTrackList();
178 void setTrackName(int row, const QString &value);
179 void setTrackMute(int row, bool mute);
180 void setTrackHidden(int row, bool hidden);
181 void setTrackComposite(int row, bool composite);
182 void setTrackLock(int row, bool lock);
183 void setTrackGain(int row, double gain);
184 int trimClipIn(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
185 void notifyClipIn(int trackIndex, int clipIndex);
186 int trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
187 void notifyClipOut(int trackIndex, int clipIndex);
188 bool moveClip(
189 int fromTrack, int toTrack, int clipIndex, int position, bool ripple, bool rippleAllTracks);
190 int overwriteClip(int trackIndex, Mlt::Producer &clip, int position, bool seek = true);
191 QString overwrite(
192 int trackIndex, Mlt::Producer &clip, int position, bool seek = true, bool notify = true);
193 int insertClip(int trackIndex,
194 Mlt::Producer &clip,
195 int position,
196 bool rippleAllTracks,
197 bool seek = true,
198 bool notify = true);
199 int appendClip(int trackIndex, Mlt::Producer &clip, bool seek = true, bool notify = true);
200 void removeClip(int trackIndex, int clipIndex, bool rippleAllTracks);
201 void liftClip(int trackIndex, int clipIndex, bool consolidate = true);
202 void consolidateBlanks(int trackIndex);
203 void splitClip(int trackIndex, int clipIndex, int position);
204 void joinClips(int trackIndex, int clipIndex);
205 void changeGain(int trackIndex, int clipIndex, double gain);
206 void fadeIn(int trackIndex, int clipIndex, int duration);
207 void fadeOut(int trackIndex, int clipIndex, int duration);
208 bool addTransitionValid(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
209 int addTransition(int trackIndex, int clipIndex, int position, bool ripple, bool rippleAllTracks);
210 void removeTransition(int trackIndex, int clipIndex);
211 void removeTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
212 void removeTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
213 bool trimTransitionInValid(int trackIndex, int clipIndex, int delta);
214 void trimTransitionIn(int trackIndex, int clipIndex, int delta, bool slip = false);
215 bool trimTransitionOutValid(int trackIndex, int clipIndex, int delta);
216 void trimTransitionOut(int trackIndex, int clipIndex, int delta, bool slip = false);
217 bool resizeTransitionValid(int trackIndex, int transitionIndex, int delta);
218 bool addTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
219 int addTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
220 bool addTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
221 void addTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
222 bool removeTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
223 bool removeTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
224 void filterAddedOrRemoved(Mlt::Producer *producer);
225 void onFilterChanged(Mlt::Service *service);
226 void reload(bool asynchronous = false);
227 void replace(int trackIndex, int clipIndex, Mlt::Producer &clip, bool copyFilters = true);
228
229private:
230 Mlt::Tractor *m_tractor;
231 TrackList m_trackList;
232 bool m_isMakingTransition;
233 bool m_trackLevelIndicatorSupported;
234 bool m_hasAudioTracks;
235 int m_trackGainPosition;
236 int m_bulkUpdateDepth = 0;
237 bool m_bulkAdjustBackgroundPending = false;
238 bool m_bulkAdjustTrackFiltersPending = false;
239 bool m_bulkRefreshBlocked = false;
240 bool m_bulkUpdateChanged = false;
241
242 void moveClipToEnd(Mlt::Playlist &playlist,
243 int trackIndex,
244 int clipIndex,
245 int position,
246 bool ripple,
247 bool rippleAllTracks);
248 void moveClipInBlank(Mlt::Playlist &playlist,
249 int trackIndex,
250 int clipIndex,
251 int position,
252 bool ripple,
253 bool rippleAllTracks,
254 int duration = 0);
255 void consolidateBlanks(Mlt::Playlist &playlist, int trackIndex);
256 void consolidateBlanksAllTracks();
257 void getAudioLevels();
258 void addBlackTrackIfNeeded();
259 void convertOldDoc();
260 void reorderMixTransitions();
261 Mlt::Transition *getTransition(const QString &name, int trackIndex) const;
262 Mlt::Filter *getFilter(const QString &name, int trackIndex) const;
263 Mlt::Filter *getFilter(const QString &name, Mlt::Service *service) const;
264 void removeBlankPlaceholder(Mlt::Playlist &playlist, int trackIndex);
265 void retainPlaylist();
266 void loadPlaylist();
267 void removeRegion(int trackIndex, int position, int length);
268 void clearMixReferences(int trackIndex, int clipIndex);
269 bool isFiltered(Mlt::Producer *producer = 0) const;
270 int getDuration();
271 void adjustServiceFilterDurations(Mlt::Service &service, int duration);
272 bool warnIfInvalid(Mlt::Service &service);
273 Mlt::Transition *getVideoBlendTransition(int trackIndex) const;
274 void refreshVideoBlendTransitions();
275 int bottomVideoTrackMltIndex() const;
276 bool hasEmptyTrack(TrackType trackType) const;
277 Mlt::Filter *ensureTrackAudioLevelFilter(Mlt::Producer *track, int mltTrackIndex) const;
278 void syncTrackAudioLevelFilterPrefixes();
279 void setTrackAudioLevel(int row, double audioLevel);
280 Mlt::Filter *ensureTrackVolumeFilter(Mlt::Producer *track);
281
282 friend class UndoHelper;
283
284private slots:
285 void adjustBackgroundDuration();
286 void adjustTrackFilters();
287};
288
289#endif // MULTITRACKMODEL_H
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition sharedframe.h:49