///*******************************************************************************
// * Copyright (c) 2006, 2007 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
// * Tom Schindl <tom.schindl@bestsolution.at> - refactoring (bug 153993)
// * fix in bug 151295
// * fix in bug 166500
// *******************************************************************************/
//
//package org.eclipse.jface.viewers;
//
//import org.eclipse.core.runtime.ListenerList;
//import org.eclipse.swt.SWT;
//import org.eclipse.swt.events.FocusAdapter;
//import org.eclipse.swt.events.FocusEvent;
//import org.eclipse.swt.events.FocusListener;
//import org.eclipse.swt.events.MouseAdapter;
//import org.eclipse.swt.events.MouseEvent;
//import org.eclipse.swt.events.MouseListener;
//import org.eclipse.swt.events.TraverseEvent;
//import org.eclipse.swt.events.TraverseListener;
//import org.eclipse.swt.widgets.Control;
//import org.eclipse.swt.widgets.Display;
//import org.eclipse.swt.widgets.Item;
//
///**
// * This is the base for all editor implementations of Viewers. ColumnViewer
// * implementators have to subclass this class and implement the missing methods
// *
// * @since 1.0
// * @see TableViewerEditor
// * @see TreeViewerEditor
// */
//public abstract class ColumnViewerEditor {
// private CellEditor cellEditor;
//
// private ICellEditorListener cellEditorListener;
//
// private FocusListener focusListener;
//
// private MouseListener mouseListener;
//
// private ColumnViewer viewer;
//
// private TraverseListener tabeditingListener;
//
// private int activationTime;
//
// private ViewerCell cell;
//
// private ColumnViewerEditorActivationEvent activationEvent;
//
// private ListenerList editorActivationListener;
//
// private ColumnViewerEditorActivationStrategy editorActivationStrategy;
//
// /**
// * Tabbing from cell to cell is turned off
// */
// public static final int DEFAULT = 1;
//
// /**
// * Should if the end of the row is reach started from the start/end of the
// * row below/above
// */
// public static final int TABBING_MOVE_TO_ROW_NEIGHBOR = 1 << 1;
//
// /**
// * Should if the end of the row is reach started from the beginning in the
// * same row
// */
// public static final int TABBING_CYCLE_IN_ROW = 1 << 2;
//
// /**
// * Support tabbing to Cell above/below the current cell
// */
// public static final int TABBING_VERTICAL = 1 << 3;
//
// /**
// * Should tabbing from column to column with in one row be supported
// */
// public static final int TABBING_HORIZONTAL = 1 << 4;
//
// /**
// * Style mask used to enable keyboard activation
// */
// public static final int KEYBOARD_ACTIVATION = 1 << 5;
//
// private int feature;
//
// /**
// * @param viewer
// * the viewer this editor is attached to
// * @param editorActivationStrategy
// * the strategy used to decide about editor activation
// * @param feature
// * bit mask controlling the editor
// * <ul>
// * <li>{@link ColumnViewerEditor#DEFAULT}</li>
// * <li>{@link ColumnViewerEditor#TABBING_CYCLE_IN_ROW}</li>
// * <li>{@link ColumnViewerEditor#TABBING_HORIZONTAL}</li>
// * <li>{@link ColumnViewerEditor#TABBING_MOVE_TO_ROW_NEIGHBOR}</li>
// * <li>{@link ColumnViewerEditor#TABBING_VERTICAL}</li>
// * </ul>
// */
// protected ColumnViewerEditor(ColumnViewer viewer,
// ColumnViewerEditorActivationStrategy editorActivationStrategy,
// int feature) {
// this.viewer = viewer;
// this.editorActivationStrategy = editorActivationStrategy;
// if ((feature & KEYBOARD_ACTIVATION) == KEYBOARD_ACTIVATION) {
// this.editorActivationStrategy
// .setEnableEditorActivationWithKeyboard(true);
// }
// this.feature = feature;
// initCellEditorListener();
// }
//
// private void initCellEditorListener() {
// cellEditorListener = new ICellEditorListener() {
// public void editorValueChanged(boolean oldValidState,
// boolean newValidState) {
// // Ignore.
// }
//
// public void cancelEditor() {
// ColumnViewerEditor.this.cancelEditing();
// }
//
// public void applyEditorValue() {
// ColumnViewerEditor.this.applyEditorValue();
// }
// };
// }
//
// void activateCellEditor() {
//
// ViewerColumn part = viewer.getViewerColumn(cell.getColumnIndex());
// Object element = cell.getElement();
//
// if (part != null && part.getEditingSupport() != null
// && part.getEditingSupport().canEdit(element)) {
//
// cellEditor = part.getEditingSupport().getCellEditor(element);
// if (cellEditor != null) {
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
//
// if (activationEvent.cancel) {
// return;
// }
//
// ((ColumnViewerEditorActivationListener) ls[i])
// .beforeEditorActivated(activationEvent);
// }
// }
//
// updateFocusCell(cell, activationEvent);
//
// cellEditor.addListener(cellEditorListener);
// part.getEditingSupport().initializeCellEditorValue(cellEditor,
// cell);
//
// // 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(activationEvent);
// if (control == null) {
// return;
// }
// setLayoutData(cellEditor.getLayoutData());
// setEditor(control, (Item) cell.getItem(), cell.getColumnIndex());
// cellEditor.setFocus();
//
// if( cellEditor.dependsOnExternalFocusListener() ) {
// 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 <= activationTime) {
// control.removeMouseListener(mouseListener);
// cancelEditing();
// handleDoubleClickEvent();
// } else if (mouseListener != null) {
// control.removeMouseListener(mouseListener);
// }
// }
// };
// control.addMouseListener(mouseListener);
//
// if (tabeditingListener == null) {
// tabeditingListener = new TraverseListener() {
//
// public void keyTraversed(TraverseEvent e) {
// if ((feature & DEFAULT) != DEFAULT) {
// processTraverseEvent(cell.getColumnIndex(),
// viewer.getViewerRowFromItem(cell
// .getItem()), e);
// }
// }
// };
// }
//
// control.addTraverseListener(tabeditingListener);
//
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
// ((ColumnViewerEditorActivationListener) ls[i])
// .afterEditorActivated(activationEvent);
// }
// }
// }
// }
// }
//
// /**
// * Applies the current value and deactivates the currently active cell
// * editor.
// */
// 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 ?
// ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
// cell);
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
//
// ((ColumnViewerEditorActivationListener) ls[i])
// .beforeEditorDeactivated(tmp);
// }
// }
//
// this.cellEditor = null;
// this.activationEvent = null;
// Item t = (Item) this.cell.getItem();
// // don't null out table item -- same item is still selected
// if (t != null && !t.isDisposed()) {
// saveEditorValue(c);
// }
// setEditor(null, null, 0);
// c.removeListener(cellEditorListener);
// Control control = c.getControl();
// if (control != null) {
// if (mouseListener != null) {
// control.removeMouseListener(mouseListener);
// // Clear the instance not needed any more
// mouseListener = null;
// }
// if (focusListener != null) {
// control.removeFocusListener(focusListener);
// }
//
// if (tabeditingListener != null) {
// control.removeTraverseListener(tabeditingListener);
// }
// }
// c.deactivate();
//
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
// ((ColumnViewerEditorActivationListener) ls[i])
// .afterEditorDeactivated(tmp);
// }
// }
// }
// }
//
// /**
// * Cancel editing
// */
// void cancelEditing() {
// if (cellEditor != null) {
// ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
// cell);
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
//
// ((ColumnViewerEditorActivationListener) ls[i])
// .beforeEditorDeactivated(tmp);
// }
// }
//
// setEditor(null, null, 0);
// cellEditor.removeListener(cellEditorListener);
//
// Control control = cellEditor.getControl();
// if (control != null) {
// if (mouseListener != null) {
// control.removeMouseListener(mouseListener);
// // Clear the instance not needed any more
// mouseListener = null;
// }
// if (focusListener != null) {
// control.removeFocusListener(focusListener);
// }
//
// if (tabeditingListener != null) {
// control.removeTraverseListener(tabeditingListener);
// }
// }
//
// CellEditor oldEditor = cellEditor;
// cellEditor = null;
// activationEvent = null;
// oldEditor.deactivate();
//
// if (editorActivationListener != null
// && !editorActivationListener.isEmpty()) {
// Object[] ls = editorActivationListener.getListeners();
// for (int i = 0; i < ls.length; i++) {
// ((ColumnViewerEditorActivationListener) ls[i])
// .afterEditorDeactivated(tmp);
// }
// }
// }
// }
//
// /**
// * Enable the editor by mouse down
// *
// * @param event
// */
// void handleEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
// if (editorActivationStrategy.isEditorActivationEvent(event)) {
// if (cellEditor != null) {
// applyEditorValue();
// }
//
// this.cell = (ViewerCell) event.getSource();
//
// activationEvent = event;
// activationTime = event.time
// + Display.getCurrent().getDoubleClickTime();
//
// activateCellEditor();
// }
// }
//
// private void saveEditorValue(CellEditor cellEditor) {
// ViewerColumn part = viewer.getViewerColumn(cell.getColumnIndex());
//
// if (part != null && part.getEditingSupport() != null) {
// part.getEditingSupport().saveCellEditorValue(cellEditor, cell);
// }
// }
//
// /**
// * Return whether there is an active cell editor.
// *
// * @return <code>true</code> if there is an active cell editor; otherwise
// * <code>false</code> is returned.
// */
// boolean isCellEditorActive() {
// return cellEditor != null;
// }
//
// void handleDoubleClickEvent() {
// viewer.fireDoubleClick(new DoubleClickEvent(viewer, viewer
// .getSelection()));
// viewer.fireOpen(new OpenEvent(viewer, viewer.getSelection()));
// }
//
// /**
// * Adds the given listener, it is to be notified when the cell editor is
// * activated or deactivated.
// *
// * @param listener
// * the listener to add
// */
// public void addEditorActivationListener(
// ColumnViewerEditorActivationListener listener) {
// if (editorActivationListener == null) {
// editorActivationListener = new ListenerList();
// }
// editorActivationListener.add(listener);
// }
//
// /**
// * Removes the given listener.
// *
// * @param listener
// * the listener to remove
// */
// public void removeEditorActivationListener(
// ColumnViewerEditorActivationListener listener) {
// if (editorActivationListener != null) {
// editorActivationListener.remove(listener);
// }
// }
//
// /**
// * Process the traverse event and opens the next available editor depending
// * of the implemented strategy. The default implementation uses the style
// * constants
// * <ul>
// * <li>{@link ColumnViewerEditor#TABBING_MOVE_TO_ROW_NEIGHBOR}</li>
// * <li>{@link ColumnViewerEditor#TABBING_CYCLE_IN_ROW}</li>
// * <li>{@link ColumnViewerEditor#TABBING_VERTICAL}</li>
// * <li>{@link ColumnViewerEditor#TABBING_HORIZONTAL}</li>
// * </ul>
// *
// * <p>
// * Subclasses may overwrite to implement their custom logic to edit the next
// * cell
// * </p>
// *
// * @param columnIndex
// * the index of the current column
// * @param row
// * the current row - may only be used for the duration of this
// * method call
// * @param event
// * the traverse event
// */
// protected void processTraverseEvent(int columnIndex, ViewerRow row,
// TraverseEvent event) {
//
// ViewerCell cell2edit = null;
//
// if (event.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
// event.doit = false;
//
// if ((event.stateMask & SWT.CTRL) == SWT.CTRL
// && (feature & TABBING_VERTICAL) == TABBING_VERTICAL) {
// cell2edit = searchCellAboveBelow(row, viewer, columnIndex, true);
// } else if ((feature & TABBING_HORIZONTAL) == TABBING_HORIZONTAL) {
// cell2edit = searchPreviousCell(row, viewer, columnIndex,
// columnIndex);
// }
// } else if (event.detail == SWT.TRAVERSE_TAB_NEXT) {
// event.doit = false;
//
// if ((event.stateMask & SWT.CTRL) == SWT.CTRL
// && (feature & TABBING_VERTICAL) == TABBING_VERTICAL) {
// cell2edit = searchCellAboveBelow(row, viewer, columnIndex,
// false);
// } else if ((feature & TABBING_HORIZONTAL) == TABBING_HORIZONTAL) {
// cell2edit = searchNextCell(row, viewer, columnIndex,
// columnIndex);
// }
// }
//
// if (cell2edit != null) {
//
// viewer.getControl().setRedraw(false);
// ColumnViewerEditorActivationEvent acEvent = new ColumnViewerEditorActivationEvent(
// cell2edit, event);
// viewer.triggerEditorActivationEvent(acEvent);
// viewer.getControl().setRedraw(true);
// }
// }
//
// private ViewerCell searchCellAboveBelow(ViewerRow row, ColumnViewer viewer,
// int columnIndex, boolean above) {
// ViewerCell rv = null;
//
// ViewerRow newRow = null;
//
// if (above) {
// newRow = row.getNeighbor(ViewerRow.ABOVE, false);
// } else {
// newRow = row.getNeighbor(ViewerRow.BELOW, false);
// }
//
// if (newRow != null) {
// ViewerColumn column = viewer.getViewerColumn(columnIndex);
// if (column != null
// && column.getEditingSupport() != null
// && column.getEditingSupport().canEdit(
// newRow.getItem().getData())) {
// rv = newRow.getCell(columnIndex);
// } else {
// rv = searchCellAboveBelow(newRow, viewer, columnIndex, above);
// }
// }
//
// return rv;
// }
//
// private ViewerCell searchPreviousCell(ViewerRow row, ColumnViewer viewer,
// int columnIndex, int startIndex) {
// ViewerCell rv = null;
//
// if (columnIndex - 1 >= 0) {
// ViewerColumn column = viewer.getViewerColumn(columnIndex - 1);
// if (column != null
// && column.getEditingSupport() != null
// && column.getEditingSupport().canEdit(
// row.getItem().getData())) {
// rv = row.getCell(columnIndex - 1);
// } else {
// rv = searchPreviousCell(row, viewer, columnIndex - 1,
// startIndex);
// }
// } else {
// if ((feature & TABBING_CYCLE_IN_ROW) == TABBING_CYCLE_IN_ROW) {
// // Check that we don't get into endless loop
// if (columnIndex - 1 != startIndex) {
// // Don't subtract -1 from getColumnCount() we need to
// // start in the virtual column
// // next to it
// rv = searchPreviousCell(row, viewer, row.getColumnCount(),
// startIndex);
// }
// } else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) == TABBING_MOVE_TO_ROW_NEIGHBOR) {
// ViewerRow rowAbove = row.getNeighbor(ViewerRow.ABOVE, false);
// if (rowAbove != null) {
// rv = searchPreviousCell(rowAbove, viewer, rowAbove
// .getColumnCount(), startIndex);
// }
// }
// }
//
// return rv;
// }
//
// private ViewerCell searchNextCell(ViewerRow row, ColumnViewer viewer,
// int columnIndex, int startIndex) {
// ViewerCell rv = null;
//
// if (columnIndex + 1 < row.getColumnCount()) {
// ViewerColumn column = viewer.getViewerColumn(columnIndex + 1);
// if (column != null
// && column.getEditingSupport() != null
// && column.getEditingSupport().canEdit(
// row.getItem().getData())) {
// rv = row.getCell(columnIndex + 1);
// } else {
// rv = searchNextCell(row, viewer, columnIndex + 1, startIndex);
// }
// } else {
// if ((feature & TABBING_CYCLE_IN_ROW) == TABBING_CYCLE_IN_ROW) {
// // Check that we don't get into endless loop
// if (columnIndex + 1 != startIndex) {
// // Start from -1 from the virtual column before the
// // first one
// rv = searchNextCell(row, viewer, -1, startIndex);
// }
// } else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) == TABBING_MOVE_TO_ROW_NEIGHBOR) {
// ViewerRow rowBelow = row.getNeighbor(ViewerRow.BELOW, false);
// if (rowBelow != null) {
// rv = searchNextCell(rowBelow, viewer, -1, startIndex);
// }
// }
// }
//
// return rv;
// }
//
// /**
// * Position the editor inside the control
// *
// * @param w
// * the editor control
// * @param item
// * the item (row) in which the editor is drawn in
// * @param fColumnNumber
// * the column number in which the editor is shown
// */
// protected abstract void setEditor(Control w, Item item, int fColumnNumber);
//
// /**
// * set the layout data for the editor
// *
// * @param layoutData
// * the layout data used when editor is displayed
// */
// protected abstract void setLayoutData(CellEditor.LayoutData layoutData);
//
// /**
// * @param focusCell
// * updates the cell with the current input focus
// * @param event
// * the event requesting to update the focusCell
// */
// protected abstract void updateFocusCell(ViewerCell focusCell,
// ColumnViewerEditorActivationEvent event);
//
// /**
// * @return the cell currently holding the focus if no cell has the focus or
// * the viewer implementation doesn't support <code>null</code> is
// * returned
// *
// */
// public ViewerCell getFocusCell() {
// return null;
// }
//
// /**
// * @return the viewer working for
// */
// protected ColumnViewer getViewer() {
// return viewer;
// }
//}