Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 154571 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/viewers/TableViewer.java (-5 / +12 lines)
Lines 311-321 Link Here
311
	 */
311
	 */
312
	public void refresh(final Object element, final boolean updateLabels,
312
	public void refresh(final Object element, final boolean updateLabels,
313
			boolean reveal) {
313
			boolean reveal) {
314
		preservingSelection(new Runnable() {
314
		if (isBusy())
315
			public void run() {
315
			return;
316
				internalRefresh(element, updateLabels);
316
		busy = true;
317
			}
317
		try {
318
		}, reveal);
318
			preservingSelection(new Runnable() {
319
				public void run() {
320
					internalRefresh(element, updateLabels);
321
				}
322
			}, reveal);
323
		} finally {
324
			busy = false;
325
		}
319
	}
326
	}
320
327
321
	/**
328
	/**
(-)src/org/eclipse/jface/viewers/AbstractTreeViewer.java (-101 / +156 lines)
Lines 127-141 Link Here
127
	public void add(Object parentElementOrTreePath, Object[] childElements) {
127
	public void add(Object parentElementOrTreePath, Object[] childElements) {
128
		Assert.isNotNull(parentElementOrTreePath);
128
		Assert.isNotNull(parentElementOrTreePath);
129
		assertElementsNotNull(childElements);
129
		assertElementsNotNull(childElements);
130
130
		if (isBusy())
131
		Widget[] widgets = internalFindItems(parentElementOrTreePath);
132
		// If parent hasn't been realized yet, just ignore the add.
133
		if (widgets.length == 0) {
134
			return;
131
			return;
135
		}
132
		busy = true;
136
133
		try {
137
		for (int i = 0; i < widgets.length; i++) {
134
			Widget[] widgets = internalFindItems(parentElementOrTreePath);
138
			internalAdd(widgets[i], parentElementOrTreePath, childElements);
135
			// If parent hasn't been realized yet, just ignore the add.
136
			if (widgets.length == 0) {
137
				return;
138
			}
139
	
140
			for (int i = 0; i < widgets.length; i++) {
141
				internalAdd(widgets[i], parentElementOrTreePath, childElements);
142
			}
143
		} finally {
144
			busy = false;
139
		}
145
		}
140
	}
146
	}
141
147
Lines 334-340 Link Here
334
			int index;
340
			int index;
335
			if (comparator == null) {
341
			if (comparator == null) {
336
				if (itemExists(items, element)) {
342
				if (itemExists(items, element)) {
337
					refresh(element);
343
					internalRefresh(element);
338
					newItem = false;
344
					newItem = false;
339
				}
345
				}
340
				index = -1;
346
				index = -1;
Lines 355-361 Link Here
355
						// any)
361
						// any)
356
						if (items[lastInsertion].getData().equals(element)) {
362
						if (items[lastInsertion].getData().equals(element)) {
357
							// refresh the element in case it has new children
363
							// refresh the element in case it has new children
358
							refresh(element);
364
							internalRefresh(element);
359
							newItem = false;
365
							newItem = false;
360
						}
366
						}
361
						lastInsertion++;// We had an insertion so increment
367
						lastInsertion++;// We had an insertion so increment
Lines 994-1002 Link Here
994
	 *            levels of the tree
1000
	 *            levels of the tree
995
	 */
1001
	 */
996
	public void expandToLevel(Object elementOrTreePath, int level) {
1002
	public void expandToLevel(Object elementOrTreePath, int level) {
997
		Widget w = internalExpand(elementOrTreePath, true);
1003
		if (isBusy())
998
		if (w != null) {
1004
			return;
999
			internalExpandToLevel(w, level);
1005
		busy = true;
1006
		try {
1007
			Widget w = internalExpand(elementOrTreePath, true);
1008
			if (w != null) {
1009
				internalExpandToLevel(w, level);
1010
			}
1011
		} finally {
1012
			busy = false;
1000
		}
1013
		}
1001
	}
1014
	}
1002
1015
Lines 2047-2057 Link Here
2047
		if (elementsOrTreePaths.length == 0) {
2060
		if (elementsOrTreePaths.length == 0) {
2048
			return;
2061
			return;
2049
		}
2062
		}
2050
		preservingSelection(new Runnable() {
2063
		if (isBusy())
2051
			public void run() {
2064
			return;
2052
				internalRemove(elementsOrTreePaths);
2065
		busy = true;
2053
			}
2066
		try {
2054
		});
2067
			preservingSelection(new Runnable() {
2068
				public void run() {
2069
					internalRemove(elementsOrTreePaths);
2070
				}
2071
			});
2072
		} finally {
2073
			busy = false;
2074
		}
