UI: Migrate undo/redo to using UUIDs

This commit is contained in:
derrod 2023-03-28 16:24:17 +02:00 committed by Lain
parent 0cb812251c
commit 67f7712d83
11 changed files with 193 additions and 196 deletions

View File

@ -440,19 +440,19 @@ void OBSAdvAudioCtrl::volumeChanged(double db)
float val = obs_db_to_mul(db); float val = obs_db_to_mul(db);
obs_source_set_volume(source, val); obs_source_set_volume(source, val);
auto undo_redo = [](const std::string &name, float val) { auto undo_redo = [](const std::string &uuid, float val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_volume(source, val); obs_source_set_volume(source, val);
}; };
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic *main = OBSBasic::Get(); OBSBasic *main = OBSBasic::Get();
main->undo_s.add_action( main->undo_s.add_action(
QTStr("Undo.Volume.Change").arg(name), QTStr("Undo.Volume.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, val), name, name, std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
true); true);
} }
@ -463,17 +463,18 @@ void OBSAdvAudioCtrl::percentChanged(int percent)
obs_source_set_volume(source, val); obs_source_set_volume(source, val);
auto undo_redo = [](const std::string &name, float val) { auto undo_redo = [](const std::string &uuid, float val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_volume(source, val); obs_source_set_volume(source, val);
}; };
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.Volume.Change").arg(name), QTStr("Undo.Volume.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, val), name, name, std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
true); true);
} }
@ -502,19 +503,20 @@ void OBSAdvAudioCtrl::downmixMonoChanged(bool val)
obs_source_set_flags(source, flags); obs_source_set_flags(source, flags);
auto undo_redo = [](const std::string &name, bool val) { auto undo_redo = [](const std::string &uuid, bool val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
set_mono(source, val); set_mono(source, val);
}; };
QString text = QTStr(val ? "Undo.ForceMono.On" : "Undo.ForceMono.Off"); QString text = QTStr(val ? "Undo.ForceMono.On" : "Undo.ForceMono.Off");
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
text.arg(name), text.arg(name),
std::bind(undo_redo, std::placeholders::_1, !val), std::bind(undo_redo, std::placeholders::_1, !val),
std::bind(undo_redo, std::placeholders::_1, val), name, name); std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid);
} }
void OBSAdvAudioCtrl::balanceChanged(int val) void OBSAdvAudioCtrl::balanceChanged(int val)
@ -531,17 +533,18 @@ void OBSAdvAudioCtrl::balanceChanged(int val)
obs_source_set_balance_value(source, bal); obs_source_set_balance_value(source, bal);
auto undo_redo = [](const std::string &name, float val) { auto undo_redo = [](const std::string &uuid, float val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_balance_value(source, val); obs_source_set_balance_value(source, val);
}; };
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.Balance.Change").arg(name), QTStr("Undo.Balance.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, bal), name, name, std::bind(undo_redo, std::placeholders::_1, bal), uuid, uuid,
true); true);
} }
@ -560,17 +563,18 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
obs_source_set_sync_offset(source, val); obs_source_set_sync_offset(source, val);
auto undo_redo = [](const std::string &name, int64_t val) { auto undo_redo = [](const std::string &uuid, int64_t val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_sync_offset(source, val); obs_source_set_sync_offset(source, val);
}; };
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.SyncOffset.Change").arg(name), QTStr("Undo.SyncOffset.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, val), name, name, std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
true); true);
} }
@ -600,16 +604,17 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
name ? name : "(null)", type); name ? name : "(null)", type);
auto undo_redo = [](const std::string &name, obs_monitoring_type val) { auto undo_redo = [](const std::string &uuid, obs_monitoring_type val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_monitoring_type(source, val); obs_source_set_monitoring_type(source, val);
}; };
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.MonitoringType.Change").arg(name), QTStr("Undo.MonitoringType.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, mt), name, name); std::bind(undo_redo, std::placeholders::_1, mt), uuid, uuid);
} }
static inline void setMixer(obs_source_t *source, const int mixerIdx, static inline void setMixer(obs_source_t *source, const int mixerIdx,
@ -625,18 +630,19 @@ static inline void setMixer(obs_source_t *source, const int mixerIdx,
obs_source_set_audio_mixers(source, new_mixers); obs_source_set_audio_mixers(source, new_mixers);
auto undo_redo = [](const std::string &name, uint32_t mixers) { auto undo_redo = [](const std::string &uuid, uint32_t mixers) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_audio_mixers(source, mixers); obs_source_set_audio_mixers(source, mixers);
}; };
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.Mixers.Change").arg(name), QTStr("Undo.Mixers.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, mixers), std::bind(undo_redo, std::placeholders::_1, mixers),
std::bind(undo_redo, std::placeholders::_1, new_mixers), name, std::bind(undo_redo, std::placeholders::_1, new_mixers), uuid,
name); uuid);
} }
void OBSAdvAudioCtrl::mixer1Changed(bool checked) void OBSAdvAudioCtrl::mixer1Changed(bool checked)

