CuteLogger
Fast and simple logging solution for Qt based applications
multitrackmodel.h
1 /*
2  * Copyright (c) 2013-2025 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 
29 typedef enum {
30  PlaylistTrackType = 0,
31  BlackTrackType,
32  SilentTrackType,
33  AudioTrackType,
34  VideoTrackType
35 } TrackType;
36 
37 typedef struct
38 {
39  TrackType type;
40  int number;
41  int mlt_index;
42 } Track;
43 
44 typedef QList<Track> TrackList;
45 
46 class 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 
55 public:
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  };
87 
88  explicit MultitrackModel(QObject *parent = 0);
89  ~MultitrackModel();
90 
91  Mlt::Tractor *tractor() const { return m_tractor; }
92  const TrackList &trackList() const { return m_trackList; }
93 
94  int rowCount(const QModelIndex &parent = QModelIndex()) const;
95  int columnCount(const QModelIndex &parent) const;
96  QVariant data(const QModelIndex &index, int role) const;
97  QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
98  QModelIndex makeIndex(int trackIndex, int clipIndex) const;
99  QModelIndex parent(const QModelIndex &index) const;
100  QHash<int, QByteArray> roleNames() const;
101  Q_INVOKABLE void audioLevelsReady(const QPersistentModelIndex &index);
102  bool createIfNeeded();
103  void addBackgroundTrack();
104  int addAudioTrack();
105  int addVideoTrack();
106  void removeTrack(int trackIndex);
107  void load();
108  void close();
109  int clipIndex(int trackIndex, int position);
110  bool trimClipInValid(int trackIndex, int clipIndex, int delta, bool ripple);
111  bool trimClipOutValid(int trackIndex, int clipIndex, int delta, bool ripple);
112  int trackHeight() const;
113  void setTrackHeight(int height);
114  int trackHeaderWidth() const;
115  void setTrackHeaderWidth(int width);
116  double scaleFactor() const;
117  void setScaleFactor(double scale);
118  bool isTransition(Mlt::Playlist &playlist, int clipIndex) const;
119  void insertTrack(int trackIndex, TrackType type = VideoTrackType);
120  void moveTrack(int fromTrackIndex, int toTrackIndex);
121  void insertOrAdjustBlankAt(QList<int> tracks, int position, int length);
122  bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
123  std::unique_ptr<Mlt::ClipInfo> findClipByUuid(const QUuid &uuid,
124  int &trackIndex,
125  int &clipIndex);
126  std::unique_ptr<Mlt::ClipInfo> getClipInfo(int trackIndex, int clipIndex);
127  QString getTrackName(int trackIndex);
128  int bottomVideoTrackIndex() const;
129  int mltIndexForTrack(int trackIndex) const;
130  bool checkForEmptyTracks(int trackIndex);
131 
132 signals:
133  void created();
134  void aboutToClose();
135  void closed();
136  void modified();
137  void seeked(int position, bool seekPlayer = true);
138  void trackHeightChanged();
139  void trackHeaderWidthChanged();
140  void scaleFactorChanged();
141  void showStatusMessage(QString);
142  void durationChanged();
143  void filteredChanged();
144  void reloadRequested();
145  void appended(int trackIndex, int clipIndex);
146  void inserted(int trackIndex, int clipIndex);
147  void overWritten(int trackIndex, int clipIndex);
148  void removing(Mlt::Service *service);
149  void noMoreEmptyTracks(bool isAudio);
150 
151 public slots:
152  void refreshTrackList();
153  void setTrackName(int row, const QString &value);
154  void setTrackMute(int row, bool mute);
155  void setTrackHidden(int row, bool hidden);
156  void setTrackComposite(int row, bool composite);
157  void setTrackLock(int row, bool lock);
158  int trimClipIn(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
159  void notifyClipIn(int trackIndex, int clipIndex);
160  int trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
161  void notifyClipOut(int trackIndex, int clipIndex);
162  bool moveClip(
163  int fromTrack, int toTrack, int clipIndex, int position, bool ripple, bool rippleAllTracks);
164  int overwriteClip(int trackIndex, Mlt::Producer &clip, int position, bool seek = true);
165  QString overwrite(
166  int trackIndex, Mlt::Producer &clip, int position, bool seek = true, bool notify = true);
167  int insertClip(int trackIndex,
168  Mlt::Producer &clip,
169  int position,
170  bool rippleAllTracks,
171  bool seek = true,
172  bool notify = true);
173  int appendClip(int trackIndex, Mlt::Producer &clip, bool seek = true, bool notify = true);
174  void removeClip(int trackIndex, int clipIndex, bool rippleAllTracks);
175  void liftClip(int trackIndex, int clipIndex);
176  void splitClip(int trackIndex, int clipIndex, int position);
177  void joinClips(int trackIndex, int clipIndex);
178  void fadeIn(int trackIndex, int clipIndex, int duration);
179  void fadeOut(int trackIndex, int clipIndex, int duration);
180  bool addTransitionValid(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
181  int addTransition(int trackIndex, int clipIndex, int position, bool ripple, bool rippleAllTracks);
182  void removeTransition(int trackIndex, int clipIndex);
183  void removeTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
184  void removeTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
185  bool trimTransitionInValid(int trackIndex, int clipIndex, int delta);
186  void trimTransitionIn(int trackIndex, int clipIndex, int delta, bool slip = false);
187  bool trimTransitionOutValid(int trackIndex, int clipIndex, int delta);
188  void trimTransitionOut(int trackIndex, int clipIndex, int delta, bool slip = false);
189  bool addTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
190  int addTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
191  bool addTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
192  void addTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
193  bool removeTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
194  bool removeTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
195  void filterAddedOrRemoved(Mlt::Producer *producer);
196  void onFilterChanged(Mlt::Service *service);
197  void reload(bool asynchronous = false);
198  void replace(int trackIndex, int clipIndex, Mlt::Producer &clip, bool copyFilters = true);
199 
200 private:
201  Mlt::Tractor *m_tractor;
202  TrackList m_trackList;
203  bool m_isMakingTransition;
204 
205  void moveClipToEnd(Mlt::Playlist &playlist,
206  int trackIndex,
207  int clipIndex,
208  int position,
209  bool ripple,
210  bool rippleAllTracks);
211  void moveClipInBlank(Mlt::Playlist &playlist,
212  int trackIndex,
213  int clipIndex,
214  int position,
215  bool ripple,
216  bool rippleAllTracks,
217  int duration = 0);
218  void consolidateBlanks(Mlt::Playlist &playlist, int trackIndex);
219  void consolidateBlanksAllTracks();
220  void getAudioLevels();
221  void addBlackTrackIfNeeded();
222  void convertOldDoc();
223  Mlt::Transition *getTransition(const QString &name, int trackIndex) const;
224  Mlt::Filter *getFilter(const QString &name, int trackIndex) const;
225  Mlt::Filter *getFilter(const QString &name, Mlt::Service *service) const;
226  void removeBlankPlaceholder(Mlt::Playlist &playlist, int trackIndex);
227  void retainPlaylist();
228  void loadPlaylist();
229  void removeRegion(int trackIndex, int position, int length);
230  void clearMixReferences(int trackIndex, int clipIndex);
231  bool isFiltered(Mlt::Producer *producer = 0) const;
232  int getDuration();
233  void adjustServiceFilterDurations(Mlt::Service &service, int duration);
234  bool warnIfInvalid(Mlt::Service &service);
235  Mlt::Transition *getVideoBlendTransition(int trackIndex) const;
236  void refreshVideoBlendTransitions();
237  int bottomVideoTrackMltIndex() const;
238  bool hasEmptyTrack(TrackType trackType) const;
239 
240  friend class UndoHelper;
241 
242 private slots:
243  void adjustBackgroundDuration();
244  void adjustTrackFilters();
245 };
246 
247 #endif // MULTITRACKMODEL_H