File indexing completed on 2024-12-08 04:25:57
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 "definitions.h" 0009 #include "klocalizedstring.h" 0010 #include <QAbstractListModel> 0011 #include <QDomElement> 0012 #include <QJsonDocument> 0013 #include <unordered_map> 0014 0015 #include <memory> 0016 #include <mlt++/MltProperties.h> 0017 0018 class KeyframeModelList; 0019 0020 typedef QVector<QPair<QString, QVariant>> paramVector; 0021 0022 enum class ParamType { 0023 Double, 0024 List, // Value can be chosen from a list of pre-defined ones 0025 ListWithDependency, // Value can be chosen from a list of pre-defined ones. Some values might not be available due to missing dependencies 0026 UrlList, // File can be chosen from a list of pre-defined ones or a custom file can be used (like url) 0027 Bool, 0028 Switch, 0029 MultiSwitch, 0030 AnimatedRect, // Animated rects have X, Y, width, height, and opacity (in [0,1]) 0031 Geometry, 0032 KeyframeParam, 0033 Color, 0034 FixedColor, // Non animated color 0035 ColorWheel, 0036 Position, 0037 Curve, 0038 Bezier_spline, 0039 Roto_spline, 0040 Wipe, 0041 Url, 0042 Keywords, 0043 Fontfamily, 0044 Filterjob, 0045 Readonly, 0046 Hidden 0047 }; 0048 Q_DECLARE_METATYPE(ParamType) 0049 0050 /** @class AssetParameterModel 0051 @brief This class is the model for a list of parameters. 0052 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 0053 using the relevant widgets. 0054 Note that internally parameters are not sorted in any ways, because some effects like sox need a precise order 0055 */ 0056 class AssetParameterModel : public QAbstractListModel, public enable_shared_from_this_virtual<AssetParameterModel> 0057 { 0058 Q_OBJECT 0059 0060 friend class KeyframeModelList; 0061 friend class KeyframeModel; 0062 0063 public: 0064 /** 0065 * 0066 * @param asset 0067 * @param assetXml XML to parse, from project file 0068 * @param assetId 0069 * @param ownerId 0070 * @param originalDecimalPoint If a decimal point other than “.” was used, try to replace all occurrences by a “.” 0071 * so numbers are parsed correctly. 0072 * @param parent 0073 */ 0074 explicit AssetParameterModel(std::unique_ptr<Mlt::Properties> asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId, 0075 const QString &originalDecimalPoint = QString(), QObject *parent = nullptr); 0076 ~AssetParameterModel() override; 0077 enum DataRoles { 0078 NameRole = Qt::UserRole + 1, 0079 TypeRole, 0080 CommentRole, 0081 AlternateNameRole, 0082 MinRole, 0083 VisualMinRole, 0084 VisualMaxRole, 0085 MaxRole, 0086 DefaultRole, 0087 SuffixRole, 0088 DecimalsRole, 0089 OddRole, 0090 ValueRole, 0091 AlphaRole, 0092 ListValuesRole, 0093 ListNamesRole, 0094 ListDependenciesRole, 0095 NewStuffRole, 0096 ModeRole, 0097 FactorRole, 0098 FilterRole, 0099 FilterJobParamsRole, 0100 FilterProgressRole, 0101 FilterParamsRole, 0102 FilterConsumerParamsRole, 0103 ScaleRole, 0104 OpacityRole, 0105 RelativePosRole, 0106 // The filter in/out should always be 0 - full length 0107 RequiresInOut, 0108 ToTimePosRole, 0109 // Don't display this param in timeline keyframes 0110 ShowInTimelineRole, 0111 InRole, 0112 OutRole, 0113 ParentInRole, 0114 ParentPositionRole, 0115 ParentDurationRole, 0116 HideKeyframesFirstRole, 0117 List1Role, 0118 List2Role, 0119 Enum1Role, 0120 Enum2Role, 0121 Enum3Role, 0122 Enum4Role, 0123 Enum5Role, 0124 Enum6Role, 0125 Enum7Role, 0126 Enum8Role, 0127 Enum9Role, 0128 Enum10Role, 0129 Enum11Role, 0130 Enum12Role, 0131 Enum13Role, 0132 Enum14Role, 0133 Enum15Role, 0134 Enum16Role 0135 }; 0136 0137 /** @brief Returns true if @param type is animated */ 0138 static bool isAnimated(ParamType type); 0139 0140 /** @brief Returns the id of the asset represented by this object */ 0141 QString getAssetId() const; 0142 const QString getAssetMltId(); 0143 void setActive(bool active); 0144 bool isActive() const; 0145 0146 /** @brief Set the parameter with given name to the given value 0147 */ 0148 Q_INVOKABLE void setParameter(const QString &name, const QString ¶mValue, bool update = true, const QModelIndex ¶mIndex = QModelIndex()); 0149 void setParameter(const QString &name, int value, bool update = true); 0150 0151 /** @brief Return all the parameters as pairs (parameter name, parameter value) */ 0152 QVector<QPair<QString, QVariant>> getAllParameters() const; 0153 /** @brief Get a parameter value from its name */ 0154 const QVariant getParamFromName(const QString ¶mName); 0155 /** @brief Get a parameter index from its name */ 0156 const QModelIndex getParamIndexFromName(const QString ¶mName); 0157 /** @brief Returns a json definition of the effect with all param values 0158 * @param selection only export keyframes matching the selected index, or all keyframes if empty 0159 * @param includeFixed if true, also export the fixed (non user editable) parameters for this effect 0160 */ 0161 QJsonDocument toJson(QVector<int> selection = {}, bool includeFixed = true) const; 0162 /** @brief Returns the interpolated value at the given position with all param values as json*/ 0163 QJsonDocument valueAsJson(int pos, bool includeFixed = true) const; 0164 0165 void savePreset(const QString &presetFile, const QString &presetName); 0166 void deletePreset(const QString &presetFile, const QString &presetName); 0167 const QStringList getPresetList(const QString &presetFile) const; 0168 const QVector<QPair<QString, QVariant>> loadPreset(const QString &presetFile, const QString &presetName); 0169 0170 /* Which monitor is attached to this asset (clip/project) 0171 */ 0172 Kdenlive::MonitorId monitorId; 0173 0174 QVariant data(const QModelIndex &index, int role) const override; 0175 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0176 0177 /** @brief Returns the id of the actual object associated with this asset */ 0178 ObjectId getOwnerId() const; 0179 0180 /** @brief Returns the keyframe model associated with this asset 0181 Return empty ptr if there is no keyframable parameter in the asset or if prepareKeyframes was not called 0182 */ 0183 Q_INVOKABLE std::shared_ptr<KeyframeModelList> getKeyframeModel(); 0184 0185 /** @brief Must be called before using the keyframes of this model */ 0186 void prepareKeyframes(int in = -1, int out = -1); 0187 void resetAsset(std::unique_ptr<Mlt::Properties> asset); 0188 /** @brief Returns true if the effect has more than one keyframe */ 0189 bool hasMoreThanOneKeyframe() const; 0190 int time_to_frames(const QString &time) const; 0191 void passProperties(Mlt::Properties &target); 0192 /** @brief Returns a list of the parameter names that are keyframable, along with param type and opacity use */ 0193 QMap<QString, std::pair<ParamType, bool>> getKeyframableParameters() const; 0194 0195 /** @brief Returns the current value of an effect parameter */ 0196 const QString getParam(const QString ¶mName); 0197 /** @brief Returns the current asset */ 0198 Mlt::Properties *getAsset(); 0199 /** @brief Returns a frame time as click time (00:00:00.000) */ 0200 const QString framesToTime(int t) const; 0201 0202 public Q_SLOTS: 0203 /** @brief Sets the value of a list of parameters 0204 @param params contains the pairs (parameter name, parameter value) 0205 */ 0206 void setParameters(const paramVector ¶ms, bool update = true); 0207 /** @brief Sets the value of a list of parameters. If the parameters have keyframes, ensuring all keyframable params get the keyframes 0208 @param params contains the pairs (parameter name, parameter value) 0209 */ 0210 void setParametersFromTask(const paramVector ¶ms); 0211 /** @brief Set a filter job's progress */ 0212 void setProgress(int progress); 0213 0214 protected: 0215 /** @brief Helper function to retrieve the type of a parameter given the string corresponding to it*/ 0216 static ParamType paramTypeFromStr(const QString &type); 0217 0218 static QString getDefaultKeyframes(int start, const QString &defaultValue, bool linearOnly); 0219 0220 /** @brief Helper function to get an attribute from a dom element, given its name. 0221 The function additionally parses following keywords: 0222 - %width and %height that are replaced with profile's height and width. 0223 If keywords are found, mathematical operations are supported for double type params. For example "%width -1" is a valid value. 0224 */ 0225 QVariant parseAttribute(const ObjectId &owner, const QString &attribute, const QDomElement &element, QVariant defaultValue = QVariant()) const; 0226 QVariant parseSubAttributes(const QString &attribute, const QDomElement &element) const; 0227 0228 /** @brief Helper function to register one more parameter that is keyframable. 0229 @param index is the index corresponding to this parameter 0230 */ 0231 void addKeyframeParam(const QModelIndex &index, int in, int out); 0232 0233 struct ParamRow 0234 { 0235 ParamType type; 0236 QDomElement xml; 0237 QVariant value; 0238 QString name; 0239 }; 0240 0241 QString m_assetId; 0242 ObjectId m_ownerId; 0243 bool m_active; 0244 /** @brief Keep track of parameter order, important for sox */ 0245 std::vector<QString> m_paramOrder; 0246 /** @brief Store all parameters by name */ 0247 std::unordered_map<QString, ParamRow> m_params; 0248 /** @brief We store values of fixed parameters aside */ 0249 std::unordered_map<QString, QVariant> m_fixedParams; 0250 /** @brief We store the params name in order of parsing. The order is important (cf some effects like sox) */ 0251 QVector<QString> m_rows; 0252 0253 std::unique_ptr<Mlt::Properties> m_asset; 0254 0255 std::shared_ptr<KeyframeModelList> m_keyframes; 0256 QVector<int> m_selectedKeyframes; 0257 int m_activeKeyframe; 0258 /** @brief if true, keyframe tools will be hidden by default */ 0259 bool m_hideKeyframesByDefault; 0260 /** @brief if true, the effect's in/out will always be synced to clip in/out */ 0261 bool m_requiresInOut; 0262 /** @brief true if this is an audio effect, used to prevent unnecessary monitor refresh / timeline invalidate */ 0263 bool m_isAudio; 0264 /** @brief Store a filter's job progress */ 0265 int m_filterProgress; 0266 0267 /** @brief Set the parameter with given name to the given value. This should be called when first 0268 * building an effect in the constructor, so that we don't call shared_from_this 0269 */ 0270 void internalSetParameter(const QString name, const QString paramValue, const QModelIndex ¶mIndex = QModelIndex()); 0271 0272 Q_SIGNALS: 0273 void modelChanged(); 0274 /** @brief inform child effects (in case of bin effect with timeline producers) 0275 * that a change occurred and a param update is needed **/ 0276 void updateChildren(const QStringList &names); 0277 void compositionTrackChanged(); 0278 void replugEffect(std::shared_ptr<AssetParameterModel> asset); 0279 void rebuildEffect(std::shared_ptr<AssetParameterModel> asset); 0280 void enabledChange(bool); 0281 void hideKeyframesChange(bool); 0282 void showEffectZone(ObjectId id, QPair<int, int> inOut, bool checked); 0283 };