diff --git a/src/assets/CMakeLists.txt b/src/assets/CMakeLists.txt index 694e03998..79eed8e3b 100644 --- a/src/assets/CMakeLists.txt +++ b/src/assets/CMakeLists.txt @@ -1,29 +1,30 @@ set(kdenlive_SRCS ${kdenlive_SRCS} assets/assetlist/view/qmltypes/asseticonprovider.cpp assets/assetlist/view/assetlistwidget.cpp assets/assetlist/model/assetfilter.cpp assets/assetlist/model/assettreemodel.cpp assets/assetpanel.cpp assets/keyframes/model/keyframemodel.cpp assets/keyframes/model/keyframemodellist.cpp assets/keyframes/view/keyframeview.cpp assets/model/assetparametermodel.cpp assets/model/assetcommand.cpp assets/view/assetparameterview.cpp assets/view/widgets/abstractparamwidget.cpp #assets/view/widgets/animationwidget.cpp assets/view/widgets/boolparamwidget.cpp assets/view/widgets/switchparamwidget.cpp + assets/view/widgets/urlparamwidget.cpp assets/view/widgets/doubleparamwidget.cpp assets/view/widgets/colorwheel.cpp assets/view/widgets/slidewidget.cpp assets/view/widgets/lumaliftgainparam.cpp # assets/view/widgets/keyframeedit.cpp assets/view/widgets/keyframewidget.cpp assets/view/widgets/listparamwidget.cpp assets/view/widgets/geometryeditwidget.cpp assets/view/widgets/positioneditwidget.cpp assets/view/widgets/coloreditwidget.cpp PARENT_SCOPE) diff --git a/src/assets/model/assetparametermodel.cpp b/src/assets/model/assetparametermodel.cpp index 992535a62..4a8049f24 100644 --- a/src/assets/model/assetparametermodel.cpp +++ b/src/assets/model/assetparametermodel.cpp @@ -1,476 +1,478 @@ /*************************************************************************** * Copyright (C) 2017 by Nicolas Carion * * This file is part of Kdenlive. See www.kdenlive.org. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) version 3 or any later version accepted by the * * membership of KDE e.V. (or its successor approved by the membership * * of KDE e.V.), which shall act as a proxy defined in Section 14 of * * version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "assetparametermodel.hpp" #include "assets/keyframes/model/keyframemodellist.hpp" #include "core.h" #include "kdenlivesettings.h" #include "klocalizedstring.h" #include "profiles/profilemodel.hpp" #include #include #include AssetParameterModel::AssetParameterModel(Mlt::Properties *asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId, QObject *parent) : QAbstractListModel(parent) , monitorId(ownerId.first == ObjectType::BinClip ? Kdenlive::ClipMonitor : Kdenlive::ProjectMonitor) , m_xml(assetXml) , m_assetId(assetId) , m_ownerId(ownerId) , m_asset(asset) { Q_ASSERT(asset->is_valid()); QDomNodeList nodeList = m_xml.elementsByTagName(QStringLiteral("parameter")); bool needsLocaleConversion = false; QChar separator, oldSeparator; // Check locale if (m_xml.hasAttribute(QStringLiteral("LC_NUMERIC"))) { QLocale locale = QLocale(m_xml.attribute(QStringLiteral("LC_NUMERIC"))); if (locale.decimalPoint() != QLocale().decimalPoint()) { needsLocaleConversion = true; separator = QLocale().decimalPoint(); oldSeparator = locale.decimalPoint(); } } qDebug() << "XML parsing of " << assetId << ". found : " << nodeList.count(); for (int i = 0; i < nodeList.count(); ++i) { QDomElement currentParameter = nodeList.item(i).toElement(); // Convert parameters if we need to if (needsLocaleConversion) { QDomNamedNodeMap attrs = currentParameter.attributes(); for (int k = 0; k < attrs.count(); ++k) { QString nodeName = attrs.item(k).nodeName(); if (nodeName != QLatin1String("type") && nodeName != QLatin1String("name")) { QString val = attrs.item(k).nodeValue(); if (val.contains(oldSeparator)) { QString newVal = val.replace(oldSeparator, separator); attrs.item(k).setNodeValue(newVal); } } } } // Parse the basic attributes of the parameter QString name = currentParameter.attribute(QStringLiteral("name")); QString type = currentParameter.attribute(QStringLiteral("type")); QString value = currentParameter.attribute(QStringLiteral("value")); if (value.isNull()) { value = parseAttribute(QStringLiteral("default"), currentParameter).toString(); } bool isFixed = (type == QLatin1String("fixed")); if (isFixed) { m_fixedParams[name] = value; } if (!name.isEmpty()) { setParameter(name, value, false); // Keep track of param order m_paramOrder.push_back(name); } if (isFixed) { // fixed parameters are not displayed so we don't store them. continue; } ParamRow currentRow; currentRow.type = paramTypeFromStr(type); currentRow.xml = currentParameter; currentRow.value = value; QString title = currentParameter.firstChildElement(QStringLiteral("name")).text(); currentRow.name = title.isEmpty() ? name : title; m_params[name] = currentRow; m_rows.push_back(name); } if (m_assetId.startsWith(QStringLiteral("sox_"))) { // Sox effects need to have a special "Effect" value set QStringList effectParam = {m_assetId.section(QLatin1Char('_'), 1)}; for (const QString &pName : m_paramOrder) { effectParam << m_asset->get(pName.toUtf8().constData()); } m_asset->set("effect", effectParam.join(QLatin1Char(' ')).toUtf8().constData()); } qDebug() << "END parsing of " << assetId << ". Number of found parameters" << m_rows.size(); emit modelChanged(); } void AssetParameterModel::prepareKeyframes() { if (m_keyframes) return; int ix = 0; for (const auto &name : m_rows) { if (m_params[name].type == ParamType::KeyframeParam || m_params[name].type == ParamType::AnimatedRect) { addKeyframeParam(index(ix, 0)); } ix++; } } void AssetParameterModel::setParameter(const QString &name, const int value, bool update) { Q_ASSERT(m_asset->is_valid()); m_asset->set(name.toLatin1().constData(), value); if (m_fixedParams.count(name) == 0) { m_params[name].value = value; } else { m_fixedParams[name] = value; } if (update) { if (m_assetId.startsWith(QStringLiteral("sox_"))) { // Warning, SOX effect, need unplug/replug qDebug()<<"// Warning, SOX effect, need unplug/replug"; QStringList effectParam = {m_assetId.section(QLatin1Char('_'), 1)}; for (const QString &pName : m_paramOrder) { effectParam << m_asset->get(pName.toUtf8().constData()); } m_asset->set("effect", effectParam.join(QLatin1Char(' ')).toUtf8().constData()); emit replugEffect(shared_from_this()); } else if (m_assetId == QLatin1String("autotrack_rectangle") || m_assetId.startsWith(QStringLiteral("ladspa"))) { // these effects don't understand param change and need to be rebuild emit replugEffect(shared_from_this()); } else { emit modelChanged(); } // Update timeline view if necessary pCore->updateItemModel(m_ownerId, m_assetId); pCore->refreshProjectItem(m_ownerId); pCore->invalidateItem(m_ownerId); } } void AssetParameterModel::setParameter(const QString &name, const QString &value, bool update) { Q_ASSERT(m_asset->is_valid()); QLocale locale; locale.setNumberOptions(QLocale::OmitGroupSeparator); bool conversionSuccess; double doubleValue = locale.toDouble(value, &conversionSuccess); if (conversionSuccess) { m_asset->set(name.toLatin1().constData(), doubleValue); if (m_fixedParams.count(name) == 0) { m_params[name].value = doubleValue; } else { m_fixedParams[name] = doubleValue; } } else { m_asset->set(name.toLatin1().constData(), value.toUtf8().constData()); if (m_fixedParams.count(name) == 0) { m_params[name].value = value; } else { m_fixedParams[name] = value; } } if (update) { if (m_assetId.startsWith(QStringLiteral("sox_"))) { // Warning, SOX effect, need unplug/replug qDebug()<<"// Warning, SOX effect, need unplug/replug"; QStringList effectParam = {m_assetId.section(QLatin1Char('_'), 1)}; for (const QString &pName : m_paramOrder) { effectParam << m_asset->get(pName.toUtf8().constData()); } m_asset->set("effect", effectParam.join(QLatin1Char(' ')).toUtf8().constData()); emit replugEffect(shared_from_this()); } else if (m_assetId == QLatin1String("autotrack_rectangle") || m_assetId.startsWith(QStringLiteral("ladspa"))) { // these effects don't understand param change and need to be rebuild emit replugEffect(shared_from_this()); } else { emit modelChanged(); } // Update timeline view if necessary pCore->updateItemModel(m_ownerId, m_assetId); pCore->refreshProjectItem(m_ownerId); pCore->invalidateItem(m_ownerId); } } void AssetParameterModel::setParameter(const QString &name, double &value) { Q_ASSERT(m_asset->is_valid()); m_asset->set(name.toLatin1().constData(), value); if (m_fixedParams.count(name) == 0) { m_params[name].value = value; } else { m_fixedParams[name] = value; } if (m_assetId.startsWith(QStringLiteral("sox_"))) { // Warning, SOX effect, need unplug/replug qDebug()<<"// Warning, SOX effect, need unplug/replug"; QStringList effectParam = {m_assetId.section(QLatin1Char('_'), 1)}; for (const QString &pName : m_paramOrder) { effectParam << m_asset->get(pName.toUtf8().constData()); } m_asset->set("effect", effectParam.join(QLatin1Char(' ')).toUtf8().constData()); emit replugEffect(shared_from_this()); } else if (m_assetId == QLatin1String("autotrack_rectangle") || m_assetId.startsWith(QStringLiteral("ladspa"))) { // these effects don't understand param change and need to be rebuild emit replugEffect(shared_from_this()); } else { emit modelChanged(); } pCore->refreshProjectItem(m_ownerId); pCore->invalidateItem(m_ownerId); } AssetParameterModel::~AssetParameterModel() = default; QVariant AssetParameterModel::data(const QModelIndex &index, int role) const { if (index.row() < 0 || index.row() >= m_rows.size() || !index.isValid()) { return QVariant(); } QString paramName = m_rows[index.row()]; Q_ASSERT(m_params.count(paramName) > 0); const QDomElement &element = m_params.at(paramName).xml; switch (role) { case Qt::DisplayRole: case Qt::EditRole: return m_params.at(paramName).name; case NameRole: return paramName; case TypeRole: return QVariant::fromValue(m_params.at(paramName).type); case CommentRole: { QDomElement commentElem = element.firstChildElement(QStringLiteral("comment")); QString comment; if (!commentElem.isNull()) { comment = i18n(commentElem.text().toUtf8().data()); } return comment; } case InRole: return m_asset->get_int("in"); case OutRole: return m_asset->get_int("out"); case ParentInRole: return pCore->getItemPosition(m_ownerId); case ParentDurationRole: return pCore->getItemDuration(m_ownerId); case MinRole: return parseAttribute(QStringLiteral("min"), element); case MaxRole: return parseAttribute(QStringLiteral("max"), element); case FactorRole: return parseAttribute(QStringLiteral("factor"), element, 1); case ScaleRole: return parseAttribute(QStringLiteral("scale"), element, 0); case DecimalsRole: return parseAttribute(QStringLiteral("decimals"), element); case DefaultRole: return parseAttribute(QStringLiteral("default"), element); + case FilterRole: + return parseAttribute(QStringLiteral("filter"), element); case SuffixRole: return element.attribute(QStringLiteral("suffix")); case OpacityRole: return element.attribute(QStringLiteral("opacity")) != QLatin1String("false"); case AlphaRole: return element.attribute(QStringLiteral("alpha")) == QLatin1String("1"); case ValueRole: { QString value(m_asset->get(paramName.toUtf8().constData())); return value.isEmpty() ? (element.attribute(QStringLiteral("value")).isNull() ? parseAttribute(QStringLiteral("default"), element) : element.attribute(QStringLiteral("value"))) : value; } case ListValuesRole: return element.attribute(QStringLiteral("paramlist")).split(QLatin1Char(';')); case ListNamesRole: { QDomElement namesElem = element.firstChildElement(QStringLiteral("paramlistdisplay")); return i18n(namesElem.text().toUtf8().data()).split(QLatin1Char(',')); } } return QVariant(); } int AssetParameterModel::rowCount(const QModelIndex &parent) const { qDebug() << "===================================================== Requested rowCount" << parent << m_rows.size(); if (parent.isValid()) return 0; return m_rows.size(); } // static ParamType AssetParameterModel::paramTypeFromStr(const QString &type) { if (type == QLatin1String("double") || type == QLatin1String("float") || type == QLatin1String("constant")) { return ParamType::Double; } if (type == QLatin1String("list")) { return ParamType::List; } if (type == QLatin1String("bool")) { return ParamType::Bool; } if (type == QLatin1String("switch")) { return ParamType::Switch; } else if (type == QLatin1String("simplekeyframe")) { return ParamType::KeyframeParam; } else if (type == QLatin1String("animatedrect")) { return ParamType::AnimatedRect; } else if (type == QLatin1String("geometry")) { return ParamType::Geometry; } else if (type == QLatin1String("addedgeometry")) { return ParamType::Addedgeometry; } else if (type == QLatin1String("keyframe") || type == QLatin1String("animated")) { return ParamType::KeyframeParam; } else if (type == QLatin1String("color")) { return ParamType::Color; } else if (type == QLatin1String("colorwheel")) { return ParamType::ColorWheel; } else if (type == QLatin1String("position")) { return ParamType::Position; } else if (type == QLatin1String("curve")) { return ParamType::Curve; } else if (type == QLatin1String("bezier_spline")) { return ParamType::Bezier_spline; } else if (type == QLatin1String("roto-spline")) { return ParamType::Roto_spline; } else if (type == QLatin1String("wipe")) { return ParamType::Wipe; } else if (type == QLatin1String("url")) { return ParamType::Url; } else if (type == QLatin1String("keywords")) { return ParamType::Keywords; } else if (type == QLatin1String("fontfamily")) { return ParamType::Fontfamily; } else if (type == QLatin1String("filterjob")) { return ParamType::Filterjob; } else if (type == QLatin1String("readonly")) { return ParamType::Readonly; } qDebug() << "WARNING: Unknown type :" << type; return ParamType::Double; } // static QString AssetParameterModel::getDefaultKeyframes(int start, const QString &defaultValue, bool linearOnly) { QString keyframes = QString::number(start); if (linearOnly) { keyframes.append(QLatin1Char('=')); } else { switch (KdenliveSettings::defaultkeyframeinterp()) { case mlt_keyframe_discrete: keyframes.append(QStringLiteral("|=")); break; case mlt_keyframe_smooth: keyframes.append(QStringLiteral("~=")); break; default: keyframes.append(QLatin1Char('=')); break; } } keyframes.append(defaultValue); return keyframes; } // static QVariant AssetParameterModel::parseAttribute(const QString &attribute, const QDomElement &element, QVariant defaultValue) { if (!element.hasAttribute(attribute) && !defaultValue.isNull()) { return defaultValue; } ParamType type = paramTypeFromStr(element.attribute(QStringLiteral("type"))); QString content = element.attribute(attribute); if (content.contains(QLatin1Char('%'))) { std::unique_ptr &profile = pCore->getCurrentProfile(); int width = profile->width(); int height = profile->height(); // replace symbols in the double parameter content.replace(QLatin1String("%maxWidth"), QString::number(width)) .replace(QLatin1String("%maxHeight"), QString::number(height)) .replace(QLatin1String("%width"), QString::number(width)) .replace(QLatin1String("%height"), QString::number(height)); if (type == ParamType::Double) { // Use a Mlt::Properties to parse mathematical operators Mlt::Properties p; p.set("eval", content.toLatin1().constData()); return p.get_double("eval"); } } else if (type == ParamType::Double) { QLocale locale; locale.setNumberOptions(QLocale::OmitGroupSeparator); return locale.toDouble(content); } if (attribute == QLatin1String("default")) { if (type == ParamType::RestrictedAnim) { content = getDefaultKeyframes(0, content, true); } else { if (element.hasAttribute(QStringLiteral("factor"))) { QLocale locale; locale.setNumberOptions(QLocale::OmitGroupSeparator); return QVariant(locale.toDouble(content) / locale.toDouble(element.attribute(QStringLiteral("factor")))); } } } return content; } QString AssetParameterModel::getAssetId() const { return m_assetId; } QVector> AssetParameterModel::getAllParameters() const { QVector> res; res.reserve((int)m_fixedParams.size() + (int)m_params.size()); for (const auto &fixed : m_fixedParams) { res.push_back(QPair(fixed.first, fixed.second)); } for (const auto ¶m : m_params) { res.push_back(QPair(param.first, param.second.value)); } return res; } void AssetParameterModel::setParameters(const QVector> ¶ms) { for (const auto ¶m : params) { setParameter(param.first, param.second.toString()); } } ObjectId AssetParameterModel::getOwnerId() const { return m_ownerId; } void AssetParameterModel::addKeyframeParam(const QModelIndex index) { if (m_keyframes) { m_keyframes->addParameter(index); } else { m_keyframes.reset(new KeyframeModelList(shared_from_this(), index, pCore->undoStack())); } } std::shared_ptr AssetParameterModel::getKeyframeModel() { return m_keyframes; } void AssetParameterModel::resetAsset(Mlt::Properties *asset) { m_asset.reset(asset); } diff --git a/src/assets/model/assetparametermodel.hpp b/src/assets/model/assetparametermodel.hpp index 36c4332e6..6890cc362 100644 --- a/src/assets/model/assetparametermodel.hpp +++ b/src/assets/model/assetparametermodel.hpp @@ -1,178 +1,179 @@ /*************************************************************************** * Copyright (C) 2017 by Nicolas Carion * * This file is part of Kdenlive. See www.kdenlive.org. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) version 3 or any later version accepted by the * * membership of KDE e.V. (or its successor approved by the membership * * of KDE e.V.), which shall act as a proxy defined in Section 14 of * * version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifndef ASSETPARAMETERMODEL_H #define ASSETPARAMETERMODEL_H #include "definitions.h" #include "klocalizedstring.h" #include #include #include #include #include #include class KeyframeModelList; /* @brief This class is the model for a list of parameters. 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 using the relevant widgets. Note that internally parameters are not sorted in any ways, because some effects like sox need a precise order */ enum class ParamType { Double, List, Bool, Switch, RestrictedAnim, // animated 1 dimensional param with linear support only Animated, AnimatedRect, Geometry, Addedgeometry, KeyframeParam, Color, ColorWheel, Position, Curve, Bezier_spline, Roto_spline, Wipe, Url, Keywords, Fontfamily, Filterjob, Readonly }; Q_DECLARE_METATYPE(ParamType) class AssetParameterModel : public QAbstractListModel, public enable_shared_from_this_virtual { Q_OBJECT public: explicit AssetParameterModel(Mlt::Properties *asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId, QObject *parent = nullptr); virtual ~AssetParameterModel(); enum { NameRole = Qt::UserRole + 1, TypeRole, CommentRole, MinRole, MaxRole, DefaultRole, SuffixRole, DecimalsRole, ValueRole, AlphaRole, ListValuesRole, ListNamesRole, FactorRole, + FilterRole, ScaleRole, OpacityRole, InRole, OutRole, ParentInRole, ParentDurationRole }; /* @brief Returns the id of the asset represented by this object */ QString getAssetId() const; /* @brief Set the parameter with given name to the given value */ Q_INVOKABLE void setParameter(const QString &name, const QString &value, bool update = true); void setParameter(const QString &name, const int value, bool update = true); Q_INVOKABLE void setParameter(const QString &name, double &value); /* @brief Return all the parameters as pairs (parameter name, parameter value) */ QVector> getAllParameters() const; /* @brief Sets the value of a list of parameters @param params contains the pairs (parameter name, parameter value) */ void setParameters(const QVector> ¶ms); /* Which monitor is attached to this asset (clip/project) */ Kdenlive::MonitorId monitorId; QVariant data(const QModelIndex &index, int role) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; /* @brief Returns the id of the actual object associated with this asset */ ObjectId getOwnerId() const; /* @brief Returns the keyframe model associated with this asset Return empty ptr if there is no keyframable parameter in the asset or if prepareKeyframes was not called */ Q_INVOKABLE std::shared_ptr getKeyframeModel(); /* @brief Must be called before using the keyframes of this model */ void prepareKeyframes(); void resetAsset(Mlt::Properties *asset); protected: /* @brief Helper function to retrieve the type of a parameter given the string corresponding to it*/ static ParamType paramTypeFromStr(const QString &type); static QString getDefaultKeyframes(int start, const QString &defaultValue, bool linearOnly); /* @brief Helper function to get an attribute from a dom element, given its name. The function additionally parses following keywords: - %width and %height that are replaced with profile's height and width. If keywords are found, mathematical operations are supported for double type params. For example "%width -1" is a valid value. */ static QVariant parseAttribute(const QString &attribute, const QDomElement &element, QVariant defaultValue = QVariant()); /* @brief Helper function to register one more parameter that is keyframable. @param index is the index corresponding to this parameter */ void addKeyframeParam(const QModelIndex index); struct ParamRow { ParamType type; QDomElement xml; QVariant value; QString name; }; QDomElement m_xml; QString m_assetId; ObjectId m_ownerId; std::vector m_paramOrder; // Keep track of parameter order, important for sox std::unordered_map m_params; // Store all parameters by name std::unordered_map m_fixedParams; // We store values of fixed parameters aside QVector m_rows; // We store the params name in order of parsing. The order is important (cf some effects like sox) std::unique_ptr m_asset; std::shared_ptr m_keyframes; signals: void modelChanged(); void compositionTrackChanged(); void replugEffect(std::shared_ptr asset); void rebuildEffect(std::shared_ptr asset); }; #endif diff --git a/src/assets/view/widgets/abstractparamwidget.cpp b/src/assets/view/widgets/abstractparamwidget.cpp index a215d78cd..ed9dd0abf 100644 --- a/src/assets/view/widgets/abstractparamwidget.cpp +++ b/src/assets/view/widgets/abstractparamwidget.cpp @@ -1,130 +1,133 @@ /*************************************************************************** * Copyright (C) 2016 by Nicolas Carion * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #include "abstractparamwidget.hpp" #include "animationwidget.h" #include "assets/model/assetparametermodel.hpp" #include "boolparamwidget.hpp" #include "switchparamwidget.hpp" #include "lumaliftgainparam.hpp" #include "doubleparamwidget.hpp" #include "geometryeditwidget.hpp" #include "keyframeedit.h" #include "keyframewidget.hpp" #include "listparamwidget.h" #include "positioneditwidget.hpp" #include "coloreditwidget.hpp" #include "slidewidget.hpp" +#include "urlparamwidget.hpp" #include #include #include // temporary place holder for parameters that don't currently have a display class class Unsupported : public AbstractParamWidget { public: Unsupported(std::shared_ptr model, QModelIndex index, QWidget *parent) : AbstractParamWidget(std::move(model), index, parent) { auto *lay = new QVBoxLayout(this); lay->setContentsMargins(4, 0, 4, 0); m_label = new QLabel(this); lay->addWidget(m_label); } void setText(const QString &str) { m_label->setText(str); } void slotRefresh() override {} void slotSetRange(QPair) override {} protected: QLabel *m_label; }; AbstractParamWidget::AbstractParamWidget(std::shared_ptr model, QModelIndex index, QWidget *parent) : QWidget(parent) , m_model(std::move(model)) , m_index(index) { } AbstractParamWidget *AbstractParamWidget::construct(const std::shared_ptr &model, QModelIndex index, QPair range, QSize frameSize, QWidget *parent) { // We retrieve the parameter type auto type = model->data(index, AssetParameterModel::TypeRole).value(); QString name = model->data(index, AssetParameterModel::NameRole).toString(); AbstractParamWidget *widget; switch (type) { case ParamType::Double: widget = new DoubleParamWidget(model, index, parent); break; case ParamType::List: widget = new ListParamWidget(model, index, parent); break; case ParamType::Bool: widget = new BoolParamWidget(model, index, parent); break; case ParamType::KeyframeParam: case ParamType::AnimatedRect: widget = new KeyframeWidget(model, index, parent); break; case ParamType::Geometry: widget = new GeometryEditWidget(model, index, range, frameSize, parent); break; case ParamType::Position: widget = new PositionEditWidget(model, index, parent); break; case ParamType::Color: widget = new ColorEditWidget(model, index, parent); break; case ParamType::ColorWheel: widget = new LumaLiftGainParam(model, index, parent); break; case ParamType::Wipe: widget = new SlideWidget(model, index, parent); break; case ParamType::Switch: widget = new SwitchParamWidget(model, index, parent); break; + case ParamType::Url: + widget = new UrlParamWidget(model, index, parent); + break; case ParamType::Animated: case ParamType::RestrictedAnim: // widget = new AnimationWidget(model, index, range, parent); // break; // case ParamType::KeyframeParam: // widget = new KeyframeEdit(model, index, parent); // break; case ParamType::Addedgeometry: case ParamType::Curve: case ParamType::Bezier_spline: case ParamType::Roto_spline: - case ParamType::Url: case ParamType::Keywords: case ParamType::Fontfamily: case ParamType::Filterjob: case ParamType::Readonly: // not reimplemented widget = new Unsupported(model, index, parent); static_cast(widget)->setText(name); } return widget; } diff --git a/src/assets/view/widgets/urlparamwidget.cpp b/src/assets/view/widgets/urlparamwidget.cpp new file mode 100644 index 000000000..a1bdf6a6a --- /dev/null +++ b/src/assets/view/widgets/urlparamwidget.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2018 by Jean-Baptiste Mardelle * + * This file is part of Kdenlive. See www.kdenlive.org. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3 or any later version accepted by the * + * membership of KDE e.V. (or its successor approved by the membership * + * of KDE e.V.), which shall act as a proxy defined in Section 14 of * + * version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "urlparamwidget.hpp" +#include "assets/model/assetparametermodel.hpp" + +#include + +UrlParamWidget::UrlParamWidget(std::shared_ptr model, QModelIndex index, QWidget *parent) + : AbstractParamWidget(std::move(model), index, parent) +{ + setupUi(this); + + // setup the comment + QString name = m_model->data(m_index, AssetParameterModel::NameRole).toString(); + QString comment = m_model->data(m_index, AssetParameterModel::CommentRole).toString(); + labelComment->setText(comment); + setToolTip(comment); + labelComment->setHidden(true); + QString filter = m_model->data(m_index, AssetParameterModel::FilterRole).toString(); + if (!filter.isEmpty()) { + urlwidget->setFilter(filter); + } + slotRefresh(); + + // setup the name + label->setText(m_model->data(m_index, Qt::DisplayRole).toString()); + + // set check state + slotRefresh(); + + // emit the signal of the base class when appropriate + connect(this->urlwidget, &KUrlRequester::urlSelected, [this](QUrl url) { + emit valueChanged(m_index, url.toLocalFile(), true); }); +} + +void UrlParamWidget::slotShowComment(bool show) +{ + if (!labelComment->text().isEmpty()) { + labelComment->setVisible(show); + } +} + +void UrlParamWidget::slotRefresh() +{ + urlwidget->setUrl(QUrl::fromLocalFile(m_model->data(m_index, AssetParameterModel::ValueRole).toString())); +} + +void UrlParamWidget::slotSetRange(QPair) +{ +} diff --git a/src/assets/view/widgets/urlparamwidget.hpp b/src/assets/view/widgets/urlparamwidget.hpp new file mode 100644 index 000000000..0187e8785 --- /dev/null +++ b/src/assets/view/widgets/urlparamwidget.hpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2018 by Jean-Baptiste Mardelle * + * This file is part of Kdenlive. See www.kdenlive.org. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3 or any later version accepted by the * + * membership of KDE e.V. (or its successor approved by the membership * + * of KDE e.V.), which shall act as a proxy defined in Section 14 of * + * version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef URLPARAMWIDGET_H +#define URLPARAMWIDGET_H + +#include "abstractparamwidget.hpp" +#include "ui_urlval_ui.h" +#include + +/** @brief This class represents a parameter that requires + the user to choose tick a checkbox + */ +class UrlParamWidget : public AbstractParamWidget, public Ui::Urlval_UI +{ + Q_OBJECT +public: + /** @brief Constructor for the widgetComment + @param name String containing the name of the parameter + @param comment Optional string containing the comment associated to the parameter + @param checked Boolean indicating wether the checkbox should initially be checked + @param parent Parent widget + */ + UrlParamWidget(std::shared_ptr model, QModelIndex index, QWidget *parent); + +public slots: + /** @brief Toggle the comments on or off + */ + void slotShowComment(bool show) override; + + /** @brief refresh the properties to reflect changes in the model + */ + void slotRefresh() override; + + /** @brief update the clip's in/out point + */ + void slotSetRange(QPair) override; +}; + +#endif diff --git a/src/ui/urlval_ui.ui b/src/ui/urlval_ui.ui index 625f4bc59..29e0e287c 100644 --- a/src/ui/urlval_ui.ui +++ b/src/ui/urlval_ui.ui @@ -1,95 +1,90 @@ Urlval_UI 0 0 159 - 23 + 60 - - - 0 - - - 0 - - - - - - - - 1 - 0 - - - - TextLabel - - - - - - - - 1 - 0 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 15 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - Qt::RichText - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 1 + 0 + + + + TextLabel + - + + + + + + 1 + 0 + + + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + -1 + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + KUrlRequester QFrame
kurlrequester.h
+ 1