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 127025 | Differences between
and this patch

Collapse All | Expand All

(-)ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java (-11 / +16 lines)
Lines 472-489 Link Here
472
			}
472
			}
473
		}
473
		}
474
	}
474
	}
475
475
	
476
	public void nodeChanged(ModelNode node) {
476
	/* (non-Javadoc)
477
		Widget widget = findItem(node);
477
	 * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChild(org.eclipse.swt.widgets.Widget, int)
478
		if (widget != null && !widget.isDisposed()) {
478
	 */
479
			if (widget instanceof TableItem) {
479
	protected void clearChild(Widget parent, int childIndex) {
480
				clear(widget);
480
		if (parent instanceof Table) {
481
				return;
481
			fTable.clear(childIndex);
482
			}
483
			widget.setData(node.getElement());
484
			internalRefresh(node);
485
		}
482
		}
486
	}
483
	}
487
	
484
485
	/* (non-Javadoc)
486
	 * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChildren(org.eclipse.swt.widgets.Widget)
487
	 */
488
	protected void clearChildren(Widget item) {
489
		if (item instanceof Table) {
490
			fTable.clearAll();
491
		}	
492
	}
488
	
493
	
489
}
494
}
(-)ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java (-42 / +48 lines)
Lines 442-448 Link Here
442
                                    return false;
442
                                    return false;
443
                                }
443
                                }
444
                            }
444
                            }
445
                            if (widget instanceof TreeItem) {
445
                            if (widget instanceof TreeItem && !widget.isDisposed()) {
446
                                TreeItem treeItem = (TreeItem) widget;
446
                                TreeItem treeItem = (TreeItem) widget;
447
                                if (treeItem.getExpanded()) {
447
                                if (treeItem.getExpanded()) {
448
                                    return path.getSegmentCount() == treePath.getSegmentCount();
448
                                    return path.getSegmentCount() == treePath.getSegmentCount();
Lines 747-774 Link Here
747
        return paths;
747
        return paths;
748
    }
748
    }
749
    
749
    
750
    /**
751
     * Container status of a node changed
752
     * 
753
     * @param node
754
     */
755
    protected void nodeContainerChanged(ModelNode node) {
756
		Widget widget = findItem(node);
757
		if (widget != null && !widget.isDisposed()) {
758
			boolean expanded = true;
759
			if (node.isContainer() && getItemCount(widget) == 0) {
760
				setItemCount(widget, 1);
761
			}
762
			if (widget instanceof TreeItem) {
763
				expanded = ((TreeItem) widget).getExpanded();
764
			}
765
			if (expanded) {
766
				updateChildren(node);
767
			}
768
		}
769
		attemptPendingUpdates();
770
	}
771
    
772
    protected int getItemCount(Widget widget) {
750
    protected int getItemCount(Widget widget) {
773
    	if (widget instanceof TreeItem) {
751
    	if (widget instanceof TreeItem) {
774
			return ((TreeItem) widget).getItemCount();
752
			return ((TreeItem) widget).getItemCount();
Lines 870-877 Link Here
870
    		fTree.clearAll(true);
848
    		fTree.clearAll(true);
871
    	}
849
    	}
872
    }
850
    }
851
    
852
    /* (non-Javadoc)
853
     * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChildren(org.eclipse.swt.widgets.Widget)
854
     */
855
    protected void clearChildren(Widget widget) {
856
    	if (widget instanceof TreeItem && !widget.isDisposed()) {
857
			TreeItem item = (TreeItem) widget;
858
			item.clearAll(true);
859
		} else {
860
			fTree.clearAll(true);
861
		}
862
    }
863
    
864
    /* (non-Javadoc)
865
     * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChild(org.eclipse.swt.widgets.Widget, int)
866
     */
867
    protected void clearChild(Widget parent, int childIndex) {
868
       	if (parent instanceof TreeItem && !parent.isDisposed()) {
869
    		TreeItem item = (TreeItem) parent;
870
    		item.clear(childIndex, true);
871
    	} else {
872
    		fTree.clear(childIndex, true);
873
    	}
874
	}
873
875
874
    /*
876
	/*
875
     * (non-Javadoc)
877
     * (non-Javadoc)
876
     * 
878
     * 
877
     * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModelViewer#newSelectionFromWidget()
879
     * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModelViewer#newSelectionFromWidget()
Lines 1169-1192 Link Here
1169
		return new AsynchronousTreeModel(this);
1171
		return new AsynchronousTreeModel(this);
1170
	}
1172
	}
1171
    
1173
    
1172
1173
    /* (non-Javadoc)
1174
     * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModelViewer#nodeChanged(org.eclipse.debug.internal.ui.viewers.ModelNode)
1175
     */
1176
    public void nodeChanged(ModelNode node) {
1177
		Widget widget = findItem(node);
1178
		if (widget != null && !widget.isDisposed()) {
1179
			if (widget instanceof TreeItem) {
1180
				clear(widget);
1181
				return;
1182
			}
1183
			widget.setData(node.getElement());
1184
			mapElement(node, widget);
1185
			internalRefresh(node);
1186
			attemptPendingUpdates();
1187
		}
1188
	}
1189
    
1190
    /**
1174
    /**
1191
	 * Attempt pending udpates. Subclasses may override but should call super.
1175
	 * Attempt pending udpates. Subclasses may override but should call super.
1192
	 */
1176
	 */
Lines 1563-1566 Link Here
1563
			}
1547
			}
