integrate stream effects with undo/redo

parent 39272b99
Pipeline #23917 passed with stage
in 13 minutes and 56 seconds
......@@ -1172,6 +1172,7 @@ ClipPropertiesController *ProjectClip::buildProperties(QWidget *parent)
auto *panel = new ClipPropertiesController(static_cast<ClipController *>(this), parent);
connect(this, &ProjectClip::refreshPropertiesPanel, panel, &ClipPropertiesController::slotReloadProperties);
connect(this, &ProjectClip::refreshAnalysisPanel, panel, &ClipPropertiesController::slotFillAnalysisData);
connect(this, &ProjectClip::updateStreamInfo, panel, &ClipPropertiesController::updateStreamInfo);
connect(panel, &ClipPropertiesController::requestProxy, [this](bool doProxy) {
QList<std::shared_ptr<ProjectClip>> clipList{std::static_pointer_cast<ProjectClip>(shared_from_this())};
pCore->currentDoc()->slotProxyCurrentItem(doProxy, clipList);
......@@ -1605,6 +1606,58 @@ void ProjectClip::renameAudioStream(int id, QString name)
}
}
void ProjectClip::requestAddStreamEffect(int streamIndex, const QString effectName)
{
QStringList readEffects = m_streamEffects.value(streamIndex);
QString oldEffect;
// Remove effect if present (parameters might have changed
for (const QString effect : readEffects) {
if (effect == effectName || effect.startsWith(effectName + QStringLiteral(" "))) {
oldEffect = effect;
break;
}
}
Fun redo = [this, streamIndex, effectName]() {
addAudioStreamEffect(streamIndex, effectName);
emit updateStreamInfo(streamIndex);
return true; };
Fun undo = [this, streamIndex, effectName, oldEffect]() {
if (!oldEffect.isEmpty()) {
// restore previous parameter value
addAudioStreamEffect(streamIndex, oldEffect);
} else {
removeAudioStreamEffect(streamIndex, effectName);
}
emit updateStreamInfo(streamIndex);
return true;
};
addAudioStreamEffect(streamIndex, effectName);
pCore->pushUndo(undo, redo, i18n("Add stream effect"));
}
void ProjectClip::requestRemoveStreamEffect(int streamIndex, const QString effectName)
{
QStringList readEffects = m_streamEffects.value(streamIndex);
QString oldEffect = effectName;
// Remove effect if present (parameters might have changed
for (const QString effect : readEffects) {
if (effect == effectName || effect.startsWith(effectName + QStringLiteral(" "))) {
oldEffect = effect;
break;
}
}
Fun undo = [this, streamIndex, effectName, oldEffect]() {
addAudioStreamEffect(streamIndex, oldEffect);
emit updateStreamInfo(streamIndex);
return true; };
Fun redo = [this, streamIndex, effectName]() {
removeAudioStreamEffect(streamIndex, effectName);
emit updateStreamInfo(streamIndex);
return true; };
removeAudioStreamEffect(streamIndex, effectName);
pCore->pushUndo(undo, redo, i18n("Remove stream effect"));
}
void ProjectClip::addAudioStreamEffect(int streamIndex, const QString effectName)
{
QString addedEffectName;
......
......@@ -233,10 +233,15 @@ public:
/** @brief Rename an audio stream for this clip
*/
void renameAudioStream(int id, QString name) override;
/** @brief Add an audio effect on a specific audio stream with undo/redo. */
void requestAddStreamEffect(int streamIndex, const QString effectName) override;
/** @brief Add an audio effect on a specific audio stream for this clip. */
void addAudioStreamEffect(int streamIndex, const QString effectName) override;
void addAudioStreamEffect(int streamIndex, const QString effectName);
/** @brief Remove an audio effect on a specific audio stream with undo/redo. */
void requestRemoveStreamEffect(int streamIndex, const QString effectName) override;
/** @brief Remove an audio effect on a specific audio stream for this clip. */
void removeAudioStreamEffect(int streamIndex, QString effectName) override;
void removeAudioStreamEffect(int streamIndex, QString effectName);
/** @brief Get the list of audio stream effects for a defined stream. */
QStringList getAudioStreamEffect(int streamIndex) const override;
......@@ -301,6 +306,7 @@ signals:
/** @brief Clip is ready, load properties. */
void loadPropertiesPanel();
void audioThumbReady();
void updateStreamInfo(int ix);
};
#endif
......@@ -102,9 +102,9 @@ public:
virtual void renameAudioStream(int id, QString name) = 0;
/** @brief Add an audio effect on a specific audio stream for this clip. */
virtual void addAudioStreamEffect(int streamIndex, const QString effectName) = 0;
virtual void requestAddStreamEffect(int streamIndex, const QString effectName) = 0;
/** @brief Remove an audio effect on a specific audio stream for this clip. */
virtual void removeAudioStreamEffect(int streamIndex, const QString effectName) = 0;
virtual void requestRemoveStreamEffect(int streamIndex, const QString effectName) = 0;
virtual QStringList getAudioStreamEffect(int streamIndex) const = 0;
/** @brief Returns the clip's duration */
......
......@@ -762,10 +762,10 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
}
if (state == Qt::Checked) {
// Add swap channels effect
m_controller->addAudioStreamEffect(m_activeAudioStreams, QStringLiteral("dynamic_loudness"));
m_controller->requestAddStreamEffect(m_activeAudioStreams, QStringLiteral("dynamic_loudness"));
} else {
// Remove swap channels effect
m_controller->removeAudioStreamEffect(m_activeAudioStreams, QStringLiteral("dynamic_loudness"));
m_controller->requestRemoveStreamEffect(m_activeAudioStreams, QStringLiteral("dynamic_loudness"));
}
updateStreamIcon(m_audioStreamsView->currentRow(), m_activeAudioStreams);
});
......@@ -780,10 +780,10 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
}
if (state == Qt::Checked) {
// Add swap channels effect
m_controller->addAudioStreamEffect(m_activeAudioStreams, QStringLiteral("channelswap"));
m_controller->requestAddStreamEffect(m_activeAudioStreams, QStringLiteral("channelswap"));
} else {
// Remove swap channels effect
m_controller->removeAudioStreamEffect(m_activeAudioStreams, QStringLiteral("channelswap"));
m_controller->requestRemoveStreamEffect(m_activeAudioStreams, QStringLiteral("channelswap"));
}
updateStreamIcon(m_audioStreamsView->currentRow(), m_activeAudioStreams);
});
......@@ -810,12 +810,12 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
m_copyChannel1->setChecked(false);
}
if (m_copyChannel1->isChecked()) {
m_controller->addAudioStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy from=0 to=1"));
m_controller->requestAddStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy from=0 to=1"));
} else if (m_copyChannel2->isChecked()) {
m_controller->addAudioStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy from=1 to=0"));
m_controller->requestAddStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy from=1 to=0"));
} else {
// Remove swap channels effect
m_controller->removeAudioStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy"));
m_controller->requestRemoveStreamEffect(m_activeAudioStreams, QStringLiteral("channelcopy"));
}
updateStreamIcon(m_audioStreamsView->currentRow(), m_activeAudioStreams);
});
......@@ -832,9 +832,9 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
}
if (value == 0) {
// Remove effect
m_controller->removeAudioStreamEffect(m_activeAudioStreams, QStringLiteral("volume"));
m_controller->requestRemoveStreamEffect(m_activeAudioStreams, QStringLiteral("volume"));
} else {
m_controller->addAudioStreamEffect(m_activeAudioStreams, QString("volume level=%1").arg(value));
m_controller->requestAddStreamEffect(m_activeAudioStreams, QString("volume level=%1").arg(value));
}
updateStreamIcon(m_audioStreamsView->currentRow(), m_activeAudioStreams);
});
......@@ -1629,3 +1629,39 @@ void ClipPropertiesController::slotSelectAllMarkers()
m_markerTree->selectAll();
}
}
void ClipPropertiesController::updateStreamInfo(int streamIndex)
{
QStringList effects = m_controller->getAudioStreamEffect(m_activeAudioStreams);
QListWidgetItem *item = nullptr;
for (int ix = 0; ix < m_audioStreamsView->count(); ix++) {
QListWidgetItem *it = m_audioStreamsView->item(ix);
int stream = it->data(Qt::UserRole).toInt();
if (stream == m_activeAudioStreams) {
item = it;
break;
}
}
if (item) {
item->setIcon(effects.isEmpty() ? QIcon() : QIcon::fromTheme(QStringLiteral("favorite")));
}
if (streamIndex == m_activeAudioStreams) {
QSignalBlocker bk(m_swapChannels);
QSignalBlocker bk1(m_copyChannelGroup);
QSignalBlocker bk2(m_normalize);
m_swapChannels->setChecked(effects.contains(QLatin1String("channelswap")));
m_copyChannel1->setChecked(effects.contains(QStringLiteral("channelcopy from=0 to=1")));
m_copyChannel2->setChecked(effects.contains(QStringLiteral("channelcopy from=1 to=0")));
m_normalize->setChecked(effects.contains(QStringLiteral("dynamic_loudness")));
int gain = 0;
for (const QString st : effects) {
if (st.startsWith(QLatin1String("volume "))) {
QSignalBlocker bk3(m_gain);
gain = st.section(QLatin1Char('='), 1).toInt();
break;
}
}
QSignalBlocker bk3(m_gain);
m_gain->setValue(gain);
}
}
......@@ -76,6 +76,7 @@ public slots:
void slotFillAnalysisData();
void slotDeleteSelectedMarkers();
void slotSelectAllMarkers();
void updateStreamInfo(int streamIndex);
private slots:
void slotColorModified(const QColor &newcolor);
......
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