From 3f42463bf4452cb2f42c11668111d2c89f9b4242 Mon Sep 17 00:00:00 2001 From: Angelo Haller Date: Sun, 20 Sep 2020 18:00:08 -0500 Subject: [PATCH 1/3] Clarify uiTableModelRowInserted API documentation. * Require the new row to have been added to the model before calling uiTableModelRowInserted. * Require the row count to be updated before calling uiTableModelRowInserted. Notes ----- darwin: does not care about row counts internally. From the docs: > The numberOfRows in the table view is automatically increased > by the count of indexes. unix: does not state anything regarding order in the documentation. windows: does not state anything in the documentation but does keep track of its own row count internally. So in theory we do not have to require increasing the row count before calling uiTableModelRowInserted, but just by the very nature of the function name (past tense) we should. --- ui.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui.h b/ui.h index 40aea9498..95561f38f 100644 --- a/ui.h +++ b/ui.h @@ -1324,11 +1324,13 @@ _UI_EXTERN uiTableModel *uiNewTableModel(uiTableModelHandler *mh); // free table models currently associated with a uiTable. _UI_EXTERN void uiFreeTableModel(uiTableModel *m); -// uiTableModelRowInserted() tells any uiTable associated with m -// that a new row has been added to m at index index. You call -// this function when the number of rows in your model has -// changed; after calling it, NumRows() should returm the new row -// count. +// uiTableModelRowInserted() tell all uiTables associated with +// the uiTableModel m that a new row has been added to m at +// index newIndex. +// You must insert the row data in your model before calling this +// function. +// NumRows() must represent the new row count before you call +// this function. _UI_EXTERN void uiTableModelRowInserted(uiTableModel *m, int newIndex); // uiTableModelRowChanged() tells any uiTable associated with m From 7336dce8c886a1a0880482a0ebde9c522baab0d3 Mon Sep 17 00:00:00 2001 From: Angelo Haller Date: Sun, 20 Sep 2020 18:21:31 -0500 Subject: [PATCH 2/3] Clarify uiTableModelRowDeleted API documentation. * Require the deleted row to have been removed from the model before calling uiTableModelRowDeleted. * Require the row count to be updated before calling uiTableModelRowDeleted. Notes ----- darwin: Does not care about row counts internally. unix: Requires the row to have been deleted prior to calling this function: > This should be called by models after a row has been removed. > The location pointed to by path should be the location that the > row previously was at. It may not be a valid location anymore. windows: Does not state anything in the documentation but does keep track of its own row count internally. --- ui.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ui.h b/ui.h index 95561f38f..34a582162 100644 --- a/ui.h +++ b/ui.h @@ -1339,12 +1339,13 @@ _UI_EXTERN void uiTableModelRowInserted(uiTableModel *m, int newIndex); // this if your data changes at some other point. _UI_EXTERN void uiTableModelRowChanged(uiTableModel *m, int index); -// uiTableModelRowDeleted() tells any uiTable associated with m -// that the row at index index has been deleted. You call this -// function when the number of rows in your model has changed; -// after calling it, NumRows() should returm the new row -// count. -// TODO for this and Inserted: make sure the "after" part is right; clarify if it's after returning or after calling +// uiTableModelRowDeleted() tells all uiTables associated with +// the uiTableModel m that the row at index oldIndex has been +// deleted. +// You must delete the row from your model before you call this +// function. +// NumRows() must represent the new row count before you call +// this function. _UI_EXTERN void uiTableModelRowDeleted(uiTableModel *m, int oldIndex); // TODO reordering/moving From 6d07723fb637dcd1b509e7fa466c95b138724499 Mon Sep 17 00:00:00 2001 From: Angelo Haller Date: Sun, 20 Sep 2020 19:51:09 -0500 Subject: [PATCH 3/3] Fix windows table insertion/deletion to match API. Fix double row insertion bug on uiTableModelRowInserted(). Fix uiTableModelRowDeleted() to match API. Remove redundant call to update row count. Remove TODOs that have been implemented. Use more readable win32 macros. --- windows/table.cpp | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/windows/table.cpp b/windows/table.cpp index 85a51c1a3..75b991951 100644 --- a/windows/table.cpp +++ b/windows/table.cpp @@ -24,28 +24,19 @@ void uiFreeTableModel(uiTableModel *m) uiprivFree(m); } -// TODO document that when this is called, the model must return the new row count when asked void uiTableModelRowInserted(uiTableModel *m, int newIndex) { - LVITEMW item; - int newCount; - - newCount = uiprivTableModelNumRows(m); - ZeroMemory(&item, sizeof (LVITEMW)); + LVITEMW item = {}; item.mask = 0; item.iItem = newIndex; item.iSubItem = 0; + for (auto t : *(m->tables)) { - // actually insert the rows - if (SendMessageW(t->hwnd, LVM_SETITEMCOUNT, (WPARAM) newCount, LVSICF_NOINVALIDATEALL) == 0) - logLastError(L"error calling LVM_SETITEMCOUNT in uiTableModelRowInserted()"); - // and redraw every row from the new row down to simulate adding it - if (SendMessageW(t->hwnd, LVM_REDRAWITEMS, (WPARAM) newIndex, (LPARAM) (newCount - 1)) == FALSE) - logLastError(L"error calling LVM_REDRAWITEMS in uiTableModelRowInserted()"); - - // update selection state - if (SendMessageW(t->hwnd, LVM_INSERTITEM, 0, (LPARAM) (&item)) == (LRESULT) (-1)) - logLastError(L"error calling LVM_INSERTITEM in uiTableModelRowInserted() to update selection state"); + if (ListView_InsertItem(t->hwnd, &item) == -1) + logLastError(L"error calling ListView_InsertItem in uiTableModelRowInserted()"); + // redraw every row from the new row down to simulate adding it + if (ListView_RedrawItems(t->hwnd, newIndex, ListView_GetItemCount(t->hwnd)-1) == -1) + logLastError(L"error calling ListView_RedrawItems in uiTableModelRowInserted()"); } } @@ -57,25 +48,14 @@ void uiTableModelRowChanged(uiTableModel *m, int index) logLastError(L"error calling LVM_UPDATE in uiTableModelRowChanged()"); } -// TODO document that when this is called, the model must return the OLD row count when asked -// TODO for this and the above, see what GTK+ requires and adjust accordingly void uiTableModelRowDeleted(uiTableModel *m, int oldIndex) { - int newCount; - - newCount = uiprivTableModelNumRows(m); - newCount--; for (auto t : *(m->tables)) { - // update selection state - if (SendMessageW(t->hwnd, LVM_DELETEITEM, (WPARAM) oldIndex, 0) == (LRESULT) (-1)) - logLastError(L"error calling LVM_DELETEITEM in uiTableModelRowDeleted() to update selection state"); - - // actually delete the rows - if (SendMessageW(t->hwnd, LVM_SETITEMCOUNT, (WPARAM) newCount, LVSICF_NOINVALIDATEALL) == 0) - logLastError(L"error calling LVM_SETITEMCOUNT in uiTableModelRowDeleted()"); - // and redraw every row from the new nth row down to simulate removing the old nth row - if (SendMessageW(t->hwnd, LVM_REDRAWITEMS, (WPARAM) oldIndex, (LPARAM) (newCount - 1)) == FALSE) - logLastError(L"error calling LVM_REDRAWITEMS in uiTableModelRowDeleted()"); + if (ListView_DeleteItem(t->hwnd, oldIndex) == -1) + logLastError(L"error calling ListView_DeleteItem() in uiTableModelRowDeleted()"); + // redraw every row from the new nth row down to simulate removing the old nth row + if (ListView_RedrawItems(t->hwnd, oldIndex, ListView_GetItemCount(t->hwnd)-1) == -1) + logLastError(L"error calling ListView_RedrawItems() in uiTableModelRowDeleted()"); } }