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