UI: Actually copy-paste filters instead of remembering the source

The current behavior makes OBS remember the source that filters should
get copied from and then clones that source's filters to the source that
filters are pasted to. This means however that if the original source
has filters added or removed after the copy-operation, that will still
effect the paste-operation, so filters that were added after copying
would still get pasted.
This commit changes this to something similar to the source clipboard.
Now, we're actually copying the filters, so if the original source has
filters added to afterwards we don't copy those as well.
This commit is contained in:
gxalpha 2024-05-25 18:28:58 +02:00
parent 6ea1520318
commit f402f7a091
No known key found for this signature in database
GPG key ID: 470184116E317811
3 changed files with 55 additions and 36 deletions

View file

@ -318,7 +318,7 @@ Undo.Item.Redo="Redo %1"
Undo.Sources.Multi="Delete %1 Sources"
Undo.Filters="Filter Changes on '%1'"
Undo.Filters.Paste.Single="Paste Filter '%1' to '%2'"
Undo.Filters.Paste.Multiple="Copy Filters from '%1' to '%2'"
Undo.Filters.Paste.Multiple="Paste %1 Filters to '%2'"
Undo.Transform="Transform source(s) In '%1'"
Undo.Transform.Paste="Paste Transformation in '%1'"
Undo.Transform.Rotate="Rotation In '%1'"

View file

@ -3934,8 +3934,7 @@ void OBSBasic::VolControlContextMenu()
copyFiltersAction.setEnabled(obs_source_filter_count(vol->GetSource()) >
0);
pasteFiltersAction.setEnabled(
!obs_weak_source_expired(copyFiltersSource));
pasteFiltersAction.setEnabled(!filtersClipboard.empty());
QMenu popup;
vol->SetContextMenu(&popup);
@ -5104,7 +5103,7 @@ void OBSBasic::ClearSceneData()
prevFTBSource = nullptr;
clipboard.clear();
copyFiltersSource = nullptr;
filtersClipboard.clear();
copyFilter = nullptr;
auto cb = [](void *, obs_source_t *source) {
@ -5623,8 +5622,7 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
&OBSBasic::SceneCopyFilters);
QAction *pasteFilters =
new QAction(QTStr("Paste.Filters"), this);
pasteFilters->setEnabled(
!obs_weak_source_expired(copyFiltersSource));
pasteFilters->setEnabled(!filtersClipboard.empty());
connect(pasteFilters, &QAction::triggered, this,
&OBSBasic::ScenePasteFilters);
@ -8647,8 +8645,8 @@ void OBSBasic::UpdateEditMenu()
ui->actionPasteTransform->setEnabled(
canTransformMultiple && hasCopiedTransform && videoCount > 0);
ui->actionCopyFilters->setEnabled(filter_count > 0);
ui->actionPasteFilters->setEnabled(
!obs_weak_source_expired(copyFiltersSource) && totalCount > 0);
ui->actionPasteFilters->setEnabled(!filtersClipboard.empty() &&
totalCount > 0);
ui->actionPasteRef->setEnabled(!!clipboard.size());
ui->actionPasteDup->setEnabled(allowPastingDuplicate);
@ -10125,25 +10123,59 @@ void OBSBasic::on_actionPasteDup_triggered()
void OBSBasic::SourceCopyFilters(OBSSource source)
{
copyFiltersSource = obs_source_get_weak_source(source);
filtersClipboard.clear();
filtersClipboard.reserve(obs_source_filter_count(source));
obs_source_enum_filters(
source,
[](obs_source_t *, obs_source_t *filter, void *param) {
auto filters =
static_cast<std::vector<OBSWeakSource> *>(
param);
filters->push_back(OBSGetWeakRef(filter));
},
&filtersClipboard);
ui->actionPasteFilters->setEnabled(true);
}
void OBSBasic::SourcePasteFilters(OBSSource source, OBSSource dstSource)
void OBSBasic::SourcePasteFilters(OBSSource dstSource)
{
if (source == dstSource)
return;
OBSDataArrayAutoRelease undo_array =
obs_source_backup_filters(dstSource);
obs_source_copy_filters(dstSource, source);
int copiedFiltersCount = 0;
OBSSource copiedFilter = nullptr;
for (auto &weakFilter : filtersClipboard) {
if (obs_weak_source_expired(weakFilter)) {
continue;
}
OBSSource filter = OBSGetStrongRef(weakFilter);
obs_source_copy_single_filter(dstSource, filter);
if (copiedFiltersCount == 0) {
copiedFilter = filter;
}
copiedFiltersCount++;
}
if (copiedFiltersCount == 0) {
return;
}
OBSDataArrayAutoRelease redo_array =
obs_source_backup_filters(dstSource);
const char *srcName = obs_source_get_name(source);
const char *dstName = obs_source_get_name(dstSource);
QString text =
QTStr("Undo.Filters.Paste.Multiple").arg(srcName, dstName);
QString text;
if (copiedFiltersCount == 1) {
const char *filterName = obs_source_get_name(copiedFilter);
text = QTStr("Undo.Filters.Paste.Single")
.arg(filterName, dstName);
} else {
text = QTStr("Undo.Filters.Paste.Multiple")
.arg(QString::number(copiedFiltersCount),
dstName);
}
CreateFilterPasteUndoRedoAction(text, dstSource, undo_array,
redo_array);
@ -10162,12 +10194,8 @@ void OBSBasic::AudioMixerPasteFilters()
{
QAction *action = reinterpret_cast<QAction *>(sender());
VolControl *vol = action->property("volControl").value<VolControl *>();
obs_source_t *dstSource = vol->GetSource();
OBSSourceAutoRelease source =
obs_weak_source_get_source(copyFiltersSource);
SourcePasteFilters(source.Get(), dstSource);
OBSSource dstSource = vol->GetSource();
SourcePasteFilters(dstSource);
}
void OBSBasic::SceneCopyFilters()
@ -10177,12 +10205,7 @@ void OBSBasic::SceneCopyFilters()
void OBSBasic::ScenePasteFilters()
{
OBSSourceAutoRelease source =
obs_weak_source_get_source(copyFiltersSource);
OBSSource dstSource = GetCurrentSceneSource();
SourcePasteFilters(source.Get(), dstSource);
SourcePasteFilters(GetCurrentSceneSource());
}
void OBSBasic::on_actionCopyFilters_triggered()
@ -10232,13 +10255,9 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
void OBSBasic::on_actionPasteFilters_triggered()
{
OBSSourceAutoRelease source =
obs_weak_source_get_source(copyFiltersSource);
OBSSceneItem sceneItem = GetCurrentSceneItem();
OBSSource dstSource = obs_sceneitem_get_source(sceneItem);
SourcePasteFilters(source.Get(), dstSource);
SourcePasteFilters(dstSource);
}
static void ConfirmColor(SourceTree *sources, const QColor &color,

View file

@ -245,7 +245,7 @@ private:
ContextBarSize contextBarSize = ContextBarSize_Normal;
std::deque<SourceCopyInfo> clipboard;
OBSWeakSourceAutoRelease copyFiltersSource;
std::vector<OBSWeakSource> filtersClipboard;
bool copyVisible = true;
obs_transform_info copiedTransformInfo;
obs_sceneitem_crop copiedCropInfo;
@ -808,7 +808,7 @@ private slots:
void AudioMixerCopyFilters();
void AudioMixerPasteFilters();
void SourceCopyFilters(OBSSource source);
void SourcePasteFilters(OBSSource source, OBSSource dstSource);
void SourcePasteFilters(OBSSource dstSource);
void ColorChange();