284 lines
9.7 KiB
Diff
284 lines
9.7 KiB
Diff
|
From 01f0cab97d222f5cd4d7468f730370e76f08b42a Mon Sep 17 00:00:00 2001
|
||
|
From: CodeYan01 <65320293+CodeYan01@users.noreply.github.com>
|
||
|
Date: Thu, 12 Jan 2023 01:01:14 +0800
|
||
|
Subject: [PATCH] UI: Refactor editable list modification
|
||
|
|
||
|
Previously would unnecessarily recreating the data array for every
|
||
|
modification (adding/removing/reordering/editing). This clears the
|
||
|
fields in the associated data array that other code/scripts would add,
|
||
|
such as an ID field for each item that could be used to distinguish
|
||
|
each item from their duplicates in the list.
|
||
|
|
||
|
I initially wanted to remove EditableListChanged, but it no longer saved
|
||
|
the item selection whenever the list is modified, so I kept the function
|
||
|
and just changed it to update the selected state in the data array.
|
||
|
---
|
||
|
UI/properties-view.cpp | 97 +++++++++++++++++++++++++++++++++++++-----
|
||
|
UI/properties-view.hpp | 6 +++
|
||
|
2 files changed, 93 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp
|
||
|
index 7d8838b3603a2..025b104d0db27 100644
|
||
|
--- a/UI/properties-view.cpp
|
||
|
+++ b/UI/properties-view.cpp
|
||
|
@@ -709,6 +709,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
|
||
|
{
|
||
|
const char *name = obs_property_name(prop);
|
||
|
OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
|
||
|
+ if (array == NULL) {
|
||
|
+ array = obs_data_array_create();
|
||
|
+ obs_data_set_array(settings, name, array);
|
||
|
+ }
|
||
|
+
|
||
|
QListWidget *list = new QListWidget();
|
||
|
size_t count = obs_data_array_count(array);
|
||
|
|
||
|
@@ -731,8 +736,8 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
|
||
|
WidgetInfo *info = new WidgetInfo(this, prop, list);
|
||
|
|
||
|
list->setDragDropMode(QAbstractItemView::InternalMove);
|
||
|
- connect(list->model(), &QAbstractItemModel::rowsMoved,
|
||
|
- [info]() { info->EditableListChanged(); });
|
||
|
+ connect(list->model(), &QAbstractItemModel::rowsMoved, info,
|
||
|
+ &WidgetInfo::EditListReordered);
|
||
|
|
||
|
QVBoxLayout *sideLayout = new QVBoxLayout();
|
||
|
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
|
||
|
@@ -1992,24 +1997,52 @@ void WidgetInfo::GroupChanged(const char *setting)
|
||
|
: true);
|
||
|
}
|
||
|
|
||
|
+void WidgetInfo::EditListReordered(const QModelIndex &sourceParent,
|
||
|
+ int sourceStart, int sourceEnd,
|
||
|
+ const QModelIndex &destinationParent,
|
||
|
+ int destinationRow)
|
||
|
+{
|
||
|
+ UNUSED_PARAMETER(sourceParent);
|
||
|
+ UNUSED_PARAMETER(destinationParent);
|
||
|
+
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
+
|
||
|
+ for (int i = sourceStart; i <= sourceEnd; i++) {
|
||
|
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
|
||
|
+ obs_data_array_insert(array, destinationRow, arrayItem);
|
||
|
+ // if moved to top, destination row increases
|
||
|
+ obs_data_array_erase(array, (i > destinationRow) ? i + 1 : i);
|
||
|
+ ++destinationRow;
|
||
|
+ }
|
||
|
+ EditableListChanged();
|
||
|
+}
|
||
|
+
|
||
|
+void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
|
||
|
+ const char *text)
|
||
|
+{
|
||
|
+ OBSDataAutoRelease arrayItem = obs_data_create();
|
||
|
+ obs_data_set_string(arrayItem, "value", text);
|
||
|
+ obs_data_set_bool(arrayItem, "selected", false);
|
||
|
+ obs_data_set_bool(arrayItem, "hidden", false);
|
||
|
+ obs_data_array_push_back(array, arrayItem);
|
||
|
+}
|
||
|
+
|
||
|
void WidgetInfo::EditableListChanged()
|
||
|
{
|
||
|
const char *setting = obs_property_name(property);
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
- OBSDataArrayAutoRelease array = obs_data_array_create();
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
for (int i = 0; i < list->count(); i++) {
|
||
|
QListWidgetItem *item = list->item(i);
|
||
|
- OBSDataAutoRelease arrayItem = obs_data_create();
|
||
|
- obs_data_set_string(arrayItem, "value",
|
||
|
- QT_TO_UTF8(item->text()));
|
||
|
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
|
||
|
obs_data_set_bool(arrayItem, "selected", item->isSelected());
|
||
|
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
|
||
|
- obs_data_array_push_back(array, arrayItem);
|
||
|
}
|
||
|
|
||
|
- obs_data_set_array(view->settings, setting, array);
|
||
|
-
|
||
|
ControlChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2263,6 +2296,9 @@ void WidgetInfo::EditListAddText()
|
||
|
{
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
const char *desc = obs_property_description(property);
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
EditableItemDialog dialog(widget->window(), QString(), false);
|
||
|
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
|
||
|
@@ -2276,6 +2312,7 @@ void WidgetInfo::EditListAddText()
|
||
|
return;
|
||
|
|
||
|
list->addItem(text);
|
||
|
+ EditableListArrayPushBack(array, QT_TO_UTF8(text));
|
||
|
EditableListChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2286,6 +2323,9 @@ void WidgetInfo::EditListAddFiles()
|
||
|
const char *filter = obs_property_editable_list_filter(property);
|
||
|
const char *default_path =
|
||
|
obs_property_editable_list_default_path(property);
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
|
||
|
.arg(QT_UTF8(desc));
|
||
|
@@ -2301,6 +2341,9 @@ void WidgetInfo::EditListAddFiles()
|
||
|
return;
|
||
|
|
||
|
list->addItems(files);
|
||
|
+ for (QString &file : files) {
|
||
|
+ EditableListArrayPushBack(array, QT_TO_UTF8(file));
|
||
|
+ }
|
||
|
EditableListChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2310,6 +2353,9 @@ void WidgetInfo::EditListAddDir()
|
||
|
const char *desc = obs_property_description(property);
|
||
|
const char *default_path =
|
||
|
obs_property_editable_list_default_path(property);
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
|
||
|
.arg(QT_UTF8(desc));
|
||
|
@@ -2325,6 +2371,7 @@ void WidgetInfo::EditListAddDir()
|
||
|
return;
|
||
|
|
||
|
list->addItem(dir);
|
||
|
+ EditableListArrayPushBack(array, QT_TO_UTF8(dir));
|
||
|
EditableListChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2332,9 +2379,15 @@ void WidgetInfo::EditListRemove()
|
||
|
{
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
QList<QListWidgetItem *> items = list->selectedItems();
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
- for (QListWidgetItem *item : items)
|
||
|
+ for (qsizetype i = items.size() - 1; i >= 0; i--) {
|
||
|
+ QListWidgetItem *item = items.at(i);
|
||
|
+ obs_data_array_erase(array, list->row(item));
|
||
|
delete item;
|
||
|
+ }
|
||
|
EditableListChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2343,6 +2396,7 @@ void WidgetInfo::EditListEdit()
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
enum obs_editable_list_type type =
|
||
|
obs_property_editable_list_type(property);
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
const char *desc = obs_property_description(property);
|
||
|
const char *filter = obs_property_editable_list_filter(property);
|
||
|
QList<QListWidgetItem *> selectedItems = list->selectedItems();
|
||
|
@@ -2351,6 +2405,10 @@ void WidgetInfo::EditListEdit()
|
||
|
return;
|
||
|
|
||
|
QListWidgetItem *item = selectedItems[0];
|
||
|
+ int row = list->row(item);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
|
||
|
|
||
|
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
|
||
|
QDir pathDir(item->text());
|
||
|
@@ -2367,6 +2425,7 @@ void WidgetInfo::EditListEdit()
|
||
|
return;
|
||
|
|
||
|
item->setText(path);
|
||
|
+ obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
|
||
|
EditableListChanged();
|
||
|
return;
|
||
|
}
|
||
|
@@ -2385,6 +2444,7 @@ void WidgetInfo::EditListEdit()
|
||
|
return;
|
||
|
|
||
|
item->setText(text);
|
||
|
+ obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
|
||
|
EditableListChanged();
|
||
|
}
|
||
|
|
||
|
@@ -2392,6 +2452,9 @@ void WidgetInfo::EditListUp()
|
||
|
{
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
int lastItemRow = -1;
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
for (int i = 0; i < list->count(); i++) {
|
||
|
QListWidgetItem *item = list->item(i);
|
||
|
@@ -2405,6 +2468,11 @@ void WidgetInfo::EditListUp()
|
||
|
list->takeItem(row);
|
||
|
list->insertItem(lastItemRow, item);
|
||
|
item->setSelected(true);
|
||
|
+
|
||
|
+ OBSDataAutoRelease arrayItem =
|
||
|
+ obs_data_array_item(array, row);
|
||
|
+ obs_data_array_insert(array, lastItemRow, arrayItem);
|
||
|
+ obs_data_array_erase(array, row + 1);
|
||
|
} else {
|
||
|
lastItemRow = row;
|
||
|
}
|
||
|
@@ -2417,6 +2485,9 @@ void WidgetInfo::EditListDown()
|
||
|
{
|
||
|
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||
|
int lastItemRow = list->count();
|
||
|
+ const char *setting = obs_property_name(property);
|
||
|
+ OBSDataArrayAutoRelease array =
|
||
|
+ obs_data_get_array(view->settings, setting);
|
||
|
|
||
|
for (int i = list->count() - 1; i >= 0; i--) {
|
||
|
QListWidgetItem *item = list->item(i);
|
||
|
@@ -2430,6 +2501,12 @@ void WidgetInfo::EditListDown()
|
||
|
list->takeItem(row);
|
||
|
list->insertItem(lastItemRow, item);
|
||
|
item->setSelected(true);
|
||
|
+
|
||
|
+ OBSDataAutoRelease arrayItem =
|
||
|
+ obs_data_array_item(array, row);
|
||
|
+ obs_data_array_insert(array, lastItemRow + 1,
|
||
|
+ arrayItem);
|
||
|
+ obs_data_array_erase(array, row);
|
||
|
} else {
|
||
|
lastItemRow = row;
|
||
|
}
|
||
|
diff --git a/UI/properties-view.hpp b/UI/properties-view.hpp
|
||
|
index e520dcdde2c90..89546b1317fba 100644
|
||
|
--- a/UI/properties-view.hpp
|
||
|
+++ b/UI/properties-view.hpp
|
||
|
@@ -47,6 +47,8 @@ class WidgetInfo : public QObject {
|
||
|
void ButtonClicked();
|
||
|
|
||
|
void TogglePasswordText(bool checked);
|
||
|
+ void EditableListArrayPushBack(obs_data_array_t *array,
|
||
|
+ const char *text);
|
||
|
|
||
|
public:
|
||
|
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
|
||
|
@@ -79,6 +81,10 @@ public slots:
|
||
|
void EditListEdit();
|
||
|
void EditListUp();
|
||
|
void EditListDown();
|
||
|
+ void EditListReordered(const QModelIndex &sourceParent, int sourceStart,
|
||
|
+ int sourceEnd,
|
||
|
+ const QModelIndex &destinationParent,
|
||
|
+ int destinationRow);
|
||
|
};
|
||
|
|
||
|
/* ------------------------------------------------------------------------- */
|