1 /*
2     SPDX-FileCopyrightText: 2017 Jean-Baptiste Mardelle
3     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
4 */
5 
6 #ifndef COMPOSITIONMODEL_H
7 #define COMPOSITIONMODEL_H
8 
9 #include "assets/model/assetparametermodel.hpp"
10 #include "moveableItem.hpp"
11 #include "undohelper.hpp"
12 #include <memory>
13 
14 namespace Mlt {
15 class Transition;
16 }
17 class TimelineModel;
18 class TrackModel;
19 class KeyframeModel;
20 
21 /** @brief This class represents a Composition object, as viewed by the backend.
22    In general, the Gui associated with it will send modification queries (such as resize or move), and this class authorize them or not depending on the
23    validity of the modifications
24 */
25 class CompositionModel : public MoveableItem<Mlt::Transition>, public AssetParameterModel
26 {
27     CompositionModel() = delete;
28 
29 protected:
30     /** This constructor is not meant to be called, call the static construct instead */
31     CompositionModel(std::weak_ptr<TimelineModel> parent, std::unique_ptr<Mlt::Transition> transition, int id, const QDomElement &transitionXml,
32                      const QString &transitionId, const QString &originalDecimalPoint);
33 
34 public:
35     /** @brief Creates a composition, which then registers itself to the parent timeline
36        Returns the (unique) id of the created composition
37        @param parent is a pointer to the timeline
38        @param transitionId is the id of the transition to be inserted
39        @param id Requested id of the clip. Automatic if -1
40     */
41     static int construct(const std::weak_ptr<TimelineModel> &parent, const QString &transitionId, const QString &originalDecimalPoint, int id = -1,
42                          std::unique_ptr<Mlt::Properties> sourceProperties = nullptr);
43 
44     friend class TrackModel;
45     friend class TimelineModel;
46 
47     /** @brief returns the length of the item on the timeline
48      */
49     int getPlaytime() const override;
50 
51     /** @brief Returns the id of the second track involved in the composition (a_track in mlt's vocabulary, the b_track being the track where the composition is
52        inserted)
53      */
54     int getATrack() const;
55     /** @brief Defines the forced_track property. If true, the a_track will not change when composition
56      * is moved to another track. When false, the a_track will automatically change to lower video track
57      */
58     void setForceTrack(bool force);
59     /** @brief Returns the id of the second track involved in the composition (a_track) or -1 if the a_track should be automatically updated when the composition
60      * changes track
61      */
62     int getForcedTrack() const;
63 
64     /** @brief Sets the id of the second track involved in the composition*/
65     void setATrack(int trackMltPosition, int trackId);
66 
67     /** @brief returns a property of the current item
68      */
69     const QString getProperty(const QString &name) const override;
70 
71     /** @brief returns the active effect's keyframe model
72      */
73     KeyframeModel *getEffectKeyframeModel();
74     Q_INVOKABLE bool showKeyframes() const;
75     Q_INVOKABLE void setShowKeyframes(bool show);
76     const QString &displayName() const;
77     Mlt::Properties *properties();
78 
79     /** @brief Returns an XML representation of the clip with its effects */
80     QDomElement toXml(QDomDocument &document);
81     void setGrab(bool grab) override;
82     void setSelected(bool sel) override;
83 
84 protected:
85     Mlt::Transition *service() const override;
86     void setInOut(int in, int out) override;
87     void setCurrentTrackId(int tid, bool finalMove = true) override;
88     int getOut() const override;
89     int getIn() const override;
90 
91     /** @brief Performs a resize of the given composition.
92        Returns true if the operation succeeded, and otherwise nothing is modified
93        This method is protected because it shouldn't be called directly. Call the function in the timeline instead.
94        If a snap point is within reach, the operation will be coerced to use it.
95        @param size is the new size of the composition
96        @param right is true if we change the right side of the composition, false otherwise
97        @param undo Lambda function containing the current undo stack. Will be updated with current operation
98        @param redo Lambda function containing the current redo queue. Will be updated with current operation
99     */
100     bool requestResize(int size, bool right, Fun &undo, Fun &redo, bool logUndo = true, bool hasMix = false) override;
101 
102 private:
103     int m_a_track;
104     QString m_compositionName;
105     int m_duration;
106 };
107 
108 #endif
109