/**
* Copyright (c) 2002-2006 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 - Initial API and implementation
*/
package org.eclipse.emf.edit.ui.celleditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableTree;
import org.eclipse.swt.custom.TableTreeItem;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.celleditor.ExtendedTableTreeEditor;
import org.eclipse.emf.common.ui.viewer.ExtendedTableTreeViewer;
import org.eclipse.emf.common.ui.viewer.ExtendedTableTreeViewer.ExtendedTableTreeItem;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
/**
* This base class for implementing {@link org.eclipse.swt.custom.TableTreeEditor}s that
* delegate to adapters produced by an {@link AdapterFactory}.
* This API is under construction; please do not use it for anything more than experimentation.
* @deprecated
* @see AdapterFactoryTreeEditor
*/
@Deprecated
public class AdapterFactoryTableTreeEditor extends ExtendedTableTreeEditor
{
protected AdapterFactory adapterFactory;
protected AdapterFactoryItemDelegator itemDelegator;
protected TableItem currentTableItem;
protected TableTreeItem currentTableTreeItem;
protected Object currentTableTreeItemData;
protected int currentColumn;
protected Image leftGradient;
protected Image rightGradient;
protected Composite canvas;
protected KeyListener keyListener;
protected PaintListener paintListener;
protected Control activeEditor;
protected boolean isDown;
protected boolean hasDropDown;
protected boolean hasLaunched;
public AdapterFactoryTableTreeEditor(TableTree tableTree, AdapterFactory adapterFactory)
{
super(tableTree);
this.adapterFactory = adapterFactory;
this.itemDelegator = new AdapterFactoryItemDelegator(adapterFactory);
keyListener =
new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent event)
{
if (event.character == ' ')
{
setDown(true);
canvas.update();
setDown(false);
activate();
}
else if (event.character == '\r' || event.character == '\n')
{
setDown(true);
canvas.update();
setDown(false);
activate();
}
else if (event.character == '\033')
{
dismiss();
}
else if (event.keyCode == SWT.ARROW_LEFT)
{
arrowLeft();
}
else if (event.keyCode == SWT.ARROW_RIGHT)
{
arrowRight();
}
else if (event.keyCode == SWT.ARROW_UP)
{
arrowUp();
}
else if (event.keyCode == SWT.ARROW_DOWN)
{
arrowDown();
}
}
};
paintListener =
new PaintListener()
{
public void paintControl(PaintEvent event)
{
AdapterFactoryTableTreeEditor.this.paintControl(event);
}
};
}
public AdapterFactory getAdapterFactory()
{
return adapterFactory;
}
public void setAdapterFactory(AdapterFactory adapterFactory)
{
this.adapterFactory = adapterFactory;
}
public IItemPropertyDescriptor getColumnPropertyDescriptor(Object object, int column)
{
return null;
}
public boolean hasInPlaceEditor(Object object, int column)
{
return column == 0;
}
public boolean hasDropDownEditor(Object object, int column)
{
return column != 0;
}
public Control createDropDownEditor(Composite parent, Object object, int column)
{
return null;
}
public boolean hasLaunchedEditor(Object object, int column)
{
return false;
}
public void createLaunchedEditor(Composite parent, Object object, int column)
{
// Do nothing
}
protected void setDown(boolean isDown)
{
this.isDown = isDown;
canvas.redraw();
}
protected boolean isDown()
{
return isDown;
}
@Override
protected void editItem(TableItem tableItem, TableTreeItem tableTreeItem, int column)
{
if (getEditor() != null)
{
getEditor().dispose();
}
currentTableItem = tableItem;
currentTableTreeItem = tableTreeItem;
currentTableTreeItemData = tableTreeItem.getData();
currentColumn = column;
horizontalAlignment = SWT.LEFT;
grabHorizontal = true;
minimumWidth = Math.max(50, currentTableTreeItem.getBounds(column).width);
hasDropDown = hasDropDownEditor(currentTableTreeItemData, currentColumn);
hasLaunched = !hasDropDown && hasLaunchedEditor(currentTableTreeItemData, currentColumn);
canvas = createComposite();
canvas.addKeyListener(keyListener);
canvas.addPaintListener(paintListener);
canvas.addMouseListener
(new MouseAdapter()
{
@Override
public void mouseDown(MouseEvent event)
{
if (event.button == 1)
{
setDown(true);
}
}
@Override
public void mouseUp(MouseEvent event)
{
if (event.button == 1 && isDown())
{
if (currentColumn == 0 && currentTableTreeItem.getItemCount() > 0)
{
Rectangle imageBounds = adjust(
getImageBounds(currentTableItem, 0),
currentTableItem.getBounds(currentColumn));
if (event.x < imageBounds.x + imageBounds.width + 3)
{
currentTableTreeItem.setExpanded(!currentTableTreeItem.getExpanded());
Event expandEvent = new Event();
expandEvent.item = currentTableTreeItem;
currentTableTreeItem.getParent().notifyListeners(SWT.Expand, expandEvent);
}
else
{
activate();
}
}
else
{
activate();
}
}
setDown(false);
}
});
Listener listener =
new Listener()
{
public void handleEvent(Event event)
{
if (event.type == SWT.Activate)
{
// System.out.println("Activate canvas");
}
else if (event.type == SWT.Deactivate)
{
// apply();
// System.out.println("Deactivate canvas");
}
}
};
canvas.addListener(SWT.Activate, listener);
canvas.addListener(SWT.Deactivate, listener);
setEditor(canvas, currentTableTreeItem, currentColumn);
canvas.setFocus();
}
protected Composite createComposite()
{
return new Canvas(currentTableItem.getParent(), SWT.NULL);
}
protected void activate()
{
Rectangle itemBounds = currentTableItem.getBounds(currentColumn);
int x = 0;
// In column 0, the drop-down is indented past the collapse/expand icon.
//
if (currentColumn == 0)
{
Rectangle imageBounds = adjust(
getImageBounds(currentTableItem, currentColumn), itemBounds);
x += imageBounds.x + imageBounds.width;
}
Point point = currentTableItem.getParent().toDisplay(
new Point(itemBounds.x, itemBounds.y));
final Shell dropDown = new Shell(
currentTableItem.getParent().getShell(), SWT.ON_TOP | SWT.NO_TRIM);
dropDown.setBackground(
dropDown.getDisplay().getSystemColor(SWT.COLOR_BLACK));
dropDown.setBounds(point.x + x, point.y + itemBounds.height, itemBounds.width - x, itemBounds.height * 5);
final Control control =
hasDropDownEditor(currentTableTreeItem.getData(), currentColumn) ?
createDropDownEditor(dropDown, currentTableTreeItem.getData(), currentColumn) :
null;
if (control != null)
{
control.setBounds(1, 1, itemBounds.width - x - 2, itemBounds.height * 5 - 2);
dropDown.setVisible(true);
dropDown.layout();
control.setFocus();
Listener dropDownListener =
new Listener()
{
public void handleEvent(Event e)
{
switch (e.type)
{
case SWT.Close:
{
// System.out.println("Close *");
cancel();
dropDown.dispose();
break;
}
case SWT.Deactivate:
{
// System.out.println("Deactivate *");
apply();
dropDown.dispose();
break;
}
/*
case SWT.Paint:
{
System.out.println("paint");
// draw black rectangle around list
Rectangle listRect = control.getBounds();
Color black = currentTableItem.getParent().getDisplay().getSystemColor(SWT.COLOR_BLACK);
e.gc.setForeground(black);
e.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1);
break;
}
*/
}
}
};
dropDown.addListener(SWT.Close, dropDownListener);
// dropDown.addListener(SWT.Paint, dropDownListener);
dropDown.addListener(SWT.Deactivate, dropDownListener);
control.addMouseListener
(new MouseAdapter()
{
@Override
public void mouseDoubleClick(MouseEvent event)
{
if (event.button == 1)
{
apply();
dropDown.dispose();
}
}
});
control.addKeyListener
(new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent e)
{
if (e.character == ' ' || e.character == '\r' || e.character == '\n')
{
apply();
dropDown.dispose();
}
else if (e.character == '\033')
{
cancel();
dropDown.dispose();
}
}
});
}
else if (hasLaunchedEditor(currentTableTreeItem.getData(), currentColumn))
{
createLaunchedEditor(dropDown, currentTableTreeItem.getData(), currentColumn);
}
activeEditor = control;
}
public void cancel()
{
activeEditor = null;
}
public void apply()
{
activeEditor = null;
if (canvas != null && canvas.isDisposed())
{
canvas.redraw();
}
}
@Override
public void dismiss()
{
if (canvas != null)
{
canvas.dispose();
canvas = null;
super.dismiss();
// setEditor(null, null, -1);
}
}
protected void arrowLeft()
{
if (currentColumn > 0)
{
editItem(currentTableItem, currentTableTreeItem, currentColumn - 1);
}
else
{
if (currentTableTreeItem.getItemCount() > 0)
{
currentTableTreeItem.setExpanded(!currentTableTreeItem.getExpanded());
Event expandEvent = new Event();
expandEvent.item = currentTableTreeItem;
currentTableTreeItem.getParent().notifyListeners(SWT.Expand, expandEvent);
}
}
}
protected void arrowRight()
{
if (currentColumn + 1 < currentTableItem.getParent().getColumnCount())
{
editItem(currentTableItem, currentTableTreeItem, currentColumn + 1);
}
}
protected void arrowUp()
{
int index = currentTableItem.getParent().indexOf(currentTableItem);
if (index > 0)
{
TableItem newTableItem = currentTableItem.getParent().getItem(index - 1);
currentTableItem.getParent().showItem(newTableItem);
currentTableItem.getParent().setSelection(index - 1);
editItem(newTableItem, (TableTreeItem)newTableItem.getData(ExtendedTableTreeViewer.ITEM_ID), currentColumn);
}
}
protected void arrowDown()
{
int index = currentTableItem.getParent().indexOf(currentTableItem);
if (index + 1 < currentTableItem.getParent().getItemCount())
{
TableItem newTableItem = currentTableItem.getParent().getItem(index + 1);
currentTableItem.getParent().showItem(newTableItem);
currentTableItem.getParent().setSelection(index + 1);
editItem(newTableItem, (TableTreeItem)newTableItem.getData(ExtendedTableTreeViewer.ITEM_ID), currentColumn);
}
}
protected static Rectangle adjust(Rectangle bounds, Rectangle baseBounds)
{
bounds.x -= baseBounds.x;
bounds.y -= baseBounds.y;
return bounds;
}
protected static Rectangle getImageBounds(TableItem item, int column)
{
return ExtendedTableTreeViewer.getImageBounds(item, column);
}
protected static void drawImage(GC gc, Image image, Rectangle bounds)
{
Rectangle imageBounds = image.getBounds();
gc.drawImage(image,
imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height,
bounds.x, bounds.y, bounds.width, bounds.height);
}
public void paintControl(PaintEvent event)
{
if (currentTableItem.isDisposed())
{
apply();
dismiss();
TableItem [] tableItems = table.getItems();
for (int i = 0; i < tableItems.length; ++i)
{
TableTreeItem tableTreeItem = (TableTreeItem)tableItems[i].getData(ExtendedTableTreeViewer.ITEM_ID);
if (tableTreeItem.getData() == currentTableTreeItemData)
{
editItem(tableItems[i], tableTreeItem, currentColumn);
}
}
return;
}
Display display = currentTableItem.getDisplay();
Rectangle itemBounds = currentTableItem.getBounds(currentColumn);
String text = currentTableTreeItem.getText(currentColumn);
Image image = currentTableItem.getImage(currentColumn);
Rectangle imageBounds = adjust(
getImageBounds(currentTableItem, currentColumn), itemBounds);
// Get extra icon and bounds for first column of ExtendedTableTreeItem.
//
Image extraImage = null;
Rectangle extraImageBounds = null;
int paddingWidth = 0;
if (currentColumn == 0 &&
currentTableTreeItem instanceof ExtendedTableTreeItem)
{
ExtendedTableTreeItem item = (ExtendedTableTreeItem)currentTableTreeItem;
extraImage = item.getFirstImage();
extraImageBounds = adjust(item.getFirstImageBounds(), itemBounds);
paddingWidth = item.getImagePaddingWidth();
}
// Fill with background.
//
event.gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
event.gc.fillRectangle(event.x, event.y, event.width, event.height);
// Draw the icons.
//
if (image != null) drawImage(event.gc, image, imageBounds);
if (extraImage != null) drawImage(event.gc, extraImage, extraImageBounds);
// Draw the text.
//
if (text != null)
{
// This came from trial and error, yielding decent results on all
// platforms. It should be consistent with activate().
//
int x = paddingWidth == 0 ? 3 : paddingWidth;
x += imageBounds.x + imageBounds.width + 3;
int width = event.gc.stringExtent(text).x;
int height = event.gc.stringExtent(text).y;
int y = height < itemBounds.height ?
(itemBounds.height + 1 - height) / 2 : 0;
event.gc.setForeground(display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
event.gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_SELECTION));
event.gc.fillRectangle(x - 3, 0, width + 8, itemBounds.height);
event.gc.drawString(text, x, y, true);
}
// Draw background of right-side button.
//
int boxX = itemBounds.width - itemBounds.height;
int boxY = itemBounds.height - 1;
if (hasLaunched || hasDropDown)
{
event.gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
event.gc.fillPolygon
(new int []
{
boxX, boxY,
boxX + itemBounds.height - 1, boxY,
boxX + itemBounds.height - 1, 1,
boxX, 1
});
}
// Draw down arrow, offset if dropped.
//
if (hasDropDown)
{
event.gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
int baseX = itemBounds.width - itemBounds.height / 2 - 1;
int baseY = itemBounds.height - itemBounds.height / 2 + 3;
if (isDown())
{
baseX += 1;
baseY += 1;
}
event.gc.fillPolygon
(new int []
{
baseX, baseY,
baseX + 4, baseY - 4,
baseX - 3, baseY - 4
});
}
// Draw ellipses, offset if down.
//
else if (hasLaunched)
{
event.gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
event.gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
int baseY = 0;
if (isDown())
{
baseY += 1;
}
event.gc.drawString("...", itemBounds.width - (itemBounds.height + event.gc.stringExtent("...").x) / 2, baseY);
}
// Draw outline.
//
event.gc.setForeground(display.getSystemColor(SWT.COLOR_DARK_GRAY));
event.gc.drawRectangle(0, 0, itemBounds.width - 1, itemBounds.height - 1);
// Draw 3D effect on right-side button.
//
if (hasLaunched || hasDropDown)
{
if (isDown())
{
event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
event.gc.drawLine(boxX, boxY - 1, boxX, 1);
event.gc.drawLine(boxX, 1, boxX + itemBounds.height - 1, 1);
event.gc.drawLine(boxX + 1, boxY - 1, boxX + itemBounds.height - 1, boxY - 1);
event.gc.drawLine(boxX + itemBounds.height - 1, boxY - 1, boxX + itemBounds.height - 1, 2);
}
else
{
event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
event.gc.drawLine(boxX + 1, boxY - 1, boxX + 1, 2);
event.gc.drawLine(boxX + 1, 2, boxX + itemBounds.height - 2, 2);
event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
event.gc.drawLine(boxX + 1, boxY - 2, boxX + itemBounds.height - 3, boxY - 2);
event.gc.drawLine(boxX + itemBounds.height - 3, boxY - 2, boxX + itemBounds.height - 3, 2);
event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
event.gc.drawLine(boxX, boxY - 1, boxX + itemBounds.height - 2, boxY - 1);
event.gc.drawLine(boxX + itemBounds.height - 2, boxY - 1, boxX + itemBounds.height - 2, 1);
}
}
}
protected Image getLeftGradient()
{
if (leftGradient == null)
{
getGradients();
}
return leftGradient;
}
protected Image getRightGradient()
{
if (rightGradient == null)
{
getGradients();
}
return rightGradient;
}
protected void getGradients()
{
int width = 20;
int height = 10;
Display display = canvas.getDisplay();
leftGradient = new Image(display, width, height);
GC leftGC = new GC(leftGradient);
rightGradient = new Image(display, width, height);
GC rightGC = new GC(rightGradient);
// EATM Color startColor = display.getSystemColor(SWT.COLOR_LIST_SELECTION);
Color startColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
RGB rgb1 = startColor.getRGB();
Color endColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
RGB rgb2 = endColor.getRGB();
for (int k = 0; k < width; k++)
{
int r = rgb1.red + k * (rgb2.red - rgb1.red) / width;
r = (rgb2.red > rgb1.red) ? Math.min(r, rgb2.red) : Math.max(r, rgb2.red);
int g = rgb1.green + k * (rgb2.green - rgb1.green) / width;
g = (rgb2.green > rgb1.green) ? Math.min(g, rgb2.green) : Math.max(g, rgb2.green);
int b = rgb1.blue + k * (rgb2.blue - rgb1.blue) / width;
b = (rgb2.blue > rgb1.blue) ? Math.min(b, rgb2.blue) : Math.max(b, rgb2.blue);
Color color = new Color(display, r, g, b);
leftGC.setBackground(color);
leftGC.fillRectangle(width - k - 1, 0, 1, height);
rightGC.setBackground(color);
rightGC.fillRectangle(k, 0, 1, height);
color.dispose();
}
leftGC.dispose();
rightGC.dispose();
}
}
/*
if (currentTableItem.getParent().getHorizontalBar() != null)
{
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getSelection());
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getMinimum());
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getMaximum());
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getIncrement());
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getThumb());
System.out.println("?? " + currentTableItem.getParent().getHorizontalBar().getPageIncrement());
System.out.println("@@@" + itemBounds);
if (itemBounds.x < currentTableItem.getParent().getHorizontalBar().getSelection())
{
System.out.println(">>");
currentTableItem.getParent().getHorizontalBar().setSelection
(Math.max(currentTableItem.getParent().getHorizontalBar().getMinimum(), itemBounds.x));
currentTableItem.getParent().layout();
}
else if (itemBounds.x + itemBounds.width > currentTableItem.getParent().getHorizontalBar().getSelection() + theTable.getHorizontalBar().getThumb())
{
System.out.println("<<");
currentTableItem.getParent().getHorizontalBar().setSelection(theTable.getHorizontalBar().getMaximum() - theTable.getHorizontalBar().getThumb());
currentTableItem.getParent().layout();
}
}
*/