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
+ 1