1 12 13 package org.eclipse.jface.viewers; 14 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.Iterator ; 18 import java.util.LinkedList ; 19 import java.util.List ; 20 21 import org.eclipse.core.runtime.Assert; 22 import org.eclipse.core.runtime.ListenerList; 23 import org.eclipse.jface.util.SafeRunnable; 24 import org.eclipse.swt.SWT; 25 import org.eclipse.swt.custom.BusyIndicator; 26 import org.eclipse.swt.events.SelectionEvent; 27 import org.eclipse.swt.events.SelectionListener; 28 import org.eclipse.swt.events.TreeEvent; 29 import org.eclipse.swt.events.TreeListener; 30 import org.eclipse.swt.graphics.Point; 31 import org.eclipse.swt.widgets.Control; 32 import org.eclipse.swt.widgets.Item; 33 import org.eclipse.swt.widgets.Widget; 34 35 57 public abstract class AbstractTreeViewer extends ColumnViewer { 58 59 66 public static final int ALL_LEVELS = -1; 67 68 72 private ListenerList treeListeners = new ListenerList(); 73 74 81 private int expandToLevel = 0; 82 83 86 class UpdateItemSafeRunnable extends SafeRunnable { 87 private Object element; 88 89 private Item item; 90 91 UpdateItemSafeRunnable(Item item, Object element) { 92 this.item = item; 93 this.element = element; 94 } 95 96 public void run() { 97 doUpdateItem(item, element); 98 } 99 100 } 101 102 107 protected AbstractTreeViewer() { 108 } 110 111 127 public void add(Object parentElementOrTreePath, Object [] childElements) { 128 Assert.isNotNull(parentElementOrTreePath); 129 assertElementsNotNull(childElements); 130 if (isBusy()) 131 return; 132 Widget[] widgets = internalFindItems(parentElementOrTreePath); 133 if (widgets.length == 0) { 135 return; 136 } 137 138 for (int i = 0; i < widgets.length; i++) { 139 internalAdd(widgets[i], parentElementOrTreePath, childElements); 140 } 141 } 142 143 152 final protected Widget[] internalFindItems(Object parentElementOrTreePath) { 153 Widget[] widgets; 154 if (parentElementOrTreePath instanceof TreePath) { 155 TreePath path = (TreePath) parentElementOrTreePath; 156 Widget w = internalFindItem(path); 157 if (w == null) { 158 widgets = new Widget[] {}; 159 } else { 160 widgets = new Widget[] { w }; 161 } 162 } else { 163 widgets = findItems(parentElementOrTreePath); 164 } 165 return widgets; 166 } 167 168 175 private Widget internalFindItem(TreePath path) { 176 Widget[] widgets = findItems(path.getLastSegment()); 177 for (int i = 0; i < widgets.length; i++) { 178 Widget widget = widgets[i]; 179 if (widget instanceof Item) { 180 Item item = (Item) widget; 181 TreePath p = getTreePathFromItem(item); 182 if (p.equals(path)) { 183 return widget; 184 } 185 } 186 } 187 return null; 188 } 189 190 209 protected void internalAdd(Widget widget, Object parentElementOrTreePath, 210 Object [] childElements) { 211 Object parent; 212 TreePath path; 213 if (parentElementOrTreePath instanceof TreePath) { 214 path = (TreePath) parentElementOrTreePath; 215 parent = path.getLastSegment(); 216 } else { 217 parent = parentElementOrTreePath; 218 path = null; 219 } 220 221 if (widget instanceof Item) { 224 Item ti = (Item) widget; 225 if (!getExpanded(ti)) { 226 boolean needDummy = isExpandable(ti, path, parent); 227 boolean haveDummy = false; 228 Item[] items = getItems(ti); 230 for (int i = 0; i < items.length; i++) { 231 if (items[i].getData() != null) { 232 disassociate(items[i]); 233 items[i].dispose(); 234 } else { 235 if (needDummy && !haveDummy) { 236 haveDummy = true; 237 } else { 238 items[i].dispose(); 239 } 240 } 241 } 242 if (needDummy && !haveDummy) { 244 newItem(ti, SWT.NULL, -1); 245 } 246 return; 247 } 248 } 249 250 if (childElements.length > 0) { 251 Object [] filtered = filter(parentElementOrTreePath, childElements); 253 ViewerComparator comparator = getComparator(); 254 if (comparator != null) { 255 if (comparator instanceof TreePathViewerSorter) { 256 TreePathViewerSorter tpvs = (TreePathViewerSorter) comparator; 257 if (path == null) { 258 path = internalGetSorterParentPath(widget, comparator); 259 } 260 tpvs.sort(this, path, filtered); 261 } else { 262 comparator.sort(this, filtered); 263 } 264 } 265 createAddedElements(widget, filtered); 266 } 267 } 268 269 278 private Object [] filter(Object parentElementOrTreePath, Object [] elements) { 279 ViewerFilter[] filters = getFilters(); 280 if (filters != null) { 281 ArrayList filtered = new ArrayList (elements.length); 282 for (int i = 0; i < elements.length; i++) { 283 boolean add = true; 284 for (int j = 0; j < filters.length; j++) { 285 add = filters[j].select(this, parentElementOrTreePath, 286 elements[i]); 287 if (!add) { 288 break; 289 } 290 } 291 if (add) { 292 filtered.add(elements[i]); 293 } 294 } 295 return filtered.toArray(); 296 } 297 return elements; 298 } 299 300 308 private void createAddedElements(Widget widget, Object [] elements) { 309 310 if (elements.length == 1) { 311 if (equals(elements[0], widget.getData())) { 312 return; 313 } 314 } 315 316 ViewerComparator comparator = getComparator(); 317 TreePath parentPath = internalGetSorterParentPath(widget, comparator); 318 Item[] items = getChildren(widget); 319 320 int lastInsertion = 0; 323 324 if (items.length == 0) { 326 for (int i = 0; i < elements.length; i++) { 327 createTreeItem(widget, elements[i], -1); 328 } 329 return; 330 } 331 332 for (int i = 0; i < elements.length; i++) { 333 boolean newItem = true; 334 Object element = elements[i]; 335 int index; 336 if (comparator == null) { 337 if (itemExists(items, element)) { 338 internalRefresh(element); 339 newItem = false; 340 } 341 index = -1; 342 } else { 343 lastInsertion = insertionPosition(items, comparator, 344 lastInsertion, element, parentPath); 345 if (lastInsertion == items.length) { 348 index = -1; 349 } else { while (lastInsertion < items.length 351 && internalCompare(comparator, parentPath, element, 352 items[lastInsertion].getData()) == 0) { 353 if (items[lastInsertion].getData().equals(element)) { 358 internalRefresh(element); 360 newItem = false; 361 } 362 lastInsertion++; } 364 if (lastInsertion == items.length) { 366 index = -1; 367 } else { 368 index = lastInsertion + i; } 371 } 372 } 373 if (newItem) { 374 createTreeItem(widget, element, index); 375 } 376 } 377 } 378 379 386 private boolean itemExists(Item[] items, Object element) { 387 if (usingElementMap()) { 388 Widget[] existingItems = findItems(element); 389 if (existingItems.length == 0) { 391 return false; 392 } else if (existingItems.length == 1) { 393 if (items.length > 0 && existingItems[0] instanceof Item) { 394 Item existingItem = (Item) existingItems[0]; 395 return getParentItem(existingItem) == getParentItem(items[0]); 396 } 397 } 398 } 399 for (int i = 0; i < items.length; i++) { 400 if (items[i].getData().equals(element)) { 401 return true; 402 } 403 } 404 return false; 405 } 406 407 429 430 private int insertionPosition(Item[] items, ViewerComparator comparator, 431 int lastInsertion, Object element, TreePath parentPath) { 432 433 int size = items.length; 434 if (comparator == null) { 435 return size; 436 } 437 int min = lastInsertion, max = size - 1; 438 439 while (min <= max) { 440 int mid = (min + max) / 2; 441 Object data = items[mid].getData(); 442 int compare = internalCompare(comparator, parentPath, data, element); 443 if (compare == 0) { 444 return mid; } 446 if (compare < 0) { 447 min = mid + 1; 448 } else { 449 max = mid - 1; 450 } 451 } 452 return min; 453 454 } 455 456 476 477 486 protected int indexForElement(Widget parent, Object element) { 487 ViewerComparator comparator = getComparator(); 488 TreePath parentPath = internalGetSorterParentPath(parent, comparator); 489 490 Item[] items = getChildren(parent); 491 int count = items.length; 492 493 if (comparator == null) { 494 return count; 495 } 496 int min = 0, max = count - 1; 497 498 while (min <= max) { 499 int mid = (min + max) / 2; 500 Object data = items[mid].getData(); 501 int compare = internalCompare(comparator, parentPath, data, element); 502 if (compare == 0) { 503 while (compare == 0) { 505 ++mid; 506 if (mid >= count) { 507 break; 508 } 509 data = items[mid].getData(); 510 compare = internalCompare(comparator, parentPath, data, 511 element); 512 } 513 return mid; 514 } 515 if (compare < 0) { 516 min = mid + 1; 517 } else { 518 max = mid - 1; 519 } 520 } 521 return min; 522 } 523 524 537 private TreePath internalGetSorterParentPath(Widget parent, 538 ViewerComparator comparator) { 539 TreePath path; 540 if (comparator instanceof TreePathViewerSorter 541 && parent instanceof Item) { 542 Item item = (Item) parent; 543 path = getTreePathFromItem(item); 544 } else { 545 path = null; 546 } 547 return path; 548 } 549 550 566 private int internalCompare(ViewerComparator comparator, 567 TreePath parentPath, Object e1, Object e2) { 568 if (comparator instanceof TreePathViewerSorter) { 569 TreePathViewerSorter tpvs = (TreePathViewerSorter) comparator; 570 return tpvs.compare(this, parentPath, e1, e2); 571 } 572 return comparator.compare(this, e1, e2); 573 } 574 575 580 protected Object [] getSortedChildren(Object parentElementOrTreePath) { 581 Object [] result = getFilteredChildren(parentElementOrTreePath); 582 ViewerComparator comparator = getComparator(); 583 if (parentElementOrTreePath != null 584 && comparator instanceof TreePathViewerSorter) { 585 TreePathViewerSorter tpvs = (TreePathViewerSorter) comparator; 586 587 result = (Object []) result.clone(); 589 590 TreePath path = null; 591 if (parentElementOrTreePath instanceof TreePath) { 592 path = (TreePath) parentElementOrTreePath; 593 } else { 594 Object parent = parentElementOrTreePath; 595 Widget w = internalGetWidgetToSelect(parent); 596 if (w != null) { 597 path = internalGetSorterParentPath(w, comparator); 598 } 599 } 600 tpvs.sort(this, path, result); 601 } else if (comparator != null) { 602 result = (Object []) result.clone(); 604 comparator.sort(this, result); 605 } 606 return result; 607 } 608 609 614 protected Object [] getFilteredChildren(Object parentElementOrTreePath) { 615 Object [] result = getRawChildren(parentElementOrTreePath); 616 ViewerFilter[] filters = getFilters(); 617 for (int i = 0; i < filters.length; i++) { 618 ViewerFilter filter = filters[i]; 619 result = filter.filter(this, parentElementOrTreePath, result); 620 } 621 return result; 622 } 623 624 642 public void add(Object parentElementOrTreePath, Object childElement) { 643 add(parentElementOrTreePath, new Object [] { childElement }); 644 } 645 646 655 protected void addSelectionListener(Control control, 656 SelectionListener listener) { 657 } 659 660 667 public void addTreeListener(ITreeViewerListener listener) { 668 treeListeners.add(listener); 669 } 670 671 679 protected abstract void addTreeListener(Control control, 680 TreeListener listener); 681 682 687 protected void associate(Object element, Item item) { 688 Object data = item.getData(); 689 if (data != null && data != element && equals(data, element)) { 690 unmapElement(data, item); 694 item.setData(element); 695 mapElement(element, item); 696 } else { 697 super.associate(element, item); 699 } 700 } 701 702 706 public void collapseAll() { 707 Object root = getRoot(); 708 if (root != null) { 709 collapseToLevel(root, ALL_LEVELS); 710 } 711 } 712 713 723 public void collapseToLevel(Object elementOrTreePath, int level) { 724 Assert.isNotNull(elementOrTreePath); 725 Widget w = internalGetWidgetToSelect(elementOrTreePath); 726 if (w != null) { 727 internalCollapseToLevel(w, level); 728 } 729 } 730 731 743 protected void createChildren(final Widget widget) { 744 boolean oldBusy = busy; 745 busy = true; 746 try { 747 final Item[] tis = getChildren(widget); 748 if (tis != null && tis.length > 0) { 749 Object data = tis[0].getData(); 750 if (data != null) { 751 return; } 753 } 754 755 BusyIndicator.showWhile(widget.getDisplay(), new Runnable () { 756 public void run() { 757 if (tis != null) { 760 for (int i = 0; i < tis.length; i++) { 761 if (tis[i].getData() != null) { 762 disassociate(tis[i]); 763 Assert.isTrue(tis[i].getData() == null, 764 "Second or later child is non -null"); 766 } 767 tis[i].dispose(); 768 } 769 } 770 Object d = widget.getData(); 771 if (d != null) { 772 Object parentElement = d; 773 Object [] children; 774 if (isTreePathContentProvider() && widget instanceof Item) { 775 TreePath path = getTreePathFromItem((Item) widget); 776 children = getSortedChildren(path); 777 } else { 778 children = getSortedChildren(parentElement); 779 } 780 for (int i = 0; i < children.length; i++) { 781 createTreeItem(widget, children[i], -1); 782 } 783 } 784 } 785 786 }); 787 } finally { 788 busy = oldBusy; 789 } 790 } 791 792 804 protected void createTreeItem(Widget parent, Object element, int index) { 805 Item item = newItem(parent, SWT.NULL, index); 806 updateItem(item, element); 807 updatePlus(item, element); 808 } 809 810 814 protected void disassociate(Item item) { 815 super.disassociate(item); 816 if (usingElementMap()) { 820 disassociateChildren(item); 821 } 822 } 823 824 831 private void disassociateChildren(Item item) { 832 Item[] items = getChildren(item); 833 for (int i = 0; i < items.length; i++) { 834 if (items[i].getData() != null) { 835 disassociate(items[i]); 836 } 837 } 838 } 839 840 841 protected Widget doFindInputItem(Object element) { 842 Object root = getRoot(); 844 if (root == null) { 845 return null; 846 } 847 848 if (equals(root, element)) { 849 return getControl(); 850 } 851 return null; 852 } 853 854 855 protected Widget doFindItem(Object element) { 856 Object root = getRoot(); 858 if (root == null) { 859 return null; 860 } 861 862 Item[] items = getChildren(getControl()); 863 if (items != null) { 864 for (int i = 0; i < items.length; i++) { 865 Widget o = internalFindItem(items[i], element); 866 if (o != null) { 867 return o; 868 } 869 } 870 } 871 return null; 872 } 873 874 882 protected void doUpdateItem(final Item item, Object element) { 883 if (item.isDisposed()) { 884 unmapElement(element, item); 885 return; 886 } 887 888 int columnCount = doGetColumnCount(); 889 if (columnCount == 0) columnCount = 1; 891 892 ViewerRow viewerRowFromItem = getViewerRowFromItem(item); 893 894 boolean isVirtual = (getControl().getStyle() & SWT.VIRTUAL) != 0; 895 896 if (isVirtual) { 898 viewerRowFromItem = (ViewerRow) viewerRowFromItem.clone(); 899 } 900 901 for (int column = 0; column < columnCount; column++) { 902 ViewerColumn columnViewer = getViewerColumn(column); 903 ViewerCell cellToUpdate = updateCell(viewerRowFromItem, column, 904 element); 905 906 if (isVirtual) { 908 cellToUpdate = new ViewerCell(cellToUpdate.getViewerRow(), cellToUpdate.getColumnIndex(), element); 909 } 910 911 columnViewer.refresh(cellToUpdate); 912 913 updateCell(null, 0, null); 915 916 if (item.isDisposed()) { 919 unmapElement(element, item); 920 return; 921 } 922 923 } 924 } 925 926 942 protected boolean isSameSelection(List items, Item[] current) { 943 int n = items.size(); 945 if (n != current.length) { 946 return false; 947 } 948 949 CustomHashtable itemSet = newHashtable(n * 2 + 1); 950 for (Iterator i = items.iterator(); i.hasNext();) { 951 Item item = (Item) i.next(); 952 Object element = item.getData(); 953 itemSet.put(element, element); 954 } 955 956 for (int i = 0; i < current.length; i++) { 959 if (current[i].getData() == null 960 || !itemSet.containsKey(current[i].getData())) { 961 return false; 962 } 963 } 964 965 return true; 966 } 967 968 969 970 971 protected void doUpdateItem(Widget widget, Object element, boolean fullMap) { 972 boolean oldBusy = busy; 973 busy = true; 974 try { 975 if (widget instanceof Item) { 976 Item item = (Item) widget; 977 978 if (fullMap) { 980 associate(element, item); 981 } else { 982 Object data = item.getData(); 983 if (data != null) { 984 unmapElement(data, item); 985 } 986 item.setData(element); 987 mapElement(element, item); 988 } 989 990 SafeRunnable.run(new UpdateItemSafeRunnable(item, element)); 992 } 993 } finally { 994 busy = oldBusy; 995 } 996 } 997 998 1002 public void expandAll() { 1003 expandToLevel(ALL_LEVELS); 1004 } 1005 1006 1013 public void expandToLevel(int level) { 1014 expandToLevel(getRoot(), level); 1015 } 1016 1017 1028 public void expandToLevel(Object elementOrTreePath, int level) { 1029 if (isBusy()) 1030 return; 1031 Widget w = internalExpand(elementOrTreePath, true); 1032 if (w != null) { 1033 internalExpandToLevel(w, level); 1034 } 1035 } 1036 1037 1045 protected void fireTreeCollapsed(final TreeExpansionEvent event) { 1046 Object [] listeners = treeListeners.getListeners(); 1047 for (int i = 0; i < listeners.length; ++i) { 1048 final ITreeViewerListener l = (ITreeViewerListener) listeners[i]; 1049 SafeRunnable.run(new SafeRunnable() { 1050 public void run() { 1051 l.treeCollapsed(event); 1052 } 1053 }); 1054 } 1055 } 1056 1057 1065 protected void fireTreeExpanded(final TreeExpansionEvent event) { 1066 Object [] listeners = treeListeners.getListeners(); 1067 for (int i = 0; i < listeners.length; ++i) { 1068 final ITreeViewerListener l = (ITreeViewerListener) listeners[i]; 1069 SafeRunnable.run(new SafeRunnable() { 1070 public void run() { 1071 l.treeExpanded(event); 1072 } 1073 }); 1074 } 1075 1076 } 1077 1078 1085 public int getAutoExpandLevel() { 1086 return expandToLevel; 1087 } 1088 1089 1096 protected abstract Item[] getChildren(Widget widget); 1097 1098 1114 protected Item getChild(Widget widget, int index) { 1115 return getChildren(widget)[index]; 1116 } 1117 1118 1126 protected abstract boolean getExpanded(Item item); 1127 1128 1140 public Object [] getExpandedElements() { 1141 ArrayList items = new ArrayList (); 1142 internalCollectExpandedItems(items, getControl()); 1143 ArrayList result = new ArrayList (items.size()); 1144 for (Iterator it = items.iterator(); it.hasNext();) { 1145 Item item = (Item) it.next(); 1146 Object data = item.getData(); 1147 if (data != null) { 1148 result.add(data); 1149 } 1150 } 1151 return result.toArray(); 1152 } 1153 1154 1163 public boolean getExpandedState(Object elementOrTreePath) { 1164 Assert.isNotNull(elementOrTreePath); 1165 Widget item = internalGetWidgetToSelect(elementOrTreePath); 1166 if (item instanceof Item) { 1167 return getExpanded((Item) item); 1168 } 1169 return false; 1170 } 1171 1172 1179 protected abstract int getItemCount(Control control); 1180 1181 1188 protected abstract int getItemCount(Item item); 1189 1190 1197 protected abstract Item[] getItems(Item item); 1198 1199 1211 protected Item getNextItem(Item item, boolean includeChildren) { 1212 if (item == null) { 1213 return null; 1214 } 1215 if (includeChildren && getExpanded(item)) { 1216 Item[] children = getItems(item); 1217 if (children != null && children.length > 0) { 1218 return children[0]; 1219 } 1220 } 1221 1222 Item parent = getParentItem(item); 1225 if (parent == null) { 1226 return null; 1227 } 1228 Item[] siblings = getItems(parent); 1229 if (siblings != null) { 1230 if (siblings.length <= 1) { 1231 return getNextItem(parent, false); 1232 } 1233 1234 for (int i = 0; i < siblings.length; i++) { 1235 if (siblings[i] == item && i < (siblings.length - 1)) { 1236 return siblings[i + 1]; 1237 } 1238 } 1239 } 1240 return getNextItem(parent, false); 1241 } 1242 1243 1251 protected abstract Item getParentItem(Item item); 1252 1253 1261 protected Item getPreviousItem(Item item) { 1262 Item parent = getParentItem(item); 1265 if (parent == null) { 1266 return null; 1267 } 1268 Item[] siblings = getItems(parent); 1269 if (siblings.length == 0 || siblings[0] == item) { 1270 return parent; 1271 } 1272 Item previous = siblings[0]; 1273 for (int i = 1; i < siblings.length; i++) { 1274 if (siblings[i] == item) { 1275 return rightMostVisibleDescendent(previous); 1276 } 1277 previous = siblings[i]; 1278 } 1279 return null; 1280 } 1281 1282 1283 protected Object [] getRawChildren(Object parentElementOrTreePath) { 1284 boolean oldBusy = busy; 1285 busy = true; 1286 try { 1287 Object parent; 1288 TreePath path; 1289 if (parentElementOrTreePath instanceof TreePath) { 1290 path = (TreePath) parentElementOrTreePath; 1291 parent = path.getLastSegment(); 1292 } else { 1293 parent = parentElementOrTreePath; 1294 path = null; 1295 } 1296 if (parent != null) { 1297 if (equals(parent, getRoot())) { 1298 return super.getRawChildren(parent); 1299 } 1300 IContentProvider cp = getContentProvider(); 1301 if (cp instanceof ITreePathContentProvider) { 1302 ITreePathContentProvider tpcp = (ITreePathContentProvider) cp; 1303 if (path == null) { 1304 Widget w = findItem(parent); 1306 if (w instanceof Item) { 1307 Item item = (Item) w; 1308 path = getTreePathFromItem(item); 1309 } 1310 if (path == null) { 1311 path = new TreePath(new Object [] { parent }); 1312 } 1313 } 1314 Object [] result = tpcp.getChildren(path); 1315 if (result != null) { 1316 return result; 1317 } 1318 } else if (cp instanceof ITreeContentProvider) { 1319 ITreeContentProvider tcp = (ITreeContentProvider) cp; 1320 Object [] result = tcp.getChildren(parent); 1321 if (result != null) { 1322 return result; 1323 } 1324 } 1325 } 1326 return new Object [0]; 1327 } finally { 1328 busy = oldBusy; 1329 } 1330 } 1331 1332 1339 protected abstract Item[] getSelection(Control control); 1340 1341 1346 protected List getSelectionFromWidget() { 1347 Widget[] items = getSelection(getControl()); 1348 ArrayList list = new ArrayList (items.length); 1349 for (int i = 0; i < items.length; i++) { 1350 Widget item = items[i]; 1351 Object e = item.getData(); 1352 if (e != null) { 1353 list.add(e); 1354 } 1355 } 1356 return list; 1357 } 1358 1359 1365 protected void handleDoubleSelect(SelectionEvent event) { 1366 Control control = getControl(); 1368 if (control != null && !control.isDisposed()) { 1369 ISelection selection; 1376 if (event.item != null && event.item.getData() != null) { 1377 1378 TreePath treePath = getTreePathFromItem((Item) event.item); 1380 selection = new TreeSelection(treePath); 1381 1383 } else { 1384 selection = getSelection(); 1385 updateSelection(selection); 1386 } 1387 fireDoubleClick(new DoubleClickEvent(this, selection)); 1388 } 1389 } 1390 1391 1397 protected void handleTreeCollapse(TreeEvent event) { 1398 if (event.item.getData() != null) { 1399 fireTreeCollapsed(new TreeExpansionEvent(this, event.item.getData())); 1400 } 1401 } 1402 1403 1409 protected void handleTreeExpand(TreeEvent event) { 1410 createChildren(event.item); 1411 if (event.item.getData() != null) { 1412 fireTreeExpanded(new TreeExpansionEvent(this, event.item.getData())); 1413 } 1414 } 1415 1416 1417 protected void hookControl(Control control) { 1418 super.hookControl(control); 1419 addTreeListener(control, new TreeListener() { 1420 public void treeExpanded(TreeEvent event) { 1421 handleTreeExpand(event); 1422 } 1423 1424 public void treeCollapsed(TreeEvent event) { 1425 handleTreeCollapse(event); 1426 } 1427 }); 1428 } 1429 1430 1434 protected void inputChanged(Object input, Object oldInput) { 1435 preservingSelection(new Runnable () { 1436 public void run() { 1437 Control tree = getControl(); 1438 boolean useRedraw = true; 1439 if (useRedraw) { 1442 tree.setRedraw(false); 1443 } 1444 removeAll(tree); 1445 tree.setData(getRoot()); 1446 internalInitializeTree(tree); 1447 if (useRedraw) { 1448 tree.setRedraw(true); 1449 } 1450 } 1451 1452 }); 1453 } 1454 1455 1462 protected void internalInitializeTree(Control tree) { 1463 createChildren(tree); 1464 internalExpandToLevel(tree, expandToLevel); 1465 } 1466 1467 1481 protected void internalCollapseToLevel(Widget widget, int level) { 1482 if (level == ALL_LEVELS || level > 0) { 1483 1484 if (widget instanceof Item) { 1485 setExpanded((Item) widget, false); 1486 } 1487 1488 if (level == ALL_LEVELS || level > 1) { 1489 Item[] children = getChildren(widget); 1490 if (children != null) { 1491 int nextLevel = (level == ALL_LEVELS ? ALL_LEVELS 1492 : level - 1); 1493 for (int i = 0; i < children.length; i++) { 1494 internalCollapseToLevel(children[i], nextLevel); 1495 } 1496 } 1497 } 1498 } 1499 } 1500 1501 1510 private void internalCollectExpandedItems(List result, Widget widget) { 1511 Item[] items = getChildren(widget); 1512 for (int i = 0; i < items.length; i++) { 1513 Item item = items[i]; 1514 if (getExpanded(item)) { 1515 result.add(item); 1516 } 1517 internalCollectExpandedItems(result, item); 1518 } 1519 } 1520 1521 1534 protected Widget internalExpand(Object elementOrPath, boolean expand) { 1535 1536 if (elementOrPath == null) { 1537 return null; 1538 } 1539 1540 Widget w = internalGetWidgetToSelect(elementOrPath); 1541 if (w == null) { 1542 if (equals(elementOrPath, getRoot())) { return null; 1544 } 1545 Object parent = getParentElement(elementOrPath); 1547 if (parent != null) { 1548 Widget pw = internalExpand(parent, false); 1549 if (pw != null) { 1550 createChildren(pw); 1552 Object element = internalToElement(elementOrPath); 1553 w = internalFindChild(pw, element); 1554 if (expand && pw instanceof Item) { 1555 Item item = (Item) pw; 1557 LinkedList toExpandList = new LinkedList (); 1558 while (item != null && !getExpanded(item)) { 1559 toExpandList.addFirst(item); 1560 item = getParentItem(item); 1561 } 1562 for (Iterator it = toExpandList.iterator(); it 1563 .hasNext();) { 1564 Item toExpand = (Item) it.next(); 1565 setExpanded(toExpand, true); 1566 } 1567 } 1568 } 1569 } 1570 } 1571 return w; 1572 } 1573 1574 1582 private Object internalToElement(Object elementOrPath) { 1583 if (elementOrPath instanceof TreePath) { 1584 return ((TreePath) elementOrPath).getLastSegment(); 1585 } 1586 return elementOrPath; 1587 } 1588 1589 1601 protected Object getParentElement(Object elementOrTreePath) { 1602 if (elementOrTreePath instanceof TreePath) { 1603 TreePath treePath = (TreePath) elementOrTreePath; 1604 return (treePath).getParentPath(); 1605 } 1606 IContentProvider cp = getContentProvider(); 1607 if (cp instanceof ITreePathContentProvider) { 1608 ITreePathContentProvider tpcp = (ITreePathContentProvider) cp; 1609 TreePath[] paths = tpcp.getParents(elementOrTreePath); 1610 if (paths.length > 0) { 1611 if (paths[0].getSegmentCount() == 0) { 1612 return getInput(); 1613 } 1614 return paths[0].getLastSegment(); 1615 } 1616 } 1617 if (cp instanceof ITreeContentProvider) { 1618 ITreeContentProvider tcp = (ITreeContentProvider) cp; 1619 return tcp.getParent(elementOrTreePath); 1620 } 1621 return null; 1622 } 1623 1624 1633 protected Widget internalGetWidgetToSelect(Object elementOrTreePath) { 1634 if (elementOrTreePath instanceof TreePath) { 1635 TreePath treePath = (TreePath) elementOrTreePath; 1636 if (treePath.getSegmentCount() == 0) { 1637 return getControl(); 1638 } 1639 Widget[] candidates = findItems(treePath.getLastSegment()); 1640 for (int i = 0; i < candidates.length; i++) { 1641 Widget candidate = candidates[i]; 1642 if (!(candidate instanceof Item)) { 1643 continue; 1644 } 1645 if (treePath.equals(getTreePathFromItem((Item) candidate), 1646 getComparer())) { 1647 return candidate; 1648 } 1649 } 1650 return null; 1651 } 1652 return findItem(elementOrTreePath); 1653 } 1654 1655 1669 protected void internalExpandToLevel(Widget widget, int level) { 1670 if (level == ALL_LEVELS || level > 0) { 1671 if (widget instanceof Item && widget.getData() != null 1672 && !isExpandable((Item) widget, null, widget.getData())) { 1673 return; 1674 } 1675 createChildren(widget); 1676 if (widget instanceof Item) { 1677 setExpanded((Item) widget, true); 1678 } 1679 if (level == ALL_LEVELS || level > 1) { 1680 Item[] children = getChildren(widget); 1681 if (children != null) { 1682 int newLevel = (level == ALL_LEVELS ? ALL_LEVELS 1683 : level - 1); 1684 for (int i = 0; i < children.length; i++) { 1685 internalExpandToLevel(children[i], newLevel); 1686 } 1687 } 1688 } 1689 } 1690 } 1691 1692 1702 private Widget internalFindChild(Widget parent, Object element) { 1703 Item[] items = getChildren(parent); 1704 for (int i = 0; i < items.length; i++) { 1705 Item item = items[i]; 1706 Object data = item.getData(); 1707 if (data != null && equals(data, element)) { 1708 return item; 1709 } 1710 } 1711 return null; 1712 } 1713 1714 1723 private Widget internalFindItem(Item parent, Object element) { 1724 1725 Object data = parent.getData(); 1727 if (data != null) { 1728 if (equals(data, element)) { 1729 return parent; 1730 } 1731 } 1732 Item[] items = getChildren(parent); 1734 for (int i = 0; i < items.length; i++) { 1735 Item item = items[i]; 1736 Widget o = internalFindItem(item, element); 1737 if (o != null) { 1738 return o; 1739 } 1740 } 1741 return null; 1742 } 1743 1744 1745 protected void internalRefresh(Object element) { 1746 internalRefresh(element, true); 1747 } 1748 1749 1750 protected void internalRefresh(Object element, boolean updateLabels) { 1751 if (element == null) { 1753 internalRefresh(getControl(), getRoot(), true, updateLabels); 1754 return; 1755 } 1756 Widget[] items = findItems(element); 1757 if (items.length != 0) { 1758 for (int i = 0; i < items.length; i++) { 1759 internalRefresh(items[i], element, true, updateLabels); 1761 } 1762 } 1763 } 1764 1765 1789 protected void internalRefresh(Widget widget, Object element, 1790 boolean doStruct, boolean updateLabels) { 1791 1792 if (widget instanceof Item) { 1793 if (doStruct) { 1794 updatePlus((Item) widget, element); 1795 } 1796 if (updateLabels || !equals(element, widget.getData())) { 1797 doUpdateItem(widget, element, true); 1798 } else { 1799 associate(element, (Item) widget); 1800 } 1801 } 1802 1803 if (doStruct) { 1804 internalRefreshStruct(widget, element, updateLabels); 1805 } else { 1806 Item[] children = getChildren(widget); 1807 if (children != null) { 1808 for (int i = 0; i < children.length; i++) { 1809 Widget item = children[i]; 1810 Object data = item.getData(); 1811 if (data != null) { 1812 internalRefresh(item, data, doStruct, updateLabels); 1813 } 1814 } 1815 } 1816 } 1817 } 1818 1819 1827 void internalRefreshStruct(Widget widget, Object element, 1828 boolean updateLabels) { 1829 updateChildren(widget, element, null, updateLabels); 1830 Item[] children = getChildren(widget); 1831 if (children != null) { 1832 for (int i = 0; i < children.length; i++) { 1833 Widget item = children[i]; 1834 Object data = item.getData(); 1835 if (data != null) { 1836 internalRefreshStruct(item, data, updateLabels); 1837 } 1838 } 1839 } 1840 } 1841 1842 1856 protected void internalRemove(Object [] elementsOrPaths) { 1857 Object input = getInput(); 1858 for (int i = 0; i < elementsOrPaths.length; ++i) { 1859 Object element = elementsOrPaths[i]; 1860 if (equals(element, input)) { 1861 setInput(null); 1862 return; 1863 } 1864 Widget[] childItems = internalFindItems(element); 1865 for (int j = 0; j < childItems.length; j++) { 1866 Widget childItem = childItems[j]; 1867 if (childItem instanceof Item) { 1868 disassociate((Item) childItem); 1869 childItem.dispose(); 1870 } 1871 } 1872 } 1873 } 1874 1875 1884 protected void internalRemove(Object parent, Object [] elements) { 1885 1886 CustomHashtable toRemove = new CustomHashtable(getComparer()); 1887 for (int i = 0; i < elements.length; i++) { 1888 toRemove.put(elements[i], elements[i]); 1889 } 1890 1891 Widget[] parentItemArray = findItems(parent); 1893 for (int i = 0; i < parentItemArray.length; i++) { 1894 Widget parentItem = parentItemArray[i]; 1895 1896 Item[] children = getChildren(parentItem); 1898 1899 for (int j = 0; j < children.length; j++) { 1900 Item child = children[j]; 1901 1902 Object data = child.getData(); 1903 if (data != null && toRemove.containsKey(data)) { 1904 disassociate(child); 1905 child.dispose(); 1906 } 1907 } 1908 } 1909 } 1910 1911 1921 private void internalSetExpanded(CustomHashtable expandedElements, 1922 Widget widget) { 1923 Item[] items = getChildren(widget); 1924 for (int i = 0; i < items.length; i++) { 1925 Item item = items[i]; 1926 Object data = item.getData(); 1927 if (data != null) { 1928 boolean expanded = expandedElements.remove(data) != null; 1931 if (expanded != getExpanded(item)) { 1932 if (expanded) { 1933 createChildren(item); 1934 } 1935 setExpanded(item, expanded); 1936 } 1937 } 1938 if (expandedElements.size() > 0) { 1939 internalSetExpanded(expandedElements, item); 1940 } 1941 } 1942 } 1943 1944 1954 private void internalSetExpandedTreePaths( 1955 CustomHashtable expandedTreePaths, Widget widget, 1956 TreePath currentPath) { 1957 Item[] items = getChildren(widget); 1958 for (int i = 0; i < items.length; i++) { 1959 Item item = items[i]; 1960 Object data = item.getData(); 1961 TreePath childPath = data == null ? null : currentPath 1962 .createChildPath(data); 1963 if (data != null && childPath != null) { 1964 boolean expanded = expandedTreePaths.remove(childPath) != null; 1967 if (expanded != getExpanded(item)) { 1968 if (expanded) { 1969 createChildren(item); 1970 } 1971 setExpanded(item, expanded); 1972 } 1973 } 1974 internalSetExpandedTreePaths(expandedTreePaths, item, childPath); 1975 } 1976 } 1977 1978 1993 public boolean isExpandable(Object elementOrTreePath) { 1994 Object element; 1995 TreePath path; 1996 if (elementOrTreePath instanceof TreePath) { 1997 path = (TreePath) elementOrTreePath; 1998 element = path.getLastSegment(); 1999 } else { 2000 element = elementOrTreePath; 2001 path = null; 2002 } 2003 IContentProvider cp = getContentProvider(); 2004 if (cp instanceof ITreePathContentProvider) { 2005 ITreePathContentProvider tpcp = (ITreePathContentProvider) cp; 2006 if (path == null) { 2007 Widget w = findItem(element); 2009 if (w instanceof Item) { 2010 Item item = (Item) w; 2011 path = getTreePathFromItem(item); 2012 } 2013 if (path == null) { 2014 path = new TreePath(new Object [] { element }); 2015 } 2016 } 2017 return tpcp.hasChildren(path); 2018 } 2019 if (cp instanceof ITreeContentProvider) { 2020 ITreeContentProvider tcp = (ITreeContentProvider) cp; 2021 return tcp.hasChildren(element); 2022 } 2023 return false; 2024 } 2025 2026 2038 private boolean isExpandable(Item item, TreePath parentPath, Object element) { 2039 Object elementOrTreePath = element; 2040 if (isTreePathContentProvider()) { 2041 if (parentPath != null) { 2042 elementOrTreePath = parentPath.createChildPath(element); 2043 } else { 2044 elementOrTreePath = getTreePathFromItem(item); 2045 } 2046 } 2047 return isExpandable(elementOrTreePath); 2048 } 2049 2050 2051 protected void labelProviderChanged() { 2052 Control tree = getControl(); 2054 tree.setRedraw(false); 2055 internalRefresh(tree, getRoot(), false, true); 2057 tree.setRedraw(true); 2058 } 2059 2060 2072 protected abstract Item newItem(Widget parent, int style, int index); 2073 2074 2086 public void remove(final Object [] elementsOrTreePaths) { 2087 assertElementsNotNull(elementsOrTreePaths); 2088 if (elementsOrTreePaths.length == 0) { 2089 return; 2090 } 2091 if (isBusy()) 2092 return; 2093 preservingSelection(new Runnable () { 2094 public void run() { 2095 internalRemove(elementsOrTreePaths); 2096 } 2097 }); 2098 } 2099 2100 2118 public void remove(final Object parent, final Object [] elements) { 2119 assertElementsNotNull(elements); 2120 if (elements.length == 0) { 2121 return; 2122 } 2123 if (isBusy()) 2124 return; 2125 preservingSelection(new Runnable () { 2126 public void run() { 2127 internalRemove(parent, elements); 2128 } 2129 }); 2130 } 2131 2132 2146 public void remove(Object elementsOrTreePaths) { 2147 remove(new Object [] { elementsOrTreePaths }); 2148 } 2149 2150 2156 protected abstract void removeAll(Control control); 2157 2158 2165 public void removeTreeListener(ITreeViewerListener listener) { 2166 treeListeners.remove(listener); 2167 } 2168 2169 2172 public void reveal(Object elementOrTreePath) { 2173 Assert.isNotNull(elementOrTreePath); 2174 Widget w = internalExpand(elementOrTreePath, true); 2175 if (w instanceof Item) { 2176 showItem((Item) w); 2177 } 2178 } 2179 2180 2189 private Item rightMostVisibleDescendent(Item item) { 2190 Item[] children = getItems(item); 2191 if (getExpanded(item) && children != null && children.length > 0) { 2192 return rightMostVisibleDescendent(children[children.length - 1]); 2193 } 2194 return item; 2195 } 2196 2197 2198 public Item scrollDown(int x, int y) { 2199 Item current = getItem(x, y); 2200 if (current != null) { 2201 Item next = getNextItem(current, true); 2202 showItem(next == null ? current : next); 2203 return next; 2204 } 2205 return null; 2206 } 2207 2208 2209 public Item scrollUp(int x, int y) { 2210 Item current = getItem(x, y); 2211 if (current != null) { 2212 Item previous = getPreviousItem(current); 2213 showItem(previous == null ? current : previous); 2214 return previous; 2215 } 2216 return null; 2217 } 2218 2219 2233 public void setAutoExpandLevel(int level) { 2234 expandToLevel = level; 2235 } 2236 2237 2242 public void setContentProvider(IContentProvider provider) { 2243 super.setContentProvider(provider); 2245 } 2246 2247 protected void assertContentProviderType(IContentProvider provider) { 2248 Assert.isTrue(provider instanceof ITreeContentProvider 2249 || provider instanceof ITreePathContentProvider); 2250 } 2251 2252 2260 protected abstract void setExpanded(Item item, boolean expand); 2261 2262 2275 public void setExpandedElements(Object [] elements) { 2276 assertElementsNotNull(elements); 2277 if (isBusy()) { 2278 return; 2279 } 2280 CustomHashtable expandedElements = newHashtable(elements.length * 2 + 1); 2281 for (int i = 0; i < elements.length; ++i) { 2282 Object element = elements[i]; 2283 internalExpand(element, false); 2288 expandedElements.put(element, element); 2289 } 2290 internalSetExpanded(expandedElements, getControl()); 2295 } 2296 2297 2312 public void setExpandedTreePaths(TreePath[] treePaths) { 2313 assertElementsNotNull(treePaths); 2314 if (isBusy()) 2315 return; 2316 final IElementComparer comparer = getComparer(); 2317 IElementComparer treePathComparer = new IElementComparer() { 2318 2319 public boolean equals(Object a, Object b) { 2320 return ((TreePath) a).equals(((TreePath) b), comparer); 2321 } 2322 2323 public int hashCode(Object element) { 2324 return ((TreePath) element).hashCode(comparer); 2325 } 2326 }; 2327 CustomHashtable expandedTreePaths = new CustomHashtable( 2328 treePaths.length * 2 + 1, treePathComparer); 2329 for (int i = 0; i < treePaths.length; ++i) { 2330 TreePath treePath = treePaths[i]; 2331 internalExpand(treePath, false); 2336 expandedTreePaths.put(treePath, treePath); 2337 } 2338 internalSetExpandedTreePaths(expandedTreePaths, getControl(), 2343 new TreePath(new Object [0])); 2344 } 2345 2346 2356 public void setExpandedState(Object elementOrTreePath, boolean expanded) { 2357 Assert.isNotNull(elementOrTreePath); 2358 if (isBusy()) 2359 return; 2360 Widget item = internalExpand(elementOrTreePath, false); 2361 if (item instanceof Item) { 2362 if (expanded) { 2363 createChildren(item); 2364 } 2365 setExpanded((Item) item, expanded); 2366 } 2367 } 2368 2369 2376 protected abstract void setSelection(List items); 2377 2378 2382 protected void setSelectionToWidget(List v, boolean reveal) { 2383 if (v == null) { 2384 setSelection(new ArrayList (0)); 2385 return; 2386 } 2387 int size = v.size(); 2388 List newSelection = new ArrayList (size); 2389 for (int i = 0; i < size; ++i) { 2390 Object elementOrTreePath = v.get(i); 2391 Widget w = internalExpand(elementOrTreePath, false); 2394 if (w instanceof Item) { 2395 newSelection.add(w); 2396 } else if (w == null && elementOrTreePath instanceof TreePath) { 2397 TreePath treePath = (TreePath) elementOrTreePath; 2398 Object element = treePath.getLastSegment(); 2399 if (element != null) { 2400 w = internalExpand(element, false); 2401 if (w instanceof Item) { 2402 newSelection.add(w); 2403 } 2404 } 2405 } 2406 } 2407 setSelection(newSelection); 2408 2409 if (reveal && newSelection.size() > 0) { 2414 showItem((Item) newSelection.get(0)); 2415 } 2416 } 2417 2418 2424 protected abstract void showItem(Item item); 2425 2426 2439 protected void updateChildren(Widget widget, Object parent, 2440 Object [] elementChildren) { 2441 updateChildren(widget, parent, elementChildren, true); 2442 } 2443 2444 2461 private void updateChildren(Widget widget, Object parent, 2462 Object [] elementChildren, boolean updateLabels) { 2463 if (widget instanceof Item) { 2465 Item ti = (Item) widget; 2466 if (!getExpanded(ti)) { 2467 boolean needDummy = isExpandable(ti, null, parent); 2470 boolean haveDummy = false; 2471 Item[] items = getItems(ti); 2473 for (int i = 0; i < items.length; i++) { 2474 if (items[i].getData() != null) { 2475 disassociate(items[i]); 2476 items[i].dispose(); 2477 } else { 2478 if (needDummy && !haveDummy) { 2479 haveDummy = true; 2480 } else { 2481 items[i].dispose(); 2482 } 2483 } 2484 } 2485 if (needDummy && !haveDummy) { 2486 newItem(ti, SWT.NULL, -1); 2487 } 2488 2489 return; 2490 } 2491 } 2492 2493 if (elementChildren == null) { 2496 if (isTreePathContentProvider() && widget instanceof Item) { 2497 TreePath path = getTreePathFromItem((Item) widget); 2498 elementChildren = getSortedChildren(path); 2499 } else { 2500 elementChildren = getSortedChildren(parent); 2501 } 2502 } 2503 2504 Control tree = getControl(); 2505 2506 int oldCnt = -1; 2508 if (widget == tree) { 2509 oldCnt = getItemCount(tree); 2510 } 2511 2512 Item[] items = getChildren(widget); 2513 2514 CustomHashtable expanded = newHashtable(CustomHashtable.DEFAULT_CAPACITY); for (int i = 0; i < items.length; ++i) { 2521 if (getExpanded(items[i])) { 2522 Object element = items[i].getData(); 2523 if (element != null) { 2524 expanded.put(element, element); 2525 } 2526 } 2527 } 2528 2529 int min = Math.min(elementChildren.length, items.length); 2530 2531 int numItemsToDispose = items.length - min; 2534 if (numItemsToDispose > 0) { 2535 CustomHashtable children = newHashtable(elementChildren.length * 2); 2536 for (int i = 0; i < elementChildren.length; i++) { 2537 Object elementChild = elementChildren[i]; 2538 children.put(elementChild, elementChild); 2539 } 2540 int i = 0; 2541 while (numItemsToDispose > 0 && i < items.length) { 2542 Object data = items[i].getData(); 2543 if (data == null || items.length - i <= numItemsToDispose || !children.containsKey(data)) { 2544 if (data != null) { 2545 disassociate(items[i]); 2546 } 2547 items[i].dispose(); 2548 if (i + 1 < items.length) { 2549 System.arraycopy(items, i + 1, items, i, items.length - (i+1)); 2553 } 2554 numItemsToDispose--; 2555 } else { 2556 i++; 2557 } 2558 } 2559 } 2560 2561 for (int i = 0; i < min; ++i) { 2569 Item item = items[i]; 2570 Object oldElement = item.getData(); 2571 if (oldElement != null) { 2572 Object newElement = elementChildren[i]; 2573 if (newElement != oldElement) { 2574 if (equals(newElement, oldElement)) { 2575 Object data = item.getData(); 2580 if (data != null) { 2581 unmapElement(data, item); 2582 } 2583 item.setData(newElement); 2584 mapElement(newElement, item); 2585 } else { 2586 disassociate(item); 2587 item.setImage(null); 2589 item.setText(""); 2591 } 2592 } 2593 } 2594 } 2595 2596 for (int i = 0; i < min; ++i) { 2597 Item item = items[i]; 2598 Object newElement = elementChildren[i]; 2599 if (item.getData() == null) { 2600 associate(newElement, item); 2602 updatePlus(item, newElement); 2603 updateItem(item, newElement); 2604 } else { 2605 updatePlus(item, newElement); 2607 if (updateLabels) { 2608 updateItem(item, newElement); 2609 } 2610 } 2611 } 2612 2613 for (int i = 0; i < min; ++i) { 2620 Item item = items[i]; 2621 Object newElement = elementChildren[i]; 2622 setExpanded(item, expanded.containsKey(newElement)); 2623 } 2624 2625 if (min < elementChildren.length) { 2627 for (int i = min; i < elementChildren.length; ++i) { 2628 createTreeItem(widget, elementChildren[i], i); 2629 } 2630 2631 if (expanded.size() > 0) { 2635 items = getChildren(widget); 2637 for (int i = min; i < elementChildren.length; ++i) { 2638 if (expanded.containsKey(elementChildren[i])) { 2645 setExpanded(items[i], true); 2646 } 2647 } 2648 } 2649 } 2650 2651 if (widget == tree && oldCnt == 0 && getItemCount(tree) != 0) { 2653 tree.setRedraw(false); 2655 tree.setRedraw(true); 2656 } 2657 } 2658 2659 2669 protected void updatePlus(Item item, Object element) { 2670 boolean hasPlus = getItemCount(item) > 0; 2671 boolean needsPlus = isExpandable(item, null, element); 2672 boolean removeAll = false; 2673 boolean addDummy = false; 2674 Object data = item.getData(); 2675 if (data != null && equals(element, data)) { 2676 if (hasPlus != needsPlus) { 2678 if (needsPlus) { 2679 addDummy = true; 2680 } else { 2681 removeAll = true; 2682 } 2683 } 2684 } else { 2685 removeAll = true; 2687 addDummy = needsPlus; 2688 2689 setExpanded(item, false); 2691 } 2692 if (removeAll) { 2693 Item[] items = getItems(item); 2695 for (int i = 0; i < items.length; i++) { 2696 if (items[i].getData() != null) { 2697 disassociate(items[i]); 2698 } 2699 items[i].dispose(); 2700 } 2701 } 2702 if (addDummy) { 2703 newItem(item, SWT.NULL, -1); } 2705 } 2706 2707 2714 public Object [] getVisibleExpandedElements() { 2715 ArrayList v = new ArrayList (); 2716 internalCollectVisibleExpanded(v, getControl()); 2717 return v.toArray(); 2718 } 2719 2720 private void internalCollectVisibleExpanded(ArrayList result, Widget widget) { 2721 Item[] items = getChildren(widget); 2722 for (int i = 0; i < items.length; i++) { 2723 Item item = items[i]; 2724 if (getExpanded(item)) { 2725 Object data = item.getData(); 2726 if (data != null) { 2727 result.add(data); 2728 } 2729 internalCollectVisibleExpanded(result, item); 2732 } 2733 } 2734 } 2735 2736 2743 protected TreePath getTreePathFromItem(Item item) { 2744 LinkedList segments = new LinkedList (); 2745 while (item != null) { 2746 Object segment = item.getData(); 2747 Assert.isNotNull(segment); 2748 segments.addFirst(segment); 2749 item = getParentItem(item); 2750 } 2751 return new TreePath(segments.toArray()); 2752 } 2753 2754 2760 public ISelection getSelection() { 2761 Control control = getControl(); 2762 if (control == null || control.isDisposed()) { 2763 return TreeSelection.EMPTY; 2764 } 2765 Widget[] items = getSelection(getControl()); 2766 ArrayList list = new ArrayList (items.length); 2767 for (int i = 0; i < items.length; i++) { 2768 Widget item = items[i]; 2769 if (item.getData() != null) { 2770 list.add(getTreePathFromItem((Item) item)); 2771 } 2772 } 2773 return new TreeSelection((TreePath[]) list.toArray(new TreePath[list 2774 .size()]), getComparer()); 2775 } 2776 2777 protected void setSelectionToWidget(ISelection selection, boolean reveal) { 2778 if (selection instanceof ITreeSelection) { 2779 ITreeSelection treeSelection = (ITreeSelection) selection; 2780 setSelectionToWidget(Arrays.asList(treeSelection.getPaths()), 2781 reveal); 2782 } else { 2783 super.setSelectionToWidget(selection, reveal); 2784 } 2785 } 2786 2787 2801 public TreePath[] getExpandedTreePaths() { 2802 ArrayList items = new ArrayList (); 2803 internalCollectExpandedItems(items, getControl()); 2804 ArrayList result = new ArrayList (items.size()); 2805 for (Iterator it = items.iterator(); it.hasNext();) { 2806 Item item = (Item) it.next(); 2807 TreePath treePath = getTreePathFromItem(item); 2808 if (treePath != null) { 2809 result.add(treePath); 2810 } 2811 } 2812 return (TreePath[]) result.toArray(new TreePath[items.size()]); 2813 } 2814 2815 private boolean isTreePathContentProvider() { 2816 return getContentProvider() instanceof ITreePathContentProvider; 2817 } 2818 2819 2840 public void insert(Object parentElementOrTreePath, Object element, 2841 int position) { 2842 Assert.isNotNull(parentElementOrTreePath); 2843 Assert.isNotNull(element); 2844 if (isBusy()) 2845 return; 2846 if (getComparator() != null || hasFilters()) { 2847 add(parentElementOrTreePath, new Object [] { element }); 2848 return; 2849 } 2850 Widget[] items; 2851 if (internalIsInputOrEmptyPath(parentElementOrTreePath)) { 2852 items = new Widget[] { getControl() }; 2853 } else { 2854 items = internalFindItems(parentElementOrTreePath); 2855 } 2856 2857 for (int i = 0; i < items.length; i++) { 2858 Widget widget = items[i]; 2859 if (widget instanceof Item) { 2860 Item item = (Item) widget; 2861 2862 Item[] childItems = getChildren(item); 2863 if (getExpanded(item) 2864 || (childItems.length > 0 && childItems[0].getData() != null)) { 2865 int insertionPosition = position; 2867 if (insertionPosition == -1) { 2868 insertionPosition = getItemCount(item); 2869 } 2870 2871 createTreeItem(item, element, insertionPosition); 2872 } 2873 } else { 2874 int insertionPosition = position; 2875 if (insertionPosition == -1) { 2876 insertionPosition = getItemCount((Control) widget); 2877 } 2878 2879 createTreeItem(widget, element, insertionPosition); 2880 } 2881 } 2882 } 2883 2884 2889 protected Widget getColumnViewerOwner(int columnIndex) { 2890 return null; 2892 } 2893 2894 2900 protected Item getItemAt(Point point) { 2901 return null; 2902 } 2903 2904 2910 protected ColumnViewerEditor createViewerEditor() { 2911 return null; 2912 } 2913 2914 2923 protected int doGetColumnCount() { 2924 return 0; 2925 } 2926 2927 2928 2939 protected void buildLabel(ViewerLabel updateLabel, Object elementOrPath) { 2940 Object element; 2941 if (elementOrPath instanceof TreePath) { 2942 TreePath path = (TreePath) elementOrPath; 2943 IBaseLabelProvider provider = getLabelProvider(); 2944 if (provider instanceof ITreePathLabelProvider) { 2945 ITreePathLabelProvider pprov = (ITreePathLabelProvider) provider; 2946 buildLabel(updateLabel, path, pprov); 2947 return; 2948 } 2949 element = path.getLastSegment(); 2950 } else { 2951 element = elementOrPath; 2952 } 2953 super.buildLabel(updateLabel, element); 2954 } 2955 2956 2965 final protected boolean internalIsInputOrEmptyPath(final Object elementOrTreePath) { 2966 if (elementOrTreePath.equals(getInput())) 2967 return true; 2968 if (!(elementOrTreePath instanceof TreePath)) 2969 return false; 2970 return ((TreePath) elementOrTreePath).getSegmentCount() == 0; 2971 } 2972 2973 2976 protected ViewerRow getViewerRowFromItem(Widget item) { 2977 return null; 2978 } 2979} 2980 | Popular Tags |