Fix effects with action button (auto mask). Fixes #21

Fix motion tracker (requires OpenCV and MLT explicitely compiled with --enable-opencv)
Fix sox/ladspa effects disappearing after changing param
Fix copy/import keyframes from keyboard
parent 5c4dbf15
......@@ -27,12 +27,12 @@
<parameter type="bool" name="obscure" default="1">
<name>Obscure</name>
</parameter>
<parameter type="filterjob" filtertag="autotrack_rectangle" filterparams="_serialize=1 motion_vector_list=0 %params in=%position" consumer="null" consumerparams="all=1 terminate_on_pause=1">
<parameter type="filterjob" filtertag="autotrack_rectangle" filterparams="_serialize=1 motion_vector_list=0" consumer="null" consumerparams="all=1 terminate_on_pause=1">
<name>Analyse</name>
<jobparam name="storedata" />
<jobparam name="projecttreefilter" />
<jobparam name="key">motion_vector_list</jobparam>
<jobparam name="finalfilter">autotrack_rectangle</jobparam>
<jobparam name="displaydataname">Motion vectors</jobparam>
<name>Analyse</name>
</parameter>
</effect>
......@@ -7,8 +7,8 @@
<name>Target Program Loudness</name>
</parameter>
<parameter type="filterjob" filtertag="loudness" filterparams="%params" consumer="null" consumerparams="video_off=1 all=1 terminate_on_pause=1">
<name>Analyse</name>
<jobparam name="key">results</jobparam>
<jobparam name="finalfilter">loudness</jobparam>
<name>Analyse</name>
</parameter>
</effect>
......@@ -7,8 +7,8 @@
<name>Gain</name>
</parameter>
<parameter type="filterjob" filtertag="sox:analysis" filterparams="" consumer="null" consumerparams="video_off=1 all=1 terminate_on_pause=1">
<name>Normalize</name>
<jobparam name="key">gain</jobparam>
<jobparam name="finalfilter">sox_gain</jobparam>
<name>Normalize</name>
</parameter>
</effect>
......@@ -29,12 +29,13 @@
</parameter>
<parameter type="readonly" name="results" value="">
<name>Tracking data</name>
<comment>Click to copy to clipboard</comment>
</parameter>
<conditionalinfo>Filter is in preview mode. Click Analyse to see real effect</conditionalinfo>
<parameter type="filterjob" filtertag="opencv.tracker" filterparams="%params" consumer="null" consumerparams=" all=1 terminate_on_pause=1">
<parameter type="filterjob" filtertag="opencv.tracker" consumer="null" consumerparams=" all=1 terminate_on_pause=1">
<name conditional="Reset">Analyse</name>
<jobparam name="conditionalinfo">Filter is in preview mode. Click Analyse to see real effect</jobparam>
<jobparam name="key">results</jobparam>
<jobparam name="finalfilter">opencv.tracker</jobparam>
<jobparam name="displaydataname">Motion tracking</jobparam>
<name conditional="Reset">Analyse</name>
<jobparam name="displaydataname">Motion tracking</jobparam>
</parameter>
</effect>
......@@ -18,6 +18,7 @@ set(kdenlive_SRCS
assets/view/widgets/abstractparamwidget.cpp
# assets/view/widgets/animationwidget.cpp
assets/view/widgets/boolparamwidget.cpp
assets/view/widgets/buttonparamwidget.cpp
assets/view/widgets/switchparamwidget.cpp
assets/view/widgets/urlparamwidget.cpp
assets/view/widgets/doubleparamwidget.cpp
......@@ -31,6 +32,7 @@ set(kdenlive_SRCS
assets/view/widgets/positioneditwidget.cpp
assets/view/widgets/coloreditwidget.cpp
assets/view/widgets/hideparamwidget.cpp
assets/view/widgets/clickablelabelwidget.cpp
# curves widget
assets/view/widgets/curves/abstractcurvewidget.h
assets/view/widgets/curves/bezier/beziersplineeditor.cpp
......
......@@ -1146,12 +1146,13 @@ QList<QPoint> KeyframeModel::getRanges(const QString &animData, const std::share
return result;
}
std::shared_ptr<Mlt::Properties> KeyframeModel::getAnimation(const QString &animData)
std::shared_ptr<Mlt::Properties> KeyframeModel::getAnimation(std::shared_ptr<AssetParameterModel> model, const QString &animData, int duration)
{
std::shared_ptr<Mlt::Properties> mlt_prop(new Mlt::Properties());
model->passProperties(*mlt_prop.get());
mlt_prop->set("key", animData.toUtf8().constData());
// This is a fake query to force the animation to be parsed
(void)mlt_prop->anim_get_rect("key", 0, 0);
(void)mlt_prop->anim_get_rect("key", 0, duration);
return mlt_prop;
}
......
......@@ -62,6 +62,7 @@ public:
enum { TypeRole = Qt::UserRole + 1, PosRole, FrameRole, ValueRole, NormalizedValueRole };
friend class KeyframeModelList;
friend class KeyframeWidget;
friend class KeyframeImport;
protected:
/** @brief These methods should ONLY be called by keyframemodellist to ensure synchronisation
......@@ -164,7 +165,7 @@ public:
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
static QList<QPoint> getRanges(const QString &animData, const std::shared_ptr<AssetParameterModel> &model);
static std::shared_ptr<Mlt::Properties> getAnimation(const QString &animData);
static std::shared_ptr<Mlt::Properties> getAnimation(std::shared_ptr<AssetParameterModel> model, const QString &animData, int duration = 0);
protected:
/** @brief Helper function that generate a lambda to change type / value of given keyframe */
......
......@@ -345,7 +345,7 @@ KeyframeModel *KeyframeModelList::getKeyModel()
KeyframeModel *KeyframeModelList::getKeyModel(const QPersistentModelIndex &index)
{
if (m_parameters.size() > 0) {
if (m_parameters.size() > 0 && m_parameters.find(index) != m_parameters.end()) {
return m_parameters.at(index).get();
}
return nullptr;
......
......@@ -103,7 +103,7 @@ AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset,
}
}
if (!name.isEmpty()) {
setParameter(name, value, false);
internalSetParameter(name, value);
// Keep track of param order
m_paramOrder.push_back(name);
}
......@@ -151,23 +151,22 @@ void AssetParameterModel::setParameter(const QString &name, int value, bool upda
} 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();
emit dataChanged(index(0, 0), index(m_rows.count() - 1, 0), {});
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());
}
if (update) {
emit modelChanged();
emit dataChanged(index(0, 0), index(m_rows.count() - 1, 0), {});
// Update fades in timeline
pCore->updateItemModel(m_ownerId, m_assetId);
// Trigger monitor refresh
......@@ -177,12 +176,11 @@ void AssetParameterModel::setParameter(const QString &name, int value, bool upda
}
}
void AssetParameterModel::setParameter(const QString &name, const QString &paramValue, bool update, const QModelIndex &paramIndex)
void AssetParameterModel::internalSetParameter(const QString &name, const QString &paramValue, const QModelIndex &paramIndex)
{
Q_ASSERT(m_asset->is_valid());
QLocale locale;
locale.setNumberOptions(QLocale::OmitGroupSeparator);
qDebug() << "// PROCESSING PARAM CHANGE: " << name << ", UPDATE: " << update << ", VAL: " << paramValue;
// TODO: this does not really belong here, but I don't see another way to do it so that undo works
if (data(paramIndex, AssetParameterModel::TypeRole).value<ParamType>() == ParamType::Curve) {
QStringList vals = paramValue.split(QLatin1Char(';'), QString::SkipEmptyParts);
......@@ -212,75 +210,62 @@ void AssetParameterModel::setParameter(const QString &name, const QString &param
qDebug() << " = = SET EFFECT PARAM: " << name << " = " << paramValue;
if (m_fixedParams.count(name) == 0) {
m_params[name].value = paramValue;
} else {
m_fixedParams[name] = paramValue;
}
}
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());
if (m_keyframes) {
KeyframeModel *km = m_keyframes->getKeyModel(paramIndex);
if (km) {
km->refresh();
}
//m_keyframes->refresh();
}
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 {
qDebug() << "// SENDING DATA CHANGE....";
if (paramIndex.isValid()) {
emit dataChanged(paramIndex, paramIndex);
} else {
QModelIndex ix = index(m_rows.indexOf(name), 0);
emit dataChanged(ix, ix);
}
emit modelChanged();
m_fixedParams[name] = paramValue;
}
}
emit updateChildren(name);
// Update timeline view if necessary
if (m_ownerId.first == ObjectType::NoItem) {
// Used for generator clips
if (!update) emit modelChanged();
} else {
// Update fades in timeline
pCore->updateItemModel(m_ownerId, m_assetId);
// Trigger monitor refresh
pCore->refreshProjectItem(m_ownerId);
// Invalidate timeline preview
pCore->invalidateItem(m_ownerId);
}
}
void AssetParameterModel::setParameter(const QString &name, double &value)
void AssetParameterModel::setParameter(const QString &name, const QString &paramValue, bool update, const QModelIndex &paramIndex)
{
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;
}
//qDebug() << "// PROCESSING PARAM CHANGE: " << name << ", UPDATE: " << update << ", VAL: " << paramValue;
internalSetParameter(name, paramValue, paramIndex);
bool updateChildRequired = true;
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());
updateChildRequired = false;
} 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 {
updateChildRequired = false;
} else if (update) {
qDebug() << "// SENDING DATA CHANGE....";
if (paramIndex.isValid()) {
emit dataChanged(paramIndex, paramIndex);
} else {
QModelIndex ix = index(m_rows.indexOf(name), 0);
emit dataChanged(ix, ix);
}
emit modelChanged();
}
pCore->refreshProjectItem(m_ownerId);
pCore->invalidateItem(m_ownerId);
if (updateChildRequired) {
emit updateChildren(name);
}
// Update timeline view if necessary
if (m_ownerId.first == ObjectType::NoItem) {
// Used for generator clips
if (!update) emit modelChanged();
} else {
// Update fades in timeline
pCore->updateItemModel(m_ownerId, m_assetId);
// Trigger monitor refresh
pCore->refreshProjectItem(m_ownerId);
// Invalidate timeline preview
pCore->invalidateItem(m_ownerId);
}
}
AssetParameterModel::~AssetParameterModel() = default;
......@@ -335,6 +320,17 @@ QVariant AssetParameterModel::data(const QModelIndex &index, int role) const
return parseAttribute(m_ownerId, QStringLiteral("default"), element);
case FilterRole:
return parseAttribute(m_ownerId, QStringLiteral("filter"), element);
case FilterParamsRole:
return parseAttribute(m_ownerId, QStringLiteral("filterparams"), element);
case FilterJobParamsRole:
return parseSubAttributes(QStringLiteral("jobparam"), element);
case AlternateNameRole: {
QDomNode child = element.firstChildElement(QStringLiteral("name"));
if (child.toElement().hasAttribute(QStringLiteral("conditional"))) {
return child.toElement().attribute(QStringLiteral("conditional"));
}
return m_params.at(paramName).name;
}
case SuffixRole:
return element.attribute(QStringLiteral("suffix"));
case OpacityRole:
......@@ -534,6 +530,21 @@ QVariant AssetParameterModel::parseAttribute(const ObjectId &owner, const QStrin
return content;
}
QVariant AssetParameterModel::parseSubAttributes(const QString &attribute, const QDomElement &element) const
{
QDomNodeList nodeList = element.elementsByTagName(attribute);
if (nodeList.isEmpty()) {
return QVariant();
}
QVariantList jobDataList;
for (int i = 0; i < nodeList.count(); ++i) {
QDomElement currentParameter = nodeList.item(i).toElement();
QStringList jobData {currentParameter.attribute(QStringLiteral("name")), currentParameter.text()};
jobDataList << jobData;
}
return jobDataList;
}
QString AssetParameterModel::getAssetId() const
{
return m_assetId;
......@@ -553,30 +564,39 @@ QVector<QPair<QString, QVariant>> AssetParameterModel::getAllParameters() const
return res;
}
QJsonDocument AssetParameterModel::toJson() const
QJsonDocument AssetParameterModel::toJson(bool includeFixed) const
{
QJsonArray list;
QLocale locale;
for (const auto &fixed : m_fixedParams) {
QJsonObject currentParam;
QModelIndex ix = index(m_rows.indexOf(fixed.first), 0);
currentParam.insert(QLatin1String("name"), QJsonValue(fixed.first));
currentParam.insert(QLatin1String("value"), fixed.second.toString());
int type = data(ix, AssetParameterModel::TypeRole).toInt();
double min = data(ix, AssetParameterModel::MinRole).toDouble();
double max = data(ix, AssetParameterModel::MaxRole).toDouble();
double factor = data(ix, AssetParameterModel::FactorRole).toDouble();
if (factor > 0) {
min /= factor;
max /= factor;
if (includeFixed) {
for (const auto &fixed : m_fixedParams) {
QJsonObject currentParam;
QModelIndex ix = index(m_rows.indexOf(fixed.first), 0);
currentParam.insert(QLatin1String("name"), QJsonValue(fixed.first));
currentParam.insert(QLatin1String("value"), fixed.second.toString());
int type = data(ix, AssetParameterModel::TypeRole).toInt();
double min = data(ix, AssetParameterModel::MinRole).toDouble();
double max = data(ix, AssetParameterModel::MaxRole).toDouble();
double factor = data(ix, AssetParameterModel::FactorRole).toDouble();
int in = data(ix, AssetParameterModel::ParentInRole).toInt();
int out = in + data(ix, AssetParameterModel::ParentDurationRole).toInt();
if (factor > 0) {
min /= factor;
max /= factor;
}
currentParam.insert(QLatin1String("type"), QJsonValue(type));
currentParam.insert(QLatin1String("min"), QJsonValue(min));
currentParam.insert(QLatin1String("max"), QJsonValue(max));
currentParam.insert(QLatin1String("in"), QJsonValue(in));
currentParam.insert(QLatin1String("out"), QJsonValue(out));
list.push_back(currentParam);
}
currentParam.insert(QLatin1String("type"), QJsonValue(type));
currentParam.insert(QLatin1String("min"), QJsonValue(min));
currentParam.insert(QLatin1String("max"), QJsonValue(max));
list.push_back(currentParam);
}
for (const auto &param : m_params) {
if (!includeFixed && param.second.type != ParamType::KeyframeParam && param.second.type != ParamType::AnimatedRect) {
continue;
}
QJsonObject currentParam;
QModelIndex ix = index(m_rows.indexOf(param.first), 0);
currentParam.insert(QLatin1String("name"), QJsonValue(param.first));
......@@ -585,6 +605,8 @@ QJsonDocument AssetParameterModel::toJson() const
double min = data(ix, AssetParameterModel::MinRole).toDouble();
double max = data(ix, AssetParameterModel::MaxRole).toDouble();
double factor = data(ix, AssetParameterModel::FactorRole).toDouble();
int in = data(ix, AssetParameterModel::ParentInRole).toInt();
int out = in + data(ix, AssetParameterModel::ParentDurationRole).toInt();
if (factor > 0) {
min /= factor;
max /= factor;
......@@ -592,6 +614,8 @@ QJsonDocument AssetParameterModel::toJson() const
currentParam.insert(QLatin1String("type"), QJsonValue(type));
currentParam.insert(QLatin1String("min"), QJsonValue(min));
currentParam.insert(QLatin1String("max"), QJsonValue(max));
currentParam.insert(QLatin1String("in"), QJsonValue(in));
currentParam.insert(QLatin1String("out"), QJsonValue(out));
list.push_back(currentParam);
}
return QJsonDocument(list);
......@@ -763,7 +787,6 @@ void AssetParameterModel::setParameters(const QVector<QPair<QString, QVariant>>
if (m_keyframes) {
m_keyframes->refresh();
}
// emit modelChanged();
emit dataChanged(index(0), index(m_rows.count()), {});
}
......
......@@ -79,6 +79,7 @@ public:
NameRole = Qt::UserRole + 1,
TypeRole,
CommentRole,
AlternateNameRole,
MinRole,
MaxRole,
DefaultRole,
......@@ -90,6 +91,8 @@ public:
ListNamesRole,
FactorRole,
FilterRole,
FilterJobParamsRole,
FilterParamsRole,
ScaleRole,
OpacityRole,
RelativePosRole,
......@@ -128,12 +131,11 @@ public:
*/
Q_INVOKABLE void setParameter(const QString &name, const QString &paramValue, bool update = true, const QModelIndex &paramIndex = QModelIndex());
void setParameter(const QString &name, 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<QPair<QString, QVariant>> getAllParameters() const;
/* @brief Returns a json definition of the effect with all param values */
QJsonDocument toJson() const;
QJsonDocument toJson(bool includeFixed = true) const;
void savePreset(const QString &presetFile, const QString &presetName);
void deletePreset(const QString &presetFile, const QString &presetName);
const QStringList getPresetList(const QString &presetFile) const;
......@@ -179,6 +181,7 @@ protected:
If keywords are found, mathematical operations are supported for double type params. For example "%width -1" is a valid value.
*/
static QVariant parseAttribute(const ObjectId &owner, const QString &attribute, const QDomElement &element, QVariant defaultValue = QVariant());
QVariant parseSubAttributes(const QString &attribute, const QDomElement &element) const;
/* @brief Helper function to register one more parameter that is keyframable.
@param index is the index corresponding to this parameter
......@@ -206,6 +209,11 @@ protected:
// if true, keyframe tools will be hidden by default
bool m_hideKeyframesByDefault;
/* @brief Set the parameter with given name to the given value. This should be called when first
* building an effect in the constructor, so that we don't call shared_from_this
*/
void internalSetParameter(const QString &name, const QString &paramValue, const QModelIndex &paramIndex = QModelIndex());
signals:
void modelChanged();
/** @brief inform child effects (in case of bin effect with timeline producers)
......
......@@ -19,6 +19,7 @@
#include "abstractparamwidget.hpp"
#include "assets/model/assetparametermodel.hpp"
#include "buttonparamwidget.hpp"
#include "boolparamwidget.hpp"
#include "coloreditwidget.hpp"
#include "curves/bezier/beziersplineeditor.h"
......@@ -26,6 +27,7 @@
#include "curves/cubic/kis_curve_widget.h"
#include "curves/curveparamwidget.h"
#include "doubleparamwidget.hpp"
#include "clickablelabelwidget.hpp"
#include "geometryeditwidget.hpp"
#include "hideparamwidget.hpp"
#include "keyframewidget.hpp"
......@@ -125,6 +127,14 @@ AbstractParamWidget *AbstractParamWidget::construct(const std::shared_ptr<AssetP
widget = new HideParamWidget(model, index, parent);
break;
}
case ParamType::Filterjob: {
widget = new ButtonParamWidget(model, index, parent);
break;
}
case ParamType::Readonly: {
widget = new ClickableLabelParamWidget(model, index, parent);
break;
}
case ParamType::Animated:
case ParamType::RestrictedAnim:
// widget = new AnimationWidget(model, index, range, parent);
......@@ -135,8 +145,6 @@ AbstractParamWidget *AbstractParamWidget::construct(const std::shared_ptr<AssetP
case ParamType::Addedgeometry:
case ParamType::Keywords:
case ParamType::Fontfamily:
case ParamType::Filterjob:
case ParamType::Readonly:
// not reimplemented
widget = new Unsupported(model, index, parent);
static_cast<Unsupported *>(widget)->setText(name);
......
/***************************************************************************
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "buttonparamwidget.hpp"
#include "assets/model/assetparametermodel.hpp"
#include "jobs/filterclipjob.h"
#include "jobs/jobmanager.h"
#include "assets/model/assetcommand.hpp"
#include "core.h"
#include <mlt++/Mlt.h>
#include <KMessageWidget>
#include <QPushButton>
#include <QHBoxLayout>
ButtonParamWidget::ButtonParamWidget(std::shared_ptr<AssetParameterModel> model, QModelIndex index, QWidget *parent)
: AbstractParamWidget(std::move(model), index, parent)
, m_label(nullptr)
{
// setup the comment
m_buttonName = m_model->data(m_index, Qt::DisplayRole).toString();
m_alternatebuttonName = m_model->data(m_index, AssetParameterModel::AlternateNameRole).toString();
//QString name = m_model->data(m_index, AssetParameterModel::NameRole).toString();
QString comment = m_model->data(m_index, AssetParameterModel::CommentRole).toString();
setToolTip(comment);
auto *layout = new QVBoxLayout(this);
QVariantList filterData = m_model->data(m_index, AssetParameterModel::FilterJobParamsRole).toList();
QStringList filterAddedParams = m_model->data(m_index, AssetParameterModel::FilterParamsRole).toString().split(QLatin1Char(' '), QString::SkipEmptyParts);
QString conditionalInfo;
for (const QVariant jobElement : filterData) {
QStringList d = jobElement.toStringList();
if (d.size() == 2) {
if (d.at(0) == QLatin1String("conditionalinfo")) {
conditionalInfo = d.at(1);
} else if (d.at(0) == QLatin1String("key")) {
m_keyParam = d.at(1);
}
}
}
QVector<QPair<QString, QVariant>> filterParams = m_model->getAllParameters();
m_displayConditional = true;
for (const auto &param : filterParams) {
if (param.first == m_keyParam) {
if (!param.second.toString().isEmpty()) {
m_displayConditional = false;
}
break;
}
}
if (!conditionalInfo.isEmpty()) {
m_label = new KMessageWidget(conditionalInfo, this);
m_label->setWordWrap(true);
layout->addWidget(m_label);
m_label->setVisible(m_displayConditional);
}
//layout->setContentsMargins(0, 0, 0, 2);
//layout->setSpacing(0);
m_button = new QPushButton(m_displayConditional ? m_buttonName : m_alternatebuttonName, this);
layout->addWidget(m_button);
// emit the signal of the base class when appropriate
connect(this->m_button, &QPushButton::clicked, [&, filterData, filterAddedParams]() {
// Trigger job
if (!m_displayConditional) {
QVector<QPair<QString, QVariant>> values;
values << QPair<QString, QVariant>(m_keyParam,QVariant());