Bug 206034 [CellEditors] ColumnViewerEditor does not check if the last cell editor listener has cancelled the event
Build ID: I20070621-1340 ColumnViewerEditor.activateCellEditor() notifies all ColumnViewerEditorActivationListeners before activating a cell editor. At each stage of the listener iteration it checks whether the activation event has been cancelled. Given the existence of this check it appears to me that it is expected that listeners might choose to cancel the activation event if they desire. If this is the case then the implementation (shown below) is not fully correct, specifically the last listener might cancel the event but the code never checks this. for (int i = 0; i < ls.length; i++) { if (activationEvent.cancel) { return; } ((ColumnViewerEditorActivationListener) ls[i]).beforeEditorActivated(activationEvent); } Swapping the order of the if block and the listener notification would fix this problem, but you then introduce the problem that the first listener may be notified of cancelled events. As a side note, it seems strange that the activationEvent is only checked if you have listeners. I would have expected a check as one of the first lines in activateCellEditor(). If this was added then you could just swap the if block and the listener notification to close the issue. I am currently working around this issue by adding two copies of the same listener in order to guarantee that any desired cancelling is honoured.
bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerEditor.java
if (isCellEditable(viewer, previousCell)) {
				rv = previousCell;
			} else {
				rv = searchPreviousCell(row, previousCell, originalCell, viewer);
			}
		} else {
			if ((feature & TABBING_CYCLE_IN_ROW) == TABBING_CYCLE_IN_ROW) {
				rv = searchPreviousCell(row, null, originalCell, viewer);
			} 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, null, originalCell, viewer);
				}
			}
		}
		return rv;
	}
	private ViewerCell searchNextCell(ViewerRow row, ViewerCell currentCell,
			ViewerCell originalCell, ColumnViewer viewer) {
		ViewerCell rv = null;
		ViewerCell nextCell;
		if (currentCell != null) {
			nextCell = currentCell.getNeighbor(ViewerCell.RIGHT, true);
		} else {
			nextCell = row.getCell(row.getCreationIndex(0));
		}
		
		if (originalCell.equals(nextCell)) {
			return null;
		}