blob: 9c8a0e9612be4496471e4e256e8184161d255a07 [file] [log] [blame]
package org.eclipse.ui.internal;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
public class CoolBarLayout {
public Point[] itemSizes = new Point[0];
public int[] itemWrapIndices = new int[0];
// the coolbar contribution items in order of display
// store the item id instead of indexes because the coolbar
// items may change between saving/restoring
ArrayList items = new ArrayList(0);
ArrayList rememberedPositions = new ArrayList();
public CoolBarLayout() {
}
public CoolBarLayout(CoolBar coolBar) {
this();
initialize(coolBar);
}
void initialize(CoolBar coolBar) {
CoolItem[] coolItems = coolBar.getItems();
ArrayList newItems = new ArrayList(coolItems.length);
for (int i = 0; i < coolItems.length; i++) {
CoolBarContributionItem item = (CoolBarContributionItem) coolItems[i].getData();
if (item != null) {
newItems.add(item.getId());
}
}
items = newItems;
itemSizes = coolBar.getItemSizes();
itemWrapIndices = getAdjustedWrapIndices(coolBar.getWrapIndices());
// Save the preferred size as actual size for the last item on a row
int count = coolBar.getItemCount();
int[] lastIndices = coolBar.getWrapIndices();
int n = lastIndices.length;
if (n == 0) {
if (count == 0) lastIndices = new int[0];
else lastIndices = new int[] {count - 1};
} else {
// convert from first item indices to last item indices
for (int i = 0; i < n - 1; ++i) {
lastIndices[i] = lastIndices[i+1] - 1;
}
lastIndices[n - 1] = count - 1;
}
for (int i = 0; i < lastIndices.length; i++) {
int lastIndex = lastIndices[i];
if (lastIndex >= 0 && lastIndex < coolItems.length) {
CoolItem lastItem = coolItems[lastIndex];
itemSizes[lastIndex] = lastItem.getPreferredSize();
}
}
}
public CoolBarLayout(ArrayList items, int[] itemWrapIndices, Point[] itemSizes, ArrayList rememberedPositions) {
this.items = items;
this.itemWrapIndices = itemWrapIndices;
this.itemSizes = itemSizes;
this.rememberedPositions = rememberedPositions;
}
/**
* Return the set of wrap indices that would be a result of adding
* an item at the given itemIndex on the the given row.
*/
int[] wrapsForNewItem(int rowIndex, int itemIndex) {
int[] newWraps = null;
int rowStartIndex = getStartIndexOfRow(rowIndex);
if (itemIndex == rowStartIndex) {
// if itemIndex is the start of the row, we are adding the item
// to the beginning of the row, so adjust the wrap indices
newWraps = new int[itemWrapIndices.length];
System.arraycopy(itemWrapIndices, 0, newWraps, 0, itemWrapIndices.length);
newWraps[rowIndex] = itemIndex;
for (int i = rowIndex + 1; i < newWraps.length; i++) {
newWraps[i]++;
}
}
return newWraps;
}
/**
* Return the set of wrap indices that would be a result of adding
* an item at the given itemIndex on the given new row.
*/
int[] wrapsForNewRow(int rowIndex, int itemIndex) {
int[] newWraps = new int[itemWrapIndices.length + 1];
for (int j = 0; j < rowIndex; j++) {
newWraps[j]=itemWrapIndices[j];
}
newWraps[rowIndex] = itemIndex;
for (int j = rowIndex; j < itemWrapIndices.length; j++) {
newWraps[j+1]=itemWrapIndices[j]+1;
}
return newWraps;
}
/**
* 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.
*/
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;
}
/**
* Return the number of rows in the layout.
*/
int getNumberOfRows() {
return itemWrapIndices.length;
}
/**
*/
int getRowOfIndex(int index) {
int row = -1;
for (row = 0; row < itemWrapIndices.length; row++) {
if (itemWrapIndices[row] > index) break;
}
if (row > 0) row--;
return row;
}
/**
* Return the item index of the first item on the given row.
*/
int getStartIndexOfRow(int rowIndex) {
// return the item index of the first item in the given row
if (rowIndex > itemWrapIndices.length - 1) return -1; // row doesn't exist
return itemWrapIndices[rowIndex];
}
boolean isOnRowAlone(int itemIndex) {
int row = getRowOfIndex(itemIndex);
int rowStart = getStartIndexOfRow(row);
int nextRowStart = getStartIndexOfRow(row + 1);
if (nextRowStart == -1) nextRowStart = rowStart;
return (rowStart == itemIndex) && (nextRowStart - rowStart <= 1);
}
/**
* Return whether or not the items from this layout that are in
* otherLayout are in the same order within the layouts.
*/
/* package */ boolean isDerivativeOf(CoolBarLayout otherLayout) {
// for the items that are in this layout,
// get the indexes of these items in otherLayout
ArrayList indexes = new ArrayList();
for (int i=0; i<this.items.size(); i++) {
String itemId = (String)this.items.get(i);
int index = otherLayout.items.indexOf(itemId);
if (index != -1) indexes.add(new Integer(index));
}
// see if the items that are shared across the two
// layouts are in the same order, if not return
// false
int previous = -1;
for (int i=0; i<indexes.size(); i++) {
int value = ((Integer)indexes.get(i)).intValue();
if (value > previous) {
previous = value;
} else {
return false;
}
}
return true;
}
/**
* Restores the object state in the given memento. Returns whether or not the
* restoration was successful.
*
* @param memento the memento to save the object state in
*/
public boolean restoreState(IMemento memento) {
IMemento [] sizes = memento.getChildren(IWorkbenchConstants.TAG_ITEM_SIZE);
if (sizes == null) return false;
itemSizes = new Point[sizes.length];
for (int i = 0; i < sizes.length; i++) {
IMemento sizeMem = sizes[i];
Integer x = sizeMem.getInteger(IWorkbenchConstants.TAG_X);
if (x == null) return false;
Integer y = sizeMem.getInteger(IWorkbenchConstants.TAG_Y);
if (y == null) return false;
itemSizes[i] = new Point(x.intValue(), y.intValue());
}
IMemento [] wraps = memento.getChildren(IWorkbenchConstants.TAG_ITEM_WRAP_INDEX);
if (wraps == null) return false;
itemWrapIndices = new int[wraps.length];
for (int i = 0; i < wraps.length; i++) {
IMemento wrapMem = wraps[i];
Integer index = wrapMem.getInteger(IWorkbenchConstants.TAG_INDEX);
if (index == null) return false;
itemWrapIndices[i] = index.intValue();
}
IMemento [] savedItems = memento.getChildren(IWorkbenchConstants.TAG_ITEM);
if (savedItems == null) return false;
items = new ArrayList(savedItems.length);
for (int i = 0; i < savedItems.length; i++) {
IMemento savedMem = savedItems[i];
String id = savedMem.getString(IWorkbenchConstants.TAG_ID);
if (id == null) return false;
items.add(id);
}
IMemento [] savedPositions = memento.getChildren(IWorkbenchConstants.TAG_POSITION);
rememberedPositions = new ArrayList(savedPositions.length);
for (int i=0; i < savedPositions.length; i++) {
CoolItemPosition position = new CoolItemPosition();
IMemento savedPos = savedPositions[i];
position.id = savedPos.getString(IWorkbenchConstants.TAG_ID);
if (position.id == null) return false;
Integer pos = savedPos.getInteger(IWorkbenchConstants.TAG_ADDED);
if (pos == null) return false;
int added = pos.intValue();
position.added = added == 1;
position.layout = new CoolBarLayout();
IMemento layoutMemento = savedPos.getChild(IWorkbenchConstants.TAG_LAYOUT);
if (layoutMemento == null) return false;
position.layout.restoreState(layoutMemento);
rememberedPositions.add(position);
}
return true;
}
/**
* Saves the object state in the given memento.
*
* @param memento the memento to save the object state in
*/
public IStatus saveState(IMemento memento) {
for (int i = 0; i < itemSizes.length; i++) {
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ITEM_SIZE);
Point pt = itemSizes[i];
child.putInteger(IWorkbenchConstants.TAG_X, pt.x);
child.putInteger(IWorkbenchConstants.TAG_Y, pt.y);
}
for (int i = 0; i < itemWrapIndices.length; i++) {
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ITEM_WRAP_INDEX);
child.putInteger(IWorkbenchConstants.TAG_INDEX, itemWrapIndices[i]);
}
Iterator iter = items.iterator();
while (iter.hasNext()) {
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ITEM);
String item = (String)iter.next();
child.putString(IWorkbenchConstants.TAG_ID, item);
}
iter = rememberedPositions.iterator();
while (iter.hasNext()) {
IMemento child = memento.createChild(IWorkbenchConstants.TAG_POSITION);
CoolItemPosition position = (CoolItemPosition)iter.next();
child.putString(IWorkbenchConstants.TAG_ID, position.id);
int value = 0;
if (position.added) value = 1;
child.putInteger(IWorkbenchConstants.TAG_ADDED, value);
IMemento layout = child.createChild(IWorkbenchConstants.TAG_LAYOUT);
position.layout.saveState(layout);
}
return new Status(IStatus.OK,PlatformUI.PLUGIN_ID,0,"",null);
}
public String toString() {
StringBuffer buffer = new StringBuffer(20);
buffer.append("items "); //$NON-NLS-1$
for (int i = 0; i < items.size(); i++) {
String item = (String)items.get(i);
buffer.append(item + " ");
}
buffer.append('\n');
buffer.append("item wrap indices "); //$NON-NLS-1$
for (int i = 0; i < itemWrapIndices.length; i++) {
buffer.append(itemWrapIndices[i] + " "); //$NON-NLS-1$
}
buffer.append('\n');
buffer.append("item sizes "); //$NON-NLS-1$
for (int i = 0; i < itemSizes.length; i++) {
buffer.append(itemSizes[i] + " "); //$NON-NLS-1$
}
buffer.append('\n');
return buffer.toString();
}
}