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