001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
011: * - bug fix for bug 187189, 182800
012: ******************************************************************************/package org.eclipse.jface.viewers;
013:
014: import org.eclipse.core.runtime.Assert;
015: import org.eclipse.swt.SWT;
016: import org.eclipse.swt.events.DisposeEvent;
017: import org.eclipse.swt.events.DisposeListener;
018: import org.eclipse.swt.graphics.Point;
019: import org.eclipse.swt.widgets.Event;
020: import org.eclipse.swt.widgets.Listener;
021:
022: /**
023: * This class is responsible to provide cell management base features for the
024: * SWT-Controls {@link org.eclipse.swt.widgets.Table} and
025: * {@link org.eclipse.swt.widgets.Tree}.
026: *
027: * @since 3.3
028: *
029: */
030: abstract class SWTFocusCellManager {
031:
032: private CellNavigationStrategy navigationStrategy;
033:
034: private ColumnViewer viewer;
035:
036: private ViewerCell focusCell;
037:
038: private FocusCellHighlighter cellHighlighter;
039:
040: private DisposeListener itemDeletionListener = new DisposeListener() {
041:
042: public void widgetDisposed(DisposeEvent e) {
043: setFocusCell(null);
044: }
045:
046: };
047:
048: /**
049: * @param viewer
050: * @param focusDrawingDelegate
051: * @param navigationDelegate
052: */
053: public SWTFocusCellManager(ColumnViewer viewer,
054: FocusCellHighlighter focusDrawingDelegate,
055: CellNavigationStrategy navigationDelegate) {
056: this .viewer = viewer;
057: this .cellHighlighter = focusDrawingDelegate;
058: this .navigationStrategy = navigationDelegate;
059: hookListener(viewer);
060: }
061:
062: /**
063: * This method is called by the framework to initialize this cell manager.
064: */
065: void init() {
066: this .cellHighlighter.init();
067: this .navigationStrategy.init();
068: }
069:
070: private void handleMouseDown(Event event) {
071: ViewerCell cell = viewer.getCell(new Point(event.x, event.y));
072: if (cell != null) {
073:
074: if (!cell.equals(focusCell)) {
075: setFocusCell(cell);
076: }
077: }
078: }
079:
080: private void handleKeyDown(Event event) {
081: ViewerCell tmp = null;
082:
083: if (navigationStrategy
084: .isCollapseEvent(viewer, focusCell, event)) {
085: navigationStrategy.collapse(viewer, focusCell, event);
086: } else if (navigationStrategy.isExpandEvent(viewer, focusCell,
087: event)) {
088: navigationStrategy.expand(viewer, focusCell, event);
089: } else if (navigationStrategy.isNavigationEvent(viewer, event)) {
090: tmp = navigationStrategy.findSelectedCell(viewer,
091: focusCell, event);
092:
093: if (tmp != null) {
094: if (!tmp.equals(focusCell)) {
095: setFocusCell(tmp);
096: }
097: }
098: }
099:
100: if (navigationStrategy.shouldCancelEvent(viewer, event)) {
101: event.doit = false;
102: }
103: }
104:
105: private void handleSelection(Event event) {
106: if (focusCell != null && focusCell.getItem() != event.item
107: && event.item != null) {
108: ViewerRow row = viewer.getViewerRowFromItem(event.item);
109: Assert
110: .isNotNull(row,
111: "Internal Structure invalid. Row item has no row ViewerRow assigned"); //$NON-NLS-1$
112: ViewerCell tmp = row.getCell(focusCell.getColumnIndex());
113: if (!focusCell.equals(tmp)) {
114: setFocusCell(tmp);
115: }
116: }
117: }
118:
119: private void handleFocusIn(Event event) {
120: if (focusCell == null) {
121: setFocusCell(getInitialFocusCell());
122: }
123: }
124:
125: abstract ViewerCell getInitialFocusCell();
126:
127: private void hookListener(ColumnViewer viewer) {
128: Listener listener = new Listener() {
129:
130: public void handleEvent(Event event) {
131: switch (event.type) {
132: case SWT.MouseDown:
133: handleMouseDown(event);
134: break;
135: case SWT.KeyDown:
136: handleKeyDown(event);
137: break;
138: case SWT.Selection:
139: handleSelection(event);
140: break;
141: case SWT.FocusIn:
142: handleFocusIn(event);
143: break;
144: }
145: }
146: };
147:
148: viewer.getControl().addListener(SWT.MouseDown, listener);
149: viewer.getControl().addListener(SWT.KeyDown, listener);
150: viewer.getControl().addListener(SWT.Selection, listener);
151: viewer
152: .addSelectionChangedListener(new ISelectionChangedListener() {
153:
154: public void selectionChanged(
155: SelectionChangedEvent event) {
156: if (event.selection.isEmpty()) {
157: setFocusCell(null);
158: }
159: }
160:
161: });
162: viewer.getControl().addListener(SWT.FocusIn, listener);
163: }
164:
165: /**
166: * @return the cell with the focus
167: *
168: */
169: public ViewerCell getFocusCell() {
170: return focusCell;
171: }
172:
173: void setFocusCell(ViewerCell focusCell) {
174: ViewerCell oldCell = this .focusCell;
175:
176: if (this .focusCell != null
177: && !this .focusCell.getItem().isDisposed()) {
178: this .focusCell.getItem().removeDisposeListener(
179: itemDeletionListener);
180: }
181:
182: this .focusCell = focusCell;
183:
184: if (this .focusCell != null
185: && !this .focusCell.getItem().isDisposed()) {
186: this .focusCell.getItem().addDisposeListener(
187: itemDeletionListener);
188: }
189:
190: this .cellHighlighter.focusCellChanged(focusCell, oldCell);
191: }
192:
193: ColumnViewer getViewer() {
194: return viewer;
195: }
196: }
|