### Eclipse Workspace Patch 1.0 #P org.eclipse.jface Index: src/org/eclipse/jface/viewers/TableViewer.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TableViewer.java,v retrieving revision 1.53 diff -u -r1.53 TableViewer.java --- src/org/eclipse/jface/viewers/TableViewer.java 8 May 2006 20:56:56 -0000 1.53 +++ src/org/eclipse/jface/viewers/TableViewer.java 19 May 2006 17:45:18 -0000 @@ -16,10 +16,16 @@ import java.util.List; import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.editing.ITabulatorTraversingSupport; +import org.eclipse.jface.viewers.editing.AbstractEditableTableColumn; +import org.eclipse.jface.viewers.editing.TabulatorTraversingDelegate; +import org.eclipse.jface.viewers.editing.TabulatorTraversingSupportWrapper; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; @@ -63,8 +69,13 @@ * @see #doFindItem(Object) * @see #internalRefresh(Object, boolean) */ -public class TableViewer extends StructuredViewer { - +public class TableViewer extends StructuredViewer implements ITabulatorTraversingSupport { + private boolean tabediting = false; + + private TabeditingListener tabeditingListener = new TabeditingListener(); + + private TabulatorTraversingDelegate tabeditingDelgate = new TabulatorTraversingDelegate(); + private class VirtualManager{ /** @@ -518,6 +529,7 @@ * Returns the cell editors of this table viewer. * * @return the list of cell editors + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public CellEditor[] getCellEditors() { return tableViewerImpl.getCellEditors(); @@ -527,6 +539,7 @@ * Returns the cell modifier of this table viewer. * * @return the cell modifier + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public ICellModifier getCellModifier() { return tableViewerImpl.getCellModifier(); @@ -538,6 +551,7 @@ * identify the column in a cell modifier. * * @return the list of column properties + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public Object[] getColumnProperties() { return tableViewerImpl.getColumnProperties(); @@ -753,6 +767,10 @@ .getSelection())); fireOpen(new OpenEvent(viewer, viewer.getSelection())); } + + TabeditingListener getTabeditingListener() { + return tabeditingListener; + } }; } @@ -1034,6 +1052,7 @@ * * @param editors * the list of cell editors + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public void setCellEditors(CellEditor[] editors) { tableViewerImpl.setCellEditors(editors); @@ -1044,6 +1063,7 @@ * * @param modifier * the cell modifier + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public void setCellModifier(ICellModifier modifier) { tableViewerImpl.setCellModifier(modifier); @@ -1056,6 +1076,7 @@ * * @param columnProperties * the list of column properties + * @deprecated please use the new interface {@link AbstractEditableTableColumn} */ public void setColumnProperties(String[] columnProperties) { tableViewerImpl.setColumnProperties(columnProperties); @@ -1278,7 +1299,62 @@ provider instanceof ILazyContentProvider); } + /** + * @param tabediting The tabediting to set. + */ + public void setTabulatorTraversalEnabled(boolean tabediting) { + this.tabediting = tabediting; + } + + public boolean isTabulatorTraversalEnabled() { + return tabediting; + } + protected class TabeditingListener implements TraverseListener { + private TabulatorTraversingSupportWrapper wrapper = new TabulatorTraversingSupportWrapper() { + + public void setSelectedRow(int index) { + TableViewer.this.table.setSelection(index); + } + + public int getColumnCount() { + return TableViewer.this.table.getColumnCount(); + } + + public int getCurrentColumnIndex() { + return TableViewer.this.tableEditor.getColumn(); + } + + public int getCurrentRowIndex() { + return TableViewer.this.table.getSelectionIndex(); + } + + public int getRowCount() { + return TableViewer.this.table.getItemCount(); + } + + }; + + public void keyTraversed(TraverseEvent e) { + if( TableViewer.this.tabeditingDelgate != null ) { + TableViewer.this.tabeditingDelgate.focusNewEditor(e, TableViewer.this, wrapper); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.editing.ITabEditingSupport#getTabeditingDelgate() + */ + public TabulatorTraversingDelegate getTabeditingDelgate() { + return this.tabeditingDelgate; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.editing.ITabEditingSupport#setTabeditingDelgate(org.eclipse.jface.viewers.editing.TabEditingDelegate) + */ + public void setTabeditingDelegate(TabulatorTraversingDelegate tabeditingDelgate) { + this.tabeditingDelgate = tabeditingDelgate; + } } Index: src/org/eclipse/jface/viewers/TreeViewer.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeViewer.java,v retrieving revision 1.48 diff -u -r1.48 TreeViewer.java --- src/org/eclipse/jface/viewers/TreeViewer.java 8 May 2006 20:56:57 -0000 1.48 +++ src/org/eclipse/jface/viewers/TreeViewer.java 19 May 2006 17:45:21 -0000 @@ -15,12 +15,18 @@ import java.util.List; import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.editing.ITabulatorTraversingSupport; +import org.eclipse.jface.viewers.editing.TabulatorTraversingDelegate; +import org.eclipse.jface.viewers.editing.TabulatorTraversingSupportWrapper; +import org.eclipse.jface.viewers.editing.AbstractEditableTreeColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.events.TreeListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; @@ -47,8 +53,15 @@ * ITreeContentProvider interface. *