View File

@ -40,7 +40,7 @@ void SourceToolbar::SaveOldProperties(obs_source_t *source)
OBSDataAutoRelease oldSettings = obs_source_get_settings(source); OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
obs_data_apply(oldData, oldSettings); obs_data_apply(oldData, oldSettings);
obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source)); obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
} }
void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable) void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
@ -55,17 +55,17 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
OBSSource currentSceneSource = main->GetCurrentSceneSource(); OBSSource currentSceneSource = main->GetCurrentSceneSource();
if (!currentSceneSource) if (!currentSceneSource)
return; return;
std::string scene_name = obs_source_get_name(currentSceneSource); std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
auto undo_redo = [scene_name = std::move(scene_name), auto undo_redo = [scene_uuid = std::move(scene_uuid),
main](const std::string &data) { main](const std::string &data) {
OBSDataAutoRelease settings = OBSDataAutoRelease settings =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(settings, "undo_sname")); obs_data_get_string(settings, "undo_suuid"));
obs_source_reset_settings(source, settings); obs_source_reset_settings(source, settings);
OBSSourceAutoRelease scene_source = OBSSourceAutoRelease scene_source =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
main->SetCurrentScene(scene_source.Get(), true); main->SetCurrentScene(scene_source.Get(), true);
main->UpdateContextBar(); main->UpdateContextBar();
@ -74,8 +74,8 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
OBSDataAutoRelease new_settings = obs_data_create(); OBSDataAutoRelease new_settings = obs_data_create();
OBSDataAutoRelease curr_settings = obs_source_get_settings(source); OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
obs_data_apply(new_settings, curr_settings); obs_data_apply(new_settings, curr_settings);
obs_data_set_string(new_settings, "undo_sname", obs_data_set_string(new_settings, "undo_suuid",
obs_source_get_name(source)); obs_source_get_uuid(source));
std::string undo_data(obs_data_get_json(oldData)); std::string undo_data(obs_data_get_json(oldData));
std::string redo_data(obs_data_get_json(new_settings)); std::string redo_data(obs_data_get_json(new_settings));

View File

