/******************************************************************************* * Copyright (c) 2004, 2011 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 * yyyymmdd bug Email and other contact information * -------- -------- ----------------------------------------------------------- * 20060505 139918 pmoogk@ca.ibm.com - Peter Moogk * 20110824 355591 kchong@ca.ibm.com - Keith Chong, [Usability] Package to mapping table doesn't handle 'enter' key properly *******************************************************************************/ package org.eclipse.jst.ws.internal.consumption.ui.widgets; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jst.ws.internal.common.ResourceUtils; import org.eclipse.jst.ws.internal.consumption.common.PropertiesResourceFilter; import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages; import org.eclipse.jst.ws.internal.ui.dialog.DialogUtils; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; 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.Image; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.wst.command.internal.env.core.common.StatusUtils; import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor; import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents; public class TableViewerWidget extends SimpleWidgetDataContributor { private int DEFAULT_TABLE_HEIGHT_HINT = 100; private int DEFAULT_COLUMN_WIDTH = 80; public static byte MAP_ONE_TO_ONE = 3; public static byte MAP_MANY_TO_ONE = 1; public static byte MAP_MANY_TO_MANY = 0; private String[] columns_; private TableViewer tableViewer_; private Table table_; private TableEditor editor_; private TableEditorListener tableEditorListener_; private Text text_; private Button import_; private Button add_; private Button remove_; private Composite parent_; private Listener statusListener_; private String message = null; private byte rescriction = MAP_MANY_TO_MANY; private List values_; private Object defaultValue_; private PropertiesResourceFilter filter_ = new PropertiesResourceFilter(); public TableViewerWidget(String[] columns, List initValues, Object defaultValue, byte rescriction) { columns_ = columns; values_ = new ArrayList(); if (initValues != null && initValues.size() > 0) values_.addAll(initValues); defaultValue_ = (defaultValue != null) ? defaultValue : new String(""); this.rescriction = rescriction; } public WidgetDataEvents addControls( Composite parent, Listener statusListener ) { parent_ = parent; statusListener_ = statusListener; Composite composite = new Composite(parent, SWT.NONE); GridLayout gl = new GridLayout(); gl.marginHeight = 0; gl.marginWidth = 0; composite.setLayout(gl); composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); table_ = new Table(composite, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER); GridData gd = new GridData(GridData.FILL_BOTH); gd.heightHint = DEFAULT_TABLE_HEIGHT_HINT; table_.setLayoutData(gd); table_.setHeaderVisible(true); table_.setLinesVisible(true); TableLayout tableLayout = new TableLayout(); int maxWidth = DEFAULT_COLUMN_WIDTH; for (int i = 0; i < columns_.length; i++) { TableColumn tableColumn = new TableColumn(table_, SWT.NONE); tableColumn.setText(columns_[i]); tableColumn.pack(); int tableColumnWidth = Math.max(DEFAULT_COLUMN_WIDTH, tableColumn.getWidth()); maxWidth = Math.max(maxWidth, tableColumnWidth); ColumnWeightData columnData = new ColumnWeightData(tableColumnWidth, tableColumnWidth, true); tableLayout.addColumnData(columnData); } table_.setLayout(tableLayout); // initialize the table editor editor_ = new TableEditor(table_); // The editor must have the same size as the cell and must // not be any smaller than 50 pixels. editor_.horizontalAlignment = SWT.LEFT; editor_.grabHorizontal = true; editor_.minimumWidth = maxWidth; tableEditorListener_ = new TableEditorListener(); table_.addMouseListener(tableEditorListener_); tableViewer_ = new TableViewer(table_); tableViewer_.getControl().addKeyListener( new KeyListener() { public void keyPressed(KeyEvent e) { int asciiDel = (int)e.character; // Del if (asciiDel == 127) handleDeleteKeyPressed(); // Enter or space if (((int)e.character) == 13 || ((int)e.character) == 32) tableEditorListener_.editSelection(); } public void keyReleased(KeyEvent e) { } } ); tableViewer_.setContentProvider(new ListContentProvider()); tableViewer_.setLabelProvider(new ListLabelProvider()); tableViewer_.setInput(values_); tableViewer_.addSelectionChangedListener( new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { enableRemove(true); } } ); Composite buttonComposite = new Composite(composite, SWT.NONE); gl = new GridLayout(); gl.numColumns = 3; gl.makeColumnsEqualWidth = true; buttonComposite.setLayout(gl); buttonComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING)); import_ = new Button(buttonComposite, SWT.PUSH); import_.setText(ConsumptionUIMessages.LABEL_IMPORT); import_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); import_.addSelectionListener( new SelectionListener() { public void widgetSelected(SelectionEvent event) { handleImportButtonSelected(event); } public void widgetDefaultSelected(SelectionEvent event) { } } ); add_ = new Button(buttonComposite, SWT.PUSH); add_.setText(ConsumptionUIMessages.LABEL_ADD); add_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); add_.addSelectionListener( new SelectionListener() { public void widgetSelected(SelectionEvent event) { handleAddButtonSelected(event); } public void widgetDefaultSelected(SelectionEvent event) { } } ); remove_ = new Button(buttonComposite, SWT.PUSH); remove_.setText(ConsumptionUIMessages.LABEL_REMOVE); remove_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); remove_.addSelectionListener( new SelectionListener() { public void widgetSelected(SelectionEvent event) { handleRemoveButtonSelected(event); } public void widgetDefaultSelected(SelectionEvent event) { } } ); enableRemove(false); return this; } private void enableRemove(boolean enabled) { remove_.setEnabled(enabled && !tableViewer_.getSelection().isEmpty()); } private void handleImportButtonSelected(SelectionEvent event) { IResource resource = DialogUtils.browseResources( parent_.getShell(), ResourceUtils.getWorkspaceRoot(), null, filter_ ); if (resource != null && resource instanceof IFile) { try { Properties props = new Properties(); props.load(((IFile)resource).getContents()); Set set = props.entrySet(); java.util.List list = new LinkedList(); Iterator i = set.iterator(); while (i.hasNext()) { Map.Entry me = (Map.Entry)i.next(); String key = (String)me.getKey(); String val = (String)me.getValue(); list.add(new String[] {key,val}); } values_.addAll(list); } catch (Exception e) { // TODO Report some error here. } } refresh(); } private void handleAddButtonSelected(SelectionEvent event) { values_.add(defaultValue_); refresh(); setSelectionAsObject(values_.get(table_.getItemCount()-1)); tableEditorListener_.editSelection(); } private void handleRemoveButtonSelected(SelectionEvent event) { handleDeleteKeyPressed(); } private void handleDeleteKeyPressed() { internalDispose(); ISelection selection = tableViewer_.getSelection(); if (selection != null && !selection.isEmpty() && (selection instanceof IStructuredSelection)) { int selectionIndex = table_.getSelectionIndex(); int selectionCount = table_.getItemCount(); values_.remove(selectionIndex); if (selectionIndex < selectionCount-1) setSelectionAsObject(values_.get(selectionIndex)); else if (selectionCount -2 >= 0) setSelectionAsObject(values_.get(selectionCount-2)); refresh(); } } private void internalRefresh() { // synchronize text field, previously selected table cell and model (inputObject) if (text_ != null) { TableItem oldTableItem = editor_.getItem(); int oldColumnIndex = editor_.getColumn(); if (oldTableItem != null && oldColumnIndex >= 0 && oldColumnIndex < columns_.length) { String oldText = text_.getText(); oldTableItem.setText(oldColumnIndex, oldText); int oldRowIndex = table_.indexOf(oldTableItem); values_.set(oldRowIndex, new String[] {oldTableItem.getText(0), oldTableItem.getText(1)}); } } checkMappingConstraints(); statusListener_.handleEvent( null ); } private void checkMappingConstraints() { HashMap map = new HashMap(); for(int cnt=0; cnt= rectangle.y && y < (rectangle.y + rectangle.height)) return i; } return -1; } private int getSelectedColumn(TableItem tableItem, int x, int y) { for (int i = 0; i < columns_.length; i++) { if (tableItem.getBounds(i).contains(x, y)) return i; } return -1; } private void editSelection(int row, int column) { editRow_ = row; editColumn_ = column; TableItem tableItem = table_.getItem(row); // Setup adapter for the new selection text_ = new Text(table_, SWT.NONE); String text = tableItem.getText(column); text_.setText((text != null) ? text : ""); text_.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { // Esc if (((int)e.character) == 27) cancelSelection(); if (e.character == SWT.CR) { // Handle the carriage return and set the value internalRefresh(); internalDispose(); } } public void keyReleased(KeyEvent e) { } } ); text_.addTraverseListener(new TraverseListener() { public void keyTraversed(TraverseEvent e) { if (e.detail == SWT.TRAVERSE_TAB_NEXT) traverseTabNext(); else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) traverseTabPrevious(); else if (e.detail == SWT.TRAVERSE_RETURN) e.doit = false; } } ); text_.addFocusListener( new FocusAdapter() { public void focusLost(FocusEvent e) { internalRefresh(); } } ); editor_.setEditor(text_, tableItem, column); text_.setFocus(); text_.selectAll(); } protected void traverseTabNext() { internalRefresh(); internalDispose(); if (!(editRow_ == table_.getItems().length-1 && editColumn_ == columns_.length-1)) { if (editColumn_ < columns_.length-1) editColumn_++; else { editColumn_ = 0; editRow_++; table_.select(editRow_); } editSelection(editRow_, editColumn_); } } protected void traverseTabPrevious() { internalRefresh(); internalDispose(); if (!(editRow_ == 0 && editColumn_ == 0)) { if (editColumn_ > 0) editColumn_--; else { editColumn_ = columns_.length-1; editRow_--; table_.select(editRow_); } editSelection(editRow_, editColumn_); } } public void cancelSelection() { internalDispose(); internalRefresh(); } public void editSelection() { int selectedRowIndex = table_.getSelectionIndex(); if (selectedRowIndex != -1 && columns_.length > 0) { // refresh table internalRefresh(); // Clean up any previous editor control internalDispose(); editSelection(selectedRowIndex, 0); } currSelectionIndex_ = selectedRowIndex; } } protected class ListContentProvider implements IStructuredContentProvider { public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { tableViewer_.add(getElements(newInput)); } public Object[] getElements(Object inputElement) { if (inputElement instanceof List) { List list = (List)inputElement; Object[] objects = new Object[list.size()]; for (int i = 0; i < objects.length; i++) objects[i] = list.get(i); return objects; } else return new Object[0]; } } protected class ListLabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { return ((String[])element)[columnIndex]; } public void addListener(ILabelProviderListener listener) { } public void removeListener(ILabelProviderListener listener) { } public boolean isLabelProperty(Object element, String property) { return true; } public void dispose() { } } }