File indexing completed on 2024-04-28 04:51:51

0001 /*
0002     SPDX-FileCopyrightText: 2017 Nicolas Carion
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "effectlistwidget.hpp"
0007 #include "../model/effectfilter.hpp"
0008 #include "../model/effecttreemodel.hpp"
0009 #include "assets/assetlist/view/asseticonprovider.hpp"
0010 
0011 #include <KActionCategory>
0012 #include <KIO/FileCopyJob>
0013 #include <KMessageBox>
0014 #include <KRecentDirs>
0015 #include <QDialog>
0016 #include <QDialogButtonBox>
0017 #include <QFileDialog>
0018 #include <QFormLayout>
0019 #include <QHeaderView>
0020 #include <QLineEdit>
0021 #include <QMenu>
0022 #include <QStandardPaths>
0023 #include <QTextEdit>
0024 #include <knewstuff_version.h>
0025 
0026 #include <memory>
0027 
0028 EffectListWidget::EffectListWidget(QWidget *parent)
0029     : AssetListWidget(true, parent)
0030 {
0031 
0032     QString effectCategory = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("kdenliveeffectscategory.rc"));
0033     m_model = EffectTreeModel::construct(effectCategory, this);
0034     m_proxyModel = std::make_unique<EffectFilter>(this);
0035     m_proxyModel->setSourceModel(m_model.get());
0036     m_proxyModel->setSortRole(EffectTreeModel::NameRole);
0037     m_proxyModel->sort(0, Qt::AscendingOrder);
0038     m_effectsTree->setModel(m_proxyModel.get());
0039     m_effectsTree->setColumnHidden(1, true);
0040     m_effectsTree->setColumnHidden(2, true);
0041     m_effectsTree->setColumnHidden(3, true);
0042     m_effectsTree->header()->setStretchLastSection(true);
0043     setFilterType("");
0044     QItemSelectionModel *sel = m_effectsTree->selectionModel();
0045     connect(sel, &QItemSelectionModel::currentChanged, this, &AssetListWidget::updateAssetInfo);
0046 }
0047 
0048 EffectListWidget::~EffectListWidget() {}
0049 
0050 void EffectListWidget::setFilterType(const QString &type)
0051 {
0052     if (type == "video") {
0053         static_cast<EffectFilter *>(m_proxyModel.get())->setFilterType(true, AssetListType::AssetType::Video);
0054     } else if (type == "audio") {
0055         static_cast<EffectFilter *>(m_proxyModel.get())->setFilterType(true, AssetListType::AssetType::Audio);
0056     } else if (type == "custom") {
0057         static_cast<EffectFilter *>(m_proxyModel.get())->setFilterType(true, AssetListType::AssetType::Custom);
0058     } else if (type == "favorites") {
0059         static_cast<EffectFilter *>(m_proxyModel.get())->setFilterType(true, AssetListType::AssetType::Favorites);
0060     } else {
0061         static_cast<EffectFilter *>(m_proxyModel.get())->setFilterType(false, AssetListType::AssetType::Preferred);
0062     }
0063 }
0064 
0065 bool EffectListWidget::isAudio(const QString &assetId) const
0066 {
0067     return EffectsRepository::get()->isAudioEffect(assetId);
0068 }
0069 
0070 QString EffectListWidget::getMimeType(const QString &assetId) const
0071 {
0072     Q_UNUSED(assetId);
0073     return QStringLiteral("kdenlive/effect");
0074 }
0075 
0076 void EffectListWidget::reloadCustomEffectIx(const QModelIndex &index)
0077 {
0078     static_cast<EffectTreeModel *>(m_model.get())->reloadEffectFromIndex(m_proxyModel->mapToSource(index));
0079     m_proxyModel->sort(0, Qt::AscendingOrder);
0080 }
0081 
0082 void EffectListWidget::reloadCustomEffect(const QString &path)
0083 {
0084     static_cast<EffectTreeModel *>(m_model.get())->reloadEffect(path);
0085     m_proxyModel->sort(0, Qt::AscendingOrder);
0086 }
0087 
0088 void EffectListWidget::reloadTemplates()
0089 {
0090     static_cast<EffectTreeModel *>(m_model.get())->reloadTemplates();
0091     m_proxyModel->sort(0, Qt::AscendingOrder);
0092 }
0093 
0094 void EffectListWidget::reloadEffectMenu(QMenu *effectsMenu, KActionCategory *effectActions)
0095 {
0096     m_model->reloadAssetMenu(effectsMenu, effectActions);
0097 }
0098 
0099 void EffectListWidget::editCustomAsset(const QModelIndex &index)
0100 {
0101     QDialog dialog(this);
0102     QFormLayout form(&dialog);
0103     QString currentName = getName(index);
0104     QString desc = getDescription(index);
0105     // Strip effect Name
0106     if (desc.contains(QLatin1Char('('))) {
0107         desc = desc.section(QLatin1Char('('), 0, -2).simplified();
0108     }
0109     auto *effectName = new QLineEdit(currentName, &dialog);
0110     auto *descriptionBox = new QTextEdit(desc, &dialog);
0111     form.addRow(i18n("Name : "), effectName);
0112     form.addRow(i18n("Comments : "), descriptionBox);
0113     QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
0114     form.addRow(&buttonBox);
0115     QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
0116     QObject::connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
0117     if (dialog.exec() == QDialog::Accepted) {
0118         QString name = effectName->text();
0119         QString enteredDescription = descriptionBox->toPlainText();
0120         if (name.trimmed().isEmpty() && enteredDescription.trimmed().isEmpty()) {
0121             return;
0122         }
0123         m_model->editCustomAsset(name, enteredDescription, m_proxyModel->mapToSource(index));
0124     }
0125 }
0126 
0127 void EffectListWidget::exportCustomEffect(const QModelIndex &index)
0128 {
0129     QString name = getName(index);
0130     if (name.isEmpty()) {
0131         return;
0132     }
0133 
0134     QString filter = QString("%1 (*.xml);;%2 (*)").arg(i18n("Kdenlive Effect definitions"), i18n("All Files"));
0135     QString startFolder = KRecentDirs::dir(QStringLiteral(":KdenliveExportCustomEffect"));
0136     QUrl source = QUrl::fromLocalFile(EffectsRepository::get()->getCustomPath(name));
0137     startFolder.append(source.fileName());
0138 
0139     QString filename = QFileDialog::getSaveFileName(this, i18nc("@title:window", "Export Custom Effect"), startFolder, filter);
0140     QUrl target = QUrl::fromLocalFile(filename);
0141 
0142     if (source.isValid() && target.isValid()) {
0143         KRecentDirs::add(QStringLiteral(":KdenliveExportCustomEffect"), target.adjusted(QUrl::RemoveFilename).toLocalFile());
0144         KIO::FileCopyJob *copyjob = KIO::file_copy(source, target);
0145         if (!copyjob->exec()) {
0146             KMessageBox::error(this, i18n("Unable to write to file %1", target.toLocalFile()));
0147         }
0148     }
0149 }