@ -133,12 +133,13 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
obs_source_t *scenesource = obs_scene_get_source(scene); obs_source_t *scenesource = obs_scene_get_source(scene);
int64_t id = obs_sceneitem_get_id(sceneitem); int64_t id = obs_sceneitem_get_id(sceneitem);
const char *name = obs_source_get_name(scenesource); const char *name = obs_source_get_name(scenesource);
const char *uuid = obs_source_get_uuid(scenesource);
obs_source_t *source = obs_sceneitem_get_source(sceneitem); obs_source_t *source = obs_sceneitem_get_source(sceneitem);
auto undo_redo = [](const std::string &name, int64_t id, auto undo_redo = [](const std::string &uuid, int64_t id,
bool val) { bool val) {
OBSSourceAutoRelease s = OBSSourceAutoRelease s =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_scene_t *sc = obs_group_or_scene_from_source(s); obs_scene_t *sc = obs_group_or_scene_from_source(s);
obs_sceneitem_t *si = obs_sceneitem_t *si =
obs_scene_find_sceneitem_by_id(sc, id); obs_scene_find_sceneitem_by_id(sc, id);
@ -154,7 +155,7 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
str.arg(obs_source_get_name(source), name), str.arg(obs_source_get_name(source), name),
std::bind(undo_redo, std::placeholders::_1, id, !val), std::bind(undo_redo, std::placeholders::_1, id, !val),
std::bind(undo_redo, std::placeholders::_1, id, val), std::bind(undo_redo, std::placeholders::_1, id, val),
name, name); uuid, uuid);
SignalBlocker sourcesSignalBlocker(this); SignalBlocker sourcesSignalBlocker(this);
obs_sceneitem_set_visible(sceneitem, val); obs_sceneitem_set_visible(sceneitem, val);
@ -452,32 +453,33 @@ void SourceTreeItem::ExitEditModeInternal(bool save)
SignalBlocker sourcesSignalBlocker(this); SignalBlocker sourcesSignalBlocker(this);
std::string prevName(obs_source_get_name(source)); std::string prevName(obs_source_get_name(source));
std::string scene_name = std::string scene_uuid =
obs_source_get_name(main->GetCurrentSceneSource()); obs_source_get_uuid(main->GetCurrentSceneSource());
auto undo = [scene_name, prevName, main](const std::string &data) { auto undo = [scene_uuid, prevName, main](const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str()); obs_get_source_by_uuid(data.c_str());
obs_source_set_name(source, prevName.c_str()); obs_source_set_name(source, prevName.c_str());
OBSSourceAutoRelease scene_source = OBSSourceAutoRelease scene_source =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
main->SetCurrentScene(scene_source.Get(), true); main->SetCurrentScene(scene_source.Get(), true);
}; };
std::string editedName = newName; std::string editedName = newName;
auto redo = [scene_name, main, editedName](const std::string &data) { auto redo = [scene_uuid, main, editedName](const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str()); obs_get_source_by_uuid(data.c_str());
obs_source_set_name(source, editedName.c_str()); obs_source_set_name(source, editedName.c_str());
OBSSourceAutoRelease scene_source = OBSSourceAutoRelease scene_source =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
main->SetCurrentScene(scene_source.Get(), true); main->SetCurrentScene(scene_source.Get(), true);
}; };
const char *uuid = obs_source_get_uuid(source);
main->undo_s.add_action(QTStr("Undo.Rename").arg(newName.c_str()), undo, main->undo_s.add_action(QTStr("Undo.Rename").arg(newName.c_str()), undo,
redo, newName, prevName); redo, uuid, uuid);
obs_source_set_name(source, newName.c_str()); obs_source_set_name(source, newName.c_str());
label->setText(QT_UTF8(newName.c_str())); label->setText(QT_UTF8(newName.c_str()));

View File

@ -156,9 +156,9 @@ void VolControl::SetMuted(bool)
ShowUnassignedWarning(obs_source_get_name(source)); ShowUnassignedWarning(obs_source_get_name(source));
} }
auto undo_redo = [](const std::string &name, bool val) { auto undo_redo = [](const std::string &uuid, bool val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_muted(source, val); obs_source_set_muted(source, val);
}; };
@ -166,11 +166,12 @@ void VolControl::SetMuted(bool)
QTStr(checked ? "Undo.Volume.Mute" : "Undo.Volume.Unmute"); QTStr(checked ? "Undo.Volume.Mute" : "Undo.Volume.Unmute");
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
text.arg(name), text.arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, checked), name, std::bind(undo_redo, std::placeholders::_1, checked), uuid,
name); uuid);
} }
void VolControl::SliderChanged(int vol) void VolControl::SliderChanged(int vol)
@ -180,18 +181,19 @@ void VolControl::SliderChanged(int vol)
obs_fader_set_deflection(obs_fader, float(vol) / FADER_PRECISION); obs_fader_set_deflection(obs_fader, float(vol) / FADER_PRECISION);
updateText(); updateText();
auto undo_redo = [](const std::string &name, float val) { auto undo_redo = [](const std::string &uuid, float val) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(name.c_str()); obs_get_source_by_uuid(uuid.c_str());
obs_source_set_volume(source, val); obs_source_set_volume(source, val);
}; };
float val = obs_source_get_volume(source); float val = obs_source_get_volume(source);
const char *name = obs_source_get_name(source); const char *name = obs_source_get_name(source);
const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action( OBSBasic::Get()->undo_s.add_action(
QTStr("Undo.Volume.Change").arg(name), QTStr("Undo.Volume.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev), std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, val), name, name, std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
true); true);
} }

View File

