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.Sources.Multi="Delete %1 Sources"
Undo.Filters="Filter Changes on '%1'" Undo.Filters="Filter Changes on '%1'"
Undo.Filters.Paste.Single="Paste Filter '%1' to '%2'" 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="Transform source(s) In '%1'"
Undo.Transform.Paste="Paste Transformation in '%1'" Undo.Transform.Paste="Paste Transformation in '%1'"
Undo.Transform.Rotate="Rotation 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()) > copyFiltersAction.setEnabled(obs_source_filter_count(vol->GetSource()) >
0); 0);
pasteFiltersAction.setEnabled( pasteFiltersAction.setEnabled(!filtersClipboard.empty());
!obs_weak_source_expired(copyFiltersSource));
QMenu popup; QMenu popup;
vol->SetContextMenu(&popup); vol->SetContextMenu(&popup);
@ -5104,7 +5103,7 @@ void OBSBasic::ClearSceneData()
prevFTBSource = nullptr; prevFTBSource = nullptr;
clipboard.clear(); clipboard.clear();
copyFiltersSource = nullptr; filtersClipboard.clear();
copyFilter = nullptr; copyFilter = nullptr;
auto cb = [](void *, obs_source_t *source) { auto cb = [](void *, obs_source_t *source) {
@ -5623,8 +5622,7 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
&OBSBasic::SceneCopyFilters); &OBSBasic::SceneCopyFilters);
QAction *pasteFilters = QAction *pasteFilters =
new QAction(QTStr("Paste.Filters"), this); new QAction(QTStr("Paste.Filters"), this);
pasteFilters->setEnabled( pasteFilters->setEnabled(!filtersClipboard.empty());
!obs_weak_source_expired(copyFiltersSource));
connect(pasteFilters, &QAction::triggered, this, connect(pasteFilters, &QAction::triggered, this,
&OBSBasic::ScenePasteFilters); &OBSBasic::ScenePasteFilters);
@ -8647,8 +8645,8 @@ void OBSBasic::UpdateEditMenu()
ui->actionPasteTransform->setEnabled( ui->actionPasteTransform->setEnabled(
canTransformMultiple && hasCopiedTransform && videoCount > 0); canTransformMultiple && hasCopiedTransform && videoCount > 0);
ui->actionCopyFilters->setEnabled(filter_count > 0); ui->actionCopyFilters->setEnabled(filter_count > 0);
ui->actionPasteFilters->setEnabled( ui->actionPasteFilters->setEnabled(!filtersClipboard.empty() &&
!obs_weak_source_expired(copyFiltersSource) && totalCount > 0); totalCount > 0);
ui->actionPasteRef->setEnabled(!!clipboard.size()); ui->actionPasteRef->setEnabled(!!clipboard.size());
ui->actionPasteDup->setEnabled(allowPastingDuplicate); ui->actionPasteDup->setEnabled(allowPastingDuplicate);
@ -10125,25 +10123,59 @@ void OBSBasic::on_actionPasteDup_triggered()
void OBSBasic::SourceCopyFilters(OBSSource source) 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); ui->actionPasteFilters->setEnabled(true);
} }
void OBSBasic::SourcePasteFilters(OBSSource source, OBSSource dstSource) void OBSBasic::SourcePasteFilters(OBSSource dstSource)
{ {
if (source == dstSource)
return;
OBSDataArrayAutoRelease undo_array = OBSDataArrayAutoRelease undo_array =
obs_source_backup_filters(dstSource); 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 = OBSDataArrayAutoRelease redo_array =
obs_source_backup_filters(dstSource); obs_source_backup_filters(dstSource);
const char *srcName = obs_source_get_name(source);
const char *dstName = obs_source_get_name(dstSource); 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, CreateFilterPasteUndoRedoAction(text, dstSource, undo_array,
redo_array); redo_array);
@ -10162,12 +10194,8 @@ void OBSBasic::AudioMixerPasteFilters()
{ {
QAction *action = reinterpret_cast<QAction *>(sender()); QAction *action = reinterpret_cast<QAction *>(sender());
VolControl *vol = action->property("volControl").value<VolControl *>(); VolControl *vol = action->property("volControl").value<VolControl *>();
obs_source_t *dstSource = vol->GetSource(); OBSSource dstSource = vol->GetSource();
SourcePasteFilters(dstSource);
OBSSourceAutoRelease source =
obs_weak_source_get_source(copyFiltersSource);
SourcePasteFilters(source.Get(), dstSource);
} }
void OBSBasic::SceneCopyFilters() void OBSBasic::SceneCopyFilters()
@ -10177,12 +10205,7 @@ void OBSBasic::SceneCopyFilters()
void OBSBasic::ScenePasteFilters() void OBSBasic::ScenePasteFilters()
{ {
OBSSourceAutoRelease source = SourcePasteFilters(GetCurrentSceneSource());
obs_weak_source_get_source(copyFiltersSource);
OBSSource dstSource = GetCurrentSceneSource();
SourcePasteFilters(source.Get(), dstSource);
} }
void OBSBasic::on_actionCopyFilters_triggered() void OBSBasic::on_actionCopyFilters_triggered()
@ -10232,13 +10255,9 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
void OBSBasic::on_actionPasteFilters_triggered() void OBSBasic::on_actionPasteFilters_triggered()
{ {
OBSSourceAutoRelease source =
obs_weak_source_get_source(copyFiltersSource);
OBSSceneItem sceneItem = GetCurrentSceneItem(); OBSSceneItem sceneItem = GetCurrentSceneItem();
OBSSource dstSource = obs_sceneitem_get_source(sceneItem); OBSSource dstSource = obs_sceneitem_get_source(sceneItem);
SourcePasteFilters(dstSource);
SourcePasteFilters(source.Get(), dstSource);
} }
static void ConfirmColor(SourceTree *sources, const QColor &color, static void ConfirmColor(SourceTree *sources, const QColor &color,

View file

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