1 /* 2 SPDX-FileCopyrightText: 2017 Nicolas Carion 3 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 4 */ 5 6 #ifndef ASSETPARAMETERMODEL_H 7 #define ASSETPARAMETERMODEL_H 8 9 #include "definitions.h" 10 #include "klocalizedstring.h" 11 #include <QAbstractListModel> 12 #include <QDomElement> 13 #include <QJsonDocument> 14 #include <unordered_map> 15 16 #include <memory> 17 #include <mlt++/MltProperties.h> 18 19 class KeyframeModelList; 20 21 typedef QVector<QPair<QString, QVariant>> paramVector; 22 23 enum class ParamType { 24 Double, 25 List, // Value can be chosen from a list of pre-defined ones 26 ListWithDependency, // Value can be chosen from a list of pre-defined ones. Some values might not be available due to missing dependencies 27 UrlList, // File can be chosen from a list of pre-defined ones or a custom file can be used (like url) 28 Bool, 29 Switch, 30 MultiSwitch, 31 RestrictedAnim, // animated 1 dimensional param with linear support only 32 Animated, 33 AnimatedRect, // Animated rects have X, Y, width, height, and opacity (in [0,1]) 34 Geometry, 35 Addedgeometry, 36 KeyframeParam, 37 Color, 38 ColorWheel, 39 Position, 40 Curve, 41 Bezier_spline, 42 Roto_spline, 43 Wipe, 44 Url, 45 Keywords, 46 Fontfamily, 47 Filterjob, 48 Readonly, 49 Hidden 50 }; 51 Q_DECLARE_METATYPE(ParamType) 52 53 /** @class AssetParameterModel 54 @brief This class is the model for a list of parameters. 55 The behaviour of a transition or an effect is typically controlled by several parameters. This class exposes this parameters as a list that can be rendered 56 using the relevant widgets. 57 Note that internally parameters are not sorted in any ways, because some effects like sox need a precise order 58 */ 59 class AssetParameterModel : public QAbstractListModel, public enable_shared_from_this_virtual<AssetParameterModel> 60 { 61 Q_OBJECT 62 63 friend class KeyframeModelList; 64 friend class KeyframeModel; 65 66 public: 67 /** 68 * 69 * @param asset 70 * @param assetXml XML to parse, from project file 71 * @param assetId 72 * @param ownerId 73 * @param originalDecimalPoint If a decimal point other than “.” was used, try to replace all occurrences by a “.” 74 * so numbers are parsed correctly. 75 * @param parent 76 */ 77 explicit AssetParameterModel(std::unique_ptr<Mlt::Properties> asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId, 78 const QString& originalDecimalPoint = QString(), 79 QObject *parent = nullptr); 80 ~AssetParameterModel() override; 81 enum DataRoles { 82 NameRole = Qt::UserRole + 1, 83 TypeRole, 84 CommentRole, 85 AlternateNameRole, 86 MinRole, 87 VisualMinRole, 88 VisualMaxRole, 89 MaxRole, 90 DefaultRole, 91 SuffixRole, 92 DecimalsRole, 93 OddRole, 94 ValueRole, 95 AlphaRole, 96 ListValuesRole, 97 InstalledValuesRole, 98 ListNamesRole, 99 ListDependenciesRole, 100 NewStuffRole, 101 ModeRole, 102 FactorRole, 103 FilterRole, 104 FilterJobParamsRole, 105 FilterProgressRole, 106 FilterParamsRole, 107 FilterConsumerParamsRole, 108 ScaleRole, 109 OpacityRole, 110 RelativePosRole, 111 // Don't display this param in timeline keyframes 112 ShowInTimelineRole, 113 InRole, 114 OutRole, 115 ParentInRole, 116 ParentPositionRole, 117 ParentDurationRole, 118 HideKeyframesFirstRole, 119 List1Role, 120 List2Role, 121 Enum1Role, 122 Enum2Role, 123 Enum3Role, 124 Enum4Role, 125 Enum5Role, 126 Enum6Role, 127 Enum7Role, 128 Enum8Role, 129 Enum9Role, 130 Enum10Role, 131 Enum11Role, 132 Enum12Role, 133 Enum13Role, 134 Enum14Role, 135 Enum15Role, 136 Enum16Role 137 }; 138 139 /** @brief Returns the id of the asset represented by this object */ 140 QString getAssetId() const; 141 const QString getAssetMltId(); 142 void setActive(bool active); 143 bool isActive() const; 144 145 /** @brief Set the parameter with given name to the given value 146 */ 147 Q_INVOKABLE void setParameter(const QString &name, const QString ¶mValue, bool update = true, const QModelIndex ¶mIndex = QModelIndex()); 148 void setParameter(const QString &name, int value, bool update = true); 149 150 /** @brief Return all the parameters as pairs (parameter name, parameter value) */ 151 QVector<QPair<QString, QVariant>> getAllParameters() const; 152 /** @brief Get a parameter value from its name */ 153 const QVariant getParamFromName(const QString ¶mName); 154 /** @brief Returns a json definition of the effect with all param values */ 155 QJsonDocument toJson(bool includeFixed = true) const; 156 /** @brief Returns the interpolated value at the given position with all param values as json*/ 157 QJsonDocument valueAsJson(int pos, bool includeFixed = true) const; 158 159 void savePreset(const QString &presetFile, const QString &presetName); 160 void deletePreset(const QString &presetFile, const QString &presetName); 161 const QStringList getPresetList(const QString &presetFile) const; 162 const QVector<QPair<QString, QVariant>> loadPreset(const QString &presetFile, const QString &presetName); 163 164 /* Which monitor is attached to this asset (clip/project) 165 */ 166 Kdenlive::MonitorId monitorId; 167 168 QVariant data(const QModelIndex &index, int role) const override; 169 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 170 171 /** @brief Returns the id of the actual object associated with this asset */ 172 ObjectId getOwnerId() const; 173 174 /** @brief Returns the keyframe model associated with this asset 175 Return empty ptr if there is no keyframable parameter in the asset or if prepareKeyframes was not called 176 */ 177 Q_INVOKABLE std::shared_ptr<KeyframeModelList> getKeyframeModel(); 178 179 /** @brief Must be called before using the keyframes of this model */ 180 void prepareKeyframes(); 181 void resetAsset(std::unique_ptr<Mlt::Properties> asset); 182 /** @brief Returns true if the effect has more than one keyframe */ 183 bool hasMoreThanOneKeyframe() const; 184 int time_to_frames(const QString &time); 185 void passProperties(Mlt::Properties &target); 186 /** @brief Returns a list of the parameter names that are keyframable */ 187 QStringList getKeyframableParameters() const; 188 189 /** @brief Returns the current value of an effect parameter */ 190 const QString getParam(const QString ¶mName); 191 /** @brief Returns the current asset */ 192 Mlt::Properties *getAsset(); 193 /** @brief Returns a frame time as click time (00:00:00.000) */ 194 const QString framesToTime(int t) const; 195 196 public slots: 197 /** @brief Sets the value of a list of parameters 198 @param params contains the pairs (parameter name, parameter value) 199 */ 200 void setParameters(const paramVector ¶ms, bool update = true); 201 /** @brief Set a filter job's progress */ 202 void setProgress(int progress); 203 204 protected: 205 /** @brief Helper function to retrieve the type of a parameter given the string corresponding to it*/ 206 static ParamType paramTypeFromStr(const QString &type); 207 208 static QString getDefaultKeyframes(int start, const QString &defaultValue, bool linearOnly); 209 210 /** @brief Helper function to get an attribute from a dom element, given its name. 211 The function additionally parses following keywords: 212 - %width and %height that are replaced with profile's height and width. 213 If keywords are found, mathematical operations are supported for double type params. For example "%width -1" is a valid value. 214 */ 215 static QVariant parseAttribute(const ObjectId &owner, const QString &attribute, const QDomElement &element, QVariant defaultValue = QVariant()); 216 QVariant parseSubAttributes(const QString &attribute, const QDomElement &element) const; 217 218 /** @brief Helper function to register one more parameter that is keyframable. 219 @param index is the index corresponding to this parameter 220 */ 221 void addKeyframeParam(const QModelIndex &index); 222 223 struct ParamRow 224 { 225 ParamType type; 226 QDomElement xml; 227 QVariant value; 228 QString name; 229 }; 230 231 QString m_assetId; 232 ObjectId m_ownerId; 233 bool m_active; 234 /** @brief Keep track of parameter order, important for sox */ 235 std::vector<QString> m_paramOrder; 236 /** @brief Store all parameters by name */ 237 std::unordered_map<QString, ParamRow> m_params; 238 /** @brief We store values of fixed parameters aside */ 239 std::unordered_map<QString, QVariant> m_fixedParams; 240 /** @brief We store the params name in order of parsing. The order is important (cf some effects like sox) */ 241 QVector<QString> m_rows; 242 243 std::unique_ptr<Mlt::Properties> m_asset; 244 245 std::shared_ptr<KeyframeModelList> m_keyframes; 246 QVector<int>m_selectedKeyframes; 247 int m_activeKeyframe; 248 /** @brief if true, keyframe tools will be hidden by default */ 249 bool m_hideKeyframesByDefault; 250 /** @brief true if this is an audio effect, used to prevent unnecessary monitor refresh / timeline invalidate */ 251 bool m_isAudio; 252 /** @brief Store a filter's job progress */ 253 int m_filterProgress; 254 255 /** @brief Set the parameter with given name to the given value. This should be called when first 256 * building an effect in the constructor, so that we don't call shared_from_this 257 */ 258 void internalSetParameter(const QString &name, const QString ¶mValue, const QModelIndex ¶mIndex = QModelIndex()); 259 260 signals: 261 void modelChanged(); 262 /** @brief inform child effects (in case of bin effect with timeline producers) 263 * that a change occurred and a param update is needed **/ 264 void updateChildren(const QStringList &names); 265 void compositionTrackChanged(); 266 void replugEffect(std::shared_ptr<AssetParameterModel> asset); 267 void rebuildEffect(std::shared_ptr<AssetParameterModel> asset); 268 void enabledChange(bool); 269 void showEffectZone(ObjectId id, QPair <int, int>inOut, bool checked); 270 }; 271 272 #endif 273