@ -199,34 +199,25 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
obs_data_t *new_settings) obs_data_t *new_settings)
{ {
obs_source_t *source = reinterpret_cast<obs_source_t *>(vp); obs_source_t *source = reinterpret_cast<obs_source_t *>(vp);
obs_source_t *parent = obs_filter_get_parent(source); const char *source_uuid = obs_source_get_uuid(source);
const char *source_name = obs_source_get_name(source);
OBSBasic *main = OBSBasic::Get(); OBSBasic *main = OBSBasic::Get();
OBSDataAutoRelease redo_wrapper = obs_data_create(); OBSDataAutoRelease redo_wrapper = obs_data_create();
obs_data_set_string(redo_wrapper, "name", source_name); obs_data_set_string(redo_wrapper, "uuid", source_uuid);
obs_data_set_string(redo_wrapper, "settings", obs_data_set_string(redo_wrapper, "settings",
obs_data_get_json(new_settings)); obs_data_get_json(new_settings));
obs_data_set_string(redo_wrapper, "parent",
obs_source_get_name(parent));
OBSDataAutoRelease filter_settings = obs_source_get_settings(source);
OBSDataAutoRelease undo_wrapper = obs_data_create(); OBSDataAutoRelease undo_wrapper = obs_data_create();
obs_data_set_string(undo_wrapper, "name", source_name); obs_data_set_string(undo_wrapper, "uuid", source_uuid);
obs_data_set_string(undo_wrapper, "settings", obs_data_set_string(undo_wrapper, "settings",
obs_data_get_json(nd_old_settings)); obs_data_get_json(nd_old_settings));
obs_data_set_string(undo_wrapper, "parent",
obs_source_get_name(parent));
auto undo_redo = [](const std::string &data) { auto undo_redo = [](const std::string &data) {
OBSDataAutoRelease dat = OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease parent_source = obs_get_source_by_name( const char *filter_uuid = obs_data_get_string(dat, "uuid");
obs_data_get_string(dat, "parent")); OBSSourceAutoRelease filter =
const char *filter_name = obs_data_get_string(dat, "name"); obs_get_source_by_uuid(filter_uuid);
OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
parent_source, filter_name);
OBSDataAutoRelease new_settings = obs_data_create_from_json( OBSDataAutoRelease new_settings = obs_data_create_from_json(
obs_data_get_string(dat, "settings")); obs_data_get_string(dat, "settings"));
@ -240,10 +231,9 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
main->undo_s.enable(); main->undo_s.enable();
std::string name = std::string(obs_source_get_name(source));
std::string undo_data = obs_data_get_json(undo_wrapper); std::string undo_data = obs_data_get_json(undo_wrapper);
std::string redo_data = obs_data_get_json(redo_wrapper); std::string redo_data = obs_data_get_json(redo_wrapper);
main->undo_s.add_action(QTStr("Undo.Filters").arg(name.c_str()), main->undo_s.add_action(QTStr("Undo.Filters").arg(source_uuid),
undo_redo, undo_redo, undo_data, redo_data); undo_redo, undo_redo, undo_data, redo_data);
obs_source_update(source, new_settings); obs_source_update(source, new_settings);
@ -602,72 +592,72 @@ void OBSBasicFilters::AddNewFilter(const char *id)
return; return;
} }
OBSDataAutoRelease wrapper = obs_data_create();
obs_data_set_string(wrapper, "sname",
obs_source_get_name(source));
obs_data_set_string(wrapper, "fname", name.c_str());
std::string scene_name = obs_source_get_name(
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->GetCurrentSceneSource());
auto undo = [scene_name](const std::string &data) {
obs_source_t *ssource =
obs_get_source_by_name(scene_name.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource, true);
obs_source_release(ssource);
obs_data_t *dat =
obs_data_create_from_json(data.c_str());
obs_source_t *source = obs_get_source_by_name(
obs_data_get_string(dat, "sname"));
obs_source_t *filter = obs_source_get_filter_by_name(
source, obs_data_get_string(dat, "fname"));
obs_source_filter_remove(source, filter);
obs_data_release(dat);
obs_source_release(source);
obs_source_release(filter);
};
OBSDataAutoRelease rwrapper = obs_data_create();
obs_data_set_string(rwrapper, "sname",
obs_source_get_name(source));
auto redo = [scene_name, id = std::string(id),
name](const std::string &data) {
OBSSourceAutoRelease ssource =
obs_get_source_by_name(scene_name.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true);
OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name(
obs_data_get_string(dat, "sname"));
OBSSourceAutoRelease filter = obs_source_create(
id.c_str(), name.c_str(), nullptr, nullptr);
if (filter) {
obs_source_filter_add(source, filter);
}
};
std::string undo_data(obs_data_get_json(wrapper));
std::string redo_data(obs_data_get_json(rwrapper));
main->undo_s.add_action(QTStr("Undo.Add").arg(name.c_str()),
undo, redo, undo_data, redo_data);
OBSSourceAutoRelease filter = OBSSourceAutoRelease filter =
obs_source_create(id, name.c_str(), nullptr, nullptr); obs_source_create(id, name.c_str(), nullptr, nullptr);
if (filter) { if (filter) {
const char *sourceName = obs_source_get_name(source); const char *sourceName = obs_source_get_name(source);
blog(LOG_INFO, blog(LOG_INFO,
"User added filter '%s' (%s) " "User added filter '%s' (%s) to source '%s'",
"to source '%s'",
name.c_str(), id, sourceName); name.c_str(), id, sourceName);
obs_source_filter_add(source, filter); obs_source_filter_add(source, filter);
} else {
blog(LOG_WARNING, "Creating filter '%s' failed!", id);
return;
} }
std::string parent_uuid(obs_source_get_uuid(source));
std::string scene_uuid = obs_source_get_uuid(
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->GetCurrentSceneSource());
/* In order to ensure that the UUID persists through undo/redo,
* we save the source data rather than just recreating the
* source from scratch. */
OBSDataAutoRelease rwrapper = obs_save_source(filter);
obs_data_set_string(rwrapper, "undo_uuid", parent_uuid.c_str());
OBSDataAutoRelease uwrapper = obs_data_create();
obs_data_set_string(uwrapper, "fname",
obs_source_get_name(filter));
obs_data_set_string(uwrapper, "suuid", parent_uuid.c_str());
auto undo = [scene_uuid](const std::string &data) {
OBSSourceAutoRelease ssource =
obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true);
OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "suuid"));
OBSSourceAutoRelease filter =
obs_source_get_filter_by_name(
source,
obs_data_get_string(dat, "fname"));
obs_source_filter_remove(source, filter);
};
auto redo = [scene_uuid](const std::string &data) {
OBSSourceAutoRelease ssource =
obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true);
OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "undo_uuid"));
OBSSourceAutoRelease filter = obs_load_source(dat);
obs_source_filter_add(source, filter);
};
std::string undo_data(obs_data_get_json(uwrapper));
std::string redo_data(obs_data_get_json(rwrapper));
main->undo_s.add_action(
QTStr("Undo.Add").arg(obs_source_get_name(filter)),
undo, redo, undo_data, redo_data, false);
} }
} }
@ -1111,43 +1101,36 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
listItem->setText(QT_UTF8(name.c_str())); listItem->setText(QT_UTF8(name.c_str()));
obs_source_set_name(filter, name.c_str()); obs_source_set_name(filter, name.c_str());
std::string scene_name = obs_source_get_name( std::string scene_uuid = obs_source_get_uuid(
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->GetCurrentSceneSource()); ->GetCurrentSceneSource());
auto undo = [scene_name, prev = std::string(prevName), auto undo = [scene_uuid, prev = std::string(prevName),
name](const std::string &data) { name](const std::string &uuid) {
OBSSourceAutoRelease ssource = OBSSourceAutoRelease ssource =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true); ->SetCurrentScene(ssource.Get(), true);
OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str());
OBSSourceAutoRelease filter = OBSSourceAutoRelease filter =
obs_source_get_filter_by_name(source, obs_get_source_by_uuid(uuid.c_str());
name.c_str());
obs_source_set_name(filter, prev.c_str()); obs_source_set_name(filter, prev.c_str());
}; };
auto redo = [scene_name, prev = std::string(prevName), auto redo = [scene_uuid, prev = std::string(prevName),
name](const std::string &data) { name](const std::string &uuid) {
OBSSourceAutoRelease ssource = OBSSourceAutoRelease ssource =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true); ->SetCurrentScene(ssource.Get(), true);
OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str());
OBSSourceAutoRelease filter = OBSSourceAutoRelease filter =
obs_source_get_filter_by_name(source, obs_get_source_by_uuid(uuid.c_str());
prev.c_str());
obs_source_set_name(filter, name.c_str()); obs_source_set_name(filter, name.c_str());
}; };
std::string undo_data(sourceName); std::string filter_uuid(obs_source_get_uuid(filter));
std::string redo_data(sourceName);
main->undo_s.add_action(QTStr("Undo.Rename").arg(name.c_str()), main->undo_s.add_action(QTStr("Undo.Rename").arg(name.c_str()),
undo, redo, undo_data, redo_data); undo, redo, filter_uuid, filter_uuid);
} }
listItem->setText(QString()); listItem->setText(QString());
@ -1236,39 +1219,39 @@ void OBSBasicFilters::PasteFilter()
void OBSBasicFilters::delete_filter(OBSSource filter) void OBSBasicFilters::delete_filter(OBSSource filter)
{ {
OBSDataAutoRelease wrapper = obs_save_source(filter); OBSDataAutoRelease wrapper = obs_save_source(filter);
std::string parent_name(obs_source_get_name(source)); std::string parent_uuid(obs_source_get_uuid(source));
obs_data_set_string(wrapper, "undo_name", parent_name.c_str()); obs_data_set_string(wrapper, "undo_uuid", parent_uuid.c_str());
std::string scene_name = obs_source_get_name( std::string scene_uuid = obs_source_get_uuid(
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->GetCurrentSceneSource()); ->GetCurrentSceneSource());
auto undo = [scene_name](const std::string &data) { auto undo = [scene_uuid](const std::string &data) {
OBSSourceAutoRelease ssource = OBSSourceAutoRelease ssource =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true); ->SetCurrentScene(ssource.Get(), true);
OBSDataAutoRelease dat = OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "undo_name")); obs_data_get_string(dat, "undo_uuid"));
OBSSourceAutoRelease filter = obs_load_source(dat); OBSSourceAutoRelease filter = obs_load_source(dat);
obs_source_filter_add(source, filter); obs_source_filter_add(source, filter);
}; };
OBSDataAutoRelease rwrapper = obs_data_create(); OBSDataAutoRelease rwrapper = obs_data_create();
obs_data_set_string(rwrapper, "fname", obs_source_get_name(filter)); obs_data_set_string(rwrapper, "fname", obs_source_get_name(filter));
obs_data_set_string(rwrapper, "sname", parent_name.c_str()); obs_data_set_string(rwrapper, "suuid", parent_uuid.c_str());
auto redo = [scene_name](const std::string &data) { auto redo = [scene_uuid](const std::string &data) {
OBSSourceAutoRelease ssource = OBSSourceAutoRelease ssource =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(ssource.Get(), true); ->SetCurrentScene(ssource.Get(), true);
OBSDataAutoRelease dat = OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "sname")); obs_data_get_string(dat, "suuid"));
OBSSourceAutoRelease filter = obs_source_get_filter_by_name( OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
source, obs_data_get_string(dat, "fname")); source, obs_data_get_string(dat, "fname"));
obs_source_filter_remove(source, filter); obs_source_filter_remove(source, filter);

