1 11 package org.eclipse.jface.action; 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.ListIterator ; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.jface.util.Policy; 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.widgets.Composite; 23 import org.eclipse.swt.widgets.Control; 24 import org.eclipse.swt.widgets.CoolBar; 25 import org.eclipse.swt.widgets.CoolItem; 26 import org.eclipse.swt.widgets.Menu; 27 28 37 public class CoolBarManager extends ContributionManager implements 38 ICoolBarManager { 39 40 43 public final static String USER_SEPARATOR = "UserSeparator"; 45 48 private ArrayList cbItemsCreationOrder = new ArrayList (); 49 50 53 private MenuManager contextMenuManager = null; 54 55 59 private CoolBar coolBar = null; 60 61 64 private int itemStyle = SWT.NONE; 65 66 70 public CoolBarManager() { 71 } 73 74 82 public CoolBarManager(CoolBar coolBar) { 83 this(); 84 Assert.isNotNull(coolBar); 85 this.coolBar = coolBar; 86 itemStyle = coolBar.getStyle(); 87 } 88 89 98 public CoolBarManager(int style) { 99 itemStyle = style; 100 } 101 102 107 public void add(IToolBarManager toolBarManager) { 108 Assert.isNotNull(toolBarManager); 109 super.add(new ToolBarContributionItem(toolBarManager)); 110 } 111 112 122 private ArrayList adjustContributionList(ArrayList contributionList) { 123 IContributionItem item; 124 if (contributionList.size() != 0) { 126 item = (IContributionItem) contributionList.get(0); 127 if (item.isSeparator()) { 128 contributionList.remove(0); 129 } 130 131 ListIterator iterator = contributionList.listIterator(); 132 while (iterator.hasNext()) { 134 item = (IContributionItem) iterator.next(); 135 if (item.isSeparator()) { 136 while (iterator.hasNext()) { 137 item = (IContributionItem) iterator.next(); 138 if (item.isSeparator()) { 139 iterator.remove(); 140 } else { 141 break; 142 } 143 } 144 145 } 146 } 147 item = (IContributionItem) contributionList.get(contributionList 149 .size() - 1); 150 if (item.isSeparator()) { 151 contributionList.remove(contributionList.size() - 1); 152 } 153 } 154 return contributionList; 155 156 } 157 158 161 protected boolean allowItem(IContributionItem itemToAdd) { 162 165 if (itemToAdd == null) { 166 return true; 167 } 168 169 171 String firstId = itemToAdd.getId(); 172 if (firstId == null) { 173 return true; 174 } 175 176 IContributionItem[] currentItems = getItems(); 178 for (int i = 0; i < currentItems.length; i++) { 179 IContributionItem currentItem = currentItems[i]; 180 181 if (currentItem == null) { 183 continue; 184 } 185 186 String secondId = currentItem.getId(); 187 if (firstId.equals(secondId)) { 188 if (Policy.TRACE_TOOLBAR) { 189 System.out.println("Trying to add a duplicate item."); new Exception ().printStackTrace(System.out); 191 System.out.println("DONE --------------------------"); } 193 return false; 194 } 195 } 196 197 return true; 198 } 199 200 208 private void collapseSeparators(ListIterator iterator) { 209 210 while (iterator.hasNext()) { 211 IContributionItem item = (IContributionItem) iterator.next(); 212 if (!item.isSeparator()) { 213 iterator.previous(); 214 return; 215 } 216 } 217 } 218 219 226 private boolean coolBarExist() { 227 return coolBar != null && !coolBar.isDisposed(); 228 } 229 230 238 public CoolBar createControl(Composite parent) { 239 Assert.isNotNull(parent); 240 if (!coolBarExist()) { 241 coolBar = new CoolBar(parent, itemStyle); 242 coolBar.setMenu(getContextMenuControl()); 243 coolBar.setLocked(false); 244 update(false); 245 } 246 return coolBar; 247 } 248 249 256 public void dispose() { 257 if (coolBarExist()) { 258 IContributionItem[] items = getItems(); 259 for (int i = 0; i < items.length; i++) { 260 items[i].dispose(); 265 } 266 coolBar.dispose(); 267 coolBar = null; 268 } 269 if (contextMenuManager != null) { 271 contextMenuManager.dispose(); 272 contextMenuManager = null; 273 } 274 275 } 276 277 283 private void dispose(CoolItem item) { 284 if ((item != null) && !item.isDisposed()) { 285 286 item.setData(null); 287 Control control = item.getControl(); 288 if ((control != null) && !control.isDisposed()) { 292 item.setControl(null); 293 } 294 item.dispose(); 295 } 296 } 297 298 305 private CoolItem findCoolItem(IContributionItem item) { 306 CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems(); 307 return findCoolItem(coolItems, item); 308 } 309 310 private CoolItem findCoolItem(CoolItem[] items, IContributionItem item) { 311 if (items == null) { 312 return null; 313 } 314 315 for (int i = 0; i < items.length; i++) { 316 CoolItem coolItem = items[i]; 317 IContributionItem data = (IContributionItem) coolItem.getData(); 318 if (data != null && data.equals(item)) { 319 return coolItem; 320 } 321 } 322 return null; 323 } 324 325 335 private int[] getAdjustedWrapIndices(int[] wraps) { 336 int[] adjustedWrapIndices; 337 if (wraps.length == 0) { 338 adjustedWrapIndices = new int[] { 0 }; 339 } else { 340 if (wraps[0] != 0) { 341 adjustedWrapIndices = new int[wraps.length + 1]; 342 adjustedWrapIndices[0] = 0; 343 for (int i = 0; i < wraps.length; i++) { 344 adjustedWrapIndices[i + 1] = wraps[i]; 345 } 346 } else { 347 adjustedWrapIndices = wraps; 348 } 349 } 350 return adjustedWrapIndices; 351 } 352 353 359 private Menu getContextMenuControl() { 360 if ((contextMenuManager != null) && (coolBar != null)) { 361 Menu menuWidget = contextMenuManager.getMenu(); 362 if ((menuWidget == null) || (menuWidget.isDisposed())) { 363 menuWidget = contextMenuManager.createContextMenu(coolBar); 364 } 365 return menuWidget; 366 } 367 return null; 368 } 369 370 375 public IMenuManager getContextMenuManager() { 376 return contextMenuManager; 377 } 378 379 384 public CoolBar getControl() { 385 return coolBar; 386 } 387 388 393 private ArrayList getItemList() { 394 IContributionItem[] cbItems = getItems(); 395 ArrayList list = new ArrayList (cbItems.length); 396 for (int i = 0; i < cbItems.length; i++) { 397 list.add(cbItems[i]); 398 } 399 return list; 400 } 401 402 407 public boolean getLockLayout() { 408 if (!coolBarExist()) { 409 return false; 410 } 411 return coolBar.getLocked(); 412 } 413 414 421 private int getNumRows(IContributionItem[] items) { 422 int numRows = 1; 423 boolean separatorFound = false; 424 for (int i = 0; i < items.length; i++) { 425 if (items[i].isSeparator()) { 426 separatorFound = true; 427 } 428 if ((separatorFound) && (items[i].isVisible()) 429 && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) { 430 numRows++; 431 separatorFound = false; 432 } 433 } 434 return numRows; 435 } 436 437 442 public int getStyle() { 443 return itemStyle; 444 } 445 446 452 protected void itemAdded(IContributionItem item) { 453 Assert.isNotNull(item); 454 super.itemAdded(item); 455 int insertedAt = indexOf(item); 456 boolean replaced = false; 457 final int size = cbItemsCreationOrder.size(); 458 for (int i = 0; i < size; i++) { 459 IContributionItem created = (IContributionItem) cbItemsCreationOrder 460 .get(i); 461 if (created.getId() != null && created.getId().equals(item.getId())) { 462 cbItemsCreationOrder.set(i, item); 463 replaced = true; 464 break; 465 } 466 } 467 468 if (!replaced) { 469 cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0), 470 cbItemsCreationOrder.size()), item); 471 } 472 } 473 474 480 protected void itemRemoved(IContributionItem item) { 481 Assert.isNotNull(item); 482 super.itemRemoved(item); 483 CoolItem coolItem = findCoolItem(item); 484 if (coolItem != null) { 485 coolItem.setData(null); 486 } 487 } 488 489 500 private void nextRow(ListIterator iterator, boolean ignoreCurrentItem) { 501 502 IContributionItem currentElement = null; 503 if (!ignoreCurrentItem && iterator.hasPrevious()) { 504 currentElement = (IContributionItem) iterator.previous(); 505 iterator.next(); 506 } 507 508 if ((currentElement != null) && (currentElement.isSeparator())) { 509 collapseSeparators(iterator); 510 return; 511 } 512 513 while (iterator.hasNext()) { 515 IContributionItem item = (IContributionItem) iterator.next(); 516 if (item.isSeparator()) { 517 collapseSeparators(iterator); 521 return; 522 } 523 } 524 } 525 526 529 555 public void refresh() { 556 if (!coolBarExist()) { 557 return; 558 } 559 560 ArrayList contributionList = getItemList(); 562 563 if (contributionList.size() == 0) { 565 return; 566 } 567 568 CoolItem[] coolItems = coolBar.getItems(); 570 int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices()); 572 573 int row = 0; 574 int coolItemIndex = 0; 575 576 ArrayList displayedItems = new ArrayList (coolBar.getItemCount()); 580 for (int i = 0; i < coolItems.length; i++) { 581 CoolItem coolItem = coolItems[i]; 582 if (coolItem.getData() instanceof IContributionItem) { 583 IContributionItem cbItem = (IContributionItem) coolItem 584 .getData(); 585 displayedItems.add(Math.min(i, displayedItems.size()), cbItem); 586 } 587 } 588 589 int offset = 0; 591 for (int i = 1; i < wrapIndicies.length; i++) { 592 int insertAt = wrapIndicies[i] + offset; 593 displayedItems.add(insertAt, new Separator(USER_SEPARATOR)); 594 offset++; 595 } 596 597 ArrayList existingVisibleRows = new ArrayList (4); 599 ListIterator rowIterator = contributionList.listIterator(); 600 collapseSeparators(rowIterator); 601 int numRow = 0; 602 while (rowIterator.hasNext()) { 603 while (rowIterator.hasNext()) { 605 IContributionItem cbItem = (IContributionItem) rowIterator 606 .next(); 607 if (displayedItems.contains(cbItem)) { 608 existingVisibleRows.add(new Integer (numRow)); 609 break; 610 } 611 if (cbItem.isSeparator()) { 612 break; 613 } 614 } 615 nextRow(rowIterator, false); 616 numRow++; 617 } 618 619 Iterator existingRows = existingVisibleRows.iterator(); 620 if (existingRows.hasNext()) { 622 row = ((Integer ) existingRows.next()).intValue(); 623 } 624 625 HashMap itemLocation = new HashMap (); 626 for (ListIterator locationIterator = displayedItems.listIterator(); locationIterator 627 .hasNext();) { 628 IContributionItem item = (IContributionItem) locationIterator 629 .next(); 630 if (item.isSeparator()) { 631 if (existingRows.hasNext()) { 632 Integer value = (Integer ) existingRows.next(); 633 row = value.intValue(); 634 } else { 635 row++; 636 } 637 } else { 638 itemLocation.put(item, new Integer (row)); 639 } 640 641 } 642 643 for (ListIterator iterator = displayedItems.listIterator(); iterator 645 .hasNext();) { 646 IContributionItem cbItem = (IContributionItem) iterator.next(); 647 if (cbItem.isSeparator()) { 648 coolItemIndex = 0; 649 } else { 650 relocate(cbItem, coolItemIndex, contributionList, itemLocation); 651 cbItem.saveWidgetState(); 652 coolItemIndex++; 653 } 654 } 655 656 if (contributionList.size() != 0) { 657 contributionList = adjustContributionList(contributionList); 658 IContributionItem[] array = new IContributionItem[contributionList 659 .size() - 1]; 660 array = (IContributionItem[]) contributionList.toArray(array); 661 internalSetItems(array); 662 } 663 664 } 665 666 677 private void relocate(IContributionItem cbItem, int index, 678 ArrayList contributionList, HashMap itemLocation) { 679 680 if (!(itemLocation.get(cbItem) instanceof Integer )) { 681 return; 682 } 683 int targetRow = ((Integer ) itemLocation.get(cbItem)).intValue(); 684 685 int cbInternalIndex = contributionList.indexOf(cbItem); 686 687 int insertAt = contributionList.size(); 689 ListIterator iterator = contributionList.listIterator(); 691 collapseSeparators(iterator); 693 int currentRow = -1; 694 while (iterator.hasNext()) { 695 696 currentRow++; 697 if (currentRow == targetRow) { 698 int virtualIndex = 0; 700 insertAt = iterator.nextIndex(); 701 while (iterator.hasNext()) { 704 IContributionItem item = (IContributionItem) iterator 705 .next(); 706 Integer itemRow = (Integer ) itemLocation.get(item); 707 if (item.isSeparator()) { 708 break; 709 } 710 if ((itemRow != null) && (itemRow.intValue() == targetRow)) { 712 if (virtualIndex >= index) { 715 break; 716 } 717 virtualIndex++; 718 719 } 720 insertAt++; 721 } 722 if (cbInternalIndex == insertAt) { 724 return; 725 } 726 break; 727 } 728 nextRow(iterator, true); 729 } 730 contributionList.remove(cbItem); 731 732 if (cbInternalIndex < insertAt) { 734 insertAt--; 735 } 736 737 if (currentRow != targetRow) { 739 contributionList.add(new Separator(USER_SEPARATOR)); 740 insertAt = contributionList.size(); 741 } 742 insertAt = Math.min(insertAt, contributionList.size()); 743 contributionList.add(insertAt, cbItem); 744 745 } 746 747 751 public void resetItemOrder() { 752 for (ListIterator iterator = cbItemsCreationOrder.listIterator(); iterator 753 .hasNext();) { 754 IContributionItem item = (IContributionItem) iterator.next(); 755 if ((item.getId() != null) && (item.getId().equals(USER_SEPARATOR))) { 757 iterator.remove(); 758 } 759 } 760 IContributionItem[] itemsToSet = new IContributionItem[cbItemsCreationOrder 761 .size()]; 762 cbItemsCreationOrder.toArray(itemsToSet); 763 setItems(itemsToSet); 764 } 765 766 771 public void setContextMenuManager(IMenuManager contextMenuManager) { 772 this.contextMenuManager = (MenuManager) contextMenuManager; 773 if (coolBar != null) { 774 coolBar.setMenu(getContextMenuControl()); 775 } 776 } 777 778 784 public void setItems(IContributionItem[] newItems) { 785 if (coolBar != null) { 787 CoolItem[] coolItems = coolBar.getItems(); 788 for (int i = 0; i < coolItems.length; i++) { 789 dispose(coolItems[i]); 790 } 791 } 792 internalSetItems(newItems); 794 update(true); 796 } 797 798 803 public void setLockLayout(boolean value) { 804 if (!coolBarExist()) { 805 return; 806 } 807 coolBar.setLocked(value); 808 } 809 810 816 public void update(boolean force) { 817 if ((!isDirty() && !force) || (!coolBarExist())) { 818 return; 819 } 820 821 boolean relock = false; 822 boolean changed = false; 823 824 try { 825 coolBar.setRedraw(false); 826 827 refresh(); 829 830 if (coolBar.getLocked()) { 831 coolBar.setLocked(false); 832 relock = true; 833 } 834 835 840 final IContributionItem[] items = getItems(); 841 final List visibleItems = new ArrayList (items.length); 842 for (int i = 0; i < items.length; i++) { 843 final IContributionItem item = items[i]; 844 if (item.isVisible()) { 845 visibleItems.add(item); 846 } 847 } 848 849 854 CoolItem[] coolItems = coolBar.getItems(); 855 final ArrayList coolItemsToRemove = new ArrayList (coolItems.length); 856 for (int i = 0; i < coolItems.length; i++) { 857 final Object data = coolItems[i].getData(); 858 if ((data == null) 859 || (!visibleItems.contains(data)) 860 || ((data instanceof IContributionItem) && ((IContributionItem) data) 861 .isDynamic())) { 862 coolItemsToRemove.add(coolItems[i]); 863 } 864 } 865 866 for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) { 868 CoolItem coolItem = (CoolItem) coolItemsToRemove.get(i); 869 if (!coolItem.isDisposed()) { 870 Control control = coolItem.getControl(); 871 if (control != null) { 872 coolItem.setControl(null); 873 control.dispose(); 874 } 875 coolItem.dispose(); 876 } 877 } 878 879 coolItems = coolBar.getItems(); 881 IContributionItem sourceItem; 882 IContributionItem destinationItem; 883 int sourceIndex = 0; 884 int destinationIndex = 0; 885 final Iterator visibleItemItr = visibleItems.iterator(); 886 while (visibleItemItr.hasNext()) { 887 sourceItem = (IContributionItem) visibleItemItr.next(); 888 889 if (sourceIndex < coolItems.length) { 892 destinationItem = (IContributionItem) coolItems[sourceIndex] 893 .getData(); 894 } else { 895 destinationItem = null; 896 } 897 898 if (destinationItem != null) { 900 if (sourceItem.equals(destinationItem)) { 901 sourceIndex++; 902 destinationIndex++; 903 sourceItem.update(); 904 continue; 905 906 } else if ((destinationItem.isSeparator()) 907 && (sourceItem.isSeparator())) { 908 coolItems[sourceIndex].setData(sourceItem); 909 sourceIndex++; 910 destinationIndex++; 911 sourceItem.update(); 912 continue; 913 914 } 915 } 916 917 final int start = coolBar.getItemCount(); 919 sourceItem.fill(coolBar, destinationIndex); 920 final int newItems = coolBar.getItemCount() - start; 921 for (int i = 0; i < newItems; i++) { 922 coolBar.getItem(destinationIndex++).setData(sourceItem); 923 } 924 changed = true; 925 } 926 927 for (int i = coolItems.length - 1; i >= sourceIndex; i--) { 929 final CoolItem item = coolItems[i]; 930 if (!item.isDisposed()) { 931 Control control = item.getControl(); 932 if (control != null) { 933 item.setControl(null); 934 control.dispose(); 935 } 936 item.dispose(); 937 changed = true; 938 } 939 } 940 941 updateWrapIndices(); 943 944 for (int i = 0; i < items.length; i++) { 946 IContributionItem item = items[i]; 947 item.update(SIZE); 948 } 949 950 if (relock) { 952 coolBar.setLocked(true); 953 } 954 955 if (changed) { 956 updateTabOrder(); 957 } 958 959 setDirty(false); 961 } finally { 962 coolBar.setRedraw(true); 963 } 964 } 965 966 969 void updateTabOrder() { 970 if (coolBar != null) { 971 CoolItem[] items = coolBar.getItems(); 972 if (items != null) { 973 ArrayList children = new ArrayList (items.length); 974 for (int i = 0; i < items.length; i++) { 975 if ((items[i].getControl() != null) 976 && (!items[i].getControl().isDisposed())) { 977 children.add(items[i].getControl()); 978 } 979 } 980 Control[] childrenArray = new Control[0]; 982 childrenArray = (Control[]) children.toArray(childrenArray); 983 984 if (childrenArray != null) { 985 coolBar.setTabList(childrenArray); 986 } 987 988 } 989 } 990 } 991 992 995 private void updateWrapIndices() { 996 final IContributionItem[] items = getItems(); 997 final int numRows = getNumRows(items) - 1; 998 999 final int[] wrapIndices = new int[numRows]; 1001 boolean foundSeparator = false; 1002 int j = 0; 1003 CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems(); 1004 1005 for (int i = 0; i < items.length; i++) { 1006 IContributionItem item = items[i]; 1007 CoolItem coolItem = findCoolItem(coolItems, item); 1008 if (item.isSeparator()) { 1009 foundSeparator = true; 1010 } 1011 if ((!item.isSeparator()) && (!item.isGroupMarker()) 1012 && (item.isVisible()) && (coolItem != null) 1013 && (foundSeparator)) { 1014 wrapIndices[j] = coolBar.indexOf(coolItem); 1015 j++; 1016 foundSeparator = false; 1017 } 1018 } 1019 1020 1024 final int[] oldIndices = coolBar.getWrapIndices(); 1025 boolean shouldUpdate = false; 1026 if (oldIndices.length == wrapIndices.length) { 1027 for (int i = 0; i < oldIndices.length; i++) { 1028 if (oldIndices[i] != wrapIndices[i]) { 1029 shouldUpdate = true; 1030 break; 1031 } 1032 } 1033 } else { 1034 shouldUpdate = true; 1035 } 1036 1037 if (shouldUpdate) { 1038 coolBar.setWrapIndices(wrapIndices); 1039 } 1040 } 1041} 1042 | Popular Tags |