blob: de94e18a0f76fded7e4bb138b84d568bb6d28003 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 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> - initial API and implementation
* - bug fix for bug 187189, 182800, 215069
*******************************************************************************/
package org.eclipse.jface.viewers;
import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
/**
* This class is responsible to provide cell management base features for the
* SWT-Controls {@link org.eclipse.swt.widgets.Table} and
* {@link org.eclipse.swt.widgets.Tree}.
*
* @since 3.3
*
*/
abstract class SWTFocusCellManager {
private CellNavigationStrategy navigationStrategy;
private ColumnViewer viewer;
private ViewerCell focusCell;
private FocusCellHighlighter cellHighlighter;
private DisposeListener itemDeletionListener = new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
setFocusCell(null);
}
};
/**
* @param viewer
* @param focusDrawingDelegate
* @param navigationDelegate
*/
public SWTFocusCellManager(ColumnViewer viewer,
FocusCellHighlighter focusDrawingDelegate,
CellNavigationStrategy navigationDelegate) {
this.viewer = viewer;
this.cellHighlighter = focusDrawingDelegate;
this.navigationStrategy = navigationDelegate;
hookListener(viewer);
}
/**
* This method is called by the framework to initialize this cell manager.
*/
void init() {
this.cellHighlighter.init();
this.navigationStrategy.init();
}
private void handleMouseDown(Event event) {
ViewerCell cell = viewer.getCell(new Point(event.x, event.y));
if (cell != null) {
if (!cell.equals(focusCell)) {
setFocusCell(cell);
}
}
}
private void handleKeyDown(Event event) {
ViewerCell tmp = null;
if (navigationStrategy.isCollapseEvent(viewer, focusCell, event)) {
navigationStrategy.collapse(viewer, focusCell, event);
} else if (navigationStrategy.isExpandEvent(viewer, focusCell, event)) {
navigationStrategy.expand(viewer, focusCell, event);
} else if (navigationStrategy.isNavigationEvent(viewer, event)) {
tmp = navigationStrategy.findSelectedCell(viewer, focusCell, event);
if (tmp != null) {
if (!tmp.equals(focusCell)) {
setFocusCell(tmp);
}
}
}
if (navigationStrategy.shouldCancelEvent(viewer, event)) {
event.doit = false;
}
}
private void handleSelection(Event event) {
if ((event.detail & SWT.CHECK) == 0 && focusCell != null && focusCell.getItem() != event.item
&& event.item != null ) {
ViewerRow row = viewer.getViewerRowFromItem(event.item);
Assert
.isNotNull(row,
"Internal Structure invalid. Row item has no row ViewerRow assigned"); //$NON-NLS-1$
ViewerCell tmp = row.getCell(focusCell.getColumnIndex());
if (!focusCell.equals(tmp)) {
setFocusCell(tmp);
}
}
}
private void handleFocusIn(Event event) {
if (focusCell == null) {
setFocusCell(getInitialFocusCell());
}
}
abstract ViewerCell getInitialFocusCell();
private void hookListener(ColumnViewer viewer) {
Listener listener = new Listener() {
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MouseDown:
handleMouseDown(event);
break;
case SWT.KeyDown:
handleKeyDown(event);
break;
case SWT.Selection:
handleSelection(event);
break;
case SWT.FocusIn:
handleFocusIn(event);
break;
}
}
};
viewer.getControl().addListener(SWT.MouseDown, listener);
viewer.getControl().addListener(SWT.KeyDown, listener);
viewer.getControl().addListener(SWT.Selection, listener);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
if( event.selection.isEmpty() ) {
setFocusCell(null);
}
}
});
viewer.getControl().addListener(SWT.FocusIn, listener);
}
/**
* @return the cell with the focus
*
*/
public ViewerCell getFocusCell() {
return focusCell;
}
void setFocusCell(ViewerCell focusCell) {
ViewerCell oldCell = this.focusCell;
if( this.focusCell != null && ! this.focusCell.getItem().isDisposed() ) {
this.focusCell.getItem().removeDisposeListener(itemDeletionListener);
}
this.focusCell = focusCell;
if( this.focusCell != null && ! this.focusCell.getItem().isDisposed() ) {
this.focusCell.getItem().addDisposeListener(itemDeletionListener);
}
this.cellHighlighter.focusCellChanged(focusCell,oldCell);
}
ColumnViewer getViewer() {
return viewer;
}
}