View File

@ -189,32 +189,37 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_source_create(type, sourceName.c_str(), settings, nullptr); obs_source_create(type, sourceName.c_str(), settings, nullptr);
if (source) { if (source) {
OBSDataAutoRelease wrapper = obs_save_source(source);
OBSScene scene = main->GetCurrentScene(); OBSScene scene = main->GetCurrentScene();
const char *sceneName = std::string sceneUUID =
obs_source_get_name(obs_scene_get_source(scene)); obs_source_get_uuid(obs_scene_get_source(scene));
auto undo = [sceneName, sourceName](const std::string &) { std::string sourceUUID = obs_source_get_uuid(source);
auto undo = [sceneUUID, sourceUUID](const std::string &) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(sourceName.c_str()); obs_get_source_by_uuid(sourceUUID.c_str());
obs_source_remove(source); obs_source_remove(source);
OBSSourceAutoRelease scene = OBSSourceAutoRelease scene =
obs_get_source_by_name(sceneName); obs_get_source_by_uuid(sceneUUID.c_str());
OBSBasic::Get()->SetCurrentScene(scene.Get(), true); OBSBasic::Get()->SetCurrentScene(scene.Get(), true);
}; };
auto redo = [sceneName, sourceName, auto redo = [sceneUUID, sourceName,
type](const std::string &data) { type](const std::string &data) {
OBSSourceAutoRelease scene = OBSSourceAutoRelease scene =
obs_get_source_by_name(sceneName); obs_get_source_by_uuid(sceneUUID.c_str());
OBSBasic::Get()->SetCurrentScene(scene.Get(), true); OBSBasic::Get()->SetCurrentScene(scene.Get(), true);
OBSDataAutoRelease settings =
OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_source_create( OBSSourceAutoRelease source = obs_load_source(dat);
type, sourceName.c_str(), settings, nullptr);
obs_scene_add(obs_scene_from_source(scene), obs_scene_add(obs_scene_from_source(scene),
source.Get()); source.Get());
}; };
undo_s.add_action(QTStr("Undo.Add").arg(sourceName.c_str()), undo_s.add_action(QTStr("Undo.Add").arg(sourceName.c_str()),
undo, redo, "", undo, redo, "",
std::string(obs_data_get_json(settings))); std::string(obs_data_get_json(wrapper)));
obs_scene_add(scene, source); obs_scene_add(scene, source);
} }
} }