2055
	}
2075
	}
2056
2076
2057
	/**
2077
	/**
Lines 2077-2087 Link Here
2077
		if (elements.length == 0) {
2097
		if (elements.length == 0) {
2078
			return;
2098
			return;
2079
		}
2099
		}
2080
		preservingSelection(new Runnable() {
2100
		if (isBusy())
2081
			public void run() {
2101
			return;
2082
				internalRemove(parent, elements);
2102
		busy = true;
2083
			}
2103
		try {
2084
		});
2104
			preservingSelection(new Runnable() {
2105
				public void run() {
2106
					internalRemove(parent, elements);
2107
				}
2108
			});
2109
		} finally {
2110
			busy = false;
2111
		}
2085
	}
2112
	}
2086
2113
2087
	/**
2114
	/**
Lines 2229-2249 Link Here
2229
	 */
2256
	 */
2230
	public void setExpandedElements(Object[] elements) {
2257
	public void setExpandedElements(Object[] elements) {
2231
		assertElementsNotNull(elements);
2258
		assertElementsNotNull(elements);
2232
		CustomHashtable expandedElements = newHashtable(elements.length * 2 + 1);
2259
		if (isBusy()) {
2233
		for (int i = 0; i < elements.length; ++i) {
2260
			return;
2234
			Object element = elements[i];
2261
		}
2235
			// Ensure item exists for element. This will materialize items for
2262
		busy = true;
2236
			// each element and their parents, if possible. This is important
2263
		try {
2237
			// to support expanding of inner tree nodes without necessarily
2264
			CustomHashtable expandedElements = newHashtable(elements.length * 2 + 1);
2238
			// expanding their parents.
2265
			for (int i = 0; i < elements.length; ++i) {
2239
			internalExpand(element, false);
2266
				Object element = elements[i];
2240
			expandedElements.put(element, element);
2267
				// Ensure item exists for element. This will materialize items for
2241
		}
2268
				// each element and their parents, if possible. This is important
2242
		// this will traverse all existing items, and create children for
2269
				// to support expanding of inner tree nodes without necessarily
2243
		// elements that need to be expanded. If the tree contains multiple
2270
				// expanding their parents.
2244
		// equal elements, and those are in the set of elements to be expanded,
2271
				internalExpand(element, false);
2245
		// only the first item found for each element will be expanded.
2272
				expandedElements.put(element, element);
2246
		internalSetExpanded(expandedElements, getControl());
2273
			}
2274
			// this will traverse all existing items, and create children for
2275
			// elements that need to be expanded. If the tree contains multiple
2276
			// equal elements, and those are in the set of elements to be expanded,
2277
			// only the first item found for each element will be expanded.
2278
			internalSetExpanded(expandedElements, getControl());
2279
		} finally {
2280
			busy = false;
2281
		}
2247
	}
2282
	}
2248
2283
2249
	/**
2284
	/**
Lines 2263-2296 Link Here
2263
	 */
2298
	 */
2264
	public void setExpandedTreePaths(TreePath[] treePaths) {
2299
	public void setExpandedTreePaths(TreePath[] treePaths) {
2265
		assertElementsNotNull(treePaths);
2300
		assertElementsNotNull(treePaths);
2266
		final IElementComparer comparer = getComparer();
2301
		if (isBusy())
2267
		IElementComparer treePathComparer = new IElementComparer() {
2302
			return;
2268
2303
		busy = true;
2269
			public boolean equals(Object a, Object b) {
2304
		try {
2270
				return ((TreePath) a).equals(((TreePath) b), comparer);
2305
			final IElementComparer comparer = getComparer();
2271
			}
2306
			IElementComparer treePathComparer = new IElementComparer() {
2272
2307
	
2273
			public int hashCode(Object element) {
2308
				public boolean equals(Object a, Object b) {
2274
				return ((TreePath) element).hashCode(comparer);
2309
					return ((TreePath) a).equals(((TreePath) b), comparer);
2275
			}
2310
				}
2276
		};
2311
	
2277
		CustomHashtable expandedTreePaths = new CustomHashtable(
2312
				public int hashCode(Object element) {
2278
				treePaths.length * 2 + 1, treePathComparer);
2313
					return ((TreePath) element).hashCode(comparer);
2279
		for (int i = 0; i < treePaths.length; ++i) {
2314
				}
2280
			TreePath treePath = treePaths[i];
2315
			};
2281
			// Ensure item exists for element. This will materialize items for
2316
			CustomHashtable expandedTreePaths = new CustomHashtable(
2282
			// each element and their parents, if possible. This is important
2317
					treePaths.length * 2 + 1, treePathComparer);
2283
			// to support expanding of inner tree nodes without necessarily
2318
			for (int i = 0; i < treePaths.length; ++i) {
2284
			// expanding their parents.
2319
				TreePath treePath = treePaths[i];
2285
			internalExpand(treePath, false);
2320
				// Ensure item exists for element. This will materialize items for
2286
			expandedTreePaths.put(treePath, treePath);
2321
				// each element and their parents, if possible. This is important
2287
		}
2322
				// to support expanding of inner tree nodes without necessarily
2288
		// this will traverse all existing items, and create children for
2323
				// expanding their parents.
2289
		// elements that need to be expanded. If the tree contains multiple
2324
				internalExpand(treePath, false);
2290
		// equal elements, and those are in the set of elements to be expanded,
2325
				expandedTreePaths.put(treePath, treePath);
2291
		// only the first item found for each element will be expanded.
2326
			}
2292
		internalSetExpandedTreePaths(expandedTreePaths, getControl(),
2327
			// this will traverse all existing items, and create children for
2293
				new TreePath(new Object[0]));
2328
			// elements that need to be expanded. If the tree contains multiple
2329
			// equal elements, and those are in the set of elements to be expanded,
2330
			// only the first item found for each element will be expanded.
2331
			internalSetExpandedTreePaths(expandedTreePaths, getControl(),
2332
					new TreePath(new Object[0]));
2333
		} finally {
2334
			busy = false;
2335
		}
2294
	}
2336
	}
