0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

UI: Undo/Redo Scene Collections

Implements undo/redo for scene collections. This includes operations
including rename, delete, and addition.
This commit is contained in:
Ford Smith 2021-03-22 01:27:10 -04:00 committed by Ford Smith
parent 3c5e2ddc37
commit a374c023a1
2 changed files with 160 additions and 12 deletions

View File

@ -151,17 +151,55 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
}
}
SaveProjectNow();
auto new_collection = [this, create_new](const std::string &file,
const std::string &name) {
SaveProjectNow();
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
name.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
file.c_str());
if (create_new) {
CreateDefaultScene(false);
}
SaveProjectNow();
RefreshSceneCollections();
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollection", name.c_str());
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile", file.c_str());
if (create_new) {
CreateDefaultScene(false);
}
SaveProjectNow();
RefreshSceneCollections();
};
new_collection(file, name);
auto undo = [this, oldName = name](const std::string &data) {
std::string newPath;
auto cb = [&](const char *name, const char *filePath) {
if (strcmp(oldName.c_str(), name) != 0) {
newPath = filePath;
return false;
}
return true;
};
EnumSceneCollections(cb);
char path[512];
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
blog(LOG_WARNING,
"Failed to get scene collection config path");
return;
}
std::string file = path + data + ".json";
os_unlink(file.c_str());
file += ".bak";
os_unlink(file.c_str());
Load(newPath.c_str());
RefreshSceneCollections();
};
auto redo = [new_collection, file, name](const std::string &) {
new_collection(file, name);
};
undo_s.add_action(QTStr("Undo.Add").arg(name.c_str()), undo, redo, file,
"", NULL);
blog(LOG_INFO, "Added scene collection '%s' (%s, %s.json)",
name.c_str(), create_new ? "clean" : "duplicate", file.c_str());
@ -245,11 +283,13 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
{
std::string name;
std::string file;
std::string oname;
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
oname = std::string(oldName);
bool success = GetSceneCollectionName(this, name, file, oldName);
if (!success)
@ -268,6 +308,59 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
return;
}
auto undo = [name = oname, file = oldFile, of = file,
this](const std::string &) {
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollection", name.c_str());
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile", file.c_str());
SaveProjectNow();
char path[512];
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
blog(LOG_WARNING,
"Failed to get scene collection config path");
return;
}
std::string oldFile = of;
oldFile.insert(0, path);
oldFile += ".json";
os_unlink(oldFile.c_str());
oldFile += ".bak";
os_unlink(oldFile.c_str());
UpdateTitleBar();
RefreshSceneCollections();
};
auto redo = [of = oldFile, name, file, this](const std::string &) {
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollection", name.c_str());
config_set_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile", file.c_str());
SaveProjectNow();
char path[512];
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
blog(LOG_WARNING,
"Failed to get scene collection config path");
return;
}
std::string oldFile = of;
oldFile.insert(0, path);
oldFile += ".json";
os_unlink(oldFile.c_str());
oldFile += ".bak";
os_unlink(oldFile.c_str());
UpdateTitleBar();
RefreshSceneCollections();
};
oldFile.insert(0, path);
oldFile += ".json";
os_unlink(oldFile.c_str());
@ -282,6 +375,9 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
UpdateTitleBar();
RefreshSceneCollections();
undo_s.add_action(QTStr("Undo.Rename").arg(name.c_str()), undo, redo,
"", "", NULL);
if (api) {
api->on_event(OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED);
api->on_event(OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED);
@ -331,6 +427,32 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
oldFile.insert(0, path);
oldFile += ".json";
obs_data_t *data =
obs_data_create_from_json_file_safe(oldFile.c_str(), "bak");
obs_data_set_string(data, "undo_filename", oldFile.c_str());
auto undo = [this](const std::string &data) {
obs_data_t *dat = obs_data_create_from_json(data.c_str());
LoadData(dat, obs_data_get_string(dat, "undo_filename"));
SaveProjectNow();
RefreshSceneCollections();
obs_data_release(dat);
};
auto redo = [this, of = oldFile, newPath](const std::string &) {
std::string oldFile = of;
os_unlink(oldFile.c_str());
oldFile += ".bak";
os_unlink(oldFile.c_str());
Load(newPath.c_str());
RefreshSceneCollections();
};
std::string undo_data = std::string(obs_data_get_json(data));
undo_s.add_action(QTStr("Undo.Delete").arg(oldName.c_str()), undo, redo,
undo_data, "", NULL);
obs_data_release(data);
os_unlink(oldFile.c_str());
oldFile += ".bak";
os_unlink(oldFile.c_str());
@ -410,6 +532,9 @@ void OBSBasic::ChangeSceneCollection()
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
std::string oldFile = std::string(config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollectionFile"));
if (action->text().compare(QT_UTF8(oldName)) == 0) {
action->setChecked(true);
return;
@ -431,6 +556,29 @@ void OBSBasic::ChangeSceneCollection()
UpdateTitleBar();
auto undo = [this, fn = std::string(oldFile)](const std::string &) {
string fileName = fn;
char path[512];
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
blog(LOG_WARNING,
"Failed to get scene collection config path");
return;
}
fileName.insert(0, path);
fileName += ".json";
Load(fileName.c_str());
RefreshSceneCollections();
};
auto redo = [this, fileName](const std::string &) {
Load(fileName.c_str());
RefreshSceneCollections();
};
undo_s.add_action(QTStr("Undo.SceneCollection.Switch").arg(newName),
undo, redo, "", "", NULL);
if (api)
api->on_event(OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED);
}

View File

@ -925,6 +925,8 @@ void OBSBasic::LogScenes()
void OBSBasic::Load(const char *file)
{
disableSaving++;
obs_data_t *data = obs_data_create_from_json_file_safe(file, "bak");
if (!data) {
disableSaving--;
@ -939,8 +941,6 @@ void OBSBasic::Load(const char *file)
void OBSBasic::LoadData(obs_data_t *data, const char *file)
{
disableSaving++;
ClearSceneData();
InitDefaultTransitions();
ClearContextBar();