View File

@ -1066,13 +1066,13 @@ void OBSBasic::PasteShowHideTransition(obs_sceneitem_t *item, bool show,
obs_source_t *tr) obs_source_t *tr)
{ {
int64_t sceneItemId = obs_sceneitem_get_id(item); int64_t sceneItemId = obs_sceneitem_get_id(item);
std::string sceneName = obs_source_get_name( std::string sceneUUID = obs_source_get_uuid(
obs_scene_get_source(obs_sceneitem_get_scene(item))); obs_scene_get_source(obs_sceneitem_get_scene(item)));
auto undo_redo = [sceneName, sceneItemId, auto undo_redo = [sceneUUID, sceneItemId,
show](const std::string &data) { show](const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(sceneName.c_str()); obs_get_source_by_uuid(sceneUUID.c_str());
obs_scene_t *scene = obs_scene_from_source(source); obs_scene_t *scene = obs_scene_from_source(source);
obs_sceneitem_t *i = obs_sceneitem_t *i =
obs_scene_find_sceneitem_by_id(scene, sceneItemId); obs_scene_find_sceneitem_by_id(scene, sceneItemId);
@ -1136,14 +1136,14 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
QString id = action->property("transition_id").toString(); QString id = action->property("transition_id").toString();
OBSSceneItem sceneItem = main->GetCurrentSceneItem(); OBSSceneItem sceneItem = main->GetCurrentSceneItem();
int64_t sceneItemId = obs_sceneitem_get_id(sceneItem); int64_t sceneItemId = obs_sceneitem_get_id(sceneItem);
std::string sceneName = std::string sceneUUID =
obs_source_get_name(obs_scene_get_source( obs_source_get_uuid(obs_scene_get_source(
obs_sceneitem_get_scene(sceneItem))); obs_sceneitem_get_scene(sceneItem)));
auto undo_redo = [sceneName, sceneItemId, auto undo_redo = [sceneUUID, sceneItemId,
visible](const std::string &data) { visible](const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(sceneName.c_str()); obs_get_source_by_uuid(sceneUUID.c_str());
obs_scene_t *scene = obs_scene_from_source(source); obs_scene_t *scene = obs_scene_from_source(source);
obs_sceneitem_t *i = obs_scene_find_sceneitem_by_id( obs_sceneitem_t *i = obs_scene_find_sceneitem_by_id(
scene, sceneItemId); scene, sceneItemId);

View File

@ -6632,21 +6632,20 @@ static void RenameListItem(OBSBasic *parent, QListWidget *listWidget,
auto undo = [prev = std::string(prevName)]( auto undo = [prev = std::string(prevName)](
const std::string &data) { const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str()); obs_get_source_by_uuid(data.c_str());
obs_source_set_name(source, prev.c_str()); obs_source_set_name(source, prev.c_str());
}; };
auto redo = [name](const std::string &data) { auto redo = [name](const std::string &data) {
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(data.c_str()); obs_get_source_by_uuid(data.c_str());
obs_source_set_name(source, name.c_str()); obs_source_set_name(source, name.c_str());
}; };
std::string undo_data(name); std::string source_uuid(obs_source_get_uuid(source));
std::string redo_data(prevName);
parent->undo_s.add_action( parent->undo_s.add_action(
QTStr("Undo.Rename").arg(name.c_str()), undo, redo, QTStr("Undo.Rename").arg(name.c_str()), undo, redo,
undo_data, redo_data); source_uuid, source_uuid);
listItem->setText(QT_UTF8(name.c_str())); listItem->setText(QT_UTF8(name.c_str()));
obs_source_set_name(source, name.c_str()); obs_source_set_name(source, name.c_str());
@ -8482,7 +8481,7 @@ void undo_redo(const std::string &data)
{ {
OBSDataAutoRelease dat = obs_data_create_from_json(data.c_str()); OBSDataAutoRelease dat = obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = OBSSourceAutoRelease source =
obs_get_source_by_name(obs_data_get_string(dat, "scene_name")); obs_get_source_by_uuid(obs_data_get_string(dat, "scene_uuid"));
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(source.Get(), true); ->SetCurrentScene(source.Get(), true);
@ -9948,8 +9947,8 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
obs_data_create_from_json(json.c_str()); obs_data_create_from_json(json.c_str());
OBSDataArrayAutoRelease array = OBSDataArrayAutoRelease array =
obs_data_get_array(data, "array"); obs_data_get_array(data, "array");
const char *name = obs_data_get_string(data, "name"); OBSSourceAutoRelease source = obs_get_source_by_uuid(
OBSSourceAutoRelease source = obs_get_source_by_name(name); obs_data_get_string(data, "uuid"));
obs_source_restore_filters(source, array); obs_source_restore_filters(source, array);
@ -9957,14 +9956,14 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
filters->UpdateSource(source); filters->UpdateSource(source);
}; };
const char *name = obs_source_get_name(source); const char *uuid = obs_source_get_uuid(source);
OBSDataAutoRelease undo_data = obs_data_create(); OBSDataAutoRelease undo_data = obs_data_create();
OBSDataAutoRelease redo_data = obs_data_create(); OBSDataAutoRelease redo_data = obs_data_create();
obs_data_set_array(undo_data, "array", undo_array); obs_data_set_array(undo_data, "array", undo_array);
obs_data_set_array(redo_data, "array", redo_array); obs_data_set_array(redo_data, "array", redo_array);
obs_data_set_string(undo_data, "name", name); obs_data_set_string(undo_data, "uuid", uuid);
obs_data_set_string(redo_data, "name", name); obs_data_set_string(redo_data, "uuid", uuid);
undo_s.add_action(text, undo_redo, undo_redo, undo_s.add_action(text, undo_redo, undo_redo,
obs_data_get_json(undo_data), obs_data_get_json(undo_data),

View File

@ -794,8 +794,8 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
auto undo_redo = [](const std::string &data) { auto undo_redo = [](const std::string &data) {
OBSDataAutoRelease dat = OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "scene_name")); obs_data_get_string(dat, "scene_uuid"));
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(source.Get(), true); ->SetCurrentScene(source.Get(), true);

View File

@ -317,20 +317,20 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
if (val == QDialogButtonBox::AcceptRole) { if (val == QDialogButtonBox::AcceptRole) {
std::string scene_name = std::string scene_uuid =
obs_source_get_name(main->GetCurrentSceneSource()); obs_source_get_uuid(main->GetCurrentSceneSource());
auto undo_redo = [scene_name](const std::string &data) { auto undo_redo = [scene_uuid](const std::string &data) {
OBSDataAutoRelease settings = OBSDataAutoRelease settings =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(settings, "undo_sname")); obs_data_get_string(settings, "undo_uuid"));
obs_source_reset_settings(source, settings); obs_source_reset_settings(source, settings);
obs_source_update_properties(source); obs_source_update_properties(source);
OBSSourceAutoRelease scene_source = OBSSourceAutoRelease scene_source =
obs_get_source_by_name(scene_name.c_str()); obs_get_source_by_uuid(scene_uuid.c_str());
OBSBasic::Get()->SetCurrentScene(scene_source.Get(), OBSBasic::Get()->SetCurrentScene(scene_source.Get(),
true); true);
@ -340,10 +340,10 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
OBSDataAutoRelease curr_settings = OBSDataAutoRelease curr_settings =
obs_source_get_settings(source); obs_source_get_settings(source);
obs_data_apply(new_settings, curr_settings); obs_data_apply(new_settings, curr_settings);
obs_data_set_string(new_settings, "undo_sname", obs_data_set_string(new_settings, "undo_uuid",
obs_source_get_name(source)); obs_source_get_uuid(source));
obs_data_set_string(oldSettings, "undo_sname", obs_data_set_string(oldSettings, "undo_uuid",
obs_source_get_name(source)); obs_source_get_uuid(source));
std::string undo_data(obs_data_get_json(oldSettings)); std::string undo_data(obs_data_get_json(oldSettings));
std::string redo_data(obs_data_get_json(new_settings)); std::string redo_data(obs_data_get_json(new_settings));

View File

@ -93,8 +93,8 @@ OBSBasicTransform::~OBSBasicTransform()
auto undo_redo = [](const std::string &data) { auto undo_redo = [](const std::string &data) {
OBSDataAutoRelease dat = OBSDataAutoRelease dat =
obs_data_create_from_json(data.c_str()); obs_data_create_from_json(data.c_str());
OBSSourceAutoRelease source = obs_get_source_by_name( OBSSourceAutoRelease source = obs_get_source_by_uuid(
obs_data_get_string(dat, "scene_name")); obs_data_get_string(dat, "scene_uuid"));
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()) reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
->SetCurrentScene(source.Get(), true); ->SetCurrentScene(source.Get(), true);
obs_scene_load_transform_states(data.c_str()); obs_scene_load_transform_states(data.c_str());