File indexing completed on 2024-05-12 04:52:51
0001 /* 0002 SPDX-FileCopyrightText: 2019 Jean-Baptiste Mardelle 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #include "buttonparamwidget.hpp" 0007 #include "assets/model/assetcommand.hpp" 0008 #include "assets/model/assetparametermodel.hpp" 0009 #include "core.h" 0010 #include "jobs/filtertask.h" 0011 #include <mlt++/Mlt.h> 0012 0013 #include <QProgressBar> 0014 #include <QPushButton> 0015 #include <QVBoxLayout> 0016 0017 ButtonParamWidget::ButtonParamWidget(std::shared_ptr<AssetParameterModel> model, QModelIndex index, QWidget *parent) 0018 : AbstractParamWidget(std::move(model), index, parent) 0019 , m_animated(false) 0020 { 0021 // setup the comment 0022 m_buttonName = m_model->data(m_index, Qt::DisplayRole).toString(); 0023 m_alternatebuttonName = m_model->data(m_index, AssetParameterModel::AlternateNameRole).toString(); 0024 // QString name = m_model->data(m_index, AssetParameterModel::NameRole).toString(); 0025 QString comment = m_model->data(m_index, AssetParameterModel::CommentRole).toString(); 0026 setToolTip(comment); 0027 // setEnabled(m_model->getOwnerId().first != KdenliveObjectType::TimelineTrack); 0028 auto *layout = new QVBoxLayout(this); 0029 QVariantList filterData = m_model->data(m_index, AssetParameterModel::FilterJobParamsRole).toList(); 0030 QStringList filterAddedParams = m_model->data(m_index, AssetParameterModel::FilterParamsRole).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts); 0031 QStringList consumerParams = m_model->data(m_index, AssetParameterModel::FilterConsumerParamsRole).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts); 0032 QString defaultValue; 0033 for (const QVariant &jobElement : qAsConst(filterData)) { 0034 QStringList d = jobElement.toStringList(); 0035 if (d.size() == 2) { 0036 if (d.at(0) == QLatin1String("conditionalinfo")) { 0037 m_conditionalText = d.at(1); 0038 } else if (d.at(0) == QLatin1String("key")) { 0039 m_keyParam = d.at(1); 0040 } else if (d.at(0) == QLatin1String("keydefault")) { 0041 defaultValue = d.at(1); 0042 } else if (d.at(0) == QLatin1String("animated")) { 0043 m_animated = true; 0044 } 0045 } 0046 } 0047 const QString paramValue = m_model->getParamFromName(m_keyParam).toString(); 0048 bool valueIsNotSet = paramValue.isEmpty() || (m_animated && !paramValue.contains(QLatin1Char(';'))); 0049 m_displayConditional = valueIsNotSet; 0050 0051 if (m_displayConditional && !m_conditionalText.isEmpty()) { 0052 setToolTip(m_conditionalText); 0053 } 0054 layout->setContentsMargins(0, 0, 0, 0); 0055 layout->setSpacing(0); 0056 m_button = new QPushButton(m_displayConditional ? m_buttonName : m_alternatebuttonName, this); 0057 layout->addWidget(m_button); 0058 m_progress = new QProgressBar(this); 0059 m_progress->setMaximumHeight(m_button->height() / 5); 0060 m_progress->setTextVisible(false); 0061 m_progress->setStyleSheet(QString("QProgressBar::chunk {background-color: %1;}").arg(m_progress->palette().highlight().color().name())); 0062 layout->addWidget(m_progress); 0063 m_progress->setVisible(false); 0064 setMinimumHeight(m_button->sizeHint().height()); 0065 0066 // Q_EMIT the signal of the base class when appropriate 0067 connect(this->m_button, &QPushButton::clicked, this, [&, filterData, filterAddedParams, consumerParams, defaultValue]() { 0068 // Trigger job 0069 bool isTracker = m_model->getAssetId() == QLatin1String("opencv.tracker"); 0070 if (!m_displayConditional) { 0071 QVector<QPair<QString, QVariant>> values; 0072 if (isTracker) { 0073 // Tracker needs some special config on reset 0074 QString current = m_model->getAsset()->get(m_keyParam.toUtf8().constData()); 0075 if (!current.isEmpty()) { 0076 // Only keep first keyframe 0077 current = current.section(QLatin1Char(';'), 0, 0); 0078 } 0079 if (current.isEmpty()) { 0080 if (defaultValue.contains(QLatin1Char('%'))) { 0081 QSize pSize = pCore->getCurrentFrameDisplaySize(); 0082 QStringList numbers = defaultValue.split(QLatin1Char(' ')); 0083 int ix = 0; 0084 for (QString &val : numbers) { 0085 if (val.endsWith(QLatin1Char('%'))) { 0086 val.chop(1); 0087 double n = val.toDouble() / 100.; 0088 if (ix % 2 == 0) { 0089 n *= pSize.width(); 0090 } else { 0091 n *= pSize.height(); 0092 } 0093 ix++; 0094 current.append(QString("%1 ").arg(qRound(n))); 0095 } else { 0096 current.append(QString("%1 ").arg(val)); 0097 } 0098 } 0099 } else { 0100 current = defaultValue; 0101 } 0102 } 0103 // values << QPair<QString, QVariant>(QString("rect"),current); 0104 // values << QPair<QString, QVariant>(QString("_reset"),1); 0105 values << QPair<QString, QVariant>(m_keyParam, current); 0106 } else { 0107 0108 values << QPair<QString, QVariant>(m_keyParam, defaultValue); 0109 } 0110 m_model->setParametersFromTask(values); 0111 return; 0112 } 0113 QVector<QPair<QString, QVariant>> filterLastParams = m_model->getAllParameters(); 0114 ObjectId owner = m_model->getOwnerId(); 0115 const QString assetId = m_model->getAssetId(); 0116 QString binId; 0117 int cid = -1; 0118 int in = -1; 0119 int out = -1; 0120 if (owner.type == KdenliveObjectType::BinClip) { 0121 binId = QString::number(owner.itemId); 0122 } else if (owner.type == KdenliveObjectType::TimelineClip) { 0123 cid = owner.itemId; 0124 binId = pCore->getTimelineClipBinId(cid); 0125 in = pCore->getItemIn(owner); 0126 out = in + pCore->getItemDuration(owner); 0127 } else if (owner.type == KdenliveObjectType::TimelineTrack || owner.type == KdenliveObjectType::Master) { 0128 in = 0; 0129 out = pCore->getItemDuration(owner); 0130 binId = QStringLiteral("-1"); 0131 } 0132 std::unordered_map<QString, QVariant> fParams; 0133 std::unordered_map<QString, QString> fData; 0134 for (const QVariant &jobElement : filterData) { 0135 QStringList d = jobElement.toStringList(); 0136 if (d.size() == 2) fData.insert({d.at(0), d.at(1)}); 0137 } 0138 for (const auto ¶m : qAsConst(filterLastParams)) { 0139 if (param.first != m_keyParam) { 0140 if (!isTracker || param.first != QLatin1String("rect")) { 0141 fParams.insert({param.first, param.second}); 0142 } 0143 } else if (isTracker) { 0144 QString initialRect = param.second.toString(); 0145 if (initialRect.contains(QLatin1Char('='))) { 0146 initialRect = initialRect.section(QLatin1Char('='), 1); 0147 } 0148 if (initialRect.contains(QLatin1Char(';'))) { 0149 initialRect = initialRect.section(QLatin1Char(';'), 0, 0); 0150 } 0151 fParams.insert({QStringLiteral("rect"), initialRect}); 0152 } 0153 } 0154 for (const QString &fparam : filterAddedParams) { 0155 if (fparam.contains(QLatin1Char('='))) { 0156 fParams.insert({fparam.section(QLatin1Char('='), 0, 0), fparam.section(QLatin1Char('='), 1)}); 0157 } 0158 } 0159 if (m_progress->value() > 0 && m_progress->value() < 100) { 0160 // The task is in progress, abort it 0161 pCore->taskManager.discardJobs(owner, AbstractTask::FILTERCLIPJOB); 0162 setToolTip(m_conditionalText); 0163 } else { 0164 FilterTask::start(owner, binId, m_model, assetId, in, out, assetId, fParams, fData, consumerParams, this); 0165 setToolTip(QString()); 0166 m_button->setEnabled(false); 0167 } 0168 }); 0169 } 0170 0171 void ButtonParamWidget::slotShowComment(bool show) 0172 { 0173 Q_UNUSED(show); 0174 // if (!m_labelComment->text().isEmpty()) { 0175 // m_widgetComment->setVisible(show); 0176 //} 0177 } 0178 0179 void ButtonParamWidget::slotRefresh() 0180 { 0181 const QString paramValue = m_model->getParamFromName(m_keyParam).toString(); 0182 bool valueIsNotSet = paramValue.isEmpty() || (m_animated && !paramValue.contains(QLatin1Char(';'))); 0183 m_displayConditional = valueIsNotSet; 0184 m_button->setEnabled(true); 0185 // Check running job percentage 0186 int progress = m_model->data(m_index, AssetParameterModel::FilterProgressRole).toInt(); 0187 if (progress > 0 && progress < 100) { 0188 m_progress->setValue(progress); 0189 if (!m_progress->isVisible()) { 0190 m_button->setText(i18n("Abort processing")); 0191 m_progress->setVisible(true); 0192 } 0193 0194 } else { 0195 m_button->setText(m_displayConditional ? m_buttonName : m_alternatebuttonName); 0196 m_progress->setValue(0); 0197 m_progress->setVisible(false); 0198 if (m_displayConditional) { 0199 setToolTip(m_conditionalText); 0200 } 0201 } 0202 } 0203 0204 bool ButtonParamWidget::getValue() 0205 { 0206 return true; 0207 }