From c8cbb2763f8b250d756b711816af78b4829f32d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 7 Feb 2011 23:17:11 +0000 Subject: [PATCH] Try to remember the last selected attribute, or select a new attribute if all other attributes are the same as before. This first is helping a feature I am going to commit next, the other is making sure that a newly created attribute is selected, I pondered other options to realize this feature against the highly asynchronous model updates, but this seems to be most robust and highly unlikely to be triggered in accident. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40378 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../filetypes/AttributeListView.cpp | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/preferences/filetypes/AttributeListView.cpp b/src/preferences/filetypes/AttributeListView.cpp index af52c8b5e9..ebdc8f73d9 100644 --- a/src/preferences/filetypes/AttributeListView.cpp +++ b/src/preferences/filetypes/AttributeListView.cpp @@ -8,6 +8,8 @@ #include +#include + const struct type_map kTypeMap[] = { {"String", B_STRING_TYPE}, @@ -269,7 +271,15 @@ AttributeListView::_DeleteItems() void AttributeListView::SetTo(BMimeType* type) { - _DeleteItems(); + AttributeItem selectedItem; + if (CurrentSelection(0) >= 0) + selectedItem = *(AttributeItem*)ItemAt(CurrentSelection(0)); + + // Remove the current items but remember them for now. Also remember + // the currently selected item. + BObjectList previousItems(CountItems(), true); + while (AttributeItem* item = (AttributeItem*)RemoveItem(0L)) + previousItems.AddItem(item); // fill it again @@ -282,8 +292,62 @@ AttributeListView::SetTo(BMimeType* type) AttributeItem* item; int32 i = 0; - while ((item = create_attribute_item(attributes, i++)) != NULL) { + while ((item = create_attribute_item(attributes, i++)) != NULL) AddItem(item); + + // Maybe all the items are the same, except for one item. That + // attribute probably just got added. We should select it so the user + // can better follow what's going on. The problem we are solving by + // doing it this way is that updates to the MIME database are very + // asynchronous. Most likely we have created the new attribute ourselves, + // but the notification comes so late, we can't know for sure. + if (CountItems() == previousItems.CountItems() + 1) { + // First try to make sure that every previous item is there again. + bool allPreviousItemsFound = true; + for (i = previousItems.CountItems() - 1; i >= 0; i--) { + bool previousItemFound = false; + for (int32 j = CountItems() - 1; j >= 0; j--) { + item = (AttributeItem*)ItemAt(j); + if (*item == *previousItems.ItemAt(i)) { + previousItemFound = true; + break; + } + } + if (!previousItemFound) { + allPreviousItemsFound = false; + break; + } + } + if (allPreviousItemsFound) { + for (i = CountItems() - 1; i >= 0; i--) { + item = (AttributeItem*)ItemAt(i); + bool foundNewItem = false; + for (int32 j = previousItems.CountItems() - 1; j >= 0; j--) { + if (*item != *previousItems.ItemAt(j)) { + foundNewItem = true; + break; + } + } + if (foundNewItem) { + Select(i); + ScrollToSelection(); + break; + } + } + } + } else { + // Try to re-selected a previously selected item, if it's the exact + // same attribute. This helps not loosing the selection, since changes + // to the model are followed by completely rebuilding the list all the + // time. + for (i = CountItems() - 1; i >= 0; i--) { + item = (AttributeItem*)ItemAt(i); + if (*item == selectedItem) { + Select(i); + ScrollToSelection(); + break; + } + } } }