1564
		}
1548
		}
1565
	}
1549
	}
1550
	
1551
	/**
1552
	 * Notification the container status of a node has changed/been computed.
1553
	 * 
1554
	 * @param node
1555
	 */
1556
	protected void nodeContainerChanged(ModelNode node) {
1557
		Widget widget = findItem(node);
1558
		if (widget != null && !widget.isDisposed()) {
1559
			if (node.isContainer()) {
1560
				if (widget instanceof TreeItem) {
1561
					if (((TreeItem)widget).getExpanded()) {
1562
						updateChildren(node);
1563
					}
1564
				} else {
1565
					updateChildren(node);
1566
				}
1567
				attemptPendingUpdates();
1568
			}
1569
		}			
1570
	}
1571
1566
}
1572
}
(-)ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java (-119 / +120 lines)
Lines 19-25 Link Here
19
import org.eclipse.core.runtime.IAdaptable;
19
import org.eclipse.core.runtime.IAdaptable;
20
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IProgressMonitor;
21
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Platform;
22
import org.eclipse.core.runtime.Status;
23
import org.eclipse.core.runtime.Status;
24
import org.eclipse.debug.internal.ui.DebugUIPlugin;
23
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor;
25
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor;
24
import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener;
26
import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener;
25
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
27
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
Lines 113-128 Link Here
113
115
114
	protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$
116
	protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$
115
	protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$
117
	protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$
116
118
	
117
    /**
119
	   // debug flags
118
     * Map of parent nodes for which children were needed to "set data"
120
	public static boolean DEBUG_VIEWER = false;
119
     * in the virtual widget. A parent is added to this map when we try go
121
	
120
     * get children but they aren't there yet. The children are retrieved
122
	static {
121
     * asynchronously, and later put back into the widgetry.
123
		DEBUG_VIEWER = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
122
     * The value is an array of ints of the indicies of the children that 
124
		 Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/viewer")); //$NON-NLS-1$
123
     * were requested. 
125
	}    	
124
     */	
125
	private Map fParentsPendingChildren = new HashMap();
126
	
126
	
127
	/**
127
	/**
128
	 * Creates a new viewer 
128
	 * Creates a new viewer 
Lines 238-244 Link Here
238
	 * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
238
	 * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
239
	 */
239
	 */
240
	protected synchronized void inputChanged(Object input, Object oldInput) {
240
	protected synchronized void inputChanged(Object input, Object oldInput) {
241
		fParentsPendingChildren.clear();
242
		if (fUpdatePolicy == null) {
241
		if (fUpdatePolicy == null) {
243
			fUpdatePolicy = createUpdatePolicy();
242
			fUpdatePolicy = createUpdatePolicy();
244
            fUpdatePolicy.init(this);
243
            fUpdatePolicy.init(this);
Lines 832-866 Link Here
832
	protected AsynchronousModel getModel() {
831
	protected AsynchronousModel getModel() {
833
		return fModel;
832
		return fModel;
834
	}	
833
	}	
835
    
836
    /**
837
     * A node has been disposed from the model.
838
     * 
839
     * @param node
840
     */
841
    protected void nodeDisposed(ModelNode node) {
842
    	Widget widget = findItem(node);
843
    	if (widget != null) {
844
    		unmapNode(node);
845
    		widget.dispose();
846
		}
847
	}
848
    
849
	/**
850
	 * Unmaps the node from its widget and all of its children nodes from
851
	 * their widgets.
852
	 * 
853
	 * @param node
854
	 */
855
	protected void unmapNode(ModelNode node) {
856
		unmapElement(node);
857
		ModelNode[] childrenNodes = node.getChildrenNodes();
858
		if (childrenNodes != null) {
859
			for (int i = 0; i < childrenNodes.length; i++) {
860
				unmapNode(childrenNodes[i]);
861
			}
862
		}
863
	}    
864
834
865
	/**
835
	/**
866
	 * A node in the model has been updated
836
	 * A node in the model has been updated
Lines 870-877 Link Here
870
	protected void nodeChanged(ModelNode node) {
840
	protected void nodeChanged(ModelNode node) {
871
		Widget widget = findItem(node);
841
		Widget widget = findItem(node);
872
		if (widget != null) {
842
		if (widget != null) {
873
			widget.setData(node.getElement());
843
			clear(widget);
874
			internalRefresh(node);
844
			attemptPendingUpdates();
875
		}
845
		}
876
	}
846
	}
877
847
Lines 892-929 Link Here
892
	}
862
	}
893
863
894
	/**
864
	/**
895
	 * Called when nodes are set in the model. The children may not have been
865
	 * Clears the given widget
896
	 * retrieved yet when the tree got the call to "set data".
897
	 * 
866
	 * 
898
	 * @param parent
867
	 * @param item
899
	 * @param children
900
	 */
868
	 */
901
	protected void nodeChildrenSet(ModelNode parent, ModelNode[] children) {
902
		int[] indicies = removePendingChildren(parent);
903
		Widget widget = findItem(parent);
904
		if (widget != null && !widget.isDisposed()) {
905
			if (indicies != null) {
906
				for (int i = 0; i < indicies.length; i++) {
907
					int index = indicies[i];
908
					Widget item = getChildWidget(widget, index);
909
					if (item != null) {
910
						if (index < children.length) {
911
							ModelNode childNode = children[index];
912
							mapElement(childNode, item);
913
							item.setData(childNode.getElement());
914
							internalRefresh(childNode);
915
						}
916
					}
917
				}
918
				setItemCount(widget, children.length);
919
			} else {
920
				setItemCount(widget, children.length);
921
			}
922
		}
923
		attemptPendingUpdates();
924
	}
925
926
    protected abstract void clear(Widget item);
869
    protected abstract void clear(Widget item);
870
    
871
    /**
872
     * Clears the children of the widget.
873
     * 
874
     * @param item
875
     */
876
    protected abstract void clearChildren(Widget item);
877
    
878
    /**
879
     * Clears the child at the given index.
880
     * 
881
     * @param parent
882
     * @param childIndex
883
     */
884
    protected abstract void clearChild(Widget parent, int childIndex);
927
885
928
	/**
886
	/**
929
	 * Returns the child widet at the given index for the given parent or
887
	 * Returns the child widet at the given index for the given parent or
Lines 949-970 Link Here
949
    protected void attemptPendingUpdates() {
907
    protected void attemptPendingUpdates() {
950
    	attemptSelection(false);
908
    	attemptSelection(false);
951
    }
909
    }
952
910
	
953
	/**
911
	/**
954
	 * The children of a node have changed.
912
	 * Notification a node's children have changed.
913
	 * Updates the child count for the parent's widget
914
	 * and clears children to be updated.
955
	 * 
915
	 * 
956
	 * @param parent
916
	 * @param parentNode
957
	 */
917
	 */
958
	protected void nodeChildrenChanged(ModelNode parentNode) {
918
	protected void nodeChildrenChanged(ModelNode parentNode) {
959
		ModelNode[] childrenNodes = parentNode.getChildrenNodes();
919
		Widget widget = findItem(parentNode);
920
		if (widget != null && !widget.isDisposed()) {
921
			int childCount = parentNode.getChildCount();
922
			setItemCount(widget, childCount);
923
			clearChildren(widget);
924
			attemptPendingUpdates();
925
		}		
926
	}
927
	
928
	/**
929
	 * Notification children have been added to the end
930
	 * of the given parent.
931
	 * 
932
	 * @param parentNode
933
	 */
934
	protected void nodeChildrenAdded(ModelNode parentNode) {
935
		Widget widget = findItem(parentNode);
936
		if (widget != null && !widget.isDisposed()) {
937
			int childCount = parentNode.getChildCount();
938
			setItemCount(widget, childCount);
939
			attemptPendingUpdates();
940
		}		
941
	}
942
	
943
	/**
944
	 * Notification children have been added to the end
945
	 * of the given parent.
946
	 * 
947
	 * @param parentNode
948
	 */
949
	protected void nodeChildRemoved(ModelNode parentNode, int index) {
950
		Widget widget = findItem(parentNode);
951
		if (widget != null && !widget.isDisposed()) {
952
			int childCount = parentNode.getChildCount();
953
			setItemCount(widget, childCount);
954
			for (int i = index; i < childCount; i ++) {
955
				clearChild(widget, i);
956
			}
957
			attemptPendingUpdates();
958
		}		
959
	}	
960
	
961
	/**
962
	 * Unmaps the node from its widget and all of its children nodes from
963
	 * their widgets.
964
	 * 
965
	 * @param node
966
	 */
967
	protected void unmapNode(ModelNode node) {
968
		unmapElement(node);
969
		ModelNode[] childrenNodes = node.getChildrenNodes();
960
		if (childrenNodes != null) {
970
		if (childrenNodes != null) {
961
			nodeChildrenSet(parentNode, childrenNodes);
971
			for (int i = 0; i < childrenNodes.length; i++) {
962
		} else {
972
				unmapNode(childrenNodes[i]);
963
			Widget widget = findItem(parentNode);
964
			if (widget != null && !widget.isDisposed()) {
965
				int childCount = parentNode.getChildCount();
966
				setItemCount(widget, childCount);
967
				attemptPendingUpdates();
968
			}
973
			}
969
		}
974
		}
970
	}
975
	}
Lines 997-1034 Link Here
997
    	return findItem((Object)node);
1002
    	return findItem((Object)node);
998
    }
1003
    }
999
1004
1000
    /**
1001
     * Note that the child at the specified index was requested by a widget
1002
     * when revealed but that the data was not in the model yet. When the data
1003
     * becomes available, map it to its widget.
1004
     * 
1005
     * @param parent
1006
     * @param index
1007
     */
1008
	protected synchronized void addPendingChildIndex(ModelNode parent, int index) {
1009
	    int[] indicies = (int[]) fParentsPendingChildren.get(parent);
1010
	    if (indicies == null) {
1011
	        indicies = new int[]{index};
1012
	    } else {
1013
	        int[] next = new int[indicies.length + 1];
1014
	        System.arraycopy(indicies, 0, next, 0, indicies.length);
1015
	        next[indicies.length] = index;
1016
	        indicies = next;
1017
	    }
1018
	    fParentsPendingChildren.put(parent, indicies);    	
1019
	}
1020
	
1021
	/**
1022
	 * Removes and returns and children indicies that were pending for the given
1023
	 * parent node. May return <code>null</code>.
1024
	 * 
1025
	 * @param parent
1026
	 * @return indicies of children that data were requested for or <code>null</code>
1027
	 */
1028
	protected int[] removePendingChildren(ModelNode parent) {
1029
		return (int[]) fParentsPendingChildren.remove(parent);
1030
	}
1031
1032
	/*
1005
	/*
1033
	 * (non-Javadoc)
1006
	 * (non-Javadoc)
1034
	 * 
1007
	 * 
Lines 1042-1047 Link Here
1042
1015
1043
		Widget parentItem = getParentWidget(event.item);
1016
		Widget parentItem = getParentWidget(event.item);
1044
		int index = event.index;
1017
		int index = event.index;
1018
		if (DEBUG_VIEWER) {
1019
			DebugUIPlugin.debug("SET DATA [" + index + "]: " + parentItem);  //$NON-NLS-1$//$NON-NLS-2$
1020
		}
1021
		if (index == -1) {
1022
			return;
1023
		}
1045
       
1024
       
1046
		ModelNode[] nodes = getModel().getNodes(parentItem.getData());
1025
		ModelNode[] nodes = getModel().getNodes(parentItem.getData());
1047
		if (nodes != null) {
1026
		if (nodes != null) {
Lines 1054-1073 Link Here
1054
		        		final ModelNode child = childrenNodes[index];
1033
		        		final ModelNode child = childrenNodes[index];
1055
		        		mapElement(child, event.item);
1034
		        		mapElement(child, event.item);
1056
		        		event.item.setData(child.getElement());
1035
		        		event.item.setData(child.getElement());
1036
		        		if (DEBUG_VIEWER) {
1037
		        			DebugUIPlugin.debug("\tPARENT: " + node); //$NON-NLS-1$
1038
		        			DebugUIPlugin.debug("\tMAPPED: " + child); //$NON-NLS-1$
1039
		        			Widget[] widgets = findItems(child);
1040
		        			if (widgets.length != 1) {
1041
		        				DebugUIPlugin.debug("\t\t*** NODE MAPPED > 1 ITEM ***"); //$NON-NLS-1$
1042
		        				for (int j = 0; j < widgets.length; j++) {
1043
									DebugUIPlugin.debug("\t\t\t" + widgets[j]); //$NON-NLS-1$
1044
								}
1045
		        			}
1046
		        		}
1057
		        		preservingSelection(new Runnable() {
1047
		        		preservingSelection(new Runnable() {
1058
		        		    public void run() {
1048
		        		    public void run() {
1059
		        		        internalRefresh(child);
1049
		        		        internalRefresh(child);
1060
		        		    }
1050
		        		    }
1061
		        		});
1051
		        		});
1062
		        	} else {
1052
		        	}
1063
		        		addPendingChildIndex(node, index);
1064
		            }
1065
		        	return;
1053
		        	return;
1054
				} else {
1055
					if (DEBUG_VIEWER) {
1056
						Widget[] widgets = findItems(node);
1057
						DebugUIPlugin.debug("\tITEM NOT FOUND: " + node); //$NON-NLS-1$
1058
						DebugUIPlugin.debug("\tITEMS WERE: "); //$NON-NLS-1$
1059
						for (int j = 0; j < widgets.length; j++) {
1060
							DebugUIPlugin.debug("\t\t" + widgets[j]); //$NON-NLS-1$
1061
						}
1062
					}
1066
				}
1063
				}
1067
			}
1064
			}
1065
        } else {
1066
        	if (DEBUG_VIEWER) {
1067
        		DebugUIPlugin.debug("\tNOT FOUND IN MODEL: " + parentItem.getData()); //$NON-NLS-1$
1068
        	}
1068
        }
1069
        }
1069
    }	
1070
    }
1070
1071
	
1071
	protected abstract void restoreLabels(Item item);
1072
	protected abstract void restoreLabels(Item item);
1072
1073
1073
	/**
1074
	/**
(-)ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeModel.java (-22 / +43 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.viewers;
11
package org.eclipse.debug.internal.ui.viewers;
12
12
13
import org.eclipse.debug.internal.ui.DebugUIPlugin;
13
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
14
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
14
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
15
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
15
import org.eclipse.jface.viewers.TreePath;
16
import org.eclipse.jface.viewers.TreePath;
Lines 130-145 Link Here
130
        if (parentNode == null) {
131
        if (parentNode == null) {
131
            return;
132
            return;
132
        }
133
        }
134
        int index = -1;
133
        synchronized (this) {
135
        synchronized (this) {
136
        	index = parentNode.getChildIndex(node);
134
            parentNode.removeChild(node);
137
            parentNode.removeChild(node);
135
            unmapNode(node);
138
            unmapNode(node);
136
            node.dispose();
139
            node.dispose();
140
            if (DEBUG_MODEL) {
141
            	DebugUIPlugin.debug("REMOVE: " + node);   //$NON-NLS-1$
142
            	DebugUIPlugin.debug(toString());
143
            }
137
        }
144
        }
145
        final int unmapFrom = index;
138
        final AsynchronousTreeViewer viewer = getTreeViewer();
146
        final AsynchronousTreeViewer viewer = getTreeViewer();
139
        preservingSelection(new Runnable() {
147
        preservingSelection(new Runnable() {
140
			public void run() {
148
			public void run() {
141
		        viewer.nodeDisposed(node);
149
				// unmap the removed node and all children that were shifted
142
				viewer.nodeChildrenChanged(parentNode);
150
				viewer.unmapNode(node);
151
				if (unmapFrom > -1) {
152
					ModelNode[] childrenNodes = parentNode.getChildrenNodes();
153
					for (int i = unmapFrom; i < childrenNodes.length; i++) {
154
						viewer.unmapNode(childrenNodes[i]);
155
					}
156
				}
157
		        viewer.nodeChildRemoved(parentNode, unmapFrom);
143
			}
158
			}
144
		});
159
		});
145
    }
160
    }
Lines 166-179 Link Here
166
            ModelNode node = new ModelNode(parent, element);
181
            ModelNode node = new ModelNode(parent, element);
167
            parent.addChild(node);
182
            parent.addChild(node);
168
            mapElement(element, node);
183
            mapElement(element, node);
184
            if (DEBUG_MODEL) {
185
            	DebugUIPlugin.debug("ADD: (parent) " + parent + " (child) " + element);   //$NON-NLS-1$//$NON-NLS-2$
186
            	DebugUIPlugin.debug(toString());
187
            }
169
        }
188
        }
170
        //TODO sort???
189
        //TODO sort???
171
        // notify the viewer to update
190
        // notify the viewer to update
172
        
191
        
173
        // TODO: this could be more efficient by not refreshing all children
174
        preservingSelection(new Runnable() {
192
        preservingSelection(new Runnable() {
175
			public void run() {
193
			public void run() {
176
				getTreeViewer().nodeChildrenChanged(parent);
194
				getTreeViewer().nodeChildrenAdded(parent);
177
			}
195
			}
178
		});
196
		});
179
        		
197
        		
Lines 240-251 Link Here
240
     * @param node
258
     * @param node
241
     * @param containsChildren
259
     * @param containsChildren
242
     */
260
     */
243
     void setIsContainer(ModelNode node, boolean containsChildren) {
261
     void setIsContainer(final ModelNode node, boolean containsChildren) {
244
    	ModelNode[] prevChildren = null;
262
    	ModelNode[] unmapChildren = null;
245
    	synchronized (this) {
263
    	synchronized (this) {
246
			prevChildren = node.getChildrenNodes();
264
    		ModelNode[] prevChildren = node.getChildrenNodes();
247
			node.setIsContainer(containsChildren);
265
			node.setIsContainer(containsChildren);
248
			if (!containsChildren && prevChildren != null) {
266
			if (!containsChildren && prevChildren != null) {
267
				unmapChildren = prevChildren;
249
                for (int i = 0; i < prevChildren.length; i++) {
268
                for (int i = 0; i < prevChildren.length; i++) {
250
                    ModelNode child = prevChildren[i];
269
                    ModelNode child = prevChildren[i];
251
                    unmapNode(child);
270
                    unmapNode(child);
Lines 253-274 Link Here
253
                }
272
                }
254
                node.setChildren(null);
273
                node.setChildren(null);
255
			}
274
			}
275
			if (DEBUG_MODEL) {
276
				DebugUIPlugin.debug("SET CONTAINER: " + node); //$NON-NLS-1$
277
				DebugUIPlugin.debug(toString());
278
			}
256
		}
279
		}
257
//    	 update tree outside lock
280
//    	 update tree outside lock
258
        AsynchronousTreeViewer viewer = getTreeViewer();
281
    	final ModelNode[] finalUnmap = unmapChildren;
259
		if (containsChildren) {
282
    	preservingSelection(new Runnable() {
260
            if (prevChildren == null) {
283
			public void run() {
261
                viewer.nodeChildrenChanged(node);
284
				if (finalUnmap != null) {
262
                viewer.nodeContainerChanged(node);
285
					for (int i = 0; i < finalUnmap.length; i++) {
263
            } else {
286
						getViewer().unmapNode(finalUnmap[i]);
264
                viewer.nodeContainerChanged(node);
287
					}
265
            }
288
				}
266
        } else if (!containsChildren && prevChildren != null) {            
289
		    	getTreeViewer().nodeContainerChanged(node);
267
            for (int i = 0; i < prevChildren.length; i++) {
290
		    	getViewer().nodeChildrenChanged(node);
268
                ModelNode child = prevChildren[i];
291
			}
269
                viewer.nodeDisposed(child);
292
		});
270
            }            
293
    	
271
            viewer.nodeChildrenChanged(node);
272
        }
273
    }    
294
    }    
274
}
295
}
(-)ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java (-44 / +95 lines)
Lines 17-22 Link Here
17
import java.util.Map;
17
import java.util.Map;
18
18
19
import org.eclipse.core.runtime.IAdaptable;
19
import org.eclipse.core.runtime.IAdaptable;
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.debug.internal.ui.DebugUIPlugin;
20
import org.eclipse.debug.internal.ui.elements.adapters.AsynchronousDebugLabelAdapter;
22
import org.eclipse.debug.internal.ui.elements.adapters.AsynchronousDebugLabelAdapter;
21
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
23
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
22
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
24
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
Lines 41-46 Link Here
41
	private Map fModelProxies = new HashMap(); // map of installed model proxies, by element
43
	private Map fModelProxies = new HashMap(); // map of installed model proxies, by element
42
	private AsynchronousViewer fViewer; // viewer this model works for
44
	private AsynchronousViewer fViewer; // viewer this model works for
43
    private boolean fDisposed = false; // whether disposed
45
    private boolean fDisposed = false; // whether disposed
46
    
47
    // debug flags
48
	public static boolean DEBUG_MODEL = false;
49
	
50
	static {
51
		DEBUG_MODEL = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
52
		 Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/model")); //$NON-NLS-1$
53
	}    
44
	
54
	
45
	/**
55
	/**
46
	 * List of requests currently being performed.
56
	 * List of requests currently being performed.
Lines 59-65 Link Here
59
	 */
69
	 */
60
	public AsynchronousModel(AsynchronousViewer viewer) {
70
	public AsynchronousModel(AsynchronousViewer viewer) {
61
		fViewer = viewer;
71
		fViewer = viewer;
62
72
		if (DEBUG_MODEL) {
73
			StringBuffer buffer = new StringBuffer();
74
			buffer.append("MODEL CREATED for: "); //$NON-NLS-1$
75
			buffer.append(fViewer);
76
			buffer.append(" ("); //$NON-NLS-1$
77
			buffer.append(this);
78
			buffer.append(")"); //$NON-NLS-1$
79
			DebugUIPlugin.debug(buffer.toString());
80
		}
63
	}
81
	}
64
	
82
	
65
	/**
83
	/**
Lines 83-88 Link Here
83
	 * Disposes this model
101
	 * Disposes this model
84
	 */
102
	 */
85
	public synchronized void dispose() {
103
	public synchronized void dispose() {
104
		if (DEBUG_MODEL) {
105
			StringBuffer buffer = new StringBuffer();
106
			buffer.append("MODEL DISPOSED for: "); //$NON-NLS-1$
107
			buffer.append(fViewer);
108
			buffer.append(" ("); //$NON-NLS-1$
109
			buffer.append(this);
110
			buffer.append(")"); //$NON-NLS-1$
111
			DebugUIPlugin.debug(buffer.toString());
112
		}
86
        fDisposed = true;
113
        fDisposed = true;
87
        cancelPendingUpdates();
114
        cancelPendingUpdates();
88
		disposeAllModelProxies();
115
		disposeAllModelProxies();
Lines 475-480 Link Here
475
        
502
        
476
        ModelNode[] prevKids = null;
503
        ModelNode[] prevKids = null;
477
        ModelNode[] newChildren = null;
504
        ModelNode[] newChildren = null;
505
        ModelNode[] unmap = null; 
478
        
506
        
479
        synchronized (this) {
507
        synchronized (this) {
480
        	if (isDisposed()) {
508
        	if (isDisposed()) {
Lines 490-546 Link Here
490
    			}
518
    			}
491
            	parentNode.setChildren(newChildren);
519
            	parentNode.setChildren(newChildren);
492
            } else {
520
            } else {
493
    	        for (int i = 0; i < prevKids.length; i++) {
521
            	newChildren = new ModelNode[children.length];
494
    				ModelNode kid = prevKids[i];
522
            	unmap = new ModelNode[prevKids.length];
495
    				if (i >= children.length) {
523
            	for (int i = 0; i < prevKids.length; i++) {
496
    					kid.dispose();
524
					unmap[i] = prevKids[i];	
497
    					unmapNode(kid);
525
				}
498
    				} else {
526
            	for (int i = 0; i < children.length; i++) {
499
    					ModelNode prevNode = prevKids[i];
527
					Object child = children[i];
500
    					Object nextChild = children[i];
528
					boolean found = false;
501
    					if (!prevNode.getElement().equals(nextChild)) {
529
					for (int j = 0; j < prevKids.length; j++) {
502
    						unmapNode(prevNode);
530
						ModelNode prevKid = prevKids[j];
503
    					}
531
						if (prevKid != null && child.equals(prevKid.getElement())) {
504
    					mapElement(nextChild, prevNode);
532
							newChildren[i] = prevKid;
505
    				}
533
							prevKids[j] = null;
506
    			}
534
							found = true;
507
    			// create new children
535
							break;
508
    	        if (children.length > prevKids.length) {
536
						}
509
    		        newChildren = new ModelNode[children.length];
537
					}
510
    		        System.arraycopy(prevKids, 0, newChildren, 0, prevKids.length);
538
					if (!found) {
511
    		        for (int i = prevKids.length; i < children.length; i ++) {
539
						newChildren[i] = new ModelNode(parentNode, child);
512
    		        	Object child = children[i];
540
						mapElement(child, newChildren[i]);
513
    					ModelNode childNode = new ModelNode(parentNode, child);
541
					}
514
    		        	mapElement(child, childNode);
542
				}
515
    		        	newChildren[i] = childNode;
543
            	for (int i = 0; i < prevKids.length; i++) {
516
    		        }
544
            		ModelNode kid = prevKids[i];
517
    		        parentNode.setChildren(newChildren);
545
            		if (kid != null) {
518
    	        }
546
            			kid.dispose();
519
                if (children.length < prevKids.length) {
547
            			unmapNode(kid);
520
                	newChildren = new ModelNode[children.length];
548
            		}
521
                    System.arraycopy(prevKids, 0, newChildren, 0, children.length);
549
            	}
522
                    parentNode.setChildren(newChildren);
550
    	        parentNode.setChildren(newChildren);
523
                }
551
            }
524
            }        	
552
            if (DEBUG_MODEL) {
553
            	DebugUIPlugin.debug("CHILDREN CHANGED: " + parentNode); //$NON-NLS-1$
554
            	DebugUIPlugin.debug(toString());
555
            }
525
        }
556
        }
526
        
557
        
527
        //update viewer outside the lock
558
        //update viewer outside the lock
528
    	final ModelNode[] finalPrevKids = prevKids; 
559
    	final ModelNode[] finalUnmap = unmap; 
529
        preservingSelection(new Runnable() {
560
        preservingSelection(new Runnable() {
530
            public void run() {
561
            public void run() {
531
            	if (finalPrevKids != null) {
562
            	if (finalUnmap != null) {
532
	                for (int i = 0; i < finalPrevKids.length; i++) {
563
	            	for (int i = 0; i < finalUnmap.length; i++) {
533
	                    ModelNode kid = finalPrevKids[i];
564
						viewer.unmapNode(finalUnmap[i]);
534
	                    if (i >= children.length) {
565
					}
535
	                        viewer.nodeDisposed(kid);
536
	                    } else {
537
	                        viewer.nodeChanged(kid);
538
	                    }
539
	                }
540
            	}
566
            	}
541
                viewer.nodeChildrenChanged(parentNode);
567
            	viewer.nodeChildrenChanged(parentNode);
542
            }
568
            }
543
        });        	        
569
        });        	        
544
570
545
	}
571
	}
572
	
573
	public String toString() {
574
		StringBuffer buf = new StringBuffer();
575
		if (fRoot != null) {
576
			buf.append("ROOT: "); //$NON-NLS-1$
577
			append(buf, fRoot, 0);
578
		} else {
579
			buf.append("ROOT: null"); //$NON-NLS-1$
580
		}
581
		return buf.toString();
582
	}
583
	
584
	private void append(StringBuffer buf, ModelNode node, int level) {
585
		for (int i = 0; i < level; i++) {
586
			buf.append('\t');
587
		}
588
		buf.append(node);
589
		buf.append('\n');
590
		ModelNode[] childrenNodes = node.getChildrenNodes();
591
		if (childrenNodes != null) {
592
			for (int i = 0; i < childrenNodes.length; i++) {
593
				append(buf, childrenNodes[i], level + 1);
594
			}
595
		}
596
	}
546
}
597
}
(-)ui/org/eclipse/debug/internal/ui/viewers/ModelNode.java (+12 lines)
Lines 194-197 Link Here
194
        fIsContainer = container;
194
        fIsContainer = container;
195
    }
195
    }
196
    
196
    
197
    public String toString() {
198
    	StringBuffer buf = new StringBuffer();
199
    	if (isDisposed()) {
200
    		buf.append("[DISPOSED] "); //$NON-NLS-1$
201
    	}
202
    	if (isContainer()) {
203
    		buf.append("[+] "); //$NON-NLS-1$
204
    	}
205
    	buf.append(getElement());
206
    	return buf.toString();
207
    }
208
    
197
}
209
}
(-)ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java (+6 lines)
Lines 43-48 Link Here
43
        protected void handleCreate(DebugEvent event) {
43
        protected void handleCreate(DebugEvent event) {
44
        	// do nothing - Launch change notification handles this
44
        	// do nothing - Launch change notification handles this
45
        }
45
        }
46
47
		protected void handleTerminate(DebugEvent event) {
48
			handleChange(event);
49
		}
50
        
51
        
46
        
52
        
47
    };
53
    };
48
54
(-)ui/org/eclipse/debug/internal/ui/DebugUIPlugin.java (-30 / +10 lines)
Lines 151-163 Link Here
151
	public static String ATTR_LAUNCHING_CONFIG_HANDLE= getUniqueIdentifier() + "launching_config_handle"; //$NON-NLS-1$
151
	public static String ATTR_LAUNCHING_CONFIG_HANDLE= getUniqueIdentifier() + "launching_config_handle"; //$NON-NLS-1$
152
	
152
	
153
	/**
153
	/**
154
	 * Flag indicating whether the debug UI is in trace
155
	 * mode. When in trace mode, extra debug information
156
	 * is produced.
157
	 */
158
	private boolean fTrace = false;	
159
	
160
	/**
161
	 * Singleton console document manager
154
	 * Singleton console document manager
162
	 */
155
	 */
163
	private ProcessConsoleManager fProcessConsoleManager = null;
156
	private ProcessConsoleManager fProcessConsoleManager = null;
Lines 190-195 Link Here
190
     */
183
     */
191
    private ServiceTracker fServiceTracker;
184
    private ServiceTracker fServiceTracker;
192
    private PackageAdmin fPackageAdminService;
185
    private PackageAdmin fPackageAdminService;
186
    
187
    public static boolean DEBUG = false;
193
	
188
	
194
    /**
189
    /**
195
     * Dummy launch node representing a launch that is waiting
190
     * Dummy launch node representing a launch that is waiting
Lines 216-232 Link Here
216
    }
211
    }
217
	
212
	
218
	/**
213
	/**
219
	 * Returns whether the debug UI plug-in is in trace
220
	 * mode.
221
	 * 
222
	 * @return whether the debug UI plug-in is in trace
223
	 *  mode
224
	 */
225
	public boolean isTraceMode() {
226
		return fTrace;
227
	}
228
	
229
	/**
230
	 * Returns the bundle the given class originated from.
214
	 * Returns the bundle the given class originated from.
231
	 * 
215
	 * 
232
	 * @param clazz a class
216
	 * @param clazz a class
Lines 242-265 Link Here
242
	}
226
	}
243
	
227
	
244
	/**
228
	/**
245
	 * Logs the given message if in trace mode.
246
	 * 
247
	 * @param String message to log
248
	 */
249
	public static void logTraceMessage(String message) {
250
		if (getDefault().isTraceMode()) {
251
			IStatus s = new Status(IStatus.WARNING, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, message, null);
252
			getDefault().getLog().log(s);
253
		}
254
	}
255
256
	/**
257
	 * Constructs the debug UI plugin
229
	 * Constructs the debug UI plugin
258
	 */
230
	 */
259
	public DebugUIPlugin() {
231
	public DebugUIPlugin() {
260
		super();
232
		super();
261
		fgDebugUIPlugin= this;
233
		fgDebugUIPlugin= this;
262
	}
234
	}
235
	
236
	public static void debug(String message) {
237
		if (DEBUG) {
238
			System.out.println(message);
239
		}
240
	}
263
		
241
		
264
	/**
242
	/**
265
	 * Returns the singleton instance of the debug plugin.
243
	 * Returns the singleton instance of the debug plugin.
Lines 409-414 Link Here
409
	public void start(BundleContext context) throws Exception {
387
	public void start(BundleContext context) throws Exception {
410
		super.start(context);
388
		super.start(context);
411
		
389
		
390
		DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.debug.ui/debug"));  //$NON-NLS-1$//$NON-NLS-2$
391
		
412
		// make sure the perspective manager is created
392
		// make sure the perspective manager is created
413
		// and be the first debug event listener
393
		// and be the first debug event listener
414
		fPerspectiveManager = new PerspectiveManager();
394
		fPerspectiveManager = new PerspectiveManager();
(-).options (-1 / +2 lines)
Lines 1-2 Link Here
1
org.eclipse.debug.ui/debug = false
1
org.eclipse.debug.ui/debug = false
2
org.eclipse.debug.ui/debug/viewer_cache_debug = false
2
org.eclipse.debug.ui/debug/viewers/model = false
3
org.eclipse.debug.ui/debug/viewers/viewer = false
(-)ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java (-5 / +2 lines)
Lines 488-498 Link Here
488
		        		// is causing the table viewer to not scroll or move cursor properly.
488
		        		// is causing the table viewer to not scroll or move cursor properly.
489
		        		// #interalRefresh on a child will never cause a structural
489
		        		// #interalRefresh on a child will never cause a structural
490
		        		// change in a table viewer.  As a result, there is no need to preserve selection
490
		        		// change in a table viewer.  As a result, there is no need to preserve selection
491
		        		internalRefresh(child);
491
		        		internalRefresh(child);	
492
		        		
492
		        	}
493
		        	} else {
494
		        		addPendingChildIndex(node, index);
495
		            }
496
		        	return;
493
		        	return;
497
				}
494
				}
498
			}
495
			}

Return to bug 127025