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