diff options
2 files changed, 51 insertions, 3 deletions
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java index d5d41d81..64d2639b 100644 --- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java +++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java @@ -13,7 +13,7 @@ * Sebastian Fuchs <spacehorst@gmail.com> - bug 243848 * Matthew Hall - bugs 208858, 213145, 243848, 208434 * Ovidio Mallo - bug 332367 - * Nigel Westbury - bug 335792 + * Nigel Westbury - bug 335792, 389394 *******************************************************************************/ package org.eclipse.core.databinding.observable.list; @@ -305,17 +305,29 @@ public class WritableList<E> extends ObservableList<E> { public boolean removeAll(Collection<?> c) { checkRealm(); + + /* + * First build the list of diff entries. All diff entries must be built + * before anything is removed from wrappedList, otherwise the indexes + * are incorrect. + */ List<ListDiffEntry<E>> entries = new ArrayList<ListDiffEntry<E>>(); for (Iterator<?> it = c.iterator(); it.hasNext();) { Object element = it.next(); int removeIndex = wrappedList.indexOf(element); if (removeIndex != -1) { E removedElement = wrappedList.get(removeIndex); - wrappedList.remove(removeIndex); entries.add(Diffs.createListDiffEntry(removeIndex, false, removedElement)); } } + + /* + * Now we have created all the diff entries with the correct indexes, we + * can remove the elements from wrappedList. + */ + wrappedList.removeAll(c); + if (entries.size() > 0) fireListChange(Diffs.createListDiff(entries)); return entries.size() > 0; diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/WritableListTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/WritableListTest.java index 2fec7c5e..9c1a6cca 100755 --- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/WritableListTest.java +++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/WritableListTest.java @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * Brad Reynolds - bug 164653, 147515 * Matthew Hall - bug 213145 - * Nigel Westbury - bug 208434 + * Nigel Westbury - bug 208434, 389394 *******************************************************************************/ package org.eclipse.core.tests.databinding.observable.list; @@ -28,6 +28,9 @@ import junit.framework.TestSuite; import org.eclipse.core.databinding.observable.IObservable; import org.eclipse.core.databinding.observable.IObservableCollection; import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.core.databinding.observable.list.IListChangeListener; +import org.eclipse.core.databinding.observable.list.ListChangeEvent; +import org.eclipse.core.databinding.observable.list.ListDiffEntry; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest; import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate; @@ -205,6 +208,39 @@ public class WritableListTest extends TestCase { assertEquals(2, wlist.size()); } + public void testRemoveAll() { + RealmTester.setDefault(new CurrentRealm(true)); + List<String> list = new ArrayList<String>(Arrays.asList(new String[] { + "a", "b", "c" })); + WritableList<String> wlist = new WritableList<String>(list, + String.class); + + final boolean[] flags = new boolean[wlist.size()]; + + wlist.addListChangeListener(new IListChangeListener<String>() { + public void handleListChange(ListChangeEvent<String> event) { + for (ListDiffEntry<String> diffEntry : event.diff + .getDifferencesAsList()) { + if (flags[diffEntry.getPosition()]) { + throw new RuntimeException("duplicate index in diff"); + } + flags[diffEntry.getPosition()] = true; + } + + } + }); + + List<String> removalList = new ArrayList<String>( + Arrays.asList(new String[] { "a", "c" })); + + wlist.removeAll(removalList); + + assertEquals(true, flags[0]); + assertEquals(false, flags[1]); + assertEquals(true, flags[2]); + assertEquals(1, wlist.size()); + } + public void testIteratorRemoval() { RealmTester.setDefault(new CurrentRealm(true)); List<String> list = new ArrayList<String>(Arrays.asList(new String[] { |