1 13 14 package org.eclipse.jface.viewers; 15 16 import java.util.ArrayList ; 17 import java.util.Arrays ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 22 import org.eclipse.core.runtime.Assert; 23 import org.eclipse.swt.SWT; 24 import org.eclipse.swt.widgets.Control; 25 import org.eclipse.swt.widgets.Event; 26 import org.eclipse.swt.widgets.Item; 27 import org.eclipse.swt.widgets.Listener; 28 import org.eclipse.swt.widgets.Widget; 29 30 37 public abstract class AbstractTableViewer extends ColumnViewer { 38 39 private class VirtualManager { 40 41 47 private Object [] cachedElements = new Object [0]; 48 49 53 public VirtualManager() { 54 addTableListener(); 55 } 56 57 60 private void addTableListener() { 61 getControl().addListener(SWT.SetData, new Listener() { 62 67 public void handleEvent(Event event) { 68 Item item = (Item) event.item; 69 final int index = doIndexOf(item); 70 Object element = resolveElement(index); 71 if (element == null) { 72 IContentProvider contentProvider = getContentProvider(); 75 if (contentProvider instanceof ILazyContentProvider) { 77 ((ILazyContentProvider) contentProvider) 78 .updateElement(index); 79 return; 80 } 81 } 82 83 associate(element, item); 84 updateItem(item, element); 85 } 86 87 }); 88 } 89 90 96 protected Object resolveElement(int index) { 97 98 Object element = null; 99 if (index < cachedElements.length) { 100 element = cachedElements[index]; 101 } 102 103 return element; 104 } 105 106 112 public void notVisibleAdded(Object element, int index) { 113 114 int requiredCount = doGetItemCount() + 1; 115 116 Object [] newCache = new Object [requiredCount]; 117 System.arraycopy(cachedElements, 0, newCache, 0, index); 118 if (index < cachedElements.length) { 119 System.arraycopy(cachedElements, index, newCache, index + 1, 120 cachedElements.length - index); 121 } 122 newCache[index] = element; 123 cachedElements = newCache; 124 125 doSetItemCount(requiredCount); 126 } 127 128 134 public void removeIndices(int[] indices) { 135 if (indices.length == 1) { 136 removeIndicesFromTo(indices[0], indices[0]); 137 } 138 int requiredCount = doGetItemCount() - indices.length; 139 140 Arrays.sort(indices); 141 Object [] newCache = new Object [requiredCount]; 142 int indexInNewCache = 0; 143 int nextToSkip = 0; 144 for (int i = 0; i < cachedElements.length; i++) { 145 if (nextToSkip < indices.length && i == indices[nextToSkip]) { 146 nextToSkip++; 147 } else { 148 newCache[indexInNewCache++] = cachedElements[i]; 149 } 150 } 151 cachedElements = newCache; 152 } 153 154 161 public void removeIndicesFromTo(int from, int to) { 162 int indexAfterTo = to + 1; 163 Object [] newCache = new Object [cachedElements.length 164 - (indexAfterTo - from)]; 165 System.arraycopy(cachedElements, 0, newCache, 0, from); 166 if (indexAfterTo < cachedElements.length) { 167 System.arraycopy(cachedElements, indexAfterTo, newCache, from, 168 cachedElements.length - indexAfterTo); 169 } 170 } 171 172 176 public int find(Object element) { 177 return Arrays.asList(cachedElements).indexOf(element); 178 } 179 180 183 public void adjustCacheSize(int count) { 184 if (count == cachedElements.length) { 185 return; 186 } else if (count < cachedElements.length) { 187 Object [] newCache = new Object [count]; 188 System.arraycopy(cachedElements, 0, newCache, 0, count); 189 cachedElements = newCache; 190 } else { 191 Object [] newCache = new Object [count]; 192 System.arraycopy(cachedElements, 0, newCache, 0, 193 cachedElements.length); 194 cachedElements = newCache; 195 } 196 } 197 198 } 199 200 private VirtualManager virtualManager; 201 202 205 public AbstractTableViewer() { 206 super(); 207 } 208 209 protected void hookControl(Control control) { 210 super.hookControl(control); 211 initializeVirtualManager(getControl().getStyle()); 212 } 213 214 220 private void initializeVirtualManager(int style) { 221 if ((style & SWT.VIRTUAL) == 0) { 222 return; 223 } 224 225 virtualManager = new VirtualManager(); 226 } 227 228 241 public void add(Object [] elements) { 242 assertElementsNotNull(elements); 243 if (isBusy()) 244 return; 245 Object [] filtered = filter(elements); 246 247 for (int i = 0; i < filtered.length; i++) { 248 Object element = filtered[i]; 249 int index = indexForElement(element); 250 createItem(element, index); 251 } 252 } 253 254 262 private void createItem(Object element, int index) { 263 if (virtualManager == null) { 264 updateItem(internalCreateNewRowPart(SWT.NONE, index).getItem(), 265 element); 266 } else { 267 virtualManager.notVisibleAdded(element, index); 268 269 } 270 } 271 272 283 protected abstract ViewerRow internalCreateNewRowPart(int style, 284 int rowIndex); 285 286 301 public void add(Object element) { 302 add(new Object [] { element }); 303 } 304 305 310 protected Widget doFindInputItem(Object element) { 311 if (equals(element, getRoot())) { 312 return getControl(); 313 } 314 return null; 315 } 316 317 322 protected Widget doFindItem(Object element) { 323 324 Item[] children = doGetItems(); 325 for (int i = 0; i < children.length; i++) { 326 Item item = children[i]; 327 Object data = item.getData(); 328 if (data != null && equals(data, element)) { 329 return item; 330 } 331 } 332 333 return null; 334 } 335 336 342 protected void doUpdateItem(Widget widget, Object element, boolean fullMap) { 343 boolean oldBusy = busy; 344 busy = true; 345 try { 346 if (widget instanceof Item) { 347 final Item item = (Item) widget; 348 349 if (fullMap) { 351 associate(element, item); 352 } else { 353 Object data = item.getData(); 354 if (data != null) { 355 unmapElement(data, item); 356 } 357 item.setData(element); 358 mapElement(element, item); 359 } 360 361 int columnCount = doGetColumnCount(); 362 if (columnCount == 0) 363 columnCount = 1; 365 ViewerRow viewerRowFromItem = getViewerRowFromItem(item); 366 367 boolean isVirtual = (getControl().getStyle() & SWT.VIRTUAL) != 0; 368 369 if (isVirtual) { 371 viewerRowFromItem = (ViewerRow) viewerRowFromItem.clone(); 372 } 373 374 for (int column = 0; column < columnCount || column == 0; column++) { 377 ViewerColumn columnViewer = getViewerColumn(column); 378 ViewerCell cellToUpdate = updateCell(viewerRowFromItem, 379 column, element); 380 381 if (isVirtual) { 383 cellToUpdate = new ViewerCell(cellToUpdate.getViewerRow(), cellToUpdate.getColumnIndex(), element); 384 } 385 386 columnViewer.refresh(cellToUpdate); 387 388 updateCell(null, 0, null); 390 391 if (item.isDisposed()) { 394 unmapElement(element, item); 395 return; 396 } 397 398 } 399 400 } 401 } finally { 402 busy = oldBusy; 403 } 404 } 405 406 411 protected Widget getColumnViewerOwner(int columnIndex) { 412 int columnCount = doGetColumnCount(); 413 414 if (columnIndex < 0 415 || (columnIndex > 0 && columnIndex >= columnCount)) { 416 return null; 417 } 418 419 if (columnCount == 0) return getControl(); 421 422 return doGetColumn(columnIndex); 423 } 424 425 437 public Object getElementAt(int index) { 438 if (index >= 0 && index < doGetItemCount()) { 439 Item i = doGetItem(index); 440 if (i != null) { 441 return i.getData(); 442 } 443 } 444 return null; 445 } 446 447 457 public IBaseLabelProvider getLabelProvider() { 458 return super.getLabelProvider(); 459 } 460 461 466 protected List getSelectionFromWidget() { 467 if (virtualManager != null) { 468 return getVirtualSelection(); 469 } 470 Widget[] items = doGetSelection(); 471 ArrayList list = new ArrayList (items.length); 472 for (int i = 0; i < items.length; i++) { 473 Widget item = items[i]; 474 Object e = item.getData(); 475 if (e != null) { 476 list.add(e); 477 } 478 } 479 return list; 480 } 481 482 488 489 private List getVirtualSelection() { 490 491 List result = new ArrayList (); 492 int[] selectionIndices = doGetSelectionIndices(); 493 if (getContentProvider() instanceof ILazyContentProvider) { 494 ILazyContentProvider lazy = (ILazyContentProvider) getContentProvider(); 495 for (int i = 0; i < selectionIndices.length; i++) { 496 int selectionIndex = selectionIndices[i]; 497 lazy.updateElement(selectionIndex); Object element = doGetItem(selectionIndex).getData(); 499 if (element != null) { 503 result.add(element); 504 } 505 } 506 } else { 507 for (int i = 0; i < selectionIndices.length; i++) { 508 Object element = null; 509 int selectionIndex = selectionIndices[i]; 511 if (selectionIndex < virtualManager.cachedElements.length) { 512 element = virtualManager.cachedElements[selectionIndex]; 513 } 514 if (element == null) { 515 Item item = doGetItem(selectionIndex); 517 element = item.getData(); 518 } 519 if (element != null) { 520 result.add(element); 521 } 522 } 523 524 } 525 return result; 526 } 527 528 533 protected int indexForElement(Object element) { 534 ViewerComparator comparator = getComparator(); 535 if (comparator == null) { 536 return doGetItemCount(); 537 } 538 int count = doGetItemCount(); 539 int min = 0, max = count - 1; 540 while (min <= max) { 541 int mid = (min + max) / 2; 542 Object data = doGetItem(mid).getData(); 543 int compare = comparator.compare(this, data, element); 544 if (compare == 0) { 545 while (compare == 0) { 547 ++mid; 548 if (mid >= count) { 549 break; 550 } 551 data = doGetItem(mid).getData(); 552 compare = comparator.compare(this, data, element); 553 } 554 return mid; 555 } 556 if (compare < 0) { 557 min = mid + 1; 558 } else { 559 max = mid - 1; 560 } 561 } 562 return min; 563 } 564 565 571 protected void inputChanged(Object input, Object oldInput) { 572 getControl().setRedraw(false); 573 try { 574 preservingSelection(new Runnable () { 575 public void run() { 576 internalRefresh(getRoot()); 577 } 578 }); 579 } finally { 580 getControl().setRedraw(true); 581 } 582 } 583 584 600 public void insert(Object element, int position) { 601 applyEditorValue(); 602 if (getComparator() != null || hasFilters()) { 603 add(element); 604 return; 605 } 606 if (position == -1) { 607 position = doGetItemCount(); 608 } 609 if (isBusy()) 610 return; 611 createItem(element, position); 612 } 613 614 619 protected void internalRefresh(Object element) { 620 internalRefresh(element, true); 621 } 622 623 629 protected void internalRefresh(Object element, boolean updateLabels) { 630 applyEditorValue(); 631 if (element == null || equals(element, getRoot())) { 632 if (virtualManager == null) { 633 internalRefreshAll(updateLabels); 634 } else { 635 internalVirtualRefreshAll(); 636 } 637 } else { 638 Widget w = findItem(element); 639 if (w != null) { 640 updateItem(w, element); 641 } 642 } 643 } 644 645 650 private void internalVirtualRefreshAll() { 651 652 Object root = getRoot(); 653 IContentProvider contentProvider = getContentProvider(); 654 655 if (!(contentProvider instanceof ILazyContentProvider) 657 && (contentProvider instanceof IStructuredContentProvider)) { 658 if (root != null) { 660 virtualManager.cachedElements = getSortedChildren(root); 661 doSetItemCount(virtualManager.cachedElements.length); 662 } 663 } 664 doClearAll(); 665 } 666 667 675 private void internalRefreshAll(boolean updateLabels) { 676 678 685 Object [] children = getSortedChildren(getRoot()); 686 Item[] items = doGetItems(); 687 int min = Math.min(children.length, items.length); 688 for (int i = 0; i < min; ++i) { 689 690 Item item = items[i]; 691 692 if (equals(children[i], item.getData())) { 694 if (updateLabels) { 695 updateItem(item, children[i]); 696 } else { 697 associate(children[i], item); 701 } 702 } else { 703 disassociate(item); 712 doClear(i); 713 } 714 } 715 if (min < items.length) { 717 for (int i = items.length; --i >= min;) { 718 719 disassociate(items[i]); 720 } 721 if (virtualManager != null) { 722 virtualManager.removeIndicesFromTo(min, items.length - 1); 723 } 724 doRemove(min, items.length - 1); 725 } 726 if (doGetItemCount() == 0) { 729 doRemoveAll(); 730 } 731 for (int i = 0; i < min; ++i) { 733 734 Item item = items[i]; 735 if (item.getData() == null) { 736 updateItem(item, children[i]); 737 } 738 } 739 for (int i = min; i < children.length; ++i) { 741 createItem(children[i], i); 742 } 743 } 744 745 751 private void internalRemove(final Object [] elements) { 752 Object input = getInput(); 753 for (int i = 0; i < elements.length; ++i) { 754 if (equals(elements[i], input)) { 755 boolean oldBusy = busy; 756 busy = false; 757 try { 758 setInput(null); 759 } finally { 760 busy = oldBusy; 761 } 762 return; 763 } 764 } 765 int[] indices = new int[elements.length]; 768 int count = 0; 769 for (int i = 0; i < elements.length; ++i) { 770 Widget w = findItem(elements[i]); 771 if (w == null && virtualManager != null) { 772 int index = virtualManager.find(elements[i]); 773 if (index != -1) { 774 indices[count++] = index; 775 } 776 } else if (w instanceof Item) { 777 Item item = (Item) w; 778 disassociate(item); 779 indices[count++] = doIndexOf(item); 780 } 781 } 782 if (count < indices.length) { 783 System.arraycopy(indices, 0, indices = new int[count], 0, count); 784 } 785 if (virtualManager != null) { 786 virtualManager.removeIndices(indices); 787 } 788 doRemove(indices); 789 790 if (doGetItemCount() == 0) { 793 doRemoveAll(); 794 } 795 } 796 797 809 public void remove(final Object [] elements) { 810 assertElementsNotNull(elements); 811 if (isBusy()) 812 return; 813 if (elements.length == 0) { 814 return; 815 } 816 preservingSelection(new Runnable () { 817 public void run() { 818 internalRemove(elements); 819 } 820 }); 821 } 822 823 839 public void remove(Object element) { 840 remove(new Object [] { element }); 841 } 842 843 848 public void reveal(Object element) { 849 Assert.isNotNull(element); 850 Widget w = findItem(element); 851 if (w instanceof Item) { 852 doShowItem((Item) w); 853 } 854 } 855 856 862 protected void setSelectionToWidget(List list, boolean reveal) { 863 if (list == null) { 864 doDeselectAll(); 865 return; 866 } 867 868 if (virtualManager != null) { 869 virtualSetSelectionToWidget(list, reveal); 870 return; 871 } 872 873 if (reveal) { 876 int size = list.size(); 877 Item[] items = new Item[size]; 878 int count = 0; 879 for (int i = 0; i < size; ++i) { 880 Object o = list.get(i); 881 Widget w = findItem(o); 882 if (w instanceof Item) { 883 Item item = (Item) w; 884 items[count++] = item; 885 } 886 } 887 if (count < size) { 888 System.arraycopy(items, 0, items = new Item[count], 0, count); 889 } 890 doSetSelection(items); 891 } else { 892 doDeselectAll(); if( ! list.isEmpty() ) { 894 int[] indices = new int[list.size()]; 895 896 Iterator it = list.iterator(); 897 Item[] items = doGetItems(); 898 Object modelElement; 899 900 int count = 0; 901 while( it.hasNext() ) { 902 modelElement = it.next(); 903 boolean found = false; 904 for (int i = 0; i < items.length && !found; i++) { 905 if (equals(modelElement, items[i].getData())) { 906 indices[count++] = i; 907 found = true; 908 } 909 } 910 } 911 912 if (count < indices.length) { 913 System.arraycopy(indices, 0, indices = new int[count], 0, count); 914 } 915 916 doSelect(indices); 917 } 918 } 919 } 920 921 929 private void virtualSetSelectionToWidget(List list, boolean reveal) { 930 int size = list.size(); 931 int[] indices = new int[list.size()]; 932 933 Item firstItem = null; 934 int count = 0; 935 HashSet virtualElements = new HashSet (); 936 for (int i = 0; i < size; ++i) { 937 Object o = list.get(i); 938 Widget w = findItem(o); 939 if (w instanceof Item) { 940 Item item = (Item) w; 941 indices[count++] = doIndexOf(item); 942 if (firstItem == null) { 943 firstItem = item; 944 } 945 } else { 946 virtualElements.add(o); 947 } 948 } 949 950 if (getContentProvider() instanceof ILazyContentProvider) { 951 ILazyContentProvider provider = (ILazyContentProvider) getContentProvider(); 952 953 for (int i = 0; virtualElements.size() > 0 && i < doGetItemCount(); i++) { 959 provider.updateElement(i); 960 Item item = doGetItem(i); 961 if (virtualElements.contains(item.getData())) { 962 indices[count++] = i; 963 virtualElements.remove(item.getData()); 964 if (firstItem == null) { 965 firstItem = item; 966 } 967 } 968 } 969 } else { 970 971 if (count != list.size()) { for (int i = 0; i < virtualManager.cachedElements.length; i++) { 975 Object element = virtualManager.cachedElements[i]; 976 if (virtualElements.contains(element)) { 977 Item item = doGetItem(i); 978 item.getText(); indices[count++] = i; 980 virtualElements.remove(element); 981 if (firstItem == null) { 982 firstItem = item; 983 } 984 } 985 } 986 } 987 } 988 989 if (count < size) { 990 System.arraycopy(indices, 0, indices = new int[count], 0, count); 991 } 992 doSetSelection(indices); 993 994 if (reveal && firstItem != null) { 995 doShowItem(firstItem); 996 } 997 } 998 999 1007 public void setItemCount(int count) { 1008 if (isBusy()) 1009 return; 1010 int oldCount = doGetItemCount(); 1011 if (count < oldCount) { 1012 for (int i = count; i < oldCount; i++) { 1014 Item item = doGetItem(i); 1015 if (item.getData() != null) { 1016 disassociate(item); 1017 } 1018 } 1019 } 1020 doSetItemCount(count); 1021 if (virtualManager != null) { 1022 virtualManager.adjustCacheSize(count); 1023 } 1024 getControl().redraw(); 1025 } 1026 1027 1039 public void replace(Object element, int index) { 1040 if (isBusy()) 1041 return; 1042 Item item = doGetItem(index); 1043 refreshItem(item, element); 1044 } 1045 1046 1054 public void clear(int index) { 1055 Item item = doGetItem(index); 1056 if (item.getData() != null) { 1057 disassociate(item); 1058 } 1059 doClear(index); 1060 } 1061 1062 1067 protected Object [] getRawChildren(Object parent) { 1068 1069 Assert.isTrue(!(getContentProvider() instanceof ILazyContentProvider), 1070 "Cannot get raw children with an ILazyContentProvider"); return super.getRawChildren(parent); 1072 1073 } 1074 1075 1080 protected void assertContentProviderType(IContentProvider provider) { 1081 Assert.isTrue(provider instanceof IStructuredContentProvider 1082 || provider instanceof ILazyContentProvider); 1083 } 1084 1085 1096 protected abstract int doIndexOf(Item item); 1097 1098 1105 protected abstract int doGetItemCount(); 1106 1107 1115 protected abstract void doSetItemCount(int count); 1116 1117 1125 protected abstract Item[] doGetItems(); 1126 1127 1145 protected abstract Widget doGetColumn(int index); 1146 1147 1160 protected abstract Item doGetItem(int index); 1161 1162 1171 protected abstract Item[] doGetSelection(); 1172 1173 1182 protected abstract int[] doGetSelectionIndices(); 1183 1184 1192 protected abstract void doClearAll(); 1193 1194 1202 protected abstract void doResetItem(Item item); 1203 1204 1219 protected abstract void doRemove(int start, int end); 1220 1221 1226 protected abstract void doRemoveAll(); 1227 1228 1242 protected abstract void doRemove(int[] indices); 1243 1244 1257 protected abstract void doShowItem(Item item); 1258 1259 1264 protected abstract void doDeselectAll(); 1265 1266 1283 protected abstract void doSetSelection(Item[] items); 1284 1285 1292 protected abstract void doShowSelection(); 1293 1294 1311 protected abstract void doSetSelection(int[] indices); 1312 1313 1331 protected abstract void doClear(int index); 1332 1333 1334 1335 1351 protected abstract void doSelect(int[] indices); 1352 1353} 1354 | Popular Tags |