1 11 package org.eclipse.debug.internal.ui.viewers; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Map ; 18 import java.util.Map.Entry; 19 20 import org.eclipse.core.runtime.IAdaptable; 21 import org.eclipse.core.runtime.IProgressMonitor; 22 import org.eclipse.core.runtime.IStatus; 23 import org.eclipse.core.runtime.Status; 24 import org.eclipse.debug.internal.ui.DebugUIPlugin; 25 import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; 26 import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor; 27 import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; 28 import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; 29 import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; 30 import org.eclipse.jface.resource.ImageDescriptor; 31 import org.eclipse.jface.util.Assert; 32 import org.eclipse.jface.viewers.CellEditor; 33 import org.eclipse.jface.viewers.DoubleClickEvent; 34 import org.eclipse.jface.viewers.ICellModifier; 35 import org.eclipse.jface.viewers.ISelection; 36 import org.eclipse.jface.viewers.IStructuredSelection; 37 import org.eclipse.jface.viewers.OpenEvent; 38 import org.eclipse.jface.viewers.StructuredSelection; 39 import org.eclipse.jface.viewers.TreePath; 40 import org.eclipse.jface.viewers.TreeSelection; 41 import org.eclipse.jface.viewers.Viewer; 42 import org.eclipse.swt.SWT; 43 import org.eclipse.swt.custom.TreeEditor; 44 import org.eclipse.swt.events.ControlEvent; 45 import org.eclipse.swt.events.ControlListener; 46 import org.eclipse.swt.events.MouseAdapter; 47 import org.eclipse.swt.events.MouseEvent; 48 import org.eclipse.swt.events.MouseListener; 49 import org.eclipse.swt.events.PaintEvent; 50 import org.eclipse.swt.events.PaintListener; 51 import org.eclipse.swt.events.TreeEvent; 52 import org.eclipse.swt.events.TreeListener; 53 import org.eclipse.swt.graphics.Color; 54 import org.eclipse.swt.graphics.Font; 55 import org.eclipse.swt.graphics.FontData; 56 import org.eclipse.swt.graphics.Image; 57 import org.eclipse.swt.graphics.Point; 58 import org.eclipse.swt.graphics.RGB; 59 import org.eclipse.swt.graphics.Rectangle; 60 import org.eclipse.swt.widgets.Composite; 61 import org.eclipse.swt.widgets.Control; 62 import org.eclipse.swt.widgets.Item; 63 import org.eclipse.swt.widgets.Tree; 64 import org.eclipse.swt.widgets.TreeColumn; 65 import org.eclipse.swt.widgets.TreeItem; 66 import org.eclipse.swt.widgets.Widget; 67 import org.eclipse.ui.IMemento; 68 import org.eclipse.ui.progress.WorkbenchJob; 69 70 81 public class AsynchronousTreeViewer extends AsynchronousViewer { 82 83 86 private Tree fTree; 87 88 91 private TreeEditorImpl fTreeEditorImpl; 92 private TreeEditor fTreeEditor; 93 94 99 private List fPendingExpansion = new ArrayList (); 100 101 104 private IColumnPresentation fColumnPresentation = null; 105 106 109 private IColumnEditor fColumnEditor = null; 110 111 115 private Map fVisibleColumns = new HashMap (); 116 117 120 private Map fColumnSizes = new HashMap (); 121 122 127 private Map fShowColumns = new HashMap (); 128 129 132 private static final String COLUMN_SIZES = "COLUMN_SIZES"; 137 private static final String VISIBLE_COLUMNS = "VISIBLE_COLUMNS"; 142 private static final String SHOW_COLUMNS = "SHOW_COLUMNS"; 147 private static final String SIZE = "SIZE"; 151 private static final String COLUMN = "COLUMN"; 153 158 class ColumnListener implements ControlListener { 159 162 public void controlMoved(ControlEvent e) { 163 } 164 165 168 public void controlResized(ControlEvent e) { 169 persistColumnSizes(); 170 } 171 } 172 173 private ColumnListener fListener = new ColumnListener(); 174 175 185 public AsynchronousTreeViewer(Composite parent) { 186 this(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL); 187 } 188 189 199 public AsynchronousTreeViewer(Composite parent, int style) { 200 this(new Tree(parent, style)); 201 } 202 203 211 public AsynchronousTreeViewer(Tree tree) { 212 super(); 213 Assert.isTrue((tree.getStyle() & SWT.VIRTUAL) != 0); 214 fTree = tree; 215 hookControl(fTree); 216 fTreeEditor = new TreeEditor(tree); 217 initTreeViewerImpl(); 218 } 219 220 223 protected void hookControl(Control control) { 224 super.hookControl(control); 225 Tree tree = (Tree)control; 226 tree.addMouseListener(new MouseAdapter() { 227 public void mouseDown(MouseEvent e) { 228 if (isShowColumns()) { 229 Item[] items = fTreeEditorImpl.getSelection(); 230 if (items.length > 0) { 231 TreeItem treeItem = (TreeItem) items[0]; 232 if (treeItem != null) { 233 Object element = treeItem.getData(); 234 updateColumnEditor(element); 235 if (fColumnEditor != null) { 236 int columnToEdit = -1; 237 int columns = fTree.getColumnCount(); 238 if (columns == 0) { 239 columnToEdit = 0; 242 } else { 243 columnToEdit = -1; 244 for (int i = 0; i < columns; i++) { 245 Rectangle bounds = fTreeEditorImpl.getBounds(treeItem, i); 246 if (bounds.contains(e.x, e.y)) { 247 columnToEdit = i; 248 break; 249 } 250 } 251 if (columnToEdit == -1) { 252 return; 253 } 254 } 255 CellEditor cellEditor = fColumnEditor.getCellEditor(getVisibleColumns()[columnToEdit], element, fTree); 256 if (cellEditor == null) { 257 return; 258 } 259 disposeCellEditors(); 260 CellEditor[] newEditors = new CellEditor[columns]; 261 newEditors[columnToEdit] = cellEditor; 262 setCellEditors(newEditors); 263 setCellModifier(fColumnEditor.getCellModifier()); 264 setColumnProperties(getVisibleColumns()); 265 } 266 } 267 } 268 } 269 270 fTreeEditorImpl.handleMouseDown(e); 271 } 272 }); 273 tree.addTreeListener(new TreeListener() { 274 public void treeExpanded(TreeEvent e) { 275 ((TreeItem) e.item).setExpanded(true); 276 ModelNode node = findNode(e.item); 277 if (node != null) { 278 internalRefresh(node); 279 } 280 } 281 282 public void treeCollapsed(TreeEvent e) { 283 } 284 }); 285 286 tree.addMouseListener(new MouseListener() { 287 public void mouseUp(MouseEvent e) { 288 } 289 290 public void mouseDown(MouseEvent e) { 291 } 292 293 public void mouseDoubleClick(MouseEvent e) { 294 TreeItem item = ((Tree) e.widget).getItem(new Point(e.x, e.y)); 295 if (item != null) { 296 if (item.getExpanded()) { 297 item.setExpanded(false); 298 } else { 299 item.setExpanded(true); 300 ModelNode node = findNode(item); 301 if (node != null) { 302 internalRefresh(node); 303 } 304 } 305 } 306 } 307 }); 308 } 309 310 315 protected void updateColumnEditor(Object element) { 316 IColumnEditorFactoryAdapter factoryAdapter = getColumnEditorFactoryAdapter(element); 317 if (factoryAdapter != null) { 318 if (fColumnEditor != null) { 319 if (fColumnEditor.getId().equals(factoryAdapter.getColumnEditorId(getPresentationContext(), element))) { 320 return; 322 } else { 323 fColumnEditor.dispose(); 325 } 326 } 327 fColumnEditor = factoryAdapter.createColumnEditor(getPresentationContext(), element); 329 if (fColumnEditor != null) { 330 fColumnEditor.init(getPresentationContext()); 331 } 332 } else { 333 if (fColumnEditor != null) { 335 fColumnEditor.dispose(); 336 fColumnEditor = null; 337 } 338 } 339 } 340 341 346 public Tree getTree() { 347 return fTree; 348 } 349 350 355 protected void updateHasChildren(ModelNode node) { 356 ((AsynchronousTreeModel)getModel()).updateHasChildren(node); 357 } 358 359 364 public synchronized void expand(ISelection selection) { 365 if (selection instanceof TreeSelection) { 366 TreePath[] paths = ((TreeSelection) selection).getPaths(); 367 for (int i = 0; i < paths.length; i++) { 368 fPendingExpansion.add(paths[i]); 369 } 370 if (getControl().getDisplay().getThread() == Thread.currentThread()) { 371 attemptExpansion(); 372 } else { 373 WorkbenchJob job = new WorkbenchJob("attemptExpansion") { public IStatus runInUIThread(IProgressMonitor monitor) { 375 attemptExpansion(); 376 return Status.OK_STATUS; 377 } 378 379 }; 380 job.setSystem(true); 381 job.schedule(); 382 } 383 } 384 } 385 386 389 synchronized void attemptExpansion() { 390 if (fPendingExpansion != null) { 391 for (Iterator i = fPendingExpansion.iterator(); i.hasNext();) { 392 TreePath path = (TreePath) i.next(); 393 if (attemptExpansion(path)) { 394 i.remove(); 395 } 396 } 397 } 398 } 399 400 407 synchronized boolean attemptExpansion(TreePath path) { 408 int segmentCount = path.getSegmentCount(); 409 for (int j = segmentCount - 1; j >= 0; j--) { 410 Object element = path.getSegment(j); 411 ModelNode[] nodes = getModel().getNodes(element); 412 if (nodes != null) { 413 for (int k = 0; k < nodes.length; k++) { 414 ModelNode node = nodes[k]; 415 TreePath treePath = node.getTreePath(); 416 if (path.startsWith(treePath, null)) { 417 if (!node.isDisposed()) { 418 Widget widget = findItem(node); 419 if (widget == null) { 420 ModelNode parent = node.getParentNode(); 422 ModelNode child = node; 423 widget = findItem(parent); 424 while (widget == null && parent != null) { 425 child = parent; 426 parent = parent.getParentNode(); 427 if (parent != null) { 428 widget = findItem(parent); 429 treePath = parent.getTreePath(); 430 } 431 } 432 int childIndex = parent.getChildIndex(child); 433 if (childIndex < 0) { 434 return false; 435 } 436 TreeItem[] items = getItems(widget); 437 if (childIndex < items.length) { 438 widget = items[childIndex]; 439 mapElement(child, widget); 440 widget.setData(child.getElement()); 441 treePath = child.getTreePath(); 442 node = child; 443 } else { 444 return false; 445 } 446 } 447 if (widget instanceof TreeItem && !widget.isDisposed()) { 448 TreeItem treeItem = (TreeItem) widget; 449 if (treeItem.getExpanded()) { 450 return path.getSegmentCount() == treePath.getSegmentCount(); 451 } 452 if (treeItem.getItemCount() > 0) { 453 updateChildren(node); 454 expand(treeItem); 455 if (path.getSegmentCount() == treePath.getSegmentCount()) { 456 return true; 457 } 458 return false; 459 } 460 } 461 } 462 } 463 } 464 } 465 } 466 return false; 467 } 468 469 474 public Control getControl() { 475 return fTree; 476 } 477 478 479 482 public synchronized void dispose() { 483 if (fColumnPresentation != null) { 484 fColumnPresentation.dispose(); 485 } 486 disposeCellEditors(); 487 if (fColumnEditor != null) { 488 fColumnEditor.dispose(); 489 } 490 super.dispose(); 491 } 492 493 496 protected void disposeCellEditors() { 497 CellEditor[] cellEditors = getCellEditors(); 498 if (cellEditors != null) { 499 for (int i = 0; i < cellEditors.length; i++) { 500 CellEditor editor = cellEditors[i]; 501 if (editor != null) { 502 editor.dispose(); 503 } 504 } 505 } 506 setCellEditors(null); 507 } 508 509 515 synchronized protected void inputChanged(Object input, Object oldInput) { 516 fPendingExpansion.clear(); 517 super.inputChanged(input, oldInput); 518 resetColumns(input); 519 } 520 521 524 public void refreshColumns() { 525 configureColumns(); 526 refresh(); 527 } 528 529 534 protected void resetColumns(Object input) { 535 if (input != null) { 536 IColumnPresentationFactoryAdapter factory = getColumnPresenetationFactoryAdapter(input); 538 PresentationContext context = (PresentationContext) getPresentationContext(); 539 String type = null; 540 if (factory != null) { 541 type = factory.getColumnPresentationId(context, input); 542 } 543 if (type != null) { 544 if (fColumnPresentation != null) { 545 if (!fColumnPresentation.getId().equals(type)) { 546 fColumnPresentation.dispose(); 548 fColumnPresentation = null; 549 } 550 } 551 if (fColumnPresentation == null) { 552 fColumnPresentation = factory.createColumnPresentation(context, input); 553 if (fColumnPresentation != null) { 554 fColumnPresentation.init(context); 555 configureColumns(); 556 } 557 } 558 } else { 559 if (fColumnPresentation != null) { 560 fColumnPresentation.dispose(); 561 fColumnPresentation = null; 562 configureColumns(); 563 } 564 } 565 } 566 } 567 568 573 protected void configureColumns() { 574 if (fColumnPresentation != null) { 575 IColumnPresentation build = null; 576 if (isShowColumns(fColumnPresentation.getId())) { 577 build = fColumnPresentation; 578 } 579 buildColumns(build); 580 } else { 581 buildColumns(null); 583 } 584 } 585 586 593 protected void buildColumns(IColumnPresentation presentation) { 594 Tree tree = getTree(); 596 final TreeColumn[] columns = tree.getColumns(); 597 String [] visibleColumnIds = getVisibleColumns(); 598 for (int i = 0; i < columns.length; i++) { 599 TreeColumn treeColumn = columns[i]; 600 treeColumn.removeControlListener(fListener); 601 treeColumn.dispose(); 602 } 603 PresentationContext presentationContext = (PresentationContext) getPresentationContext(); 604 if (presentation != null) { 605 for (int i = 0; i < visibleColumnIds.length; i++) { 606 String id = visibleColumnIds[i]; 607 String header = presentation.getHeader(id); 608 TreeColumn column = new TreeColumn(tree, SWT.LEFT, i); 610 column.setMoveable(true); 611 column.setText(header); 612 column.setWidth(1); 613 ImageDescriptor image = presentation.getImageDescriptor(id); 614 if (image != null) { 615 column.setImage(getImage(image)); 616 } 617 column.setData(id); 618 } 619 tree.setHeaderVisible(true); 620 tree.setLinesVisible(true); 621 presentationContext.setColumns(getVisibleColumns()); 622 } else { 623 tree.setHeaderVisible(false); 624 tree.setLinesVisible(false); 625 presentationContext.setColumns(null); 626 } 627 628 int avg = tree.getSize().x; 629 if (visibleColumnIds != null) 630 avg /= visibleColumnIds.length; 631 632 if (avg == 0) { 633 tree.addPaintListener(new PaintListener() { 634 public void paintControl(PaintEvent e) { 635 Tree tree2 = getTree(); 636 String [] visibleColumns = getVisibleColumns(); 637 if (visibleColumns != null) { 638 int avg1 = tree2.getSize().x / visibleColumns.length; 639 initColumns(avg1); 640 } 641 tree2.removePaintListener(this); 642 } 643 }); 644 } else { 645 initColumns(avg); 646 } 647 } 648 649 private void initColumns(int widthHint) { 650 TreeColumn[] columns = getTree().getColumns(); 651 for (int i = 0; i < columns.length; i++) { 652 TreeColumn treeColumn = columns[i]; 653 Integer width = (Integer ) fColumnSizes.get(treeColumn.getData()); 654 if (width == null) { 655 treeColumn.setWidth(widthHint); 656 } else { 657 treeColumn.setWidth(width.intValue()); 658 } 659 treeColumn.addControlListener(fListener); 660 } 661 } 662 665 protected void persistColumnSizes() { 666 Tree tree = getTree(); 667 TreeColumn[] columns = tree.getColumns(); 668 for (int i = 0; i < columns.length; i++) { 669 TreeColumn treeColumn = columns[i]; 670 Object id = treeColumn.getData(); 671 fColumnSizes.put(id, new Integer (treeColumn.getWidth())); 672 } 673 } 674 675 681 protected IColumnPresentationFactoryAdapter getColumnPresenetationFactoryAdapter(Object input) { 682 if (input instanceof IColumnPresentationFactoryAdapter) { 683 return (IColumnPresentationFactoryAdapter) input; 684 } 685 if (input instanceof IAdaptable) { 686 IAdaptable adaptable = (IAdaptable) input; 687 return (IColumnPresentationFactoryAdapter) adaptable.getAdapter(IColumnPresentationFactoryAdapter.class); 688 } 689 return null; 690 } 691 692 698 protected IColumnEditorFactoryAdapter getColumnEditorFactoryAdapter(Object input) { 699 if (input instanceof IColumnEditorFactoryAdapter) { 700 return (IColumnEditorFactoryAdapter) input; 701 } 702 if (input instanceof IAdaptable) { 703 IAdaptable adaptable = (IAdaptable) input; 704 return (IColumnEditorFactoryAdapter) adaptable.getAdapter(IColumnEditorFactoryAdapter.class); 705 } 706 return null; 707 } 708 709 718 protected synchronized TreePath getTreePath(TreeItem item) { 719 TreeItem parent = item; 720 List path = new ArrayList (); 721 while (parent != null && !parent.isDisposed()) { 722 Object parentElement = parent.getData(); 723 if (parentElement == null) { 724 parent.getItemCount(); 729 parentElement = parent.getData(); 730 if (parentElement == null) 731 return null; 732 } 733 path.add(0, parentElement); 734 parent = parent.getParentItem(); 735 } 736 Object data = fTree.getData(); 737 if (data == null) { 738 return null; 739 } 740 path.add(0, data); 741 return new TreePath(path.toArray()); 742 } 743 744 751 public TreePath[] getTreePaths(Object element) { 752 ModelNode[] nodes = getModel().getNodes(element); 753 if (nodes == null) { 754 return new TreePath[]{}; 755 } 756 TreePath[] paths = new TreePath[nodes.length]; 757 for (int i = 0; i < nodes.length; i++) { 758 paths[i] = nodes[i].getTreePath(); 759 } 760 return paths; 761 } 762 763 protected int getItemCount(Widget widget) { 764 if (widget instanceof TreeItem) { 765 return ((TreeItem) widget).getItemCount(); 766 } 767 return ((Tree) widget).getItemCount(); 768 } 769 770 773 protected void setItemCount(Widget widget, int itemCount) { 774 if (widget == fTree) { 775 fTree.setItemCount(itemCount); 776 } else { 777 ((TreeItem) widget).setItemCount(itemCount); 778 } 779 } 780 781 784 protected Widget getChildWidget(Widget parent, int index) { 785 if (parent instanceof Tree) { 786 Tree tree = (Tree) parent; 787 if (index < tree.getItemCount()) { 788 return tree.getItem(index); 789 } 790 } else if (parent instanceof TreeItem){ 791 TreeItem item = (TreeItem) parent; 792 if (index < item.getItemCount()) { 793 return item.getItem(index); 794 } 795 } 796 return null; 797 } 798 799 private TreeItem[] getItems(Widget widget) { 800 if (widget instanceof TreeItem) { 801 return ((TreeItem) widget).getItems(); 802 } else { 803 return fTree.getItems(); 804 } 805 } 806 807 813 protected Widget getParentWidget(Widget widget) { 814 if (widget instanceof TreeItem) { 815 TreeItem parentItem = ((TreeItem)widget).getParentItem(); 816 if (parentItem == null) { 817 return getControl(); 818 } 819 return parentItem; 820 } 821 return null; 822 } 823 824 825 832 private void expand(TreeItem child) { 833 if (!child.getExpanded()) { 834 child.setExpanded(true); 835 836 TreeItem parent = child.getParentItem(); 837 if (parent != null) { 838 expand(parent); 839 } 840 } 841 } 842 843 846 protected void clear(Widget widget) { 847 if (DEBUG_VIEWER) { 848 DebugUIPlugin.debug("CLEAR [" + widget + "]"); } 850 851 if (widget instanceof TreeItem && !widget.isDisposed()) { 852 TreeItem item = (TreeItem) widget; 853 TreeItem parentItem = item.getParentItem(); 854 if (parentItem == null) { 855 int index = fTree.indexOf(item); 856 if (index >= 0) 857 fTree.clear(index, true); 858 } else { 859 int index = parentItem.indexOf(item); 860 if (index >= 0) 861 parentItem.clear(index, true); 862 } 863 item.clearAll(true); 864 } else { 865 fTree.clearAll(true); 866 } 867 } 868 869 872 protected void clearChildren(Widget widget) { 873 if (DEBUG_VIEWER) { 874 DebugUIPlugin.debug("CLEAR_CHILDREN [" + widget + "]"); } 876 877 if (widget instanceof TreeItem && !widget.isDisposed()) { 878 TreeItem item = (TreeItem) widget; 879 item.clearAll(true); 880 } else { 881 fTree.clearAll(true); 882 } 883 } 884 885 888 protected void clearChild(Widget parent, int childIndex) { 889 if (DEBUG_VIEWER) { 890 DebugUIPlugin.debug("CLEAR_CHILD [" + parent + "]: " + childIndex); } 892 893 if (parent instanceof TreeItem && !parent.isDisposed()) { 894 TreeItem item = (TreeItem) parent; 895 item.clear(childIndex, true); 896 } else { 897 fTree.clear(childIndex, true); 898 } 899 } 900 901 906 protected ISelection newSelectionFromWidget() { 907 Control control = getControl(); 908 if (control == null || control.isDisposed()) { 909 return StructuredSelection.EMPTY; 910 } 911 List list = getSelectionFromWidget(); 912 return new TreeSelection((TreePath[]) list.toArray(new TreePath[list.size()])); 913 } 914 915 920 protected synchronized List getSelectionFromWidget() { 921 TreeItem[] selection = fTree.getSelection(); 922 List paths = new ArrayList (selection.length); 923 for (int i = 0; i < selection.length; i++) { 924 TreePath treePath = getTreePath(selection[i]); 925 if (treePath != null) { 926 paths.add(treePath); 927 } 928 } 929 return paths; 930 } 931 932 935 protected void internalRefresh(ModelNode node) { 936 super.internalRefresh(node); 937 updateHasChildren(node); 938 } 939 940 945 public void reveal(Object element) { 946 ModelNode[] nodes = getModel().getNodes(element); 948 if (nodes != null) { 949 for (int i = 0; i < nodes.length; i++) { 950 ModelNode node = nodes[i]; 951 Widget widget = findItem(node); 952 if (widget instanceof TreeItem) { 953 TreeItem item = (TreeItem) widget; 955 Tree tree = (Tree) getControl(); 956 tree.showItem(item); 957 return; 958 } 959 } 960 } 961 } 962 963 969 protected synchronized ISelection doAttemptSelectionToWidget(ISelection selection, boolean reveal) { 970 List remaining = new ArrayList (); 971 if (!selection.isEmpty()) { 972 List toSelect = new ArrayList (); 973 List theNodes = new ArrayList (); 974 List theElements = new ArrayList (); 975 TreeSelection treeSelection = (TreeSelection) selection; 976 TreePath[] paths = treeSelection.getPaths(); 977 for (int i = 0; i < paths.length; i++) { 978 TreePath path = paths[i]; 979 if (path == null) { 980 continue; 981 } 982 ModelNode[] nodes = getModel().getNodes(path.getLastSegment()); 983 boolean selected = false; 984 if (nodes != null) { 985 for (int j = 0; j < nodes.length; j++) { 986 ModelNode node = nodes[j]; 987 if (node.correspondsTo(path)) { 988 Widget widget = findItem(node); 989 if (widget != null && !widget.isDisposed()) { 990 toSelect.add(widget); 991 theNodes.add(node); 992 theElements.add(path.getLastSegment()); 993 selected = true; 994 break; 995 } 996 } 997 ModelNode parent = node.getParentNode(); 999 ModelNode child = node; 1000 if (parent != null) { 1001 Widget widget = findItem(parent); 1002 if (widget != null && !widget.isDisposed()) { 1003 int childIndex = parent.getChildIndex(child); 1004 if (childIndex < 0) { 1005 break; 1006 } 1007 TreeItem[] items = getItems(widget); 1008 if (childIndex < items.length) { 1009 widget = items[childIndex]; 1010 mapElement(child, widget); 1011 widget.setData(child.getElement()); 1012 toSelect.add(widget); 1013 theNodes.add(child); 1014 theElements.add(child.getElement()); 1015 selected = true; 1016 } else { 1017 break; 1018 } 1019 } 1020 } 1021 } 1022 } 1023 if (!selected) { 1024 remaining.add(path); 1025 } 1026 } 1027 if (!toSelect.isEmpty()) { 1028 final TreeItem[] items = (TreeItem[]) toSelect.toArray(new TreeItem[toSelect.size()]); 1029 for (int i = 0; i < items.length; i++) { 1033 TreeItem item = items[i]; 1034 Object element = theElements.get(i); 1035 if (!item.isDisposed() && item.getData() != element) { 1036 ModelNode theNode = (ModelNode) theNodes.get(i); 1037 Widget mapped = findItem(theNode); 1038 if (mapped == null) { 1039 return selection; 1041 } 1042 theNode.remap(element); 1043 item.setData(element); 1044 } 1045 } 1046 fTree.setSelection(items); 1047 if (reveal) { 1048 fTree.showItem(items[0]); 1049 } 1050 } 1051 } else { 1052 fTree.setSelection(new TreeItem[0]); 1053 } 1054 return new TreeSelection((TreePath[]) remaining.toArray(new TreePath[remaining.size()])); 1055 } 1056 1057 1060 public void collapseAll() { 1061 TreeItem[] items = fTree.getItems(); 1062 for (int i = 0; i < items.length; i++) { 1063 TreeItem item = items[i]; 1064 if (item.getExpanded()) 1065 collapse(item); 1066 } 1067 } 1068 1069 1075 protected void collapse(TreeItem item) { 1076 TreeItem[] items = item.getItems(); 1077 for (int i = 0; i < items.length; i++) { 1078 TreeItem child = items[i]; 1079 if (child.getExpanded()) { 1080 collapse(child); 1081 } 1082 } 1083 item.setExpanded(false); 1084 } 1085 1086 1092 protected void setColors(Widget widget, RGB[] foregrounds, RGB[] backgrounds) { 1093 if (widget instanceof TreeItem) { 1094 TreeItem item = (TreeItem) widget; 1095 Color[] fgs = getColors(foregrounds); 1096 for (int i = 0; i < fgs.length; i++) { 1097 item.setForeground(i, fgs[i]); 1098 } 1099 Color[] bgs = getColors(backgrounds); 1100 for (int i = 0; i < bgs.length; i++) { 1101 item.setBackground(i, bgs[i]); 1102 } 1103 } 1104 } 1105 1106 1112 protected void setFonts(Widget widget, FontData[] fontData) { 1113 if (widget instanceof TreeItem) { 1114 TreeItem item = (TreeItem) widget; 1115 Font[] fonts = getFonts(fontData); 1116 for (int i = 0; i < fonts.length; i++) { 1117 item.setFont(i, fonts[i]); 1118 } 1119 } 1120 } 1121 1122 1127 protected boolean acceptsSelection(ISelection selection) { 1128 return selection instanceof TreeSelection; 1129 } 1130 1131 1136 protected ISelection getEmptySelection() { 1137 return new TreeSelection(new TreePath[0]); 1138 } 1139 1140 1146 public void add(TreePath treePath) { 1147 ((AsynchronousTreeModel)getModel()).add(treePath); 1148 } 1149 1150 1156 public void remove(TreePath treePath) { 1157 synchronized (this) { 1158 for (Iterator i = fPendingExpansion.iterator(); i.hasNext();) { 1159 TreePath expansionPath = (TreePath) i.next(); 1160 if (expansionPath.startsWith(treePath, null)) { 1161 i.remove(); 1162 } 1163 } 1164 } 1165 ((AsynchronousTreeModel)getModel()).remove(treePath); 1166 } 1167 1168 1169 protected void restoreLabels(Item item) { 1170 TreeItem treeItem = (TreeItem) item; 1171 String [] values = (String []) treeItem.getData(OLD_LABEL); 1172 Image[] images = (Image[])treeItem.getData(OLD_IMAGE); 1173 if (values != null) { 1174 treeItem.setText(values); 1175 treeItem.setImage(images); 1176 } 1177 } 1178 1179 protected void setLabels(Widget widget, String [] text, ImageDescriptor[] image) { 1180 if (widget instanceof TreeItem) { 1181 TreeItem item = (TreeItem) widget; 1182 if (!item.isDisposed()) { 1183 item.setText(text); 1184 item.setData(OLD_LABEL, text); 1185 Image[] images = getImages(image); 1186 item.setImage(images); 1187 item.setData(OLD_IMAGE, images); 1188 } 1189 } 1190 } 1191 1192 1195 protected AsynchronousModel createModel() { 1196 return new AsynchronousTreeModel(this); 1197 } 1198 1199 1202 protected void attemptPendingUpdates() { 1203 attemptExpansion(); 1204 super.attemptPendingUpdates(); 1205 } 1206 1207 1210 public AbstractUpdatePolicy createUpdatePolicy() { 1211 return new TreeUpdatePolicy(); 1212 } 1213 1214 protected synchronized void unmapAllElements() { 1215 super.unmapAllElements(); 1216 Tree tree = getTree(); 1217 if (!tree.isDisposed()) { 1218 TreeItem[] items = tree.getItems(); 1219 for (int i = 0; i < items.length; i++) { 1220 items[i].dispose(); 1221 } 1222 clear(tree); 1223 } 1224 } 1225 1226 1232 public IColumnPresentation getColumnPresentation() { 1233 return fColumnPresentation; 1234 } 1235 1236 1242 public String [] getVisibleColumns() { 1243 IColumnPresentation presentation = getColumnPresentation(); 1244 if (presentation != null) { 1245 String [] columns = (String []) fVisibleColumns.get(presentation.getId()); 1246 if (columns == null) { 1247 return presentation.getInitialColumns(); 1248 } 1249 return columns; 1250 } 1251 return null; 1252 } 1253 1254 1260 public void setVisibleColumns(String [] ids) { 1261 IColumnPresentation presentation = getColumnPresentation(); 1262 if (presentation != null) { 1263 fVisibleColumns.remove(presentation.getId()); 1264 if (ids != null) { 1265 String [] columns = presentation.getInitialColumns(); 1267 if (columns.length == ids.length) { 1268 for (int i = 0; i < columns.length; i++) { 1269 if (!ids[i].equals(columns[i])) { 1270 fVisibleColumns.put(presentation.getId(), ids); 1271 break; 1272 } 1273 } 1274 } else { 1275 fVisibleColumns.put(presentation.getId(), ids); 1276 } 1277 } 1278 PresentationContext presentationContext = (PresentationContext) getPresentationContext(); 1279 presentationContext.setColumns(getVisibleColumns()); 1280 refreshColumns(); 1281 } 1282 } 1283 1284 1289 public void saveState(IMemento memento) { 1290 if (!fColumnSizes.isEmpty()) { 1291 Iterator iterator = fColumnSizes.entrySet().iterator(); 1292 while (iterator.hasNext()) { 1293 Map.Entry entry = (Entry) iterator.next(); 1294 IMemento sizes = memento.createChild(COLUMN_SIZES, (String )entry.getKey()); 1295 sizes.putInteger(SIZE, ((Integer )entry.getValue()).intValue()); 1296 } 1297 } 1298 if (!fShowColumns.isEmpty()) { 1299 Iterator iterator = fShowColumns.entrySet().iterator(); 1300 while (iterator.hasNext()) { 1301 Map.Entry entry = (Entry) iterator.next(); 1302 IMemento sizes = memento.createChild(SHOW_COLUMNS, (String )entry.getKey()); 1303 sizes.putString(SHOW_COLUMNS, ((Boolean )entry.getValue()).toString()); 1304 } 1305 } 1306 if (!fVisibleColumns.isEmpty()) { 1307 Iterator iterator = fVisibleColumns.entrySet().iterator(); 1308 while (iterator.hasNext()) { 1309 Map.Entry entry = (Entry) iterator.next(); 1310 String id = (String ) entry.getKey(); 1311 IMemento visible = memento.createChild(VISIBLE_COLUMNS, id); 1312 String [] columns = (String []) entry.getValue(); 1313 visible.putInteger(SIZE, columns.length); 1314 for (int i = 0; i < columns.length; i++) { 1315 visible.putString(COLUMN+Integer.toString(i), columns[i]); 1316 } 1317 } 1318 } 1319 } 1320 1321 1324 public void resetColumnSizes(String [] columnIds) { 1325 for (int i = 0; i < columnIds.length; i++) { 1326 fColumnSizes.remove(columnIds[i]); 1327 } 1328 } 1329 1330 1335 public void initState(IMemento memento) { 1336 IMemento[] mementos = memento.getChildren(COLUMN_SIZES); 1337 for (int i = 0; i < mementos.length; i++) { 1338 IMemento child = mementos[i]; 1339 String id = child.getID(); 1340 Integer size = child.getInteger(SIZE); 1341 if (size != null) { 1342 fColumnSizes.put(id, size); 1343 } 1344 } 1345 mementos = memento.getChildren(SHOW_COLUMNS); 1346 for (int i = 0; i < mementos.length; i++) { 1347 IMemento child = mementos[i]; 1348 String id = child.getID(); 1349 Boolean bool = Boolean.valueOf(child.getString(SHOW_COLUMNS)); 1350 if (!bool.booleanValue()) { 1351 fShowColumns.put(id, bool); 1352 } 1353 } 1354 mementos = memento.getChildren(VISIBLE_COLUMNS); 1355 for (int i = 0; i < mementos.length; i++) { 1356 IMemento child = mementos[i]; 1357 String id = child.getID(); 1358 Integer integer = child.getInteger(SIZE); 1359 if (integer != null) { 1360 int length = integer.intValue(); 1361 String [] columns = new String [length]; 1362 for (int j = 0; j < length; j++) { 1363 columns[j] = child.getString(COLUMN+Integer.toString(j)); 1364 } 1365 fVisibleColumns.put(id, columns); 1366 } 1367 } 1368 1369 } 1370 1371 1374 private void initTreeViewerImpl() { 1375 fTreeEditorImpl = new TreeEditorImpl(this) { 1376 Rectangle getBounds(Item item, int columnNumber) { 1377 return ((TreeItem) item).getBounds(columnNumber); 1378 } 1379 1380 int getColumnCount() { 1381 return getTree().getColumnCount(); 1382 } 1383 1384 Item[] getSelection() { 1385 return getTree().getSelection(); 1386 } 1387 1388 void setEditor(Control w, Item item, int columnNumber) { 1389 fTreeEditor.setEditor(w, (TreeItem) item, columnNumber); 1390 } 1391 1392 void setSelection(IStructuredSelection selection, boolean b) { 1393 AsynchronousTreeViewer.this.setSelection(selection, b); 1394 } 1395 1396 void showSelection() { 1397 getTree().showSelection(); 1398 } 1399 1400 void setLayoutData(CellEditor.LayoutData layoutData) { 1401 fTreeEditor.grabHorizontal = layoutData.grabHorizontal; 1402 fTreeEditor.horizontalAlignment = layoutData.horizontalAlignment; 1403 fTreeEditor.minimumWidth = layoutData.minimumWidth; 1404 } 1405 1406 void handleDoubleClickEvent() { 1407 Viewer viewer = getViewer(); 1408 fireDoubleClick(new DoubleClickEvent(viewer, viewer 1409 .getSelection())); 1410 fireOpen(new OpenEvent(viewer, viewer.getSelection())); 1411 } 1412 }; 1413 } 1414 1415 1423 public void editElement(Object element, int column) { 1424 fTreeEditorImpl.editElement(element, column); 1425 } 1426 1427 1432 public CellEditor[] getCellEditors() { 1433 return fTreeEditorImpl.getCellEditors(); 1434 } 1435 1436 1441 public ICellModifier getCellModifier() { 1442 return fTreeEditorImpl.getCellModifier(); 1443 } 1444 1445 1450 public void cancelEditing() { 1451 fTreeEditorImpl.cancelEditing(); 1452 } 1453 1454 1460 public boolean isCellEditorActive() { 1461 return fTreeEditorImpl.isCellEditorActive(); 1462 } 1463 1464 1470 protected void setCellEditors(CellEditor[] editors) { 1471 fTreeEditorImpl.setCellEditors(editors); 1472 } 1473 1474 1480 protected void setCellModifier(ICellModifier modifier) { 1481 fTreeEditorImpl.setCellModifier(modifier); 1482 } 1483 1484 1492 protected void setColumnProperties(String [] columnProperties) { 1493 fTreeEditorImpl.setColumnProperties(columnProperties); 1494 } 1495 1496 1502 public void setShowColumns(boolean show) { 1503 if (show) { 1504 if (!isShowColumns()) { 1505 fShowColumns.remove(fColumnPresentation.getId()); 1506 } 1507 } else { 1508 if (isShowColumns()){ 1509 fShowColumns.put(fColumnPresentation.getId(), Boolean.FALSE); 1510 } 1511 } 1512 refreshColumns(); 1513 } 1514 1515 1520 public boolean isShowColumns() { 1521 if (fColumnPresentation != null) { 1522 return isShowColumns(fColumnPresentation.getId()); 1523 } 1524 return false; 1525 } 1526 1527 1532 public boolean canToggleColumns() { 1533 return fColumnPresentation != null && fColumnPresentation.isOptional(); 1534 } 1535 1536 protected boolean isShowColumns(String columnPresentationId) { 1537 Boolean bool = (Boolean ) fShowColumns.get(columnPresentationId); 1538 if (bool == null) { 1539 return true; 1540 } 1541 return bool.booleanValue(); 1542 } 1543 1544 1549 protected void nodeContainerChanged(ModelNode node) { 1550 Widget widget = findItem(node); 1551 if (widget != null && !widget.isDisposed()) { 1552 if (node.isContainer()) { 1553 if (widget instanceof TreeItem) { 1554 if (((TreeItem)widget).getExpanded()) { 1555 updateChildren(node); 1556 } 1557 } else { 1558 updateChildren(node); 1559 } 1560 attemptPendingUpdates(); 1561 } 1562 } 1563 } 1564 1565 1574 public List buildLabels(IProgressMonitor monitor, Object element, String taskName) { 1575 ModelNode[] theNodes = getModel().getNodes(element); 1576 List results = new ArrayList (); 1577 if (theNodes != null && theNodes.length > 0) { 1578 ModelNode root = theNodes[0]; 1579 List nodes = new ArrayList (); 1580 collectNodes(nodes, root); 1581 monitor.beginTask(taskName, nodes.size()); 1582 Iterator iterator = nodes.iterator(); 1583 while (!monitor.isCanceled() && iterator.hasNext()) { 1584 ModelNode node = (ModelNode) iterator.next(); 1585 IAsynchronousLabelAdapter labelAdapter = getModel().getLabelAdapter(node.getElement()); 1586 if (labelAdapter != null) { 1587 LabelResult result = new LabelResult(node, getModel()); 1588 labelAdapter.retrieveLabel(node.getElement(), getPresentationContext(), result); 1589 synchronized (result) { 1590 if (!result.isDone()) { 1591 try { 1592 result.wait(); 1593 } catch (InterruptedException e) { 1594 monitor.setCanceled(true); 1595 return null; 1596 } 1597 } 1598 } 1599 IStatus status = result.getStatus(); 1600 if (status == null || status.isOK()) { 1601 results.add(result); 1602 } 1603 } 1604 monitor.worked(1); 1605 } 1606 } 1607 monitor.done(); 1608 return results; 1609 } 1610 1611 private void collectNodes(List nodes, ModelNode node) { 1612 if (node.getParentNode() != null) { 1613 nodes.add(node); 1614 } 1615 ModelNode[] childrenNodes = node.getChildrenNodes(); 1616 if (childrenNodes != null) { 1617 for (int i = 0; i < childrenNodes.length; i++) { 1618 collectNodes(nodes, childrenNodes[i]); 1619 } 1620 } 1621 } 1622 1623 1626 protected int indexOf(Widget parent, Widget child) { 1627 if (parent instanceof Tree) { 1628 return ((Tree)parent).indexOf((TreeItem)child); 1629 } else { 1630 return ((TreeItem)parent).indexOf((TreeItem)child); 1631 } 1632 } 1633 1634 1637 protected boolean selectionExists(ISelection selection) { 1638 if (!selection.isEmpty() && selection instanceof TreeSelection) { 1639 TreeSelection ts = (TreeSelection) selection; 1640 TreePath[] paths = ts.getPaths(); 1641 int matchingPaths = 0; 1642 for (int i = 0; i < paths.length; i++) { 1643 TreePath path = paths[i]; 1644 Object element = path.getLastSegment(); 1645 ModelNode[] nodes = getModel().getNodes(element); 1646 if (nodes != null) { 1647 for (int j = 0; j < nodes.length; j++) { 1648 ModelNode node = nodes[j]; 1649 if (node.getTreePath().equals(path)) { 1650 matchingPaths++; 1651 break; 1652 } 1653 } 1654 } 1655 } 1656 return matchingPaths == paths.length; 1657 } 1658 return super.selectionExists(selection); 1659 } 1660 1661 1662 1663 1664} 1665 | Popular Tags |