package org.eclipse.nebula.widgets.xviewer.edit;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.nebula.widgets.xviewer.XViewer;
import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
/**
* Adapter to edit cells in the XViewer <br>
* <br>
* To edit your columns the columns must be ExtendedViewerColumns. <br>
* Use the map in the ExtendedViewerColumn class to define the cells
*
* @author Juergen Reichl
*/
public class XViewerEditAdapter {
XViewer xv;
ViewerCell klickedCell;
TreeColumn klickedColumn;
final XViewerControlFactory factory;
final XViewerConverter converter;
/**
* TODO MouseDoubleClick and MouseUp not implemented yet swtEvent - SWT.MouseDoubleClick or SWT.MouseDown or
* SWT.MouseUp
*/
private int swtEvent = 0;
private MyMouseListener mouseListener = null;
public XViewerEditAdapter(XViewerControlFactory factory, XViewerConverter converter) {
this.factory = factory;
this.converter = converter;
this.swtEvent = SWT.MouseDown;
}
public void activate(final XViewer xv) {
this.xv = xv;
mouseListener = new MyMouseListener(swtEvent);
xv.getTree().addMouseListener(mouseListener);
xv.getTree().addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
handleEditEvent(event);
}
});
}
private class MyMouseListener implements MouseListener {
private int swtStyle = 0;
public MyMouseListener(int swtStyle) {
this.swtStyle = swtStyle;
}
@Override
public void mouseDoubleClick(MouseEvent e) {
// not supported yet!
if (swtStyle == SWT.MouseDoubleClick) {
klickedColumn = xv.getColumnUnderMouseClick(new Point(e.x, e.y));
klickedCell = xv.getCell(new Point(e.x, e.y));
}
}
@Override
public void mouseDown(MouseEvent e) {
if (swtStyle == SWT.MouseDown) {
klickedColumn = xv.getColumnUnderMouseClick(new Point(e.x, e.y));
klickedCell = xv.getCell(new Point(e.x, e.y));
}
}
@Override
public void mouseUp(MouseEvent e) {
// not supported yet!
if (swtStyle == SWT.MouseUp) {
klickedColumn = xv.getColumnUnderMouseClick(new Point(e.x, e.y));
klickedCell = xv.getCell(new Point(e.x, e.y));
}
}
}
private void doHandleEvent(Event event) {
handleEditEvent(event);
}
boolean handleEditEvent(Event event) {
if (klickedColumn == null || klickedCell == null) {
return false;
}
final Control c;
try {
XViewerColumn xColumn =
xv.getXViewerFactory().getDefaultXViewerColumn(((XViewerColumn) klickedColumn.getData()).getId());
if (xColumn instanceof ExtendedViewerColumn) {
ExtendedViewerColumn extendedColumn = (ExtendedViewerColumn) xColumn;
CellEditDescriptor ced = extendedColumn.getCellEditDescriptorMap().get(klickedCell.getElement().getClass());
if (ced != null) {
if (ced.getControl() == null) {
return false;
}
if (ced.getAction() != null && !ced.getAction().isEnabled()) {
return false;
}
if (!converter.isValid(ced, klickedCell.getElement())) {
return false;
}
c = factory.createControl(ced, xv);
if (c == null) {
return false;
}
} else {
return false;
}
} else {
return false;
}
if (((TreeItem) event.item) != null) {
Listener myListener = new Listener() {
@Override
public void handleEvent(final Event e) {
switch (e.type) {
case SWT.FocusOut:
// set new value
getInput(c);
c.dispose();
break;
case SWT.Verify:
c.setBounds(klickedCell.getBounds());
break;
case SWT.Traverse:
boolean neighbor = false;
switch (e.detail) {
case SWT.TRAVERSE_RETURN:
// set new value
getInput(c);
//$FALL-THROUGH$
case SWT.TRAVERSE_ESCAPE:
c.dispose();
e.doit = false;
break;
case SWT.TRAVERSE_TAB_NEXT:
getInput(c);
neighbor = getNeighbor(ViewerCell.RIGHT, true);
e.doit = false;
c.dispose();
Event eN = new Event();
eN.type = SWT.Selection;
eN.widget = xv.getTree();
if (neighbor) {
eN.item = klickedCell.getItem();
}
doHandleEvent(eN);
break;
case SWT.TRAVERSE_TAB_PREVIOUS:
getInput(c);
neighbor = getNeighbor(ViewerCell.LEFT, true);
e.doit = false;
c.dispose();
Event eP = new Event();
eP.type = SWT.Selection;
eP.widget = xv.getTree();
if (neighbor) {
eP.item = klickedCell.getItem();
}
doHandleEvent(eP);
break;
}
}
}
};
c.addListener(SWT.FocusOut, myListener);
c.addListener(SWT.Traverse, myListener);
c.addListener(SWT.Verify, myListener);
// set old value
setInput(c);
c.setFocus();
return true;
}
} catch (Exception ex) {
return false;
}
return false;
}
private boolean getNeighbor(int directionMask, boolean sameLevel) {
try {
if (klickedCell == null) {
return false;
}
Point cellPosition = new Point(klickedCell.getBounds().x, klickedCell.getBounds().y);
klickedCell = xv.getCell(cellPosition).getNeighbor(directionMask, sameLevel);
klickedColumn = xv.getColumnUnderMouseClick(new Point(klickedCell.getBounds().x, klickedCell.getBounds().y));
XViewerColumn xColumn =
xv.getXViewerFactory().getDefaultXViewerColumn(((XViewerColumn) klickedColumn.getData()).getId());
if (xColumn instanceof ExtendedViewerColumn) {
ExtendedViewerColumn extendedColumn = (ExtendedViewerColumn) xColumn;
CellEditDescriptor ced = extendedColumn.getCellEditDescriptorMap().get(klickedCell.getElement().getClass());
if (ced == null) {
return getNeighbor(directionMask, sameLevel);
}
if (ced.getControl() == null) {
return getNeighbor(directionMask, sameLevel);
}
} else {
return getNeighbor(directionMask, sameLevel);
}
return true;
} catch (Exception ex) {
return false;
}
}
private static boolean InInput = false;
void getInput(Control c) {
if (InInput) {
return;
}
if (klickedCell == null) {
return;
}
XViewerColumn xCol =
xv.getXViewerFactory().getDefaultXViewerColumn(((XViewerColumn) klickedColumn.getData()).getId());
if (xCol instanceof ExtendedViewerColumn) {
ExtendedViewerColumn extendedCol = (ExtendedViewerColumn) xCol;
CellEditDescriptor ced = extendedCol.getCellEditDescriptorMap().get(klickedCell.getElement().getClass());
if (ced == null || ced.getControl() == null) {
return;
}
InInput = true;
try {
Object toModify = getInputToModify();
Object obj = converter.getInput(c, ced, toModify);
if (obj == null) {
refreshElement(toModify);
} else {
refreshElement(obj);
}
} catch (Exception ex) {
// do nothing
} finally {
InInput = false;
}
}
}
void refreshElement(Object toRefresh) {
xv.refresh(toRefresh);
}
Object getInputToModify() {
return klickedCell.getElement();
}
void setInput(Control c) {
if (klickedCell == null) {
return;
}
boolean fitInCell = true;
XViewerColumn xCol =
xv.getXViewerFactory().getDefaultXViewerColumn(((XViewerColumn) klickedColumn.getData()).getId());
if (xCol instanceof ExtendedViewerColumn) {
ExtendedViewerColumn extendedCol = (ExtendedViewerColumn) xCol;
CellEditDescriptor ced = extendedCol.getCellEditDescriptorMap().get(klickedCell.getElement().getClass());
if (ced == null || ced.getControl() == null) {
return;
}
converter.setInput(c, ced, klickedCell.getElement());
fitInCell = ced.isFitInCell();
}
if (fitInCell) {
c.setBounds(klickedCell.getBounds());
} else {
Rectangle bounds = klickedCell.getBounds();
Point point = c.computeSize(SWT.DEFAULT, SWT.DEFAULT);
bounds.width = point.x;
bounds.height = point.y;
c.setBounds(bounds);
}
}
}