2295
2337
2296
	/**
2338
	/**
Lines 2305-2316 Link Here
2305
	 */
2347
	 */
2306
	public void setExpandedState(Object elementOrTreePath, boolean expanded) {
2348
	public void setExpandedState(Object elementOrTreePath, boolean expanded) {
2307
		Assert.isNotNull(elementOrTreePath);
2349
		Assert.isNotNull(elementOrTreePath);
2308
		Widget item = internalExpand(elementOrTreePath, false);
2350
		if (isBusy())
2309
		if (item instanceof Item) {
2351
			return;
2310
			if (expanded) {
2352
		busy = true;
2311
				createChildren(item);
2353
		try {
2354
			Widget item = internalExpand(elementOrTreePath, false);
2355
			if (item instanceof Item) {
2356
				if (expanded) {
2357
					createChildren(item);
2358
				}
2359
				setExpanded((Item) item, expanded);
2312
			}
2360
			}
2313
			setExpanded((Item) item, expanded);
2361
		} finally {
2362
			busy = false;
2314
		}
2363
		}
2315
	}
2364
	}
2316
2365
Lines 2789-2830 Link Here
2789
			int position) {
2838
			int position) {
2790
		Assert.isNotNull(parentElementOrTreePath);
2839
		Assert.isNotNull(parentElementOrTreePath);
2791
		Assert.isNotNull(element);
2840
		Assert.isNotNull(element);
2792
2841
		if (isBusy())
2793
		if (getComparator() != null || hasFilters()) {
2794
			add(parentElementOrTreePath, new Object[] { element });
2795
			return;
2842
			return;
2796
		}
2843
		busy = true;
2797
		Widget[] items;
2844
		try {
2798
		if (internalIsInputOrEmptyPath(parentElementOrTreePath)) {
2845
			if (getComparator() != null || hasFilters()) {
2799
			items = new Widget[] { getControl() };
2846
				add(parentElementOrTreePath, new Object[] { element });
2800
		} else {
2847
				return;
2801
			items = internalFindItems(parentElementOrTreePath);
2848
			}
2802
		}
2849
			Widget[] items;
2803
2850
			if (internalIsInputOrEmptyPath(parentElementOrTreePath)) {
2804
		for (int i = 0; i < items.length; i++) {
2851
				items = new Widget[] { getControl() };
2805
			Widget widget = items[i];
2852
			} else {
2806
			if (widget instanceof Item) {
2853
				items = internalFindItems(parentElementOrTreePath);
2807
				Item item = (Item) widget;
2854
			}
2808
2855
	
2809
				Item[] childItems = getChildren(item);
2856
			for (int i = 0; i < items.length; i++) {
2810
				if (getExpanded(item)
2857
				Widget widget = items[i];
2811
						|| (childItems.length > 0 && childItems[0].getData() != null)) {
2858
				if (widget instanceof Item) {
2812
					// item has real children, go ahead and add
2859
					Item item = (Item) widget;
2860
	
2861
					Item[] childItems = getChildren(item);
2862
					if (getExpanded(item)
2863
							|| (childItems.length > 0 && childItems[0].getData() != null)) {
2864
						// item has real children, go ahead and add
2865
						int insertionPosition = position;
2866
						if (insertionPosition == -1) {
2867
							insertionPosition = getItemCount(item);
2868
						}
2869
	
2870
						createTreeItem(item, element, insertionPosition);
2871
					}
2872
				} else {
2813
					int insertionPosition = position;
2873
					int insertionPosition = position;
2814
					if (insertionPosition == -1) {
2874
					if (insertionPosition == -1) {
2815
						insertionPosition = getItemCount(item);
2875
						insertionPosition = getItemCount((Control) widget);
2816
					}
2876
					}
2817
2877
	
2818
					createTreeItem(item, element, insertionPosition);
2878
					createTreeItem(widget, element, insertionPosition);
2819
				}
2820
			} else {
2821
				int insertionPosition = position;
2822
				if (insertionPosition == -1) {
2823
					insertionPosition = getItemCount((Control) widget);
2824
				}
2879
				}
2825
2826
				createTreeItem(widget, element, insertionPosition);
2827
			}
2880
			}
2881
		} finally {
2882
			busy = false;
2828
		}
2883
		}
2829
	}
