Skip to content

Commit 52ccbc4

Browse files
committed
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.
1 parent c58e511 commit 52ccbc4

2 files changed

Lines changed: 89 additions & 12 deletions

File tree

UI/properties-view.cpp

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
671671
{
672672
const char *name = obs_property_name(prop);
673673
OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
674+
if (array == NULL) {
675+
array = obs_data_array_create();
676+
obs_data_set_array(settings, name, array);
677+
}
678+
674679
QListWidget *list = new QListWidget();
675680
size_t count = obs_data_array_count(array);
676681

@@ -693,8 +698,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
693698
WidgetInfo *info = new WidgetInfo(this, prop, list);
694699

695700
list->setDragDropMode(QAbstractItemView::InternalMove);
696-
connect(list->model(), SIGNAL(rowsMoved()), info,
697-
SLOT(EditListReordered()));
701+
connect(list->model(),
702+
SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)),
703+
info,
704+
SLOT(EditListReordered(const QModelIndex &, int, int,
705+
const QModelIndex &, int)));
698706

699707
QVBoxLayout *sideLayout = new QVBoxLayout();
700708
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -1932,29 +1940,51 @@ void WidgetInfo::GroupChanged(const char *setting)
19321940
: true);
19331941
}
19341942

1935-
void WidgetInfo::EditListReordered()
1943+
void WidgetInfo::EditListReordered(const QModelIndex &parent, int start,
1944+
int end, const QModelIndex &destination,
1945+
int row)
19361946
{
1947+
UNUSED_PARAMETER(parent);
1948+
UNUSED_PARAMETER(destination);
1949+
1950+
const char *setting = obs_property_name(property);
1951+
OBSDataArrayAutoRelease array =
1952+
obs_data_get_array(view->settings, setting);
1953+
1954+
for (int i = start; i <= end; i++) {
1955+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
1956+
obs_data_array_insert(array, row, arrayItem);
1957+
// if moved to top, item row increases
1958+
obs_data_array_erase(array, (i > row) ? i + 1 : i);
1959+
++row;
1960+
}
19371961
EditableListChanged();
19381962
}
19391963

1964+
void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
1965+
const char *text)
1966+
{
1967+
OBSDataAutoRelease arrayItem = obs_data_create();
1968+
obs_data_set_string(arrayItem, "value", text);
1969+
obs_data_set_bool(arrayItem, "selected", false);
1970+
obs_data_set_bool(arrayItem, "hidden", false);
1971+
obs_data_array_push_back(array, arrayItem);
1972+
}
1973+
19401974
void WidgetInfo::EditableListChanged()
19411975
{
19421976
const char *setting = obs_property_name(property);
19431977
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
1944-
OBSDataArrayAutoRelease array = obs_data_array_create();
1978+
OBSDataArrayAutoRelease array =
1979+
obs_data_get_array(view->settings, setting);
19451980

19461981
for (int i = 0; i < list->count(); i++) {
19471982
QListWidgetItem *item = list->item(i);
1948-
OBSDataAutoRelease arrayItem = obs_data_create();
1949-
obs_data_set_string(arrayItem, "value",
1950-
QT_TO_UTF8(item->text()));
1983+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
19511984
obs_data_set_bool(arrayItem, "selected", item->isSelected());
19521985
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
1953-
obs_data_array_push_back(array, arrayItem);
19541986
}
19551987

1956-
obs_data_set_array(view->settings, setting, array);
1957-
19581988
ControlChanged();
19591989
}
19601990

@@ -2206,6 +2236,9 @@ void WidgetInfo::EditListAddText()
22062236
{
22072237
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22082238
const char *desc = obs_property_description(property);
2239+
const char *setting = obs_property_name(property);
2240+
OBSDataArrayAutoRelease array =
2241+
obs_data_get_array(view->settings, setting);
22092242

22102243
EditableItemDialog dialog(widget->window(), QString(), false);
22112244
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
@@ -2219,6 +2252,7 @@ void WidgetInfo::EditListAddText()
22192252
return;
22202253

22212254
list->addItem(text);
2255+
EditableListArrayPushBack(array, QT_TO_UTF8(text));
22222256
EditableListChanged();
22232257
}
22242258

@@ -2229,6 +2263,9 @@ void WidgetInfo::EditListAddFiles()
22292263
const char *filter = obs_property_editable_list_filter(property);
22302264
const char *default_path =
22312265
obs_property_editable_list_default_path(property);
2266+
const char *setting = obs_property_name(property);
2267+
OBSDataArrayAutoRelease array =
2268+
obs_data_get_array(view->settings, setting);
22322269

22332270
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
22342271
.arg(QT_UTF8(desc));
@@ -2244,6 +2281,9 @@ void WidgetInfo::EditListAddFiles()
22442281
return;
22452282

22462283
list->addItems(files);
2284+
for (QString &file : files) {
2285+
EditableListArrayPushBack(array, QT_TO_UTF8(file));
2286+
}
22472287
EditableListChanged();
22482288
}
22492289

@@ -2253,6 +2293,9 @@ void WidgetInfo::EditListAddDir()
22532293
const char *desc = obs_property_description(property);
22542294
const char *default_path =
22552295
obs_property_editable_list_default_path(property);
2296+
const char *setting = obs_property_name(property);
2297+
OBSDataArrayAutoRelease array =
2298+
obs_data_get_array(view->settings, setting);
22562299

22572300
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
22582301
.arg(QT_UTF8(desc));
@@ -2268,16 +2311,23 @@ void WidgetInfo::EditListAddDir()
22682311
return;
22692312

22702313
list->addItem(dir);
2314+
EditableListArrayPushBack(array, QT_TO_UTF8(dir));
22712315
EditableListChanged();
22722316
}
22732317

22742318
void WidgetInfo::EditListRemove()
22752319
{
22762320
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22772321
QList<QListWidgetItem *> items = list->selectedItems();
2322+
const char *setting = obs_property_name(property);
2323+
OBSDataArrayAutoRelease array =
2324+
obs_data_get_array(view->settings, setting);
22782325

2279-
for (QListWidgetItem *item : items)
2326+
for (qsizetype i = items.size() - 1; i >= 0; i--) {
2327+
QListWidgetItem *item = items.at(i);
2328+
obs_data_array_erase(array, list->row(item));
22802329
delete item;
2330+
}
22812331
EditableListChanged();
22822332
}
22832333

@@ -2286,6 +2336,7 @@ void WidgetInfo::EditListEdit()
22862336
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22872337
enum obs_editable_list_type type =
22882338
obs_property_editable_list_type(property);
2339+
const char *setting = obs_property_name(property);
22892340
const char *desc = obs_property_description(property);
22902341
const char *filter = obs_property_editable_list_filter(property);
22912342
QList<QListWidgetItem *> selectedItems = list->selectedItems();
@@ -2294,6 +2345,10 @@ void WidgetInfo::EditListEdit()
22942345
return;
22952346

22962347
QListWidgetItem *item = selectedItems[0];
2348+
int row = list->row(item);
2349+
OBSDataArrayAutoRelease array =
2350+
obs_data_get_array(view->settings, setting);
2351+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
22972352

22982353
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
22992354
QDir pathDir(item->text());
@@ -2310,6 +2365,7 @@ void WidgetInfo::EditListEdit()
23102365
return;
23112366

23122367
item->setText(path);
2368+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
23132369
EditableListChanged();
23142370
return;
23152371
}
@@ -2328,13 +2384,17 @@ void WidgetInfo::EditListEdit()
23282384
return;
23292385

23302386
item->setText(text);
2387+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
23312388
EditableListChanged();
23322389
}
23332390

23342391
void WidgetInfo::EditListUp()
23352392
{
23362393
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23372394
int lastItemRow = -1;
2395+
const char *setting = obs_property_name(property);
2396+
OBSDataArrayAutoRelease array =
2397+
obs_data_get_array(view->settings, setting);
23382398

23392399
for (int i = 0; i < list->count(); i++) {
23402400
QListWidgetItem *item = list->item(i);
@@ -2348,6 +2408,11 @@ void WidgetInfo::EditListUp()
23482408
list->takeItem(row);
23492409
list->insertItem(lastItemRow, item);
23502410
item->setSelected(true);
2411+
2412+
OBSDataAutoRelease arrayItem =
2413+
obs_data_array_item(array, row);
2414+
obs_data_array_insert(array, lastItemRow, arrayItem);
2415+
obs_data_array_erase(array, row + 1);
23512416
} else {
23522417
lastItemRow = row;
23532418
}
@@ -2360,6 +2425,9 @@ void WidgetInfo::EditListDown()
23602425
{
23612426
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23622427
int lastItemRow = list->count();
2428+
const char *setting = obs_property_name(property);
2429+
OBSDataArrayAutoRelease array =
2430+
obs_data_get_array(view->settings, setting);
23632431

23642432
for (int i = list->count() - 1; i >= 0; i--) {
23652433
QListWidgetItem *item = list->item(i);
@@ -2373,6 +2441,12 @@ void WidgetInfo::EditListDown()
23732441
list->takeItem(row);
23742442
list->insertItem(lastItemRow, item);
23752443
item->setSelected(true);
2444+
2445+
OBSDataAutoRelease arrayItem =
2446+
obs_data_array_item(array, row);
2447+
obs_data_array_insert(array, lastItemRow + 1,
2448+
arrayItem);
2449+
obs_data_array_erase(array, row);
23762450
} else {
23772451
lastItemRow = row;
23782452
}

UI/properties-view.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class WidgetInfo : public QObject {
4747
void ButtonClicked();
4848

4949
void TogglePasswordText(bool checked);
50+
void EditableListArrayPushBack(obs_data_array_t *array,
51+
const char *text);
5052

5153
public:
5254
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
@@ -77,7 +79,8 @@ public slots:
7779
void EditListEdit();
7880
void EditListUp();
7981
void EditListDown();
80-
void EditListReordered();
82+
void EditListReordered(const QModelIndex &parent, int start, int end,
83+
const QModelIndex &destination, int row);
8184
};
8285

8386
/* ------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)