/** * Copyright (c) 2009 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 - Initial API and implementation */ package org.eclipse.emf.common.ui.celleditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; /** * An abstract base class for implementing table editing where only a single column is editable. * Clicking anywhere on a row or pressing enter when a row is selected edits the editable column. * <p><b>Provisional API.</b> Please do not use it for anything more than experimentation. * @since 2.5 */ public abstract class SingleColumnTableEditor extends BasicTableEditor implements MouseListener, SelectionListener, TraverseListener { protected int editableColumn; // These are used to avoid restarting editing immediately when the user ends editing // by clicking outside of an open editor but within the same item. // protected int editorFocusLostTime; protected TableItem editorFocusLostItem; public SingleColumnTableEditor(Table table) { this(table, table.getColumnCount() - 1); } public SingleColumnTableEditor(Table table, int editableColumn) { super(table); this.editableColumn = editableColumn; table.addMouseListener(this); table.addSelectionListener(this); table.addTraverseListener(this); } @Override public void dispose() { if (table != null) { table.removeMouseListener(this); table.removeSelectionListener(this); table.removeTraverseListener(this); table = null; } editorFocusLostItem = null; } public void widgetSelected(SelectionEvent e) { // Do nothing. } public void widgetDefaultSelected(SelectionEvent e) { TableItem item = getSelection(); if (item != null) { edit(item, editableColumn); } } public void mouseDoubleClick(MouseEvent e) { // Do nothing. } public void mouseDown(MouseEvent e) { if (e.time != editorFocusLostTime) { editorFocusLostItem = null; } // If the table is not full selection style (SWT.FULL_SELECTION), the selection must be updated manually. // TableItem item = getItem(e.x, e.y); if (item != null && item != getSelection()) { table.setSelection(item); } } public void mouseUp(MouseEvent e) { TableItem item = getItem(e.x, e.y); if (item != null && !item.equals(editorFocusLostItem)) { edit(item, editableColumn); } } protected TableItem getItem(int x, int y) { int tableWidth = table.getClientArea().width; TableItem[] items = table.getItems(); for (int row = table.getTopIndex(); row < items.length; row++) { TableItem item = items[row]; Rectangle bounds = item.getBounds(0); bounds.width = tableWidth - bounds.x; if (bounds.contains(x, y)) { return item; } } return null; } // Prevent return press from escaping to the table's container. // public void keyTraversed(TraverseEvent e) { if (e.detail == SWT.TRAVERSE_RETURN) { e.doit = false; } } @Override protected boolean canEdit(TableItem item, int column) { return column == editableColumn; } @Override protected Text createTextEditor(final TableItem item, final int column) { final Text text = super.createTextEditor(item, column); text.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { editorFocusLostTime = e.time; editorFocusLostItem = item; } }); return text; } }