2884
	}
2830
2885
(-)src/org/eclipse/jface/viewers/TreeViewer.java (-107 / +153 lines)
Lines 376-394 Link Here
376
	 * @since 3.2
376
	 * @since 3.2
377
	 */
377
	 */
378
	public void setChildCount(final Object elementOrTreePath, final int count) {
378
	public void setChildCount(final Object elementOrTreePath, final int count) {
379
		preservingSelection(new Runnable() {
379
		if (isBusy())
380
			public void run() {
380
			return;
381
				if (internalIsInputOrEmptyPath(elementOrTreePath)) {
381
		busy = true;
382
					getTree().setItemCount(count);
382
		try {
383
					return;
383
			preservingSelection(new Runnable() {
384
				}
384
				public void run() {
385
				Widget[] items = internalFindItems(elementOrTreePath);
385
					if (internalIsInputOrEmptyPath(elementOrTreePath)) {
386
				for (int i = 0; i < items.length; i++) {
386
						getTree().setItemCount(count);
387
					TreeItem treeItem = (TreeItem) items[i];
387
						return;
388
					treeItem.setItemCount(count);
388
					}
389
					Widget[] items = internalFindItems(elementOrTreePath);
390
					for (int i = 0; i < items.length; i++) {
391
						TreeItem treeItem = (TreeItem) items[i];
392
						treeItem.setItemCount(count);
393
					}
389
				}
394
				}
390
			}
395
			});
391
		});
396
		} finally {
397
			busy = false;
398
		}
392
	}
399
	}
393
400
394
	/**
401
	/**
Lines 417-440 Link Here
417
	 */
424
	 */
418
	public void replace(final Object parentElementOrTreePath, final int index,
425
	public void replace(final Object parentElementOrTreePath, final int index,
419
			final Object element) {
426
			final Object element) {
420
		preservingSelection(new Runnable() {
427
		if (isBusy())
421
			public void run() {
428
			return;
422
				if (internalIsInputOrEmptyPath(parentElementOrTreePath)) {
429
		busy = true;
423
					if (index < tree.getItemCount()) {
430
		try {
424
						updateItem(tree.getItem(index), element);
431
			preservingSelection(new Runnable() {
425
					}
432
				public void run() {
426
				} else {
433
					if (internalIsInputOrEmptyPath(parentElementOrTreePath)) {
427
					Widget[] parentItems = internalFindItems(parentElementOrTreePath);
434
						if (index < tree.getItemCount()) {
428
					for (int i = 0; i < parentItems.length; i++) {
435
							updateItem(tree.getItem(index), element);
429
						TreeItem parentItem = (TreeItem) parentItems[i];
436
						}
430
						if (index < parentItem.getItemCount()) {
437
					} else {
431
							updateItem(parentItem.getItem(index), element);
438
						Widget[] parentItems = internalFindItems(parentElementOrTreePath);
439
						for (int i = 0; i < parentItems.length; i++) {
440
							TreeItem parentItem = (TreeItem) parentItems[i];
441
							if (index < parentItem.getItemCount()) {
442
								updateItem(parentItem.getItem(index), element);
443
							}
432
						}
444
						}
433
					}
445
					}
434
				}
446
				}
435
			}
447
				
436
448
			});
437
		});
449
		} finally {
450
			busy = false;
451
		}
438
	}
452
	}
