UI: Add Group/Ungroup Undo/Redo actions

This commit is contained in:
jp9000 2021-05-21 18:15:25 -07:00
parent 64cd451def
commit c4c5b0d21d
3 changed files with 87 additions and 9 deletions

View File

@ -311,6 +311,7 @@ Undo.MoveToTop="Move '%1' to top in '%2'"
Undo.MoveToBottom="Move '%1' to bottom in '%2'" Undo.MoveToBottom="Move '%1' to bottom in '%2'"
Undo.PasteSource="Paste Source(s) in '%1'" Undo.PasteSource="Paste Source(s) in '%1'"
Undo.PasteSourceRef="Paste Source Reference(s) in '%1'" Undo.PasteSourceRef="Paste Source Reference(s) in '%1'"
Undo.GroupItems="Group Items into '%1'"
# transition name dialog # transition name dialog
TransitionNameDlg.Text="Please enter the name of the transition" TransitionNameDlg.Text="Please enter the name of the transition"

View File

@ -377,13 +377,32 @@ void SourceTreeItem::EnterEditMode()
void SourceTreeItem::ExitEditMode(bool save) void SourceTreeItem::ExitEditMode(bool save)
{ {
if (!editor) ExitEditModeInternal(save);
if (tree->undoSceneData) {
OBSBasic *main = OBSBasic::Get();
main->undo_s.pop_disabled();
OBSData redoSceneData = main->BackupScene(GetCurrentScene());
QString text = QTStr("Undo.GroupItems").arg(newName.c_str());
main->CreateSceneUndoRedoAction(text, tree->undoSceneData,
redoSceneData);
tree->undoSceneData = nullptr;
}
}
void SourceTreeItem::ExitEditModeInternal(bool save)
{
if (!editor) {
return; return;
}
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow()); OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene(); OBSScene scene = main->GetCurrentScene();
std::string newName = QT_TO_UTF8(editor->text()); newName = QT_TO_UTF8(editor->text());
setFocusProxy(nullptr); setFocusProxy(nullptr);
int index = boxLayout->indexOf(editor); int index = boxLayout->indexOf(editor);
@ -444,9 +463,11 @@ void SourceTreeItem::ExitEditMode(bool save)
obs_source_release(scene_source); obs_source_release(scene_source);
}; };
auto redo = [scene_name, main, newName](const std::string &data) { std::string editedName = newName;
auto redo = [scene_name, main, editedName](const std::string &data) {
obs_source_t *source = obs_get_source_by_name(data.c_str()); obs_source_t *source = obs_get_source_by_name(data.c_str());
obs_source_set_name(source, newName.c_str()); obs_source_set_name(source, editedName.c_str());
obs_source_release(source); obs_source_release(source);
obs_source_t *scene_source = obs_source_t *scene_source =
@ -913,6 +934,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
if (indices.count() == 0) if (indices.count() == 0)
return; return;
OBSBasic *main = OBSBasic::Get();
OBSScene scene = GetCurrentScene(); OBSScene scene = GetCurrentScene();
QString name = GetNewGroupName(); QString name = GetNewGroupName();
@ -923,12 +945,17 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
item_order << item; item_order << item;
} }
st->undoSceneData = main->BackupScene(scene);
obs_sceneitem_t *item = obs_scene_insert_group( obs_sceneitem_t *item = obs_scene_insert_group(
scene, QT_TO_UTF8(name), item_order.data(), item_order.size()); scene, QT_TO_UTF8(name), item_order.data(), item_order.size());
if (!item) { if (!item) {
st->undoSceneData = nullptr;
return; return;
} }
main->undo_s.push_disabled();
for (obs_sceneitem_t *item : item_order) for (obs_sceneitem_t *item : item_order)
obs_sceneitem_select(item, false); obs_sceneitem_select(item, false);
@ -954,21 +981,29 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
obs_sceneitem_select(item, true); obs_sceneitem_select(item, true);
QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection, QMetaObject::invokeMethod(st, "NewGroupEdit", Qt::QueuedConnection,
Q_ARG(int, newIdx)); Q_ARG(int, newIdx));
} }
void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices) void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices)
{ {
OBSBasic *main = OBSBasic::Get();
if (indices.count() == 0) if (indices.count() == 0)
return; return;
OBSScene scene = main->GetCurrentScene();
OBSData undoData = main->BackupScene(scene);
for (int i = indices.count() - 1; i >= 0; i--) { for (int i = indices.count() - 1; i >= 0; i--) {
obs_sceneitem_t *item = items[indices[i].row()]; obs_sceneitem_t *item = items[indices[i].row()];
obs_sceneitem_group_ungroup(item); obs_sceneitem_group_ungroup(item);
} }
SceneChanged(); SceneChanged();
OBSData redoData = main->BackupScene(scene);
main->CreateSceneUndoRedoAction(QTStr("Basic.Main.Ungroup"), undoData,
redoData);
} }
void SourceTreeModel::ExpandGroup(obs_sceneitem_t *item) void SourceTreeModel::ExpandGroup(obs_sceneitem_t *item)
@ -1495,20 +1530,55 @@ void SourceTree::selectionChanged(const QItemSelection &selected,
QListView::selectionChanged(selected, deselected); QListView::selectionChanged(selected, deselected);
} }
void SourceTree::Edit(int row) void SourceTree::NewGroupEdit(int row)
{
if (!Edit(row)) {
OBSBasic *main = OBSBasic::Get();
main->undo_s.pop_disabled();
blog(LOG_WARNING, "Uh, somehow the edit didn't process, this "
"code should never be reached.\nAnd by "
"\"never be reached\", I mean that "
"theoretically, it should be\nimpossible "
"for this code to be reached. But if this "
"code is reached,\nfeel free to laugh at "
"Jim, because apparently it is, in fact, "
"actually\npossible for this code to be "
"reached. But I mean, again, theoretically\n"
"it should be impossible. So if you see "
"this in your log, just know that\nit's "
"really dumb, and depressing. But at least "
"the undo/redo action is\nstill covered, so "
"in theory things *should* be fine. But "
"it's entirely\npossible that they might "
"not be exactly. But again, yea. This "
"really\nshould not be possible.");
OBSData redoSceneData = main->BackupScene(GetCurrentScene());
QString text = QTStr("Undo.GroupItems").arg("Unknown");
main->CreateSceneUndoRedoAction(text, undoSceneData,
redoSceneData);
undoSceneData = nullptr;
}
}
bool SourceTree::Edit(int row)
{ {
SourceTreeModel *stm = GetStm(); SourceTreeModel *stm = GetStm();
if (row < 0 || row >= stm->items.count()) if (row < 0 || row >= stm->items.count())
return; return false;
QModelIndex index = stm->createIndex(row, 0); QModelIndex index = stm->createIndex(row, 0);
QWidget *widget = indexWidget(index); QWidget *widget = indexWidget(index);
SourceTreeItem *itemWidget = reinterpret_cast<SourceTreeItem *>(widget); SourceTreeItem *itemWidget = reinterpret_cast<SourceTreeItem *>(widget);
if (itemWidget->IsEditing()) if (itemWidget->IsEditing())
return; return false;
itemWidget->EnterEditMode(); itemWidget->EnterEditMode();
edit(index); edit(index);
return true;
} }
bool SourceTree::MultipleBaseSelected() const bool SourceTree::MultipleBaseSelected() const

