|
Lines 113-128
Link Here
|
| 113 |
|
113 |
|
| 114 |
protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$ |
114 |
protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$ |
| 115 |
protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$ |
115 |
protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$ |
| 116 |
|
|
|
| 117 |
/** |
| 118 |
* Map of parent nodes for which children were needed to "set data" |
| 119 |
* in the virtual widget. A parent is added to this map when we try go |
| 120 |
* get children but they aren't there yet. The children are retrieved |
| 121 |
* asynchronously, and later put back into the widgetry. |
| 122 |
* The value is an array of ints of the indicies of the children that |
| 123 |
* were requested. |
| 124 |
*/ |
| 125 |
private Map fParentsPendingChildren = new HashMap(); |
| 126 |
|
116 |
|
| 127 |
/** |
117 |
/** |
| 128 |
* Creates a new viewer |
118 |
* Creates a new viewer |
|
Lines 241-247
Link Here
|
| 241 |
* @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) |
231 |
* @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) |
| 242 |
*/ |
232 |
*/ |
| 243 |
protected synchronized void inputChanged(Object input, Object oldInput) { |
233 |
protected synchronized void inputChanged(Object input, Object oldInput) { |
| 244 |
fParentsPendingChildren.clear(); |
|
|
| 245 |
if (fUpdatePolicy == null) { |
234 |
if (fUpdatePolicy == null) { |
| 246 |
fUpdatePolicy = createUpdatePolicy(); |
235 |
fUpdatePolicy = createUpdatePolicy(); |
| 247 |
fUpdatePolicy.init(this); |
236 |
fUpdatePolicy.init(this); |
|
Lines 736-746
Link Here
|
| 736 |
} |
725 |
} |
| 737 |
|
726 |
|
| 738 |
protected synchronized void restoreSelection(ISelection oldSelection) { |
727 |
protected synchronized void restoreSelection(ISelection oldSelection) { |
| 739 |
doAttemptSelectionToWidget(oldSelection, false); |
728 |
ISelection remaining = doAttemptSelectionToWidget(oldSelection, false); |
| 740 |
// send out notification if old and new differ |
729 |
// send out notification if old and new differ |
| 741 |
fCurrentSelection = newSelectionFromWidget(); |
730 |
fCurrentSelection = newSelectionFromWidget(); |
| 742 |
if (!fCurrentSelection.equals(oldSelection)) |
731 |
if (!fCurrentSelection.equals(oldSelection)) { |
| 743 |
handleInvalidSelection(oldSelection, fCurrentSelection); |
732 |
handleInvalidSelection(oldSelection, fCurrentSelection); |
|
|
733 |
// if the remaining selection still exists in the model, make it pending |
| 734 |
if (selectionExists(remaining)) { |
| 735 |
setSelection(remaining); |
| 736 |
} |
| 737 |
} |
| 738 |
} |
| 739 |
|
| 740 |
/** |
| 741 |
* Returns whether the selection exists in the model |
| 742 |
*/ |
| 743 |
protected boolean selectionExists(ISelection selection) { |
| 744 |
if (selection.isEmpty()) { |
| 745 |
return false; |
| 746 |
} |
| 747 |
if (selection instanceof IStructuredSelection) { |
| 748 |
IStructuredSelection ss = (IStructuredSelection) selection; |
| 749 |
Iterator iterator = ss.iterator(); |
| 750 |
while (iterator.hasNext()) { |
| 751 |
Object element = iterator.next(); |
| 752 |
if (getModel().getNodes(element) == null) { |
| 753 |
return false; |
| 754 |
} |
| 755 |
} |
| 756 |
} |
| 757 |
return true; |
| 744 |
} |
758 |
} |
| 745 |
|
759 |
|
| 746 |
/** |
760 |
/** |
|
Lines 818-831
Link Here
|
| 818 |
protected void nodeDisposed(ModelNode node) { |
832 |
protected void nodeDisposed(ModelNode node) { |
| 819 |
Widget widget = findItem(node); |
833 |
Widget widget = findItem(node); |
| 820 |
if (widget != null) { |
834 |
if (widget != null) { |
| 821 |
unmapElement(node); |
835 |
unmapNode(node); |
| 822 |
widget.dispose(); |
836 |
widget.dispose(); |
| 823 |
ModelNode[] childrenNodes = node.getChildrenNodes(); |
|
|
| 824 |
if (childrenNodes != null) { |
| 825 |
for (int i = 0; i < childrenNodes.length; i++) { |
| 826 |
nodeDisposed(childrenNodes[i]); |
| 827 |
} |
| 828 |
} |
| 829 |
} |
837 |
} |
| 830 |
} |
838 |
} |
| 831 |
|
839 |
|
|
Lines 837-844
Link Here
|
| 837 |
public void nodeChanged(ModelNode node) { |
845 |
public void nodeChanged(ModelNode node) { |
| 838 |
Widget widget = findItem(node); |
846 |
Widget widget = findItem(node); |
| 839 |
if (widget != null) { |
847 |
if (widget != null) { |
| 840 |
widget.setData(node.getElement()); |
848 |
clear(widget); |
| 841 |
internalRefresh(node); |
849 |
attemptPendingUpdates(); |
| 842 |
} |
850 |
} |
| 843 |
} |
851 |
} |
| 844 |
|
852 |
|
|
Lines 859-896
Link Here
|
| 859 |
} |
867 |
} |
| 860 |
|
868 |
|
| 861 |
/** |
869 |
/** |
| 862 |
* Called when nodes are set in the model. The children may not have been |
870 |
* Clears the given widget |
| 863 |
* retrieved yet when the tree got the call to "set data". |
|
|
| 864 |
* |
871 |
* |
| 865 |
* @param parent |
872 |
* @param item |
| 866 |
* @param children |
|
|
| 867 |
*/ |
873 |
*/ |
| 868 |
protected void nodeChildrenSet(ModelNode parent, ModelNode[] children) { |
|
|
| 869 |
int[] indicies = removePendingChildren(parent); |
| 870 |
Widget widget = findItem(parent); |
| 871 |
if (widget != null && !widget.isDisposed()) { |
| 872 |
if (indicies != null) { |
| 873 |
for (int i = 0; i < indicies.length; i++) { |
| 874 |
int index = indicies[i]; |
| 875 |
Widget item = getChildWidget(widget, index); |
| 876 |
if (item != null) { |
| 877 |
if (index < children.length) { |
| 878 |
ModelNode childNode = children[index]; |
| 879 |
mapElement(childNode, item); |
| 880 |
item.setData(childNode.getElement()); |
| 881 |
internalRefresh(childNode); |
| 882 |
} |
| 883 |
} |
| 884 |
} |
| 885 |
setItemCount(widget, children.length); |
| 886 |
} else { |
| 887 |
setItemCount(widget, children.length); |
| 888 |
} |
| 889 |
} |
| 890 |
attemptPendingUpdates(); |
| 891 |
} |
| 892 |
|
| 893 |
protected abstract void clear(Widget item); |
874 |
protected abstract void clear(Widget item); |
|
|
875 |
|
| 876 |
/** |
| 877 |
* Clears the children of the widget. |
| 878 |
* |
| 879 |
* @param item |
| 880 |
*/ |
| 881 |
protected abstract void clearChildren(Widget item); |
| 894 |
|
882 |
|
| 895 |
/** |
883 |
/** |
| 896 |
* Returns the child widet at the given index for the given parent or |
884 |
* Returns the child widet at the given index for the given parent or |
|
Lines 916-937
Link Here
|
| 916 |
protected void attemptPendingUpdates() { |
904 |
protected void attemptPendingUpdates() { |
| 917 |
attemptSelection(false); |
905 |
attemptSelection(false); |
| 918 |
} |
906 |
} |
| 919 |
|
907 |
|
| 920 |
/** |
908 |
/** |
| 921 |
* The children of a node have changed. |
909 |
* Updates the child count for the parent's widget |
|
|
910 |
* and clears children to be updated. |
| 922 |
* |
911 |
* |
| 923 |
* @param parent |
912 |
* @param parentNode |
| 924 |
*/ |
913 |
*/ |
| 925 |
protected void nodeChildrenChanged(ModelNode parentNode) { |
914 |
protected void xxxChildrenChanged(ModelNode parentNode) { |
| 926 |
ModelNode[] childrenNodes = parentNode.getChildrenNodes(); |
915 |
Widget widget = findItem(parentNode); |
|
|
916 |
if (widget != null && !widget.isDisposed()) { |
| 917 |
int childCount = parentNode.getChildCount(); |
| 918 |
clearChildren(widget); |
| 919 |
setItemCount(widget, childCount); |
| 920 |
attemptPendingUpdates(); |
| 921 |
} |
| 922 |
} |
| 923 |
|
| 924 |
/** |
| 925 |
* Unmaps the node from its widget and all of its children nodes from |
| 926 |
* their widgets. |
| 927 |
* |
| 928 |
* @param node |
| 929 |
*/ |
| 930 |
protected void unmapNode(ModelNode node) { |
| 931 |
unmapElement(node); |
| 932 |
ModelNode[] childrenNodes = node.getChildrenNodes(); |
| 927 |
if (childrenNodes != null) { |
933 |
if (childrenNodes != null) { |
| 928 |
nodeChildrenSet(parentNode, childrenNodes); |
934 |
for (int i = 0; i < childrenNodes.length; i++) { |
| 929 |
} else { |
935 |
unmapNode(childrenNodes[i]); |
| 930 |
Widget widget = findItem(parentNode); |
|
|
| 931 |
if (widget != null && !widget.isDisposed()) { |
| 932 |
int childCount = parentNode.getChildCount(); |
| 933 |
setItemCount(widget, childCount); |
| 934 |
attemptPendingUpdates(); |
| 935 |
} |
936 |
} |
| 936 |
} |
937 |
} |
| 937 |
} |
938 |
} |
|
Lines 964-1001
Link Here
|
| 964 |
return findItem((Object)node); |
965 |
return findItem((Object)node); |
| 965 |
} |
966 |
} |
| 966 |
|
967 |
|
| 967 |
/** |
|
|
| 968 |
* Note that the child at the specified index was requested by a widget |
| 969 |
* when revealed but that the data was not in the model yet. When the data |
| 970 |
* becomes available, map it to its widget. |
| 971 |
* |
| 972 |
* @param parent |
| 973 |
* @param index |
| 974 |
*/ |
| 975 |
protected synchronized void addPendingChildIndex(ModelNode parent, int index) { |
| 976 |
int[] indicies = (int[]) fParentsPendingChildren.get(parent); |
| 977 |
if (indicies == null) { |
| 978 |
indicies = new int[]{index}; |
| 979 |
} else { |
| 980 |
int[] next = new int[indicies.length + 1]; |
| 981 |
System.arraycopy(indicies, 0, next, 0, indicies.length); |
| 982 |
next[indicies.length] = index; |
| 983 |
indicies = next; |
| 984 |
} |
| 985 |
fParentsPendingChildren.put(parent, indicies); |
| 986 |
} |
| 987 |
|
| 988 |
/** |
| 989 |
* Removes and returns and children indicies that were pending for the given |
| 990 |
* parent node. May return <code>null</code>. |
| 991 |
* |
| 992 |
* @param parent |
| 993 |
* @return indicies of children that data were requested for or <code>null</code> |
| 994 |
*/ |
| 995 |
protected int[] removePendingChildren(ModelNode parent) { |
| 996 |
return (int[]) fParentsPendingChildren.remove(parent); |
| 997 |
} |
| 998 |
|
| 999 |
/* |
968 |
/* |
| 1000 |
* (non-Javadoc) |
969 |
* (non-Javadoc) |
| 1001 |
* |
970 |
* |
|
Lines 1026-1034
Link Here
|
| 1026 |
internalRefresh(child); |
995 |
internalRefresh(child); |
| 1027 |
} |
996 |
} |
| 1028 |
}); |
997 |
}); |
| 1029 |
} else { |
998 |
} |
| 1030 |
addPendingChildIndex(node, index); |
|
|
| 1031 |
} |
| 1032 |
return; |
999 |
return; |
| 1033 |
} |
1000 |
} |
| 1034 |
} |
1001 |
} |