package com.topsun.posclient.sales.ui.menu;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.widgets.Table;
public class TableViewerKeyBoardSupporter
{
protected TableViewer fTableViewer = null;
public TableViewerKeyBoardSupporter(TableViewer tableViewer)
{
fTableViewer = tableViewer;
}
/**
* After the cell editors have been set on tableviewer, this method
* should be called to start giving keyboard support.
*/
public void startSupport()
{
/* add table key listener */
getTable().addKeyListener(new TableKeyListener(this));
/* add table traverse listener */
getTable().addTraverseListener(new TableTraverseListener(this));
/* add table-textcelleditors key and traverse listeners */
CellEditor[] cellEditors = fTableViewer.getCellEditors();
if( cellEditors != null )
{
for(int colIndex=0; colIndex<cellEditors.length; colIndex++)
{
CellEditor cellEditor = cellEditors[colIndex];
if( cellEditor != null )
{
cellEditor.getControl().addKeyListener(new
CellEditorKeyListener(this, cellEditor, colIndex));
cellEditor.getControl().addTraverseListener(new
CellEditorTraverseListener(this, cellEditor, colIndex));
}
}
}
}
protected TableViewer getTableViewer()
{
return fTableViewer;
}
protected Table getTable()
{
return fTableViewer.getTable();
}
protected int nextColumn(int column) {
return (column >= getTable().getColumnCount() - 1) ? 0 : column + 1;
}
protected int prevColumn(int column) {
return (column <= 0) ? getTable().getColumnCount() - 1 : column - 1;
}
protected void editColumnOrNextPossible(final int column)
{
Object selectedElem = getSelectedElement();
if( selectedElem == null )
return;
int nextColumn= column;
do {
fTableViewer.editElement(selectedElem, nextColumn);
if (fTableViewer.isCellEditorActive())
return;
nextColumn = nextColumn(nextColumn);
} while (nextColumn != column);
}
protected void editColumnOrPrevPossible(int column)
{
Object selectedElem = getSelectedElement();
if( selectedElem == null )
return;
int prevColumn= column;
do {
fTableViewer.editElement(selectedElem, prevColumn);
if (fTableViewer.isCellEditorActive())
return;
prevColumn= prevColumn(prevColumn);
} while (prevColumn != column);
}
private Object getSelectedElement() {
IStructuredSelection selection = (IStructuredSelection)fTableViewer.getSelection();
if( selection == null || selection.isEmpty() )
return null;
return selection.getFirstElement();
}
}
class CellEditorKeyListener extends KeyAdapter
{
private TableViewerKeyBoardSupporter fKeyBoardSupporter = null;
private CellEditor fEditor = null;
private int fEditorColumn = -1;
public CellEditorKeyListener(TableViewerKeyBoardSupporter keyBoardSupporter, CellEditor editor, int editorColumn)
{
fKeyBoardSupporter = keyBoardSupporter;
fEditor = editor;
fEditorColumn = editorColumn;
}
public void keyPressed(KeyEvent e) {
if (e.stateMask == SWT.MOD1 || e.stateMask == SWT.MOD2)
{
if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
// allow starting multi-selection even if in edit mode
fEditor.deactivate();
e.doit= false;
return;
}
}
if (e.stateMask != SWT.NONE)
return;
switch (e.keyCode)
{
case SWT.ARROW_DOWN :
e.doit= false;
int nextRow= fKeyBoardSupporter.getTable().getSelectionIndex() + 1;
if (nextRow >= fKeyBoardSupporter.getTable().getItemCount())
break;
fKeyBoardSupporter.getTable().setSelection(nextRow);
fKeyBoardSupporter.editColumnOrPrevPossible(fEditorColumn);
break;
case SWT.ARROW_UP :
e.doit= false;
int prevRow= fKeyBoardSupporter.getTable().getSelectionIndex() - 1;
if (prevRow < 0)
break;
fKeyBoardSupporter.getTable().setSelection(prevRow);
fKeyBoardSupporter.editColumnOrPrevPossible(fEditorColumn);
break;
case SWT.F2 :
e.doit= false;
fEditor.deactivate();
break;
}
}
}
class CellEditorTraverseListener implements TraverseListener
{
private TableViewerKeyBoardSupporter fKeyBoardSupporter = null;
private CellEditor fEditor = null;
private int fEditorColumn = -1;
public CellEditorTraverseListener(TableViewerKeyBoardSupporter keyBoardSupporter, CellEditor editor, int editorColumn)
{
fKeyBoardSupporter = keyBoardSupporter;
fEditor = editor;
fEditorColumn = editorColumn;
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
*/
public void keyTraversed(TraverseEvent e) {
switch (e.detail) {
case SWT.TRAVERSE_TAB_NEXT :
fKeyBoardSupporter.editColumnOrNextPossible(fKeyBoardSupporter.nextColumn(fEditorColumn));
e.detail= SWT.TRAVERSE_NONE;
break;
case SWT.TRAVERSE_TAB_PREVIOUS :
fKeyBoardSupporter.editColumnOrPrevPossible(fKeyBoardSupporter.prevColumn(fEditorColumn));
e.detail= SWT.TRAVERSE_NONE;
break;
case SWT.TRAVERSE_ESCAPE :
fKeyBoardSupporter.getTableViewer().cancelEditing();
e.detail= SWT.TRAVERSE_NONE;
break;
case SWT.TRAVERSE_RETURN :
fEditor.deactivate();
e.detail= SWT.TRAVERSE_NONE;
break;
default :
break;
}
}
}
class TableTraverseListener implements TraverseListener
{
private TableViewerKeyBoardSupporter fKeyBoardSupporter = null;
public TableTraverseListener(TableViewerKeyBoardSupporter keyBoardSupporter)
{
fKeyBoardSupporter = keyBoardSupporter;
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
*/
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_RETURN && e.stateMask == SWT.NONE) {
fKeyBoardSupporter.editColumnOrNextPossible(0);
e.detail= SWT.TRAVERSE_NONE;
}
}
}
class TableKeyListener extends KeyAdapter
{
private TableViewerKeyBoardSupporter fKeyBoardSupporter = null;
public TableKeyListener(TableViewerKeyBoardSupporter keyBoardSupporter)
{
fKeyBoardSupporter = keyBoardSupporter;
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
*/
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
fKeyBoardSupporter.editColumnOrNextPossible(0);
e.doit= false;
}
}
}