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 &param : 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 }