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; } } }