*/ -public class TreeViewer extends AbstractTreeViewer { +public class TreeViewer extends AbstractTreeViewer implements ITabulatorTraversingSupport { + private boolean tabediting = false; + + private TabeditingListener tabeditingListener = new TabeditingListener(); + + private TabulatorTraversingDelegate tabeditingDelgate = new TabulatorTraversingDelegate(); + + /** * TreeColorAndFontCollector is an helper class for color and font support * for trees that support the ITableFontProvider and the @@ -357,6 +370,7 @@ * * @return the list of cell editors * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public CellEditor[] getCellEditors() { return treeViewerImpl.getCellEditors(); @@ -367,6 +381,7 @@ * * @return the cell modifier * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public ICellModifier getCellModifier() { return treeViewerImpl.getCellModifier(); @@ -392,6 +407,7 @@ * * @return the list of column properties * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public Object[] getColumnProperties() { return treeViewerImpl.getColumnProperties(); @@ -558,6 +574,10 @@ .getSelection())); fireOpen(new OpenEvent(viewer, viewer.getSelection())); } + + TabeditingListener getTabeditingListener() { + return tabeditingListener; + } }; } @@ -606,6 +626,7 @@ * @param editors * the list of cell editors * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public void setCellEditors(CellEditor[] editors) { treeViewerImpl.setCellEditors(editors); @@ -617,9 +638,11 @@ * @param modifier * the cell modifier * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public void setCellModifier(ICellModifier modifier) { treeViewerImpl.setCellModifier(modifier); + } /** @@ -630,6 +653,7 @@ * @param columnProperties * the list of column properties * @since 3.1 + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} */ public void setColumnProperties(String[] columnProperties) { treeViewerImpl.setColumnProperties(columnProperties); @@ -985,4 +1009,67 @@ }}); } } + + /** + * @param tabediting The tabediting to set. + */ + public void setTabulatorTraversalEnabled(boolean tabediting) { + this.tabediting = tabediting; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.editing.ITabEditingSupport#isTabediting() + */ + public boolean isTabulatorTraversalEnabled() { + return this.tabediting; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.editing.ITabEditingSupport#getTabeditingDelgate() + */ + public TabulatorTraversingDelegate getTabeditingDelgate() { + return tabeditingDelgate; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.editing.ITabEditingSupport#setTabeditingDelgate(org.eclipse.jface.viewers.editing.TabEditingDelegate) + */ + public void setTabeditingDelegate(TabulatorTraversingDelegate tabeditingDelgate) { + this.tabeditingDelgate = tabeditingDelgate; + } + + protected class TabeditingListener implements TraverseListener { + private TabulatorTraversingSupportWrapper wrapper = new TabulatorTraversingSupportWrapper() { + + public void setSelectedRow(int index) { + TreeItem item = TreeViewer.this.tree.getItem(index); + TreeViewer.this.tree.setSelection(item); + } + + public int getColumnCount() { + return TreeViewer.this.tree.getColumnCount(); + } + + public int getCurrentColumnIndex() { + return TreeViewer.this.treeEditor.getColumn(); + } + + public int getCurrentRowIndex() { + // FIXME TABING FROM ROW TO ROW + return 0; + } + + public int getRowCount() { + // FIXME TABING FROM ROW TO ROW + return 0; + } + + }; + + public void keyTraversed(TraverseEvent e) { + if( TreeViewer.this.tabeditingDelgate != null ) { + TreeViewer.this.tabeditingDelgate.focusNewEditor(e, TreeViewer.this, wrapper); + } + } + } } Index: src/org/eclipse/jface/viewers/TreeEditorImpl.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeEditorImpl.java,v retrieving revision 1.7 diff -u -r1.7 TreeEditorImpl.java --- src/org/eclipse/jface/viewers/TreeEditorImpl.java 8 May 2006 20:56:56 -0000 1.7 +++ src/org/eclipse/jface/viewers/TreeEditorImpl.java 19 May 2006 17:45:19 -0000 @@ -11,6 +11,10 @@ package org.eclipse.jface.viewers; +import org.eclipse.jface.viewers.TreeViewer.TabeditingListener; +import org.eclipse.jface.viewers.editing.IEditableColumn; +import org.eclipse.jface.viewers.editing.IEditableMultiColumn; +import org.eclipse.jface.viewers.editing.ITabulatorTraversingSupport; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; @@ -29,331 +33,433 @@ */ /* package */abstract class TreeEditorImpl { - private CellEditor cellEditor; + private CellEditor cellEditor; - private CellEditor[] cellEditors; + /** + * @deprecated + */ + private CellEditor[] cellEditors; - private ICellModifier cellModifier; + /** + * @deprecated + */ + private ICellModifier cellModifier; - private String[] columnProperties; + /** + * @deprecated + */ + private String[] columnProperties; - private Item treeItem; - - private int columnNumber; - - private ICellEditorListener cellEditorListener; - - private FocusListener focusListener; - - private MouseListener mouseListener; - - private int doubleClickExpirationTime; - - private StructuredViewer viewer; - - TreeEditorImpl(StructuredViewer viewer) { - this.viewer = viewer; - initCellEditorListener(); - } - - /** - * Returns this TreeViewerImpl viewer - * - * @return the viewer - */ - public StructuredViewer getViewer() { - return viewer; - } - - private void activateCellEditor() { - if (cellEditors != null) { - if (cellEditors[columnNumber] != null && cellModifier != null) { - Object element = treeItem.getData(); - String property = columnProperties[columnNumber]; - if (cellModifier.canModify(element, property)) { - cellEditor = cellEditors[columnNumber]; - //tree.showSelection(); - cellEditor.addListener(cellEditorListener); - Object value = cellModifier.getValue(element, property); - cellEditor.setValue(value); - // Tricky flow of control here: - // activate() can trigger callback to cellEditorListener which will clear cellEditor - // so must get control first, but must still call activate() even if there is no control. - final Control control = cellEditor.getControl(); - cellEditor.activate(); - if (control == null) { - return; + private Item treeItem; + + private int columnNumber; + + private ICellEditorListener cellEditorListener; + + private FocusListener focusListener; + + private MouseListener mouseListener; + + private int doubleClickExpirationTime; + + private StructuredViewer viewer; + + TreeEditorImpl(StructuredViewer viewer) { + this.viewer = viewer; + initCellEditorListener(); + } + + /** + * Returns this TreeViewerImpl viewer + * + * @return the viewer + */ + public StructuredViewer getViewer() { + return viewer; + } + + private void activateCellEditor() { + CellEditor editor = getEditor(columnNumber); + + if (editor != null) { + Object element = treeItem.getData(); + + cellEditor = editor; + + if (viewer instanceof ITabulatorTraversingSupport + && ((ITabulatorTraversingSupport) viewer).isTabulatorTraversalEnabled()) { + cellEditor.getControl().addTraverseListener( + getTabeditingListener()); + } + + // tree.showSelection(); + cellEditor.addListener(cellEditorListener); + Object value = getModelValue(element, columnNumber); + cellEditor.setValue(value); + // Tricky flow of control here: + // activate() can trigger callback to cellEditorListener which will + // clear cellEditor + // so must get control first, but must still call activate() even if + // there is no control. + final Control control = cellEditor.getControl(); + cellEditor.activate(); + if (control == null) { + return; + } + setLayoutData(cellEditor.getLayoutData()); + setEditor(control, treeItem, columnNumber); + cellEditor.setFocus(); + if (focusListener == null) { + focusListener = new FocusAdapter() { + public void focusLost(FocusEvent e) { + applyEditorValue(); } - setLayoutData(cellEditor.getLayoutData()); - setEditor(control, treeItem, columnNumber); - cellEditor.setFocus(); - if (focusListener == null) { - focusListener = new FocusAdapter() { - public void focusLost(FocusEvent e) { - applyEditorValue(); - } - }; - } - control.addFocusListener(focusListener); - mouseListener = new MouseAdapter() { - public void mouseDown(MouseEvent e) { - // time wrap? - // check for expiration of doubleClickTime - if (e.time <= doubleClickExpirationTime) { - control.removeMouseListener(mouseListener); - cancelEditing(); - handleDoubleClickEvent(); - } else if (mouseListener != null) { - control.removeMouseListener(mouseListener); - } - } - }; - control.addMouseListener(mouseListener); - } - } - } - } + }; + } + control.addFocusListener(focusListener); + mouseListener = new MouseAdapter() { + public void mouseDown(MouseEvent e) { + // time wrap? + // check for expiration of doubleClickTime + if (e.time <= doubleClickExpirationTime) { + control.removeMouseListener(mouseListener); + cancelEditing(); + handleDoubleClickEvent(); + } else if (mouseListener != null) { + control.removeMouseListener(mouseListener); + } + } + }; + control.addMouseListener(mouseListener); + } + } - /** - * Activate a cell editor for the given mouse position. - */ - private void activateCellEditor(MouseEvent event) { - if (treeItem == null || treeItem.isDisposed()) { - //item no longer exists - return; - } - int columnToEdit; - int columns = getColumnCount(); - if (columns == 0) { - // If no TreeColumn, Tree acts as if it has a single column - // which takes the whole width. - columnToEdit = 0; - } else { - columnToEdit = -1; - for (int i = 0; i < columns; i++) { - Rectangle bounds = getBounds(treeItem, i); - if (bounds.contains(event.x, event.y)) { - columnToEdit = i; - break; - } - } - if (columnToEdit == -1) { - return; - } - } + private CellEditor getEditor(int columnNumber) { + CellEditor editor = null; - columnNumber = columnToEdit; - activateCellEditor(); - } - - /** - * Deactivates the currently active cell editor. - */ - public void applyEditorValue() { - CellEditor c = this.cellEditor; - if (c != null) { - // null out cell editor before calling save - // in case save results in applyEditorValue being re-entered - // see 1GAHI8Z: ITPUI:ALL - How to code event notification when using cell editor ? - this.cellEditor = null; - Item t = this.treeItem; - // don't null out tree item -- same item is still selected - if (t != null && !t.isDisposed()) { - saveEditorValue(c, t); - } - setEditor(null, null, 0); - c.removeListener(cellEditorListener); - Control control = c.getControl(); - if (control != null) { - if (mouseListener != null) { - control.removeMouseListener(mouseListener); - } - if (focusListener != null) { - control.removeFocusListener(focusListener); - } - } - c.deactivate(); - } - } - - /** - * Cancels the active cell editor, without saving the value - * back to the domain model. - */ - public void cancelEditing() { - if (cellEditor != null) { - setEditor(null, null, 0); - cellEditor.removeListener(cellEditorListener); - CellEditor oldEditor = cellEditor; - cellEditor = null; - oldEditor.deactivate(); - } - } - - /** - * Start editing the given element. - * @param element - * @param column - */ - public void editElement(Object element, int column) { - if (cellEditor != null) { + // Ensure compatility with old interface + if (cellEditors != null) { + if (cellEditors[columnNumber] != null && cellModifier != null) { + Object element = treeItem.getData(); + String property = columnProperties[columnNumber]; + + if (cellModifier.canModify(element, property)) { + editor = cellEditors[columnNumber]; + } + } + } else { + if (viewer instanceof TreeViewer) { + org.eclipse.swt.widgets.TreeColumn column = ((TreeViewer) viewer) + .getTree().getColumn(columnNumber); + if (column instanceof IEditableColumn) { + Object element = treeItem.getData(); + editor = ((IEditableColumn) column).getCellEditor(element); + } + } + } + + return editor; + } + + private Object getModelValue(Object element, int columnNumber) { + Object value = null; + if (cellEditors != null) { + if (cellModifier != null) { + String property = columnProperties[columnNumber]; + value = cellModifier.getValue(element, property); + } + } else { + IEditableColumn column = (IEditableColumn) ((TreeViewer) viewer).getTree() + .getColumn(columnNumber); + + if (column instanceof IEditableMultiColumn) { + value = ((IEditableMultiColumn) column).getValue(element, columnNumber); + } else { + value = column.getValue(element); + } + } + + return value; + } + + /** + * Activate a cell editor for the given mouse position. + */ + private void activateCellEditor(MouseEvent event) { + if (treeItem == null || treeItem.isDisposed()) { + // item no longer exists + return; + } + int columnToEdit; + int columns = getColumnCount(); + if (columns == 0) { + // If no TreeColumn, Tree acts as if it has a single column + // which takes the whole width. + columnToEdit = 0; + } else { + columnToEdit = -1; + for (int i = 0; i < columns; i++) { + Rectangle bounds = getBounds(treeItem, i); + if (bounds.contains(event.x, event.y)) { + columnToEdit = i; + break; + } + } + if (columnToEdit == -1) { + return; + } + } + + columnNumber = columnToEdit; + activateCellEditor(); + } + + /** + * Deactivates the currently active cell editor. + */ + public void applyEditorValue() { + CellEditor c = this.cellEditor; + if (c != null) { + + if( viewer instanceof ITabulatorTraversingSupport ) { + c.getControl().removeTraverseListener(getTabeditingListener()); + } + + // null out cell editor before calling save + // in case save results in applyEditorValue being re-entered + // see 1GAHI8Z: ITPUI:ALL - How to code event notification when + // using cell editor ? + this.cellEditor = null; + Item t = this.treeItem; + // don't null out tree item -- same item is still selected + if (t != null && !t.isDisposed()) { + saveEditorValue(c, t); + } + setEditor(null, null, 0); + c.removeListener(cellEditorListener); + Control control = c.getControl(); + if (control != null) { + if (mouseListener != null) { + control.removeMouseListener(mouseListener); + } + if (focusListener != null) { + control.removeFocusListener(focusListener); + } + } + c.deactivate(); + } + } + + /** + * Cancels the active cell editor, without saving the value back to the + * domain model. + */ + public void cancelEditing() { + if (cellEditor != null) { + + if( viewer instanceof ITabulatorTraversingSupport ) { + cellEditor.getControl().removeTraverseListener(getTabeditingListener()); + } + + setEditor(null, null, 0); + cellEditor.removeListener(cellEditorListener); + CellEditor oldEditor = cellEditor; + cellEditor = null; + oldEditor.deactivate(); + } + } + + /** + * Start editing the given element. + * + * @param element + * @param column + */ + public void editElement(Object element, int column) { + if (cellEditor != null) { applyEditorValue(); } - IStructuredSelection structuredSelection; - if(element instanceof TreePath) { - structuredSelection = new TreeSelection((TreePath)element, viewer.getComparer()); - } else { - structuredSelection = new StructuredSelection(element); - } - setSelection(structuredSelection, true); - Item[] selection = getSelection(); - if (selection.length != 1) { + IStructuredSelection structuredSelection; + if (element instanceof TreePath) { + structuredSelection = new TreeSelection((TreePath) element, viewer + .getComparer()); + } else { + structuredSelection = new StructuredSelection(element); + } + setSelection(structuredSelection, true); + Item[] selection = getSelection(); + if (selection.length != 1) { return; } - treeItem = selection[0]; + treeItem = selection[0]; - // Make sure selection is visible - showSelection(); - columnNumber = column; - activateCellEditor(); - - } - - abstract Rectangle getBounds(Item item, int columnNumber); - - /** - * Get the Cell Editors for the receiver. - * @return CellEditor[] - */ - public CellEditor[] getCellEditors() { - return cellEditors; - } - - /** - * Get the cell modifier for the receiver. - * @return ICellModifier - */ - public ICellModifier getCellModifier() { - return cellModifier; - } - - abstract int getColumnCount(); - - /** - * Get the column properties for the receiver. - * @return Object[] - */ - public Object[] getColumnProperties() { - return columnProperties; - } - - abstract Item[] getSelection(); - - /** - * Handles the mouse down event; activates the cell editor. - * @param event - */ - public void handleMouseDown(MouseEvent event) { - if (event.button != 1) { + // Make sure selection is visible + showSelection(); + columnNumber = column; + activateCellEditor(); + + } + + abstract Rectangle getBounds(Item item, int columnNumber); + + /** + * Get the Cell Editors for the receiver. + * + * @return CellEditor[] + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public CellEditor[] getCellEditors() { + return cellEditors; + } + + /** + * Get the cell modifier for the receiver. + * + * @return ICellModifier + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public ICellModifier getCellModifier() { + return cellModifier; + } + + abstract int getColumnCount(); + + /** + * Get the column properties for the receiver. + * + * @return Object[] + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public Object[] getColumnProperties() { + return columnProperties; + } + + abstract Item[] getSelection(); + + /** + * Handles the mouse down event; activates the cell editor. + * + * @param event + */ + public void handleMouseDown(MouseEvent event) { + if (event.button != 1) { return; } - if (cellEditor != null) { + if (cellEditor != null) { applyEditorValue(); } - // activate the cell editor immediately. If a second mouseDown - // is received prior to the expiration of the doubleClick time then - // the cell editor will be deactivated and a doubleClick event will - // be processed. - // - doubleClickExpirationTime = event.time - + Display.getCurrent().getDoubleClickTime(); - - Item[] items = getSelection(); - // Do not edit if more than one row is selected. - if (items.length != 1) { - treeItem = null; - return; - } - treeItem = items[0]; - activateCellEditor(event); - } - - private void initCellEditorListener() { - cellEditorListener = new ICellEditorListener() { - public void editorValueChanged(boolean oldValidState, - boolean newValidState) { - // Ignore. - } + // activate the cell editor immediately. If a second mouseDown + // is received prior to the expiration of the doubleClick time then + // the cell editor will be deactivated and a doubleClick event will + // be processed. + // + doubleClickExpirationTime = event.time + + Display.getCurrent().getDoubleClickTime(); + + Item[] items = getSelection(); + // Do not edit if more than one row is selected. + if (items.length != 1) { + treeItem = null; + return; + } + treeItem = items[0]; + activateCellEditor(event); + } + + private void initCellEditorListener() { + cellEditorListener = new ICellEditorListener() { + public void editorValueChanged(boolean oldValidState, + boolean newValidState) { + // Ignore. + } - public void cancelEditor() { - TreeEditorImpl.this.cancelEditing(); - } + public void cancelEditor() { + TreeEditorImpl.this.cancelEditing(); + } - public void applyEditorValue() { - TreeEditorImpl.this.applyEditorValue(); + public void applyEditorValue() { + TreeEditorImpl.this.applyEditorValue(); + } + }; + } + + /** + * Return whether or not there is an active cell editor. + * + * @return boolean true if there is an active cell editor; + * otherwise false is returned. + */ + public boolean isCellEditorActive() { + return cellEditor != null; + } + + /** + * Saves the value of the currently active cell editor, by delegating to the + * cell modifier. + */ + private void saveEditorValue(CellEditor cellEditor, Item treeItem) { + if( cellEditors != null ) { + if (cellModifier != null) { + String property = null; + if (columnProperties != null + && columnNumber < columnProperties.length) { + property = columnProperties[columnNumber]; + } + cellModifier.modify(treeItem, property, cellEditor.getValue()); + } + } else { + IEditableColumn column = (IEditableColumn)((TreeViewer)viewer).getTree().getColumn(columnNumber); + if( column instanceof IEditableMultiColumn ) { + ((IEditableMultiColumn)column).setValue(treeItem.getData(),cellEditor.getValue(),columnNumber); + } else { + column.setValue(treeItem.getData(),cellEditor.getValue()); } - }; - } + } + } - /** - * Return whether or not there is an active cell editor. - * @return boolean true if there is an active cell editor; otherwise - * false is returned. - */ - public boolean isCellEditorActive() { - return cellEditor != null; - } - - /** - * Saves the value of the currently active cell editor, - * by delegating to the cell modifier. - */ - private void saveEditorValue(CellEditor cellEditor, Item treeItem) { - if (cellModifier != null) { - String property = null; - if (columnProperties != null - && columnNumber < columnProperties.length) { - property = columnProperties[columnNumber]; - } - cellModifier.modify(treeItem, property, cellEditor.getValue()); - } - } - - /** - * Set the cell editors for the receiver. - * @param editors - */ - public void setCellEditors(CellEditor[] editors) { - this.cellEditors = editors; - } - - /** - * Set the cell modifier for the receiver. - * @param modifier - */ - public void setCellModifier(ICellModifier modifier) { - this.cellModifier = modifier; - } - - /** - * Set the column properties for the receiver. - * @param columnProperties - */ - public void setColumnProperties(String[] columnProperties) { - this.columnProperties = columnProperties; - } - - abstract void setEditor(Control w, Item item, int fColumnNumber); + /** + * Set the cell editors for the receiver. + * + * @param editors + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public void setCellEditors(CellEditor[] editors) { + this.cellEditors = editors; + } + + /** + * Set the cell modifier for the receiver. + * + * @param modifier + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public void setCellModifier(ICellModifier modifier) { + this.cellModifier = modifier; + } + + /** + * Set the column properties for the receiver. + * + * @param columnProperties + * @deprecated please use the new interface {@link AbstractEditableTreeColumn} + */ + public void setColumnProperties(String[] columnProperties) { + this.columnProperties = columnProperties; + } + + abstract void setEditor(Control w, Item item, int fColumnNumber); + + abstract void setLayoutData(CellEditor.LayoutData layoutData); - abstract void setLayoutData(CellEditor.LayoutData layoutData); + abstract void setSelection(IStructuredSelection selection, boolean b); - abstract void setSelection(IStructuredSelection selection, boolean b); + abstract void showSelection(); - abstract void showSelection(); + abstract void handleDoubleClickEvent(); - abstract void handleDoubleClickEvent(); + abstract TabeditingListener getTabeditingListener(); } Index: src/org/eclipse/jface/viewers/TableEditorImpl.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TableEditorImpl.java,v retrieving revision 1.7 diff -u -r1.7 TableEditorImpl.java --- src/org/eclipse/jface/viewers/TableEditorImpl.java 8 May 2006 20:56:57 -0000 1.7 +++ src/org/eclipse/jface/viewers/TableEditorImpl.java 19 May 2006 17:45:14 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jface.viewers; +import org.eclipse.jface.viewers.TableViewer.TabeditingListener; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; @@ -21,6 +22,9 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Item; +import org.eclipse.jface.viewers.editing.IEditableColumn; +import org.eclipse.jface.viewers.editing.ITabulatorTraversingSupport; +import org.eclipse.jface.viewers.editing.IEditableMultiColumn; /** * Internal table viewer implementation. @@ -29,329 +33,438 @@ */ /* package */abstract class TableEditorImpl { - private CellEditor cellEditor; + private CellEditor cellEditor; - private CellEditor[] cellEditors; - - private ICellModifier cellModifier; + /** + * @deprecated + */ + private CellEditor[] cellEditors; + + /** + * @deprecated + */ + private ICellModifier cellModifier; + + /** + * @deprecated + */ + private String[] columnProperties; + + private Item tableItem; + + private int columnNumber; + + private ICellEditorListener cellEditorListener; + + private FocusListener focusListener; + + private MouseListener mouseListener; + + private int doubleClickExpirationTime; + + private StructuredViewer viewer; + + TableEditorImpl(StructuredViewer viewer) { + this.viewer = viewer; + initCellEditorListener(); + } + + /** + * Returns this TableViewerImpl viewer + * + * @return the viewer + */ + public StructuredViewer getViewer() { + return viewer; + } + + private void activateCellEditor() { + + CellEditor editor = getEditor(columnNumber); + + if (editor != null) { + Object element = tableItem.getData(); + cellEditor = editor; + + if( viewer instanceof ITabulatorTraversingSupport && ((ITabulatorTraversingSupport)viewer).isTabulatorTraversalEnabled() ) { + cellEditor.getControl().addTraverseListener(getTabeditingListener()); + } + + // table.showSelection(); + cellEditor.addListener(cellEditorListener); + Object value = getModelValue(element, columnNumber); + cellEditor.setValue(value); + // Tricky flow of control here: + // activate() can trigger callback to cellEditorListener which will + // clear cellEditor + // so must get control first, but must still call activate() even if + // there is no control. + final Control control = cellEditor.getControl(); + cellEditor.activate(); + if (control == null) { + return; + } + setLayoutData(cellEditor.getLayoutData()); + setEditor(control, tableItem, columnNumber); + cellEditor.setFocus(); + if (focusListener == null) { + focusListener = new FocusAdapter() { + public void focusLost(FocusEvent e) { + applyEditorValue(); + } + }; + } + control.addFocusListener(focusListener); + mouseListener = new MouseAdapter() { + public void mouseDown(MouseEvent e) { + // time wrap? + // check for expiration of doubleClickTime + if (e.time <= doubleClickExpirationTime) { + control.removeMouseListener(mouseListener); + cancelEditing(); + handleDoubleClickEvent(); + } else if (mouseListener != null) { + control.removeMouseListener(mouseListener); + } + } + }; + control.addMouseListener(mouseListener); + } + } - private String[] columnProperties; + private CellEditor getEditor(int columnNumber) { + CellEditor editor = null; - private Item tableItem; - - private int columnNumber; - - private ICellEditorListener cellEditorListener; - - private FocusListener focusListener; - - private MouseListener mouseListener; - - private int doubleClickExpirationTime; - - private StructuredViewer viewer; - - TableEditorImpl(StructuredViewer viewer) { - this.viewer = viewer; - initCellEditorListener(); - } - - /** - * Returns this TableViewerImpl viewer - * - * @return the viewer - */ - public StructuredViewer getViewer() { - return viewer; - } - - private void activateCellEditor() { - if (cellEditors != null) { - if (cellEditors[columnNumber] != null && cellModifier != null) { - Object element = tableItem.getData(); - String property = columnProperties[columnNumber]; - if (cellModifier.canModify(element, property)) { - cellEditor = cellEditors[columnNumber]; - //table.showSelection(); - cellEditor.addListener(cellEditorListener); - Object value = cellModifier.getValue(element, property); - cellEditor.setValue(value); - // Tricky flow of control here: - // activate() can trigger callback to cellEditorListener which will clear cellEditor - // so must get control first, but must still call activate() even if there is no control. - final Control control = cellEditor.getControl(); - cellEditor.activate(); - if (control == null) { - return; + // Ensure compatility with old interface + if (cellEditors != null) { + if (cellEditors[columnNumber] != null && cellModifier != null) { + Object element = tableItem.getData(); + String property = columnProperties[columnNumber]; + + if (cellModifier.canModify(element, property)) { + editor = cellEditors[columnNumber]; + } + } + } else { + if( viewer instanceof TableViewer ) { + org.eclipse.swt.widgets.TableColumn column = ((TableViewer)viewer).getTable().getColumn(columnNumber); + if( column instanceof IEditableColumn ) { + Object element = tableItem.getData(); + + if( column instanceof IEditableMultiColumn ) { + IEditableMultiColumn t = (IEditableMultiColumn)column; + + if( t.canEdit(element, columnNumber) ) { + editor = t.getCellEditor(element, columnNumber); + } + } else { + IEditableColumn t = (IEditableColumn)column; + + if( t.canEdit(element)) { + editor = t.getCellEditor(element); + } } - setLayoutData(cellEditor.getLayoutData()); - setEditor(control, tableItem, columnNumber); - cellEditor.setFocus(); - if (focusListener == null) { - focusListener = new FocusAdapter() { - public void focusLost(FocusEvent e) { - applyEditorValue(); - } - }; - } - control.addFocusListener(focusListener); - mouseListener = new MouseAdapter() { - public void mouseDown(MouseEvent e) { - // time wrap? - // check for expiration of doubleClickTime - if (e.time <= doubleClickExpirationTime) { - control.removeMouseListener(mouseListener); - cancelEditing(); - handleDoubleClickEvent(); - } else if (mouseListener != null) { - control.removeMouseListener(mouseListener); - } - } - }; - control.addMouseListener(mouseListener); - } - } - } - } + } + } + } - /** - * Activate a cell editor for the given mouse position. - */ - private void activateCellEditor(MouseEvent event) { - if (tableItem == null || tableItem.isDisposed()) { - //item no longer exists - return; - } - int columnToEdit; - int columns = getColumnCount(); - if (columns == 0) { - // If no TableColumn, Table acts as if it has a single column - // which takes the whole width. - columnToEdit = 0; - } else { - columnToEdit = -1; - for (int i = 0; i < columns; i++) { - Rectangle bounds = getBounds(tableItem, i); - if (bounds.contains(event.x, event.y)) { - columnToEdit = i; - break; - } - } - if (columnToEdit == -1) { - return; - } - } + return editor; + } - columnNumber = columnToEdit; - activateCellEditor(); - } - - /** - * Deactivates the currently active cell editor. - */ - public void applyEditorValue() { - CellEditor c = this.cellEditor; - if (c != null) { - // null out cell editor before calling save - // in case save results in applyEditorValue being re-entered - // see 1GAHI8Z: ITPUI:ALL - How to code event notification when using cell editor ? - this.cellEditor = null; - Item t = this.tableItem; - // don't null out table item -- same item is still selected - if (t != null && !t.isDisposed()) { - saveEditorValue(c, t); - } - setEditor(null, null, 0); - c.removeListener(cellEditorListener); - Control control = c.getControl(); - if (control != null) { - if (mouseListener != null) { - control.removeMouseListener(mouseListener); - } - if (focusListener != null) { - control.removeFocusListener(focusListener); - } + private Object getModelValue(Object element, int columnNumber) { + Object value = null; + if (cellEditors != null ) { + if( cellModifier != null ) { + String property = columnProperties[columnNumber]; + value = cellModifier.getValue(element, property); + } + } else { + IEditableColumn column = (IEditableColumn)((TableViewer)viewer).getTable().getColumn(columnNumber); + + if( column instanceof IEditableMultiColumn ) { + value = ((IEditableMultiColumn)column).getValue(element,columnNumber); + } else { + value = column.getValue(element); } - c.deactivate(); - } - } - - /** - * Cancels the active cell editor, without saving the value - * back to the domain model. - */ - public void cancelEditing() { - if (cellEditor != null) { - setEditor(null, null, 0); - cellEditor.removeListener(cellEditorListener); - CellEditor oldEditor = cellEditor; - cellEditor = null; - oldEditor.deactivate(); - } - } - - /** - * Start editing the given element. - * @param element - * @param column - */ - public void editElement(Object element, int column) { - if (cellEditor != null) { + } + + return value; + } + + /** + * Activate a cell editor for the given mouse position. + */ + private void activateCellEditor(MouseEvent event) { + if (tableItem == null || tableItem.isDisposed()) { + // item no longer exists + return; + } + int columnToEdit; + int columns = getColumnCount(); + if (columns == 0) { + // If no TableColumn, Table acts as if it has a single column + // which takes the whole width. + columnToEdit = 0; + } else { + columnToEdit = -1; + for (int i = 0; i < columns; i++) { + Rectangle bounds = getBounds(tableItem, i); + if (bounds.contains(event.x, event.y)) { + columnToEdit = i; + break; + } + } + if (columnToEdit == -1) { + return; + } + } + + columnNumber = columnToEdit; + activateCellEditor(); + } + + /** + * Deactivates the currently active cell editor. + */ + public void applyEditorValue() { + CellEditor c = this.cellEditor; + if (c != null) { + if( viewer instanceof ITabulatorTraversingSupport ) { + c.getControl().removeTraverseListener(getTabeditingListener()); + } + + // null out cell editor before calling save + // in case save results in applyEditorValue being re-entered + // see 1GAHI8Z: ITPUI:ALL - How to code event notification when + // using cell editor ? + this.cellEditor = null; + Item t = this.tableItem; + // don't null out table item -- same item is still selected + if (t != null && !t.isDisposed()) { + saveEditorValue(c, t); + } + setEditor(null, null, 0); + c.removeListener(cellEditorListener); + Control control = c.getControl(); + if (control != null) { + if (mouseListener != null) { + control.removeMouseListener(mouseListener); + } + if (focusListener != null) { + control.removeFocusListener(focusListener); + } + } + c.deactivate(); + } + } + + /** + * Cancels the active cell editor, without saving the value back to the + * domain model. + */ + public void cancelEditing() { + if (cellEditor != null) { + + if( viewer instanceof ITabulatorTraversingSupport ) { + cellEditor.getControl().removeTraverseListener(getTabeditingListener()); + } + + setEditor(null, null, 0); + cellEditor.removeListener(cellEditorListener); + CellEditor oldEditor = cellEditor; + cellEditor = null; + oldEditor.deactivate(); + } + } + + /** + * Start editing the given element. + * + * @param element + * @param column + */ + public void editElement(Object element, int column) { + if (cellEditor != null) { applyEditorValue(); } - setSelection(new StructuredSelection(element), true); - Item[] selection = getSelection(); - if (selection.length != 1) { + setSelection(new StructuredSelection(element), true); + Item[] selection = getSelection(); + if (selection.length != 1) { return; } - tableItem = selection[0]; + tableItem = selection[0]; - // Make sure selection is visible - showSelection(); - columnNumber = column; - activateCellEditor(); - - } - - abstract Rectangle getBounds(Item item, int columnNumber); - - /** - * Return the array of CellEditors used in the viewer - * @return the cell editors - */ - public CellEditor[] getCellEditors() { - return cellEditors; - } - - /** - * Get the cell modifier - * @return the cell modifier - */ - public ICellModifier getCellModifier() { - return cellModifier; - } - - abstract int getColumnCount(); - - /** - * Return the properties for the column - * @return the array of column properties - */ - public Object[] getColumnProperties() { - return columnProperties; - } - - abstract Item[] getSelection(); - - /** - * Handles the mouse down event; activates the cell editor. - * @param event the mouse event that should be handled - */ - public void handleMouseDown(MouseEvent event) { - if (event.button != 1) { + // Make sure selection is visible + showSelection(); + columnNumber = column; + activateCellEditor(); + + } + + abstract Rectangle getBounds(Item item, int columnNumber); + + /** + * Return the array of CellEditors used in the viewer + * + * @return the cell editors + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public CellEditor[] getCellEditors() { + return cellEditors; + } + + /** + * Get the cell modifier + * + * @return the cell modifier + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public ICellModifier getCellModifier() { + return cellModifier; + } + + abstract int getColumnCount(); + + /** + * Return the properties for the column + * + * @return the array of column properties + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public Object[] getColumnProperties() { + return columnProperties; + } + + abstract Item[] getSelection(); + + /** + * Handles the mouse down event; activates the cell editor. + * + * @param event + * the mouse event that should be handled + */ + public void handleMouseDown(MouseEvent event) { + if (event.button != 1) { return; } - if (cellEditor != null) { + if (cellEditor != null) { applyEditorValue(); } - // activate the cell editor immediately. If a second mouseDown - // is received prior to the expiration of the doubleClick time then - // the cell editor will be deactivated and a doubleClick event will - // be processed. - // - doubleClickExpirationTime = event.time - + Display.getCurrent().getDoubleClickTime(); - - Item[] items = getSelection(); - // Do not edit if more than one row is selected. - if (items.length != 1) { - tableItem = null; - return; - } - tableItem = items[0]; - activateCellEditor(event); - } - - private void initCellEditorListener() { - cellEditorListener = new ICellEditorListener() { - public void editorValueChanged(boolean oldValidState, - boolean newValidState) { - // Ignore. - } + // activate the cell editor immediately. If a second mouseDown + // is received prior to the expiration of the doubleClick time then + // the cell editor will be deactivated and a doubleClick event will + // be processed. + // + doubleClickExpirationTime = event.time + + Display.getCurrent().getDoubleClickTime(); + + Item[] items = getSelection(); + // Do not edit if more than one row is selected. + if (items.length != 1) { + tableItem = null; + return; + } + tableItem = items[0]; + activateCellEditor(event); + } + + private void initCellEditorListener() { + cellEditorListener = new ICellEditorListener() { + public void editorValueChanged(boolean oldValidState, + boolean newValidState) { + // Ignore. + } - public void cancelEditor() { - TableEditorImpl.this.cancelEditing(); - } + public void cancelEditor() { + TableEditorImpl.this.cancelEditing(); + } - public void applyEditorValue() { - TableEditorImpl.this.applyEditorValue(); - } - }; - } + public void applyEditorValue() { + TableEditorImpl.this.applyEditorValue(); + } + }; + } - /** - * Return whether there is an active cell editor. - * - * @return true if there is an active cell editor; otherwise - * false is returned. - */ - public boolean isCellEditorActive() { - return cellEditor != null; - } - - /** - * Saves the value of the currently active cell editor, - * by delegating to the cell modifier. - */ - private void saveEditorValue(CellEditor cellEditor, Item tableItem) { - if (cellModifier != null) { - if (!cellEditor.isValueValid()) { - ///Do what ??? + /** + * Return whether there is an active cell editor. + * + * @return true if there is an active cell editor; otherwise + * false is returned. + */ + public boolean isCellEditorActive() { + return cellEditor != null; + } + + /** + * Saves the value of the currently active cell editor, by delegating to the + * cell modifier. + */ + private void saveEditorValue(CellEditor cellEditor, Item tableItem) { + if( cellEditors != null ) { + if (cellModifier != null) { + if (!cellEditor.isValueValid()) { + // /Do what ??? + } + String property = null; + if (columnProperties != null + && columnNumber < columnProperties.length) { + property = columnProperties[columnNumber]; + } + cellModifier.modify(tableItem, property, cellEditor.getValue()); + } + } else { + IEditableColumn column = (IEditableColumn)((TableViewer)viewer).getTable().getColumn(columnNumber); + if( column instanceof IEditableMultiColumn ) { + ((IEditableMultiColumn)column).setValue(tableItem.getData(),cellEditor.getValue(),columnNumber); + } else { + column.setValue(tableItem.getData(),cellEditor.getValue()); } - String property = null; - if (columnProperties != null - && columnNumber < columnProperties.length) { - property = columnProperties[columnNumber]; - } - cellModifier.modify(tableItem, property, cellEditor.getValue()); - } - } - - /** - * Set the cell editors - * @param editors - */ - public void setCellEditors(CellEditor[] editors) { - this.cellEditors = editors; - } - - /** - * Set the cell modifier - * @param modifier - */ - public void setCellModifier(ICellModifier modifier) { - this.cellModifier = modifier; - } - - /** - * Set the column properties - * @param columnProperties - */ - public void setColumnProperties(String[] columnProperties) { - this.columnProperties = columnProperties; - } - - abstract void setEditor(Control w, Item item, int fColumnNumber); + } + } + + /** + * Set the cell editors + * + * @param editors + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public void setCellEditors(CellEditor[] editors) { + this.cellEditors = editors; + } + + /** + * Set the cell modifier + * + * @param modifier + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public void setCellModifier(ICellModifier modifier) { + this.cellModifier = modifier; + } + + /** + * Set the column properties + * + * @param columnProperties + * @deprecated please use the new interface {@link AbstractEditableTableColumn} + */ + public void setColumnProperties(String[] columnProperties) { + this.columnProperties = columnProperties; + } + + abstract void setEditor(Control w, Item item, int fColumnNumber); + + abstract void setLayoutData(CellEditor.LayoutData layoutData); - abstract void setLayoutData(CellEditor.LayoutData layoutData); + abstract void setSelection(StructuredSelection selection, boolean b); - abstract void setSelection(StructuredSelection selection, boolean b); + abstract void showSelection(); - abstract void showSelection(); + abstract void handleDoubleClickEvent(); - abstract void handleDoubleClickEvent(); + abstract TabeditingListener getTabeditingListener(); } Index: src/org/eclipse/jface/viewers/TableTreeViewer.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TableTreeViewer.java,v retrieving revision 1.21 diff -u -r1.21 TableTreeViewer.java --- src/org/eclipse/jface/viewers/TableTreeViewer.java 8 May 2006 20:56:57 -0000 1.21 +++ src/org/eclipse/jface/viewers/TableTreeViewer.java 19 May 2006 17:45:15 -0000 @@ -14,6 +14,7 @@ import java.util.List; import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.TableViewer.TabeditingListener; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableTree; import org.eclipse.swt.custom.TableTreeEditor; @@ -107,6 +108,14 @@ fireDoubleClick(new DoubleClickEvent(viewer, viewer.getSelection())); fireOpen(new OpenEvent(viewer, viewer.getSelection())); } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.TableEditorImpl#getTabeditingListener() + */ + TabeditingListener getTabeditingListener() { + // TODO Auto-generated method stub + return null; + } } /** Index: META-INF/MANIFEST.MF =================================================================== RCS file: /home/eclipse/org.eclipse.jface/META-INF/MANIFEST.MF,v retrieving revision 1.19 diff -u -r1.19 MANIFEST.MF --- META-INF/MANIFEST.MF 11 May 2006 03:33:35 -0000 1.19 +++ META-INF/MANIFEST.MF 19 May 2006 17:45:13 -0000 @@ -29,6 +29,7 @@ org.eclipse.jface.util, org.eclipse.jface.viewers, org.eclipse.jface.viewers.deferred, + org.eclipse.jface.viewers.editing, org.eclipse.jface.window, org.eclipse.jface.wizard, org.eclipse.jface.wizard.images Index: src/org/eclipse/jface/viewers/editing/TabulatorTraversingDelegate.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/TabulatorTraversingDelegate.java diff -N src/org/eclipse/jface/viewers/editing/TabulatorTraversingDelegate.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/TabulatorTraversingDelegate.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.TraverseEvent; + +/** + * TableViewer delegates tabulator traversing to the class which implements how + * elements are the next column in the table is selected. You may sub-class this + * class and implement your own selection algorithm. + * + * @author Tom Schindl + * + * @since 3.3 + * @see TableViewer#setTabeditingDelegate(TabEditingDelegate) + * @see TableViewer#setTabulatorTraversalEnabled(boolean) + * + */ +public class TabulatorTraversingDelegate { + private boolean moveToRowNeighbor = false; + + private boolean cycleInRow = false; + + private boolean rowTabing = true; + + private boolean columnTabing = true; + + /** + * This method is called when in the actually active cell-editor a traversal + * event is kicked of by the user. Subclasses may override this method to + * implement their own selection mechanism. + * + * @param e + * the traversal event + * + * @param activeColumn + * the currently active column + * @param totalColumns + * the totla number of columns + * @param activeRow + * the active row + * @param totalRows + * the total number of rows + * @param viewer + * the viewer which support tabing + * @param widgetWrapper + * the swt wigdet wrapped in a helper class + * @return true of a new column is activated + * @since 3.3 + */ + public boolean focusNewEditor(TraverseEvent e, ITabulatorTraversingSupport viewer, + TabulatorTraversingSupportWrapper widgetWrapper) { + // FIXME WHAT TO DO WHEN THE NEXT COLUMN IS NOT EDITABLE/HAS NO FOCUS + + int activeColumn = widgetWrapper.getCurrentColumnIndex(); + int totalColumns = widgetWrapper.getColumnCount(); + int activeRow = widgetWrapper.getCurrentRowIndex(); + int totalRows = widgetWrapper.getRowCount(); + + int editColumn = -1; + + if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { + e.doit = false; + + if ((e.stateMask & SWT.CTRL) == SWT.CTRL && rowTabing) { + if (activeRow > 0) { + widgetWrapper.setSelectedRow(--activeRow); + editColumn = activeColumn; + } + } else if (columnTabing) { + if (activeColumn > 0) { + editColumn = --activeColumn; + } else if (cycleInRow) { + editColumn = totalColumns - 1; + } else if (moveToRowNeighbor) { + if (activeRow > 0) { + widgetWrapper.setSelectedRow(--activeRow); + editColumn = totalColumns - 1; + } + } + } + } else if (e.detail == SWT.TRAVERSE_TAB_NEXT) { + e.doit = false; + + if ((e.stateMask & SWT.CTRL) == SWT.CTRL && rowTabing) { + if (activeRow < totalRows - 1) { + widgetWrapper.setSelectedRow(++activeRow); + editColumn = activeColumn; + } + } else if (columnTabing) { + if (activeColumn < totalColumns - 1) { + editColumn = ++activeColumn; + } else if (cycleInRow) { + editColumn = 0; + } else if (moveToRowNeighbor) { + if (activeRow < totalRows - 1) { + widgetWrapper.setSelectedRow(++activeRow); + editColumn = 0; + } + } + } + } + + if (editColumn >= 0) { + viewer.editElement(((IStructuredSelection) viewer.getSelection()) + .getFirstElement(), editColumn); + return true; + } + + return false; + } + + /** + * @return Returns the columnTabing. + * @since 3.3 + */ + public boolean isColumnTabing() { + return columnTabing; + } + + /** + * Setting this to true the user can move from column to column pressing TAB + * and SHIFT+TAB. This is turned on by default. + * + * @param columnTabing + * The columnTabing to set. + * @since 3.3 + */ + public void setColumnTabing(boolean columnTabing) { + this.columnTabing = columnTabing; + } + + /** + * @return Returns the cycleInRow. + * @since 3.3 + */ + public boolean isCycleInRow() { + return cycleInRow; + } + + /** + * Setting this to true results in the fact that when the end of the row is + * reached the cursor is moved to the first column in the row. This is + * turned of by default. + * + * @param cycleInRow + * The cycleInRow to set. + * @since 3.3 + */ + public void setCycleInRow(boolean cycleInRow) { + this.cycleInRow = cycleInRow; + } + + /** + * Setting this to true results in the fact that when the end of the current + * row is reached the cursor is moved to first/last column in the + * successor/predecessor. This is turned of by default. + * + * @return Returns the moveToRowNeighbor. + * @since 3.3 + */ + public boolean isMoveToRowNeighbor() { + return moveToRowNeighbor; + } + + /** + * @param moveToRowNeighbor + * The moveToRowNeighbor to set. + * @since 3.3 + */ + public void setMoveToRowNeighbor(boolean moveToRowNeighbor) { + this.moveToRowNeighbor = moveToRowNeighbor; + } + + /** + * @return Returns the rowTabing. + * @since 3.3 + */ + public boolean isRowTabing() { + return rowTabing; + } + + /** + * Setting this to true results in the fact that you user can jump from row + * to row using CTRL+TAB/CTRL+SHIFT+TAB. This is turned on by default. + * + * @param rowTabing + * The rowTabing to set. + * @since 3.3 + */ + public void setRowTabing(boolean rowTabing) { + this.rowTabing = rowTabing; + } +} Index: src/org/eclipse/jface/viewers/editing/AbstractEditableTableColumn.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/AbstractEditableTableColumn.java diff -N src/org/eclipse/jface/viewers/editing/AbstractEditableTableColumn.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/AbstractEditableTableColumn.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import java.util.HashMap; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TableViewer; + +/** + * This class represents an editable column in a table. It holds a Mapping + * between Object types from your model and CellEditors used to edit the element + * and is responsible for providing the cell-editor values to the editor and + * restoring the values after editing has finished + * + * @author Tom Schindl + * @since 3.3 + */ +public abstract class AbstractEditableTableColumn extends org.eclipse.swt.widgets.TableColumn implements IEditableColumn { + /** + * The map between object types and cell-editors + */ + private HashMap cellEditors = new HashMap(); + + /** + * Creates a new TableColumn which supports editing + * + * @param viewer + * the viewer the column is child of + * @param style + * the style used for the column + * @since 3.3 + */ + public AbstractEditableTableColumn(TableViewer viewer, int style) { + super(viewer.getTable(), style); + } + + public CellEditor getCellEditor(Object element) { + return (CellEditor) this.cellEditors.get(element.getClass()); + } + + /** + * Add a mapping for the model element class type to your own type + * + * @param elementType + * the element type used + * @param cellEditor + * the cell-editor used to edit this model element + * @since 3.3 + */ + public void addCellEditorMapping(Class elementType, CellEditor cellEditor) { + this.cellEditors.put(elementType, cellEditor); + } + + protected void checkSubclass() { + } + +} Index: src/org/eclipse/jface/viewers/editing/TabulatorTraversingSupportWrapper.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/TabulatorTraversingSupportWrapper.java diff -N src/org/eclipse/jface/viewers/editing/TabulatorTraversingSupportWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/TabulatorTraversingSupportWrapper.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +/** + * This class wraps calls to really objects because they are not accessible + * through an interface because they are done on the concrete SWT-Classes e.g. + * Tree/Table/... + * + * @author Tom Schindl + * @since 3.3 + */ +public abstract class TabulatorTraversingSupportWrapper { + /** + * Set the current selected row + * + * @param index + * the new row index + * @since 3.3 + */ + public abstract void setSelectedRow(int index); + + /** + * @return the total number of columns + * @since 3.3 + */ + public abstract int getColumnCount(); + + /** + * @return the total number of rows + * @since 3.3 + */ + public abstract int getRowCount(); + + /** + * @return the current column index + * @since 3.3 + */ + public abstract int getCurrentColumnIndex(); + + /** + * @return the current row index + * @since 3.3 + */ + public abstract int getCurrentRowIndex(); +} Index: src/org/eclipse/jface/viewers/editing/ITabulatorTraversingSupport.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/ITabulatorTraversingSupport.java diff -N src/org/eclipse/jface/viewers/editing/ITabulatorTraversingSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/ITabulatorTraversingSupport.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import org.eclipse.jface.viewers.ISelection; + +/** + * Viewers who want to provide tabulator traversal features have to implement + * this interface. + * + * @author Tom Schindl + * @since 3.3 + */ +public interface ITabulatorTraversingSupport { + + /** + * @param tabulatorTraversalEnabled + * Turn on/off tab-editing support + * @since 3.3 + */ + public void setTabulatorTraversalEnabled(boolean tabulatorTraversalEnabled); + + /** + * @return is tab-editing turned on + * @since 3.3 + */ + public boolean isTabulatorTraversalEnabled(); + + /** + * Set your own tab-editing delegate + * + * @param tabeditingDelgate + * the new delegate + * @since 3.3 + */ + public void setTabeditingDelegate( + TabulatorTraversingDelegate tabeditingDelgate); + + /** + * @return the tabediting delegate + * @since 3.3 + */ + public TabulatorTraversingDelegate getTabeditingDelgate(); + + /** + * Starts editing the given element. + * + * @param element + * the element + * @param column + * the column number + * @see TableViewer#editElement(Object, int) + * @see AdvancedTreeViewer#editElement(Object, int) + */ + public void editElement(Object element, int column); + + /** + * The StructuredViewer implementation of this method returns + * the result as an IStructuredSelection. + *

+ * Subclasses do not typically override this method, but implement + * getSelectionFromWidget(List) instead. + *

+ * + * @return ISelection + * @see ISelectionProvider#getSelection() + */ + public ISelection getSelection(); +} Index: src/org/eclipse/jface/viewers/editing/IEditableMultiColumn.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/IEditableMultiColumn.java diff -N src/org/eclipse/jface/viewers/editing/IEditableMultiColumn.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/IEditableMultiColumn.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; + +/** + * This interface can be used if there are multiple columns using the same + * editor. The resulting code is very similar to the one found in: + *

    + *
  • {@link ICellModifier#modify(Object, String, Object)}
  • + *
  • {@link ICellModifier#getValue(Object, String)}
  • + *
+ * + * @author Tom Schindl + * @since 3.3 + */ +public interface IEditableMultiColumn extends IEditableColumn { + + /** + * Fetch the cell editor for this model element + * + * @param element + * the model element + * @param columnIndex + * the current column index + * @return the celleditor or null if none is known for this object type + * @since 3.3 + */ + public CellEditor getCellEditor(Object element, int columnIndex); + + /** + * enable/disable editing + * + * @param element + * the model element which should be edited + * @param columnIndex + * the current column index + * @return true if a editor should be displayed + * @since 3.3 + */ + public boolean canEdit(Object element, int columnIndex); + + /** + * fetch the value for the desired column index passed on to the CellEditor + * + * @param element + * the model element + * @param columnIndex + * the column-index + * @return the value for editing + * @see AbstractEditableTableColumn#getValue(Object) + * @see AbstractEditableTreeColumn#getValue(Object) + * @since 3.3 + */ + public abstract Object getValue(Object element, int columnIndex); + + /** + * restore the value from the editor in the model object + * + * @param element + * the model element + * @param value + * the value entered into the cell-editor + * @param columnIndex + * the current column index + * @since 3.3 + */ + public abstract void setValue(Object element, Object value, int columnIndex); +} Index: src/org/eclipse/jface/viewers/editing/IEditableColumn.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/IEditableColumn.java diff -N src/org/eclipse/jface/viewers/editing/IEditableColumn.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/IEditableColumn.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import org.eclipse.jface.viewers.CellEditor; + +/** + * This interface has to be implemented by any editable Column which is added to + * a TreeViewer or a TableViewer + * + * @author Tom Schindl + * @since 3.3 + */ +public interface IEditableColumn { + /** + * Fetch the cell editor for this model element + * + * @param element + * the model element + * @return the celleditor or null if none is known for this object type + * @since 3.3 + */ + public CellEditor getCellEditor(Object element); + + /** + * enable/disable editing + * + * @param element + * the model element which should be edited + * @return true if a editor should be displayed + * @since 3.3 + */ + public boolean canEdit(Object element); + + /** + * @param element + * the model element + * @return the value which is put in the cell-editor when it pops up + * @since 3.3 + */ + public Object getValue(Object element); + + /** + * Restore the value in the model element + * + * @param element + * the model element + * @param value + * the new value from the cell-editor + * @since 3.3 + */ + public void setValue(Object element, Object value); +} Index: src/org/eclipse/jface/viewers/editing/AbstractEditableTreeColumn.java =================================================================== RCS file: src/org/eclipse/jface/viewers/editing/AbstractEditableTreeColumn.java diff -N src/org/eclipse/jface/viewers/editing/AbstractEditableTreeColumn.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/viewers/editing/AbstractEditableTreeColumn.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.jface.viewers.editing; + +import java.util.HashMap; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * This class represents an editable column in a tree. It holds a Mapping + * between Object types from your model and CellEditors used to edit the element + * and is responsible for providing the cell-editor values to the editor and + * restoring the values after editing has finished + * + * @author Tom Schindl + * @since 3.3 + */ +public abstract class AbstractEditableTreeColumn extends org.eclipse.swt.widgets.TreeColumn implements IEditableColumn { + /** + * The map between object types and cell-editors + */ + private HashMap cellEditors = new HashMap(); + + /** + * Creates a new TreeColumn which supports editing + * + * @param parent + * the viewer the column is child of + * @param style + * the style used for the column + * @since 3.3 + */ + public AbstractEditableTreeColumn(TreeViewer parent, int style) { + super(parent.getTree(), style); + } + + public CellEditor getCellEditor(Object element) { + return (CellEditor) this.cellEditors.get(element.getClass()); + } + + /** + * Add a mapping for the model element class type to your own type + * + * @param elementType + * the element type used + * @param cellEditor + * the cell-editor used to edit this model element + * @since 3.3 + */ + public void addCellEditorMapping(Class elementType, CellEditor cellEditor) { + this.cellEditors.put(elementType, cellEditor); + } + + protected void checkSubclass() { + } +}