blob: fd26e40455c78a3502dc83f74834582cb0224919 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.util.Policy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Menu;
/**
* A cool bar manager is a contribution manager which realizes itself and its
* items in a cool bar control.
* <p>
* This class may be instantiated; it may also be subclassed.
* </p>
*
* @since 3.0
*/
public class CoolBarManager extends ContributionManager implements
ICoolBarManager {
/**
* A separator created by the end user.
*/
public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$
/**
* The original creation order of the contribution items.
*/
private ArrayList cbItemsCreationOrder = new ArrayList();
/**
* MenuManager for cool bar pop-up menu, or null if none.
*/
private MenuManager contextMenuManager = null;
/**
* The cool bar control; <code>null</code> before creation and after
* disposal.
*/
private CoolBar coolBar = null;
/**
* The cool bar items style; <code>SWT.NONE</code> by default.
*/
private int itemStyle = SWT.NONE;
/**
* Creates a new cool bar manager with the default style. Equivalent to
* <code>CoolBarManager(SWT.NONE)</code>.
*/
public CoolBarManager() {
// do nothing
}
/**
* Creates a cool bar manager for an existing cool bar control. This
* manager becomes responsible for the control, and will dispose of it when
* the manager is disposed.
*
* @param coolBar
* the cool bar control
*/
public CoolBarManager(CoolBar coolBar) {
this();
Assert.isNotNull(coolBar);
this.coolBar = coolBar;
itemStyle = coolBar.getStyle();
}
/**
* Creates a cool bar manager with the given SWT style. Calling <code>createControl</code>
* will create the cool bar control.
*
* @param style
* the cool bar item style; see
* {@link org.eclipse.swt.widgets.CoolBar CoolBar}for for valid
* style bits
*/
public CoolBarManager(int style) {
itemStyle = style;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#add(org.eclipse.jface.action.IToolBarManager)
*/
public void add(IToolBarManager toolBarManager) {
Assert.isNotNull(toolBarManager);
super.add(new ToolBarContributionItem(toolBarManager));
}
/**
* Collapses consecutive separators and removes a separator from the
* beginning and end of the list.
*
* @param contributionList
* the list of contributions; must not be <code>null</code>.
* @return The contribution list provided with extraneous separators
* removed; this value is never <code>null</code>, but may be
* empty.
*/
private ArrayList adjustContributionList(ArrayList contributionList) {
IContributionItem item;
// Fist remove a separator if it is the first element of the list
if (contributionList.size() != 0) {
item = (IContributionItem) contributionList.get(0);
if (item.isSeparator()) {
contributionList.remove(0);
}
ListIterator iterator = contributionList.listIterator();
// collapse consecutive separators
while (iterator.hasNext()) {
item = (IContributionItem) iterator.next();
if (item.isSeparator()) {
while (iterator.hasNext()) {
item = (IContributionItem) iterator.next();
if (item.isSeparator()) {
iterator.remove();
} else {
break;
}
}
}
}
// Now check last element to see if there is a separator
item = (IContributionItem) contributionList.get(contributionList
.size() - 1);
if (item.isSeparator()) {
contributionList.remove(contributionList.size() - 1);
}
}
return contributionList;
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.ContributionManager#checkDuplication(org.eclipse.jface.action.IContributionItem)
*/
protected boolean allowItem(IContributionItem itemToAdd) {
/* We will allow as many null entries as they like, though there should
* be none.
*/
if (itemToAdd == null) {
return true;
}
/* Null identifiers can be expected in generic contribution items.
*/
String firstId = itemToAdd.getId();
if (firstId == null) {
return true;
}
// Cycle through the current list looking for duplicates.
IContributionItem[] currentItems = getItems();
for (int i = 0; i < currentItems.length; i++) {
IContributionItem currentItem = currentItems[i];
// We ignore null entries.
if (currentItem == null) {
continue;
}
String secondId = currentItem.getId();
if (firstId.equals(secondId)) {
if (Policy.TRACE_TOOLBAR) {
System.out.println("Trying to add a duplicate item."); //$NON-NLS-1$
new Exception().printStackTrace(System.out);
System.out.println("DONE --------------------------"); //$NON-NLS-1$
}
return false;
}
}
return true;
}
/**
* Positions the list iterator to the end of all the separators. Calling
* <code>next()</code> the iterator should return the immediate object
* following the last separator.
*
* @param iterator
* the list iterator.
*/
private void collapseSeparators(ListIterator iterator) {
while (iterator.hasNext()) {
IContributionItem item = (IContributionItem) iterator.next();
if (!item.isSeparator()) {
iterator.previous();
return;
}
}
}
/**
* Returns whether the cool bar control has been created and not yet
* disposed.
*
* @return <code>true</code> if the control has been created and not yet
* disposed, <code>false</code> otherwise
*/
private boolean coolBarExist() {
return coolBar != null && !coolBar.isDisposed();
}
/**
* Creates and returns this manager's cool bar control. Does not create a
* new control if one already exists.
*
* @param parent
* the parent control
* @return the cool bar control
*/
public CoolBar createControl(Composite parent) {
Assert.isNotNull(parent);
if (!coolBarExist()) {
coolBar = new CoolBar(parent, itemStyle);
coolBar.setMenu(getContextMenuControl());
coolBar.setLocked(false);
update(false);
}
return coolBar;
}
/**
* Disposes of this cool bar manager and frees all allocated SWT resources.
* Notifies all contribution items of the dispose. Note that this method
* does not clean up references between this cool bar manager and its
* associated contribution items. Use <code>removeAll</code> for that
* purpose.
*/
public void dispose() {
if (coolBarExist()) {
IContributionItem[] items = getItems();
for (int i = 0; i < items.length; i++) {
// Disposes of the contribution item.
// If Contribution Item is a toolbar then it will dispose of
// all the nested
// contribution items.
items[i].dispose();
}
coolBar.dispose();
coolBar = null;
}
// If a context menu existed then dispose of it.
if (contextMenuManager != null) {
contextMenuManager.dispose();
contextMenuManager = null;
}
}
/**
* Disposes the given cool item.
*
* @param item
* the cool item to dispose
*/
private void dispose(CoolItem item) {
if ((item != null) && !item.isDisposed()) {
item.setData(null);
Control control = item.getControl();
// if the control is already disposed, setting the coolitem
// control to null will cause an SWT exception, workaround
// for 19630
if ((control != null) && !control.isDisposed()) {
item.setControl(null);
}
item.dispose();
}
}
/**
* Finds the cool item associated with the given contribution item.
*
* @param item
* the contribution item
* @return the associated cool item, or <code>null</code> if not found
*/
private CoolItem findCoolItem(IContributionItem item) {
CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems();
return findCoolItem(coolItems, item);
}
private CoolItem findCoolItem(CoolItem[] items, IContributionItem item) {
if (items == null)
return null;
for (int i = 0; i < items.length; i++) {
CoolItem coolItem = items[i];
IContributionItem data = (IContributionItem) coolItem.getData();
if (data != null && data.equals(item))
return coolItem;
}
return null;
}
/**
* Return a consistent set of wrap indices. The return value will always
* include at least one entry and the first entry will always be zero.
* CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
* index for the first row.
*
* @param wraps
* the wrap indicies from the cool bar widget
* @return the adjusted wrap indicies.
*/
private int[] getAdjustedWrapIndices(int[] wraps) {
int[] adjustedWrapIndices;
if (wraps.length == 0) {
adjustedWrapIndices = new int[] { 0 };
} else {
if (wraps[0] != 0) {
adjustedWrapIndices = new int[wraps.length + 1];
adjustedWrapIndices[0] = 0;
for (int i = 0; i < wraps.length; i++) {
adjustedWrapIndices[i + 1] = wraps[i];
}
} else {
adjustedWrapIndices = wraps;
}
}
return adjustedWrapIndices;
}
/**
* Returns the control of the Menu Manager. If the menu manager does not
* have a control then one is created.
*
* @return menu control associated with manager, or null if none
*/
private Menu getContextMenuControl() {
if ((contextMenuManager != null) && (coolBar != null)) {
Menu menuWidget = contextMenuManager.getMenu();
if ((menuWidget == null) || (menuWidget.isDisposed())) {
menuWidget = contextMenuManager.createContextMenu(coolBar);
}
return menuWidget;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
*/
public IMenuManager getContextMenuManager() {
return contextMenuManager;
}
/**
* Returns the cool bar control for this manager.
*
* @return the cool bar control, or <code>null</code> if none
*/
public CoolBar getControl() {
return coolBar;
}
/**
* Returns an array list of all the contribution items in the manager.
*
* @return an array list of contribution items.
*/
private ArrayList getItemList() {
IContributionItem[] cbItems = getItems();
ArrayList list = new ArrayList(cbItems.length);
for (int i = 0; i < cbItems.length; i++) {
list.add(cbItems[i]);
}
return list;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
*/
public boolean getLockLayout() {
if (!coolBarExist()) {
return false;
}
return coolBar.getLocked();
}
/**
* Returns the number of rows that should be displayed visually.
*
* @param items
* the array of contributin items
* @return the number of rows
*/
private int getNumRows(IContributionItem[] items) {
int numRows = 1;
boolean separatorFound = false;
for (int i = 0; i < items.length; i++) {
if (items[i].isSeparator()) {
separatorFound = true;
}
if ((separatorFound) && (items[i].isVisible())
&& (!items[i].isGroupMarker()) && (!items[i].isSeparator())) {
numRows++;
separatorFound = false;
}
}
return numRows;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#getStyle()
*/
public int getStyle() {
return itemStyle;
}
/**
* Subclasses may extend this <code>ContributionManager</code> method,
* but must call <code>super.itemAdded</code>.
*
* @see org.eclipse.jface.action.ContributionManager#itemAdded(org.eclipse.jface.action.IContributionItem)
*/
protected void itemAdded(IContributionItem item) {
Assert.isNotNull(item);
super.itemAdded(item);
int insertedAt = indexOf(item);
boolean replaced = false;
final int size = cbItemsCreationOrder.size();
for (int i = 0; i < size; i++) {
IContributionItem created = (IContributionItem) cbItemsCreationOrder
.get(i);
if (created.getId() != null && created.getId().equals(item.getId())) {
cbItemsCreationOrder.set(i, item);
replaced = true;
break;
}
}
if (!replaced) {
cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0),
cbItemsCreationOrder.size()), item);
}
}
/**
* Subclasses may extend this <code>ContributionManager</code> method,
* but must call <code>super.itemRemoved</code>.
*
* @see org.eclipse.jface.action.ContributionManager#itemRemoved(org.eclipse.jface.action.IContributionItem)
*/
protected void itemRemoved(IContributionItem item) {
Assert.isNotNull(item);
super.itemRemoved(item);
CoolItem coolItem = findCoolItem(item);
if (coolItem != null) {
coolItem.setData(null);
}
}
/**
* Positions the list iterator to the starting of the next row. By calling
* next on the returned iterator, it will return the first element of the
* next row.
*
* @param iterator
* the list iterator of contribution items
* @param ignoreCurrentItem
* Whether the current item in the iterator should be considered
* (as well as subsequent items).
*/
private void nextRow(ListIterator iterator, boolean ignoreCurrentItem) {
IContributionItem currentElement = null;
if (!ignoreCurrentItem && iterator.hasPrevious()) {
currentElement = (IContributionItem) iterator.previous();
iterator.next();
}
if ((currentElement != null) && (currentElement.isSeparator())) {
collapseSeparators(iterator);
return;
}
//Find next separator
while (iterator.hasNext()) {
IContributionItem item = (IContributionItem) iterator.next();
if (item.isSeparator()) {
// we we find a separator, collapse any consecutive
// separators
// and return
collapseSeparators(iterator);
return;
}
}
}
/*
* Used for debuging. Prints all the items in the internal structures.
*/
// private void printContributions(ArrayList contributionList) {
// int index = 0;
// System.out.println("----------------------------------\n"); //$NON-NLS-1$
// for (Iterator i = contributionList.iterator(); i.hasNext(); index++) {
// IContributionItem item = (IContributionItem) i.next();
// if (item.isSeparator()) {
// System.out.println("Separator"); //$NON-NLS-1$
// } else {
// System.out.println(index + ". Item id: " + item.getId() //$NON-NLS-1$
// + " - is Visible: " //$NON-NLS-1$
// + item.isVisible());
// }
// }
// }
/**
* Synchronizes the visual order of the cool items in the control with this
* manager's internal data structures. This method should be called before
* requesting the order of the contribution items to ensure that the order
* is accurate.
* <p>
* Note that <code>update()</code> and <code>refresh()</code> are
* converses: <code>update()</code> changes the visual order to match the
* internal structures, and <code>refresh</code> changes the internal
* structures to match the visual order.
* </p>
*/
public void refresh() {
if (!coolBarExist()) {
return;
}
// Retreives the list of contribution items as an array list
ArrayList contributionList = getItemList();
// Check the size of the list
if (contributionList.size() == 0)
return;
// The list of all the cool items in their visual order
CoolItem[] coolItems = coolBar.getItems();
// The wrap indicies of the coolbar
int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
int row = 0;
int coolItemIndex = 0;
// Traverse through all cool items in the coolbar add them to a new
// data structure
// in the correct order
ArrayList displayedItems = new ArrayList(coolBar.getItemCount());
for (int i = 0; i < coolItems.length; i++) {
CoolItem coolItem = coolItems[i];
if (coolItem.getData() instanceof IContributionItem) {
IContributionItem cbItem = (IContributionItem) coolItem
.getData();
displayedItems.add(Math.min(i, displayedItems.size()), cbItem);
}
}
// Add separators to the displayed Items data structure
int offset = 0;
for (int i = 1; i < wrapIndicies.length; i++) {
int insertAt = wrapIndicies[i] + offset;
displayedItems.add(insertAt, new Separator(USER_SEPARATOR));
offset++;
}
// Determine which rows are invisible
ArrayList existingVisibleRows = new ArrayList(4);
ListIterator rowIterator = contributionList.listIterator();
collapseSeparators(rowIterator);
int numRow = 0;
while (rowIterator.hasNext()) {
// Scan row
while (rowIterator.hasNext()) {
IContributionItem cbItem = (IContributionItem) rowIterator
.next();
if (displayedItems.contains(cbItem)) {
existingVisibleRows.add(new Integer(numRow));
break;
}
if (cbItem.isSeparator()) {
break;
}
}
nextRow(rowIterator, false);
numRow++;
}
Iterator existingRows = existingVisibleRows.iterator();
// Adjust row number to the first visible
if (existingRows.hasNext()) {
row = ((Integer) existingRows.next()).intValue();
}
HashMap itemLocation = new HashMap();
for (ListIterator locationIterator = displayedItems.listIterator(); locationIterator
.hasNext();) {
IContributionItem item = (IContributionItem) locationIterator
.next();
if (item.isSeparator()) {
if (existingRows.hasNext()) {
Integer value = (Integer) existingRows.next();
row = value.intValue();
} else {
row++;
}
} else {
itemLocation.put(item, new Integer(row));
}
}
// Insert the contribution items in their correct location
for (ListIterator iterator = displayedItems.listIterator(); iterator
.hasNext();) {
IContributionItem cbItem = (IContributionItem) iterator.next();
if (cbItem.isSeparator()) {
coolItemIndex = 0;
} else {
relocate(cbItem, coolItemIndex, contributionList, itemLocation);
cbItem.saveWidgetState();
coolItemIndex++;
}
}
if (contributionList.size() != 0) {
contributionList = adjustContributionList(contributionList);
IContributionItem[] array = new IContributionItem[contributionList
.size() - 1];
array = (IContributionItem[]) contributionList.toArray(array);
internalSetItems(array);
}
}
/**
* Relocates the given contribution item to the specified index.
*
* @param cbItem
* the conribution item to relocate
* @param index
* the index to locate this item
* @param contributionList
* the current list of conrtributions
* @param itemLocation
*/
private void relocate(IContributionItem cbItem, int index,
ArrayList contributionList, HashMap itemLocation) {
if (!(itemLocation.get(cbItem) instanceof Integer))
return;
int targetRow = ((Integer) itemLocation.get(cbItem)).intValue();
int cbInternalIndex = contributionList.indexOf(cbItem);
// by default add to end of list
int insertAt = contributionList.size();
// Find the row to place this item in.
ListIterator iterator = contributionList.listIterator();
// bypass any separators at the begining
collapseSeparators(iterator);
int currentRow = -1;
while (iterator.hasNext()) {
currentRow++;
if (currentRow == targetRow) {
// We found the row to insert the item
int virtualIndex = 0;
insertAt = iterator.nextIndex();
// first check the position of the current element (item)
// then get the next element
while (iterator.hasNext()) {
IContributionItem item = (IContributionItem) iterator
.next();
Integer itemRow = (Integer) itemLocation.get(item);
if (item.isSeparator())
break;
// if the item has an associate widget
if ((itemRow != null) && (itemRow.intValue() == targetRow)) {
// if the next element is the index we are looking for
// then break
if (virtualIndex >= index)
break;
virtualIndex++;
}
insertAt++;
}
// If we don't need to move it then we return
if (cbInternalIndex == insertAt)
return;
break;
}
nextRow(iterator, true);
}
contributionList.remove(cbItem);
// Adjust insertAt index
if (cbInternalIndex < insertAt) {
insertAt--;
}
// if we didn't find the row then add a new row
if (currentRow != targetRow) {
contributionList.add(new Separator(USER_SEPARATOR));
insertAt = contributionList.size();
}
insertAt = Math.min(insertAt, contributionList.size());
contributionList.add(insertAt, cbItem);
}
/**
* Restores the canonical order of this cool bar manager. The canonical
* order is the order in which the contribution items where added.
*/
public void resetItemOrder() {
for (ListIterator iterator = cbItemsCreationOrder.listIterator(); iterator
.hasNext();) {
IContributionItem item = (IContributionItem) iterator.next();
// if its a user separator then do not include in original order.
if ((item.getId() != null) && (item.getId().equals(USER_SEPARATOR))) {
iterator.remove();
}
}
IContributionItem[] itemsToSet = new IContributionItem[cbItemsCreationOrder
.size()];
cbItemsCreationOrder.toArray(itemsToSet);
setItems(itemsToSet);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#setContextMenuManager(org.eclipse.jface.action.IMenuManager)
*/
public void setContextMenuManager(IMenuManager contextMenuManager) {
this.contextMenuManager = (MenuManager) contextMenuManager;
if (coolBar != null) {
coolBar.setMenu(getContextMenuControl());
}
}
/**
* Replaces the current items with the given items.
* Forces an update.
*
* @param newItems the items with which to replace the current items
*/
public void setItems(IContributionItem[] newItems) {
// dispose of all the cool items on the cool bar manager
if (coolBar != null) {
CoolItem[] coolItems = coolBar.getItems();
for (int i = 0; i < coolItems.length; i++) {
dispose(coolItems[i]);
}
}
// Set the internal structure to this order
internalSetItems(newItems);
// Force and update
update(true);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.ICoolBarManager#lockLayout(boolean)
*/
public void setLockLayout(boolean value) {
if (!coolBarExist()) {
return;
}
coolBar.setLocked(value);
}
/**
* Subclasses may extend this <code>IContributionManager</code> method,
* but must call <code>super.update</code>.
*
* @see org.eclipse.jface.action.IContributionManager#update(boolean)
*/
public void update(boolean force) {
if ((!isDirty() && !force) || (!coolBarExist())) {
return;
}
boolean relock = false;
boolean changed = false;
try {
coolBar.setRedraw(false);
// Refresh the widget data with the internal data structure.
refresh();
if (coolBar.getLocked()) {
coolBar.setLocked(false);
relock = true;
}
/*
* Make a list of items including only those items that are
* visible. Separators should stay because they mark line breaks in
* a cool bar.
*/
final IContributionItem[] items = getItems();
final List visibleItems = new ArrayList(items.length);
for (int i = 0; i < items.length; i++) {
final IContributionItem item = items[i];
if (item.isVisible()) {
visibleItems.add(item);
}
}
/*
* Make a list of CoolItem widgets in the cool bar for which there
* is no current visible contribution item. These are the widgets
* to be disposed. Dynamic items are also removed.
*/
CoolItem[] coolItems = coolBar.getItems();
final ArrayList coolItemsToRemove = new ArrayList(coolItems.length);
for (int i = 0; i < coolItems.length; i++) {
final Object data = coolItems[i].getData();
if ((data == null)
|| (!visibleItems.contains(data))
|| ((data instanceof IContributionItem) && ((IContributionItem) data)
.isDynamic())) {
coolItemsToRemove.add(coolItems[i]);
}
}
// Dispose of any items in the list to be removed.
for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) {
CoolItem coolItem = (CoolItem) coolItemsToRemove.get(i);
if (!coolItem.isDisposed()) {
Control control = coolItem.getControl();
if (control != null) {
coolItem.setControl(null);
control.dispose();
}
coolItem.dispose();
}
}
// Add any new items by telling them to fill.
coolItems = coolBar.getItems();
IContributionItem sourceItem;
IContributionItem destinationItem;
int sourceIndex = 0;
int destinationIndex = 0;
final Iterator visibleItemItr = visibleItems.iterator();
while (visibleItemItr.hasNext()) {
sourceItem = (IContributionItem) visibleItemItr.next();
// Retrieve the corresponding contribution item from SWT's
// data.
if (sourceIndex < coolItems.length) {
destinationItem = (IContributionItem) coolItems[sourceIndex]
.getData();
} else {
destinationItem = null;
}
// The items match is they are equal or both separators.
if (destinationItem != null) {
if (sourceItem.equals(destinationItem)) {
sourceIndex++;
destinationIndex++;
sourceItem.update();
continue;
} else if ((destinationItem.isSeparator())
&& (sourceItem.isSeparator())) {
coolItems[sourceIndex].setData(sourceItem);
sourceIndex++;
destinationIndex++;
sourceItem.update();
continue;
}
}
// Otherwise, a new item has to be added.
final int start = coolBar.getItemCount();
sourceItem.fill(coolBar, destinationIndex);
final int newItems = coolBar.getItemCount() - start;
for (int i = 0; i < newItems; i++) {
coolBar.getItem(destinationIndex++).setData(sourceItem);
}
changed = true;
}
// Remove any old widgets not accounted for.
for (int i = coolItems.length - 1; i >= sourceIndex; i--) {
final CoolItem item = coolItems[i];
if (!item.isDisposed()) {
Control control = item.getControl();
if (control != null) {
item.setControl(null);
control.dispose();
}
item.dispose();
changed = true;
}
}
// Update wrap indices.
updateWrapIndices();
// Update the sizes.
for (int i = 0; i < items.length; i++) {
IContributionItem item = items[i];
item.update(SIZE);
}
// if the coolBar was previously locked then lock it
if (relock) {
coolBar.setLocked(true);
}
if (changed) {
updateTabOrder();
}
// We are no longer dirty.
setDirty(false);
} finally {
coolBar.setRedraw(true);
}
}
/**
* Sets the tab order of the coolbar to the visual order of its items.
*/
/* package */void updateTabOrder() {
if (coolBar != null) {
CoolItem[] items = coolBar.getItems();
if (items != null) {
ArrayList children = new ArrayList(items.length);
for (int i = 0; i < items.length; i++) {
if ((items[i].getControl() != null)
&& (!items[i].getControl().isDisposed())) {
children.add(items[i].getControl());
}
}
// Convert array
Control[] childrenArray = new Control[0];
childrenArray = (Control[]) children.toArray(childrenArray);
if (childrenArray != null) {
coolBar.setTabList(childrenArray);
}
}
}
}
/**
* Updates the indices at which the cool bar should wrap.
*/
private void updateWrapIndices() {
final IContributionItem[] items = getItems();
final int numRows = getNumRows(items) - 1;
// Generate the list of wrap indices.
final int[] wrapIndices = new int[numRows];
boolean foundSeparator = false;
int j = 0;
CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems();
for (int i = 0; i < items.length; i++) {
IContributionItem item = items[i];
CoolItem coolItem = findCoolItem(coolItems, item);
if (item.isSeparator()) {
foundSeparator = true;
}
if ((!item.isSeparator()) && (!item.isGroupMarker())
&& (item.isVisible()) && (coolItem != null)
&& (foundSeparator)) {
wrapIndices[j] = coolBar.indexOf(coolItem);
j++;
foundSeparator = false;
}
}
/*
* Check to see if these new wrap indices are different than the old
* ones.
*/
final int[] oldIndices = coolBar.getWrapIndices();
boolean shouldUpdate = false;
if (oldIndices.length == wrapIndices.length) {
for (int i = 0; i < oldIndices.length; i++) {
if (oldIndices[i] != wrapIndices[i]) {
shouldUpdate = true;
break;
}
}
} else {
shouldUpdate = true;
}
if (shouldUpdate) {
coolBar.setWrapIndices(wrapIndices);
}
}
}