Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Fix custom effect saving

parent 8ea4a005
......@@ -98,6 +98,7 @@ AssetPanel::AssetPanel(QWidget *parent)
m_effectStackWidget->setVisible(false);
updatePalette();
connect(m_effectStackWidget, &EffectStackView::seekToPos, this, &AssetPanel::seekToPos);
connect(m_effectStackWidget, &EffectStackView::reloadEffect, this, &AssetPanel::reloadEffect);
connect(m_transitionWidget, &TransitionStackView::seekToTransPos, this, &AssetPanel::seekToPos);
}
......
......@@ -92,6 +92,7 @@ signals:
void doSplitBinEffect(bool);
void seekToPos(int);
void changeSpeed(int);
void reloadEffect(const QString &path);
};
#endif
......@@ -34,6 +34,7 @@
EffectTreeModel::EffectTreeModel(QObject *parent)
: AssetTreeModel(parent)
, m_customCategory(nullptr)
{
}
......@@ -51,7 +52,6 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
std::shared_ptr<TreeItem> miscCategory = nullptr;
std::shared_ptr<TreeItem> audioCategory = nullptr;
std::shared_ptr<TreeItem> customCategory = nullptr;
// We parse category file
if (!categoryFile.isEmpty()) {
QDomDocument doc;
......@@ -75,12 +75,12 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
// We also create "Misc", "Audio" and "Custom" categories
miscCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Misc"), QStringLiteral("root")});
audioCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Audio"), QStringLiteral("root")});
customCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Custom"), QStringLiteral("root")});
self->m_customCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Custom"), QStringLiteral("root")});
} else {
// Flat view
miscCategory = self->rootItem;
audioCategory = self->rootItem;
customCategory = self->rootItem;
self->m_customCategory = self->rootItem;
}
// We parse effects
......@@ -98,7 +98,7 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
}
if (type == EffectType::Custom) {
targetCategory = customCategory;
targetCategory = self->m_customCategory;
}
// we create the data list corresponding to this profile
......@@ -111,3 +111,15 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
}
return self;
}
void EffectTreeModel::reloadEffect(const QString &path)
{
QPair <QString, QString> asset = EffectsRepository::get()->reloadCustom(path);
if (asset.first.isEmpty() || m_customCategory == nullptr) {
return;
}
QList<QVariant> data;
bool isFav = KdenliveSettings::favorite_effects().contains(asset.first);
data << asset.second << asset.first << QVariant::fromValue(EffectType::Custom) << isFav;
m_customCategory->appendChild(data);
}
......@@ -36,8 +36,10 @@ protected:
public:
static std::shared_ptr<EffectTreeModel> construct(const QString &categoryFile, QObject *parent);
void reloadEffect(const QString &path);
protected:
std::shared_ptr<TreeItem> m_customCategory;
};
#endif
......@@ -79,3 +79,8 @@ QString EffectListWidget::getMimeType(const QString &assetId) const
return QStringLiteral("kdenlive/effect");
}
void EffectListWidget::reloadCustomEffect(const QString &path)
{
static_cast<EffectTreeModel *>(m_model.get())->reloadEffect(path);
}
......@@ -45,6 +45,9 @@ public:
QString getMimeType(const QString &assetId) const override;
void updateFavorite(const QModelIndex &index);
public slots:
void reloadCustomEffect(const QString &path);
private:
EffectListWidgetProxy *m_proxy;
......
......@@ -110,7 +110,6 @@ void EffectsRepository::parseCustomAssetFile(const QString &file_name, std::unor
if (!ok) {
continue;
}
if (customAssets.count(result.id) > 0) {
qDebug() << "Warning: duplicate custom definition of effect" << result.id << "found. Only last one will be considered";
}
......@@ -164,3 +163,18 @@ Mlt::Filter *EffectsRepository::getEffect(const QString &effectId) const
Mlt::Filter *filter = new Mlt::Filter(pCore->getCurrentProfile()->profile(), service_name.toLatin1().constData(), nullptr);
return filter;
}
QPair <QString, QString> EffectsRepository::reloadCustom(const QString &path)
{
std::unordered_map<QString, Info> customAssets;
parseCustomAssetFile(path, customAssets);
QPair <QString, QString> result;
//TODO: handle files with several effects
for (const auto &custom : customAssets) {
// Custom assets should override default ones
m_assets[custom.first] = custom.second;
result.first = custom.first;
result.second = custom.second.mltId;
}
return result;
}
......@@ -48,6 +48,7 @@ public:
/* @brief returns a fresh instance of the given effect */
Mlt::Filter *getEffect(const QString &effectId) const;
void setFavorite(const QString &id, bool favorite) override;
QPair <QString, QString> reloadCustom(const QString &path);
protected:
// Constructor is protected because class is a Singleton
......
......@@ -41,6 +41,7 @@ signals:
void moveEffect(const QList<int> &current_pos, int new_pos, int groupIndex, const QString &groupName);
/** @brief An effect was saved, trigger effect list reload. */
void reloadEffects();
void reloadEffect(const QString &path);
void seekToPos(int);
};
......
......@@ -55,10 +55,6 @@
CollapsibleEffectView::CollapsibleEffectView(std::shared_ptr<EffectItemModel> effectModel, QSize frameSize, QImage icon, QWidget *parent)
: AbstractCollapsibleWidget(parent)
/* , m_effect(effect)
, m_itemInfo(info)
, m_original_effect(original_effect)
, m_isMovable(true)*/
, m_view(nullptr)
, m_model(effectModel)
, m_regionEffect(false)
......@@ -380,7 +376,29 @@ void CollapsibleEffectView::slotSaveEffect()
}
QDomDocument doc;
QDomElement effect = m_effect.cloneNode().toElement();
// Get base effect xml
QString effectId = m_model->getAssetId();
QDomElement effect = EffectsRepository::get()->getXml(effectId);
// Adjust param values
QVector<QPair<QString, QVariant>> currentValues = m_model->getAllParameters();
QMap <QString, QString> values;
QLocale locale;
for (const auto &param : currentValues) {
if (param.second.type() == QVariant::Double) {
values.insert(param.first, locale.toString(param.second.toDouble()));
} else {
values.insert(param.first, param.second.toString());
}
}
QDomNodeList params = effect.elementsByTagName("parameter");
for (int i = 0; i < params.count(); ++i) {
const QString paramName = params.item(i).toElement().attribute("name");
const QString paramType = params.item(i).toElement().attribute("type");
if (paramType == QLatin1String("fixed") || !values.contains(paramName)) {
continue;
}
params.item(i).toElement().setAttribute(QStringLiteral("value"), values.value(paramName));
}
doc.appendChild(doc.importNode(effect, true));
effect = doc.firstChild().toElement();
effect.removeAttribute(QStringLiteral("kdenlive_ix"));
......@@ -408,7 +426,7 @@ void CollapsibleEffectView::slotSaveEffect()
out << doc.toString();
}
file.close();
emit reloadEffects();
emit reloadEffect(dir.absoluteFilePath(name + QStringLiteral(".xml")));
}
void CollapsibleEffectView::slotResetEffect()
......
......@@ -202,6 +202,7 @@ void EffectStackView::loadEffects()
view = new CollapsibleEffectView(effectModel, m_sourceFrameSize, effectIcon, this);
connect(view, &CollapsibleEffectView::deleteEffect, m_model.get(), &EffectStackModel::removeEffect);
connect(view, &CollapsibleEffectView::moveEffect, m_model.get(), &EffectStackModel::moveEffect);
connect(view, &CollapsibleEffectView::reloadEffect, this, &EffectStackView::reloadEffect);
connect(view, &CollapsibleEffectView::switchHeight, this, &EffectStackView::slotAdjustDelegate, Qt::DirectConnection);
connect(view, &CollapsibleEffectView::startDrag, this, &EffectStackView::slotStartDrag);
connect(view, &CollapsibleEffectView::createGroup, m_model.get(), &EffectStackModel::slotCreateGroup);
......
......@@ -93,6 +93,7 @@ private slots:
signals:
void doActivateEffect(QModelIndex);
void seekToPos(int);
void reloadEffect(const QString &path);
};
#endif
......@@ -316,7 +316,6 @@ void MainWindow::init()
connect(m_timelineTabs, &TimelineTabs::showItemEffectStack, m_assetPanel, &AssetPanel::showEffectStack);
connect(pCore->bin(), &Bin::requestShowEffectStack, m_assetPanel, &AssetPanel::showEffectStack);
connect(this, &MainWindow::clearAssetPanel, m_assetPanel, &AssetPanel::clearAssetPanel);
connect(m_assetPanel, &AssetPanel::seekToPos, [this](int pos) {
ObjectId oId = m_assetPanel->effectStackOwner();
switch (oId.first) {
......@@ -340,6 +339,7 @@ void MainWindow::init()
m_effectList2 = new EffectListWidget(this);
connect(m_effectList2, &EffectListWidget::activateAsset, pCore->projectManager(), &ProjectManager::activateAsset);
connect(m_assetPanel, &AssetPanel::reloadEffect, m_effectList2, &EffectListWidget::reloadCustomEffect);
m_effectListDock = addDock(i18n("Effects"), QStringLiteral("effect_list"), m_effectList2);
m_transitionList = new EffectsListView(EffectsListView::TransitionMode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment