|
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 |
/** |