439
453
440
	public boolean isExpandable(Object element) {
454
	public boolean isExpandable(Object element) {
Lines 702-733 Link Here
702
	 * @since 3.3
716
	 * @since 3.3
703
	 */
717
	 */
704
	public void remove(final Object parentOrTreePath, final int index) {
718
	public void remove(final Object parentOrTreePath, final int index) {
705
		preservingSelection(new Runnable() {
719
		if (isBusy())
706
			public void run() {
720
			return;
707
				if (internalIsInputOrEmptyPath(parentOrTreePath)) {
721
		busy = true;
708
					Tree tree = (Tree) getControl();
722
		try {
709
					if (index < tree.getItemCount()) {
723
			preservingSelection(new Runnable() {
710
						TreeItem item = tree.getItem(index);
724
				public void run() {
711
						if (item.getData() != null) {
725
					if (internalIsInputOrEmptyPath(parentOrTreePath)) {
712
							disassociate(item);
726
						Tree tree = (Tree) getControl();
713
						}
727
						if (index < tree.getItemCount()) {
714
						item.dispose();
728
							TreeItem item = tree.getItem(index);
715
					}
716
				} else {
717
					Widget[] parentItems = internalFindItems(parentOrTreePath);
718
					for (int i = 0; i < parentItems.length; i++) {
719
						TreeItem parentItem = (TreeItem) parentItems[i];
720
						if (index < parentItem.getItemCount()) {
721
							TreeItem item = parentItem.getItem(index);
722
							if (item.getData() != null) {
729
							if (item.getData() != null) {
723
								disassociate(item);
730
								disassociate(item);
724
							}
731
							}
725
							item.dispose();
732
							item.dispose();
726
						}
733
						}
734
					} else {
735
						Widget[] parentItems = internalFindItems(parentOrTreePath);
736
						for (int i = 0; i < parentItems.length; i++) {
737
							TreeItem parentItem = (TreeItem) parentItems[i];
738
							if (index < parentItem.getItemCount()) {
739
								TreeItem item = parentItem.getItem(index);
740
								if (item.getData() != null) {
741
									disassociate(item);
742
								}
743
								item.dispose();
744
							}
745
						}
727
					}
746
					}
728
				}
747
				}
729
			}
748
			});
730
		});
749
		} finally {
750
			busy = false;
751
		}
731
	}
752
	}
732
	
753
	
733
	/* (non-Javadoc)
754
	/* (non-Javadoc)
Lines 772-808 Link Here
772
	 * @since 3.3
793
	 * @since 3.3
773
	 */
794
	 */
774
	public void setHasChildren(final Object elementOrTreePath, final boolean hasChildren) {
795
	public void setHasChildren(final Object elementOrTreePath, final boolean hasChildren) {
775
		preservingSelection(new Runnable() {
796
		if (isBusy())
776
			public void run() {
797
			return;
777
				if (internalIsInputOrEmptyPath(elementOrTreePath)) {
798
		busy = true;
778
					if (hasChildren) {
799
		try {
779
						virtualLazyUpdateChildCount(getTree(),
800
			preservingSelection(new Runnable() {
780
								getChildren(getTree()).length);
801
				public void run() {
781
					} else {
802
					if (internalIsInputOrEmptyPath(elementOrTreePath)) {
782
						setChildCount(elementOrTreePath, 0);
803
						if (hasChildren) {
804
							virtualLazyUpdateChildCount(getTree(),
805
									getChildren(getTree()).length);
806
						} else {
807
							setChildCount(elementOrTreePath, 0);
808
						}
809
						return;
783
					}
810
					}
784
					return;
811
					Widget[] items = internalFindItems(elementOrTreePath);
785
				}
812
					for (int i = 0; i < items.length; i++) {
786
				Widget[] items = internalFindItems(elementOrTreePath);
813
						TreeItem item = (TreeItem) items[i];
787
				for (int i = 0; i < items.length; i++) {
814
						if (!hasChildren) {
788
					TreeItem item = (TreeItem) items[i];
815
							item.setItemCount(0);
789
					if (!hasChildren) {
790
						item.setItemCount(0);
791
					} else {
792
						if (!item.getExpanded()) {
793
							item.setItemCount(1);
794
							TreeItem child = item.getItem(0);
795
							if (child.getData() != null) {
796
								disassociate(child);
797
							}
798
							item.clear(0, true);
799
						} else {
816
						} else {
800
                            virtualLazyUpdateChildCount(item, item.getItemCount());
817
							if (!item.getExpanded()) {
801
                        }                            
818
								item.setItemCount(1);
819
								TreeItem child = item.getItem(0);
820
								if (child.getData() != null) {
821
									disassociate(child);
822
								}
823
								item.clear(0, true);
824
							} else {
825
								virtualLazyUpdateChildCount(item, item.getItemCount());
826
							}                            
827
						}
802
					}
828
					}
803
				}
829
				}
804
			}
830
			});
805
		});
831
		} finally {
832
			busy = false;
833
		}
806
	}
834
	}
807
835
808
	/**
836
	/**
Lines 811-833 Link Here
811
	 * @param index
839
	 * @param index
812
	 */
840
	 */
813
	private void virtualLazyUpdateWidget(Widget widget, int index) {
841
	private void virtualLazyUpdateWidget(Widget widget, int index) {
814
		if (contentProviderIsTreeBased) {
842
		boolean oldBusy = busy;
815
			TreePath treePath;
843
		busy = false;
816
			if (widget instanceof Item) {
844
		try {
817
				if (widget.getData() == null) {
845
			if (contentProviderIsTreeBased) {
818
					// temporary fix to avoid a NPE (the tree will still be screwed up)
846
				TreePath treePath;
819
					// see bug 167668
847
				if (widget instanceof Item) {
820
					return;
848
					if (widget.getData() == null) {
849
						// temporary fix to avoid a NPE (the tree will still be screwed up)
850
						// see bug 167668
851
						return;
852
					}
853
					treePath = getTreePathFromItem((Item) widget);
854
				} else {
855
					treePath = TreePath.EMPTY;
821
				}
856
				}
822
				treePath = getTreePathFromItem((Item) widget);
857
				((ILazyTreePathContentProvider) getContentProvider())
858
				.updateElement(treePath, index);
823
			} else {
859
			} else {
824
				treePath = TreePath.EMPTY;
860
				((ILazyTreeContentProvider) getContentProvider()).updateElement(
861
						widget.getData(), index);
825
			}
862
			}
826
			((ILazyTreePathContentProvider) getContentProvider())
863
		} finally {
827
					.updateElement(treePath, index);
864
			busy = oldBusy;
828
		} else {
829
			((ILazyTreeContentProvider) getContentProvider()).updateElement(
830
					widget.getData(), index);
831
		}
865
		}
832
	}
866
	}
833
867
Lines 837-853 Link Here
837
	 * @param currentChildCount
871
	 * @param currentChildCount
838
	 */
872
	 */
839
	private void virtualLazyUpdateChildCount(Widget widget, int currentChildCount) {
873
	private void virtualLazyUpdateChildCount(Widget widget, int currentChildCount) {
840
		if (contentProviderIsTreeBased) {
874
		boolean oldBusy = busy;
841
			TreePath treePath;
875
		busy = false;
842
			if (widget instanceof Item) {
876
		try {
843
				treePath = getTreePathFromItem((Item) widget);
877
			if (contentProviderIsTreeBased) {
878
				TreePath treePath;
879
				if (widget instanceof Item) {
880
					treePath = getTreePathFromItem((Item) widget);
881
				} else {
882
					treePath = TreePath.EMPTY;
883
				}
884
				((ILazyTreePathContentProvider) getContentProvider())
885
						.updateChildCount(treePath, currentChildCount);
844
			} else {
886
			} else {
845
				treePath = TreePath.EMPTY;
887
				((ILazyTreeContentProvider) getContentProvider()).updateChildCount(widget.getData(), currentChildCount);
846
			}
888
			}
847
			((ILazyTreePathContentProvider) getContentProvider())
889
		} finally {
848
					.updateChildCount(treePath, currentChildCount);
890
			busy = oldBusy;
849
		} else {
850
			((ILazyTreeContentProvider) getContentProvider()).updateChildCount(widget.getData(), currentChildCount);
851
		}
891
		}
852
	}
892
	}
853
	
893
	
Lines 857-875 Link Here
857
	 * @param currentChildCount
897
	 * @param currentChildCount
858
	 */
898
	 */
859
	private void virtualLazyUpdateHasChildren(Item item, int currentChildCount) {
899
	private void virtualLazyUpdateHasChildren(Item item, int currentChildCount) {
860
		if (contentProviderIsTreeBased) {
900
		boolean oldBusy = busy;
861
			TreePath treePath;
901
		busy = false;
862
			treePath = getTreePathFromItem(item);
902
		try {
863
			if (currentChildCount == 0) {
903
			if (contentProviderIsTreeBased) {
864
				// item is not expanded (but may have a plus currently)
904
				TreePath treePath;
865
				((ILazyTreePathContentProvider) getContentProvider())
905
				treePath = getTreePathFromItem(item);
866
						.updateHasChildren(treePath);
906
				if (currentChildCount == 0) {
907
					// item is not expanded (but may have a plus currently)
908
					((ILazyTreePathContentProvider) getContentProvider())
909
					.updateHasChildren(treePath);
910
				} else {
911
					((ILazyTreePathContentProvider) getContentProvider())
912
					.updateChildCount(treePath, currentChildCount);
913
				}
867
			} else {
914
			} else {
868
				((ILazyTreePathContentProvider) getContentProvider())
915
				((ILazyTreeContentProvider) getContentProvider()).updateChildCount(item.getData(), currentChildCount);
869
						.updateChildCount(treePath, currentChildCount);
870
			}
916
			}
871
		} else {
917
		} finally {
872
			((ILazyTreeContentProvider) getContentProvider()).updateChildCount(item.getData(), currentChildCount);
918
			busy = oldBusy;
873
		}
919
		}
874
	}
920
	}
875
921
(-)src/org/eclipse/jface/viewers/AbstractTableViewer.java (-30 / +68 lines)
Lines 239-250 Link Here
239
	 */
239
	 */
240
	public void add(Object[] elements) {
240
	public void add(Object[] elements) {
241
		assertElementsNotNull(elements);
241
		assertElementsNotNull(elements);
242
		Object[] filtered = filter(elements);
242
		if (isBusy())
243
243
			return;
244
		for (int i = 0; i < filtered.length; i++) {
244
		busy = true;
245
			Object element = filtered[i];
245
		try {
246
			int index = indexForElement(element);
246
			Object[] filtered = filter(elements);
247
			createItem(element, index);
247
			
248
			for (int i = 0; i < filtered.length; i++) {
249
				Object element = filtered[i];
250
				int index = indexForElement(element);
251
				createItem(element, index);
252
			}
253
		} finally {
254
			busy = false;
248
		}
255
		}
249
	}
256
	}
250
257
Lines 541-548 Link Here
541
	protected void inputChanged(Object input, Object oldInput) {
548
	protected void inputChanged(Object input, Object oldInput) {
542
		getControl().setRedraw(false);
549
		getControl().setRedraw(false);
543
		try {
550
		try {
544
			// refresh() attempts to preserve selection, which we want here
551
			preservingSelection(new Runnable() {
545
			refresh();
552
				public void run() {
553
					internalRefresh(getRoot());
554
				}
555
			});
546
		} finally {
556
		} finally {
547
			getControl().setRedraw(true);
557
			getControl().setRedraw(true);
548
		}
558
		}
Lines 573-580 Link Here
573
		if (position == -1) {
583
		if (position == -1) {
574
			position = doGetItemCount();
584
			position = doGetItemCount();
575
		}
585
		}
576
586
		if (isBusy())
577
		createItem(element, position);
587
			return;
588
		busy = true;
589
		try {
590
			createItem(element, position);
591
		} finally {
592
			busy = false;
593
		}
578
	}
594
	}
579
595
580
	/*
596
	/*
Lines 719-724 Link Here
719
		Object input = getInput();
735
		Object input = getInput();
720
		for (int i = 0; i < elements.length; ++i) {
736
		for (int i = 0; i < elements.length; ++i) {
721
			if (equals(elements[i], input)) {
737
			if (equals(elements[i], input)) {
738
				busy = false;
722
				setInput(null);
739
				setInput(null);
723
				return;
740
				return;
724
			}
741
			}
Lines 769-782 Link Here
769
	 */
786
	 */
770
	public void remove(final Object[] elements) {
787
	public void remove(final Object[] elements) {
771
		assertElementsNotNull(elements);
788
		assertElementsNotNull(elements);
772
		if (elements.length == 0) {
789
		if (isBusy())
773
			return;
790
			return;
774
		}
791
		busy = true;
775
		preservingSelection(new Runnable() {
792
		try {
776
			public void run() {
793
			if (elements.length == 0) {
777
				internalRemove(elements);
794
				return;
778
			}
795
			}
779
		});
796
			preservingSelection(new Runnable() {
797
				public void run() {
798
					internalRemove(elements);
799
				}
800
			});
801
		} finally {
802
			busy = false;
803
		}
780
	}
804
	}
781
805
782
	/**
806
	/**
Lines 960-980 Link Here
960
	 * @since 3.1
984
	 * @since 3.1
961
	 */
985
	 */
962
	public void setItemCount(int count) {
986
	public void setItemCount(int count) {
963
		int oldCount = doGetItemCount();
987
		if (isBusy())
964
		if (count < oldCount) {
988
			return;
965
			// need to disassociate elements that are being disposed
989
		busy = true;
966
			for (int i = count; i < oldCount; i++) {
990
		try {
967
				Item item = doGetItem(i);
991
			int oldCount = doGetItemCount();
968
				if (item.getData() != null) {
992
			if (count < oldCount) {
969
					disassociate(item);
993
				// need to disassociate elements that are being disposed
994
				for (int i = count; i < oldCount; i++) {
995
					Item item = doGetItem(i);
996
					if (item.getData() != null) {
997
						disassociate(item);
998
					}
970
				}
999
				}
971
			}
1000
			}
1001
			doSetItemCount(count);
1002
			if (virtualManager != null) {
1003
				virtualManager.adjustCacheSize(count);
1004
			}
1005
			getControl().redraw();
1006
		} finally {
1007
			busy = false;
972
		}
1008
		}
973
		doSetItemCount(count);
974
		if (virtualManager != null) {
975
			virtualManager.adjustCacheSize(count);
976
		}
977
		getControl().redraw();
978
	}
1009
	}
979
1010
980
	/**
1011
	/**
Lines 990-997 Link Here
990
	 * @since 3.1
1021
	 * @since 3.1
991
	 */
1022
	 */
992
	public void replace(Object element, int index) {
1023
	public void replace(Object element, int index) {
993
		Item item = doGetItem(index);
1024
		if (isBusy())
994
		refreshItem(item, element);
1025
			return;
1026
		busy = true;
1027
		try {
1028
			Item item = doGetItem(index);
1029
			refreshItem(item, element);
1030
		} finally {
1031
			busy = false;
1032
		}
995
	}
1033
	}
996
1034
997
	/**
1035
	/**
(-)src/org/eclipse/jface/viewers/ColumnViewer.java (+50 lines)
Lines 16-21 Link Here
16
16
17
17
18
import org.eclipse.core.runtime.Assert;
18
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Status;
21
import org.eclipse.jface.util.Policy;
19
import org.eclipse.swt.events.MouseAdapter;
22
import org.eclipse.swt.events.MouseAdapter;
20
import org.eclipse.swt.events.MouseEvent;
23
import org.eclipse.swt.events.MouseEvent;
21
import org.eclipse.swt.graphics.Point;
24
import org.eclipse.swt.graphics.Point;
Lines 48-53 Link Here
48
	private ViewerCell cell = new ViewerCell(null, 0);
51
	private ViewerCell cell = new ViewerCell(null, 0);
49
52
50
	private ColumnViewerEditor viewerEditor;
53
	private ColumnViewerEditor viewerEditor;
54
	
55
	/* package */ boolean busy;
51
56
52
	/**
57
	/**
53
	 * Create a new instance of the receiver.
58
	 * Create a new instance of the receiver.
Lines 56-61 Link Here
56
61
57
	}
62
	}
58
63
64
	/* package */ boolean isBusy() {
65
		if (busy) {
66
			Policy.getLog().log(
67
				new Status(
68
					IStatus.WARNING,
69
					Policy.JFACE,
70
					"Ignoring reentrant call while viewer is busy", new RuntimeException())); //$NON-NLS-1$
71
			return true;
72
		}
73
		return false;
74
	}
75
59
	protected void hookControl(Control control) {
76
	protected void hookControl(Control control) {
60
		super.hookControl(control);
77
		super.hookControl(control);
61
		viewerEditor = createViewerEditor();
78
		viewerEditor = createViewerEditor();
Lines 457-462 Link Here
457
		}
474
		}
458
		return false;
475
		return false;
459
	}
476
	}
