File indexing completed on 2024-04-28 08:44:35

0001 /*
0002     SPDX-FileCopyrightText: 2017 Nicolas Carion
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #pragma once
0007 
0008 #include "timelinemodel.hpp"
0009 #include "undohelper.hpp"
0010 
0011 class MarkerListModel;
0012 
0013 /** @class TimelineItemModel
0014     @brief This class is the thin wrapper around the TimelineModel that provides interface for the QML.
0015 
0016    It derives from AbstractItemModel to provide the model to the QML interface. An itemModel is organized with row and columns that contain the data. It can be
0017    hierarchical, meaning that a given index (row,column) can contain another level of rows and column.
0018    Our organization is as follows: at the top level, each row contains a track. These rows are in the same order as in the actual timeline.
0019    Then each of this row contains itself sub-rows that correspond to the clips.
0020    Here the order of these sub-rows is unrelated to the chronological order of the clips,
0021    but correspond to their Id order. For example, if you have three clips, with ids 12, 45 and 150, they will receive row index 0,1 and 2.
0022    This is because the order actually doesn't matter since the clips are rendered based on their positions rather than their row order.
0023    The id order has been chosen because it is consistent with a valid ordering of the clips.
0024    The columns are never used, so the data is always in column 0
0025 
0026    An ModelIndex in the ItemModel consists of a row number, a column number, and a parent index. In our case, tracks have always an empty parent, and the clip
0027    have a track index as parent.
0028    A ModelIndex can also store one additional integer, and we exploit this feature to store the unique ID of the object it corresponds to.
0029    */
0030 class TimelineItemModel : public TimelineModel
0031 {
0032     Q_OBJECT
0033 
0034 public:
0035     /** @brief construct a timeline object and returns a pointer to the created object
0036        @param undo_stack is a weak pointer to the undo stack of the project
0037        @param guideModel ptr to the guide model of the project
0038      */
0039     static std::shared_ptr<TimelineItemModel> construct(const QUuid &uuid, std::weak_ptr<DocUndoStack> undo_stack);
0040 
0041     friend bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor tractor);
0042 
0043 protected:
0044     /** @brief this constructor should not be called. Call the static construct instead
0045      */
0046     TimelineItemModel(const QUuid &uuid, std::weak_ptr<DocUndoStack> undo_stack);
0047 
0048 public:
0049     ~TimelineItemModel() override;
0050     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0051     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
0052     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0053     QHash<int, QByteArray> roleNames() const override;
0054     QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
0055     // QModelIndex makeIndex(int trackIndex, int clipIndex) const;
0056 
0057     /** @brief Add multiple tracks at a specific position (used by the Add Track
0058      * dialog). Returns true if successful, false otherwise. */
0059     bool addTracksAtPosition(int position, int tracksCount, QString &trackName, bool addAudioTrack, bool addAVTrack, bool addRecTrack);
0060 
0061     /** @brief Creates an index based on the ID of the clip*/
0062     QModelIndex makeClipIndexFromID(int clipId) const override;
0063     /** @brief Creates an index based on the ID of the compoition*/
0064     QModelIndex makeCompositionIndexFromID(int compoId) const override;
0065     void subtitleChanged(int subId, const QVector<int> &roles);
0066     /** @brief Creates an index based on the ID of the track*/
0067     QModelIndex makeTrackIndexFromID(int trackId) const override;
0068     QModelIndex parent(const QModelIndex &index) const override;
0069     Q_INVOKABLE void setTrackProperty(int tid, const QString &name, const QString &value);
0070     /** @brief Enabled/disabled a track's effect stack */
0071     Q_INVOKABLE void setTrackStackEnabled(int tid, bool enable);
0072     Q_INVOKABLE QVariant getTrackProperty(int tid, const QString &name) const;
0073     /** @brief Sets a track name
0074        @param trackId is of the track to alter
0075        @param text is the new track name.
0076     */
0077     Q_INVOKABLE void setTrackName(int trackId, const QString &text);
0078     Q_INVOKABLE bool copyClipEffect(int clipId, const QString sourceId);
0079     /** @brief returns the lower video track index in timeline.
0080      **/
0081     int getFirstVideoTrackIndex() const;
0082     int getFirstAudioTrackIndex() const;
0083     const QString getTrackFullName(int tid) const;
0084     void notifyChange(const QModelIndex &topleft, const QModelIndex &bottomright, bool start, bool duration, bool updateThumb) override;
0085     void notifyChange(const QModelIndex &topleft, const QModelIndex &bottomright, const QVector<int> &roles) override;
0086     void notifyChange(const QModelIndex &topleft, const QModelIndex &bottomright, int role) override;
0087 
0088     /** @brief Import track effects */
0089     void importTrackEffects(int tid, std::weak_ptr<Mlt::Service> service);
0090     /** @brief Save the sequence properties in MLT tractor */
0091     void passSequenceProperties(const QMap<QString, QString> baseProperties);
0092 
0093     const QString groupsData();
0094     bool loadGroups(const QString &groupsData);
0095     std::shared_ptr<SubtitleModel> createSubtitleModel();
0096     void processTimelineReplacement(QList<int> instances, const QString &originalId, const QString &replacementId, int maxDuration, bool replaceAudio,
0097                                     bool replaceVideo);
0098 
0099     /** @brief Rebuild track compositing */
0100     void buildTrackCompositing(bool rebuild = false) override;
0101     /** @brief Register all tracks in the mixer */
0102     void rebuildMixer();
0103     void _beginRemoveRows(const QModelIndex & /*unused*/, int /*unused*/, int /*unused*/) override;
0104     void _beginInsertRows(const QModelIndex & /*unused*/, int /*unused*/, int /*unused*/) override;
0105     void _endRemoveRows() override;
0106     void _endInsertRows() override;
0107     void _resetView() override;
0108 
0109 protected:
0110     /** @brief This is an helper function that finishes a construction of a freshly created TimelineItemModel */
0111     static void finishConstruct(const std::shared_ptr<TimelineItemModel> &ptr);
0112 
0113 Q_SIGNALS:
0114     /** @brief Triggered when a video track visibility changed */
0115     void trackVisibilityChanged();
0116     void showTrackEffectStack(int tid);
0117     void subtitleModelInitialized();
0118 };