View File

@ -69,6 +69,8 @@ private:
QLineEdit *editor = nullptr; QLineEdit *editor = nullptr;
std::string newName;
SourceTree *tree; SourceTree *tree;
OBSSceneItem sceneitem; OBSSceneItem sceneitem;
OBSSignal sceneRemoveSignal; OBSSignal sceneRemoveSignal;
@ -83,6 +85,8 @@ private:
virtual void paintEvent(QPaintEvent *event) override; virtual void paintEvent(QPaintEvent *event) override;
void ExitEditModeInternal(bool save);
private slots: private slots:
void Clear(); void Clear();
@ -152,6 +156,8 @@ class SourceTree : public QListView {
QStaticText textNoSources; QStaticText textNoSources;
QSvgRenderer iconNoSources; QSvgRenderer iconNoSources;
OBSData undoSceneData;
bool iconsVisible = true; bool iconsVisible = true;
void UpdateNoSourcesMessage(); void UpdateNoSourcesMessage();
@ -197,7 +203,8 @@ public slots:
void GroupSelectedItems(); void GroupSelectedItems();
void UngroupSelectedGroups(); void UngroupSelectedGroups();
void AddGroup(); void AddGroup();
void Edit(int idx); bool Edit(int idx);
void NewGroupEdit(int idx);
protected: protected:
virtual void mouseDoubleClickEvent(QMouseEvent *event) override; virtual void mouseDoubleClickEvent(QMouseEvent *event) override;