477
	
478
	public void refresh(Object element) {
479
		if (isBusy())
480
			return;
481
		busy = true;
482
		try {
483
			super.refresh(element);
484
		} finally {
485
			busy = false;
486
		}
487
	}
488
	
489
	public void refresh(Object element, boolean updateLabels) {
490
		if (isBusy())
491
			return;
492
		busy = true;
493
		try {
494
			super.refresh(element, updateLabels);
495
		} finally {
496
			busy = false;
497
		}
498
	}
499
	
500
	public void update(Object element, String[] properties) {
501
		if (isBusy())
502
			return;
503
		busy = true;
504
		try {
505
			super.update(element, properties);
506
		} finally {
507
			busy = false;
508
		}
509
	}
460
510
461
	/**
511
	/**
462
	 * Sets the cell editors of this column viewer. If editing is not supported
512
	 * Sets the cell editors of this column viewer. If editing is not supported
(-)src/org/eclipse/jface/viewers/StructuredViewer.java (-1 / +5 lines)
Lines 1999-2005 Link Here
1999
			}
1999
			}
2000
		}
2000
		}
2001
		if (needsRefilter) {
2001
		if (needsRefilter) {
2002
			refresh();
2002
			preservingSelection(new Runnable() {
2003
				public void run() {
2004
					internalRefresh(getRoot());
2005
				}
2006
			});
2003
			return;
2007
			return;
2004
		}
2008
		}
2005
